实验环境:


按照图示部署好了K8s集群,一个Master,两个worker nodes。

无状态(stateless)的容器:

在Master上通过yaml文件在worker node上创建pod:

[root@vms201 volume_practice]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: pod1resources: {}ports:- name: httpcontainerPort: 80protocol: TCPhostPort: 80dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

查看此pod运行在哪个worker node上:

[root@vms201 volume_practice]# kubectl get pod pod1 -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP              NODE             NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          3h21m   10.244.58.220   vms202.rhce.cc   <none>           <none>

可以看到运行在vms202.rhce.cc这个worker node上。进入此pod,创建一个文件:

[root@vms201 volume_practice]# kubectl exec -it pod1 -- bash
root@pod1:/# touch aaa.txt

然后再其宿主机vms202.rhce.cc上查看是否存在此文件:

[root@vms202 ~]# find / -name aaa.txt
/var/lib/docker/overlay2/1b1b095a4902ad80c4e83e85163e36050d0a8a78799041602b9787a1f05dddd8/diff/aaa.txt
/var/lib/docker/overlay2/1b1b095a4902ad80c4e83e85163e36050d0a8a78799041602b9787a1f05dddd8/merged/aaa.txt

可以看到,pod内的文件已经被映射到了物理机上。然后再Master上删除此节点:

[root@vms201 volume_practice]# kubectl delete pod pod1
pod "pod1" deleted

紧接着再vms202.rhce.cc上查看是否还有aaa.txt文件:

[root@vms202 ~]# find / -name aaa.txt
[root@vms202 ~]#

可以看到,vms202.rhce.cc上映射出来的aaa.txt文件也被删除了。这样的容器不存储任何数据,被称为无状态(stateless)的容器。如果想要保证容器即使删除,其上的信息也会保留,则用数据卷的方式来完成。

如何定义卷:

定义卷的格式:

volumes:
- name: 卷名类型:卷的参数

在任何容器里引用卷:

volumeMounts:
- name: 卷名mountPath: /目录

一、本地卷

类型:

  1. emptyDir–以内存为介质,不能永久存储;
  2. hostPath–可以永久保存容器信息,类似于docker的volume挂载。

emptyDir测试:

编辑pod文件,设置empty挂载。

apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:terminationGracePeriodSeconds: 0volumes:- name: v1emptyDir: {}containers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}volumeMounts:- name: v1mountPath: /aa# readOnly: true- image: nginximagePullPolicy: IfNotPresentname: c2command: ["sh", "-c", "sleep 1000"]resources: {}volumeMounts:- name: v1mountPath: /aadnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

我们在yaml文件中定义了2个容器,并且都设置了将同一个数据卷挂载上来,这样就实现了两个容器数据的同步。

[root@vms201 volume_practice]# kubectl apply -f pod1.yaml
pod/pod1 created

可以看到,两个容器在worker node vms203.rhce.cc上运行:

[root@vms201 volume_practice]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE             NOMINATED NODE   READINESS GATES
pod1   2/2     Running   0          32s   10.244.185.83   vms203.rhce.cc   <none>           <none>

在vms203.rhce.cc上查看pod中c2的数据卷挂载信息;其中643159dcc94c为容器c2的ID号:

[root@vms203 ~]# docker inspect 643159dcc94c | grep -A10 Mount"Mounts": [{"Type": "bind","Source": "/var/lib/kubelet/pods/fd9e24e8-2b7a-4609-94f3-ed62e5edd2d2/volumes/kubernetes.io~empty-dir/v1","Destination": "/aa","Mode": "","RW": true,"Propagation": "rprivate"},{"Type": "bind",

可以看到Source便是宿主机卷的目录,Destination则是容器挂载的目录。进入宿主机数据卷的目录,创建test.text文件:

[root@vms203 v1]# cd /var/lib/kubelet/pods/fd9e24e8-2b7a-4609-94f3-ed62e5edd2d2/volumes/kubernetes.io~empty-dir/v1
[root@vms203 v1]# touch test.txt

返回到Master上,分别进入查看pod中2个容器被挂载的目录下是否也生成了test.txt文件:

[root@vms201 volume_practice]# kubectl exec -it pod1 -c c1 -- ls /aa
test.txt
[root@vms201 volume_practice]# kubectl exec -it pod1 -c c2 -- ls /aa
test.txt

可以看到,两个容器的/aa目录下都存在了test.txt文件,完成了数据的同步和共享。

hostPath测试:

在master上编辑pod的yaml文件,将在宿主机上设置卷的路径为/test_data,并挂载pod中c1容器的/aa目录下:

[root@vms201 volume_practice]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:terminationGracePeriodSeconds: 0volumes:- name: v1hostPath:path: /test_datacontainers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}volumeMounts:- name: v1mountPath: /aadnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

创建pod并查看其运行的Node:

[root@vms201 volume_practice]# kubectl apply -f pod1.yaml
pod/pod1 created
[root@vms201 volume_practice]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE             NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          24s   10.244.185.86   vms203.rhce.cc   <none>           <none>

进入容器,在/aa下创建文件test.txt:

[root@vms201 volume_practice]# kubectl exec -it pod1 -- bash
root@pod1:/# touch /aa/test.txt

在运行的Node vms203.rhce.cc上的/test_data目录下查看是否也同步了test.txt文件信息:

[root@vms203 /]# ls /test_data/
test.txt

可以看到已经同步了容器中/aa目录下的信息。然后我们在Master上将这个pod删除后,再查看vms203.rhce.cc上存储的数据是否依然存在:

[root@vms201 volume_practice]# kubectl delete pod pod1
pod "pod1" deleted
[root@vms203 /]# ls /test_data/
test.txt

可以看到,即使将此pod删除后,宿主机上依旧保存了以前的数据。所以后续想要恢复容器,只需要保存好此pod的yaml文件,后续通过此yaml文件创建pod时,数据信息自动会同步到容器中来。

hostPath缺陷:如果pod删除重新启动后,调度到了另外一个node上(没有保存之前的数据),那么重新生成的容器数据无法恢复。

二、网络卷

为了解决hostPath的缺陷,可以使用网络卷的形式,没有将本地的目录挂载到容器内,而是将共享磁盘(iscsi、ceph、nfs等)上的目录进行挂载,保证pod即使在不同的node上,也能同步数据。

步骤1:安装NFS

在新的虚拟机上安装NFS,做NFS服务器:

yum -y install nfs-utils

在所有worker node上安装NFS,做NFS客户端:

yum -y install nfs-utils

步骤2: 在NFS服务器上启动NFS服务,并共享目录:

[root@nfs ~]# systemctl start nfs-server.service ; systemctl enable nfs-server.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.[root@nfs ~]# mkdir /aa
[root@nfs ~]# vim /etc/exports
/aa     *(rw,async,no_root_squash)
[root@nfs ~]# exportfs -arv
exporting *:/aa

步骤3: 在worker上测试查看是否能够连接到NFS服务器,并挂载目录
查看NFS服务器上共享的目录

[root@vms202 ~]# showmount -e 192.168.0.205
Export list for 192.168.0.205:
/aa *

挂载本地目录:

[root@vms202 ~]# mount 192.168.0.205:/aa /mnt
[root@vms202 ~]# umount /mnt

步骤4: 在master上创建pod,设置卷为NFS共享目录,并挂载

[root@vms201 volume_practice]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: podnfs
spec:terminationGracePeriodSeconds: 0nodeName: vms202.rhce.ccvolumes:- name: v1nfs:server: 192.168.0.205path: /aacontainers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}volumeMounts:- name: v1mountPath: /bbdnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

yaml文件设置了将共享的/aa目录挂载到了容器内的/bb目录,并创建容器:

[root@vms201 volume_practice]# kubectl apply -f pod1.yaml
pod/podnfs created

步骤5: 检查是否挂载成功
进入容器,在挂载的目录下创建测试文件test.txt:

[root@vms201 volume_practice]# kubectl exec -it podnfs -- bash
root@podnfs:/# touch /bb/test.txt

返回NFS服务,查看卷目录/aa下是否同步了文件:已经正常同步了文件。

[root@nfs ~]# ls /aa
test.txt

目前pod是在vms-202上运行,删除掉pod后,让其运行在另一个worker vms-203上:

[root@vms201 volume_practice]# kubectl get pods -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP              NODE             NOMINATED NODE   READINESS GATES
podnfs   1/1     Running   0          6m15s   10.244.58.227   vms202.rhce.cc   <none>           <none>
[root@vms201 volume_practice]# kubectl delete pod podnfs
pod "podnfs" deleted

修改pod的yaml文件,使nodeName为vms203.rhce.cc即可,然后应用,并进入容器,查看/bb目录下是否还存在test.txt文件:

[root@vms201 volume_practice]# kubectl get pods -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP              NODE             NOMINATED NODE   READINESS GATES
podnfs   1/1     Running   0          3m15s   10.244.58.229   vms203.rhce.cc   <none>           <none>
[root@vms201 volume_practice]# kubectl exec -it podnfs -- bash
root@podnfs:/# ls /bb
test.txt

可以看到,pod切换了node后数据依旧保存成功。

三、持久性存储

Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:

  1. 要么询问管理员。

  2. 要么自己就是管理员。

这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。如果系统规模较小或者对于开发环境这样的情况还可以接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必须要解决的问题。

Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。

PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。注意:PVC是基于命名空间的,同一时刻,一个PV和一个PVC是一对一关联。

有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。

步骤1: 在NFS上创建一个共享的目录/bb

[root@nfs ~]# mkdir /bb
[root@nfs ~]# vim /etc/exports
/bb     *(rw,async,no_root_squash)
[root@nfs ~]#  exportfs -arv
exporting *:/bb
exporting *:/aa

步骤2: 在master上创建pv,yaml文件如下

[root@vms201 volume_practice]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: pv1
spec:capacity:storage: 5GivolumeMode: FilesystemaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: Recycle#storagesClassName: xxnfs:path: /bbserver: 192.168.0.205

其中 accessMode为的模式为:

  1. ReadWriteOnce:当多个容器使用一个存储时,同一时间只有一个容器能够读写;
  2. ReadOnlyMany:当多个容器使用一个存储时,同一时间只有一个容器能够写,但是可以多个容器一起读;
  3. ReadWriteMany:当多个容器使用一个存储时,同一时间可以多个容器进行读写。

capacity可以控制存储的容量,例如在使用块存储时会起到作用。

persistentVolumeReclaimPolicy为回收策略,有如下类型

  1. Recycle:也就是pvc一旦删除,其存储的数据也删除,并pv变为Available状态;
  2. Retain:pvc如果删除,其存储的数据为会被保存,并且pv变为Released,不可被新的pvc关联。并且可以删除掉此pv,也不会造成数据丢失;
  3. Delete:删除网络存储(例如)云盘里面的数据。

创建pv1,并查看:

[root@vms201 volume_practice]# kubectl apply -f pv.yaml
persistentvolume/pv1 created
[root@vms201 volume_practice]# kubectl get pv -n default
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    5Gi        RWO            Recycle          Available                                   27s
[root@vms201 volume_practice]# kubectl get pv -n 2-pod
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    5Gi        RWO            Recycle          Available                                   38s

可以看到,pv是独立于命名空间的,在多个命名空间中都能查看到pv。同时目前STATUS为Available,说明没有绑定PVC。

步骤3: 创建PVC

编辑pvc的yaml文件:

[root@vms201 volume_practice]# cat pvc1.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: myclaim
spec:accessModes:- ReadWriteOncevolumeMode: Filesystemresources:requests:storage: 5Gi#storagesClassName: xx

应用yaml文件生成pvc:

[root@vms201 volume_practice]# kubectl apply -f pvc1.yaml
persistentvolumeclaim/myclaim created
[root@vms201 volume_practice]# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim   Bound    pv1      5Gi        RWO                           56s

可以看懂到,pvc的状态为Bound,说明已经与pv关联上了。虽然我们再定义的yaml文件并没有指定具体使用那个pv,但是pvc和pv关联主要是通过,如果三个要素来完成的:

  1. capcity
  2. accessmode
  3. storageClassName

首先PVC要求的容器要<=PV的容量,accessmode、storageClassName(可以为空)需要一致。由于只有一个PVC和PV之间能互相绑定,如果我们再另外一个命名空间中创建PVC,则会出现绑定失败的情况:(先来后到)

[root@vms201 volume_practice]# kubectl apply -f pvc1.yaml -n default
persistentvolumeclaim/myclaim created
[root@vms201 volume_practice]# kubectl get pvc -n default
NAME      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim   Pending                                                     13s

步骤4: 在pod的yaml文件中调用pvc,并创建pod

编辑pod的yaml文件:

[root@vms201 volume_practice]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: podpvc
spec:terminationGracePeriodSeconds: 0# nodeName: vms203.rhce.ccvolumes:- name: v1persistentVolumeClaim:claimName: myclaimcontainers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}volumeMounts:- name: v1mountPath: /bbdnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

创建podpvc:

[root@vms201 volume_practice]# kubectl apply -f pod1.yaml
pod/podpvc created

步骤完成后,NFS的/bb目录也就挂载到了pod的/bb目录下。

步骤5: 检查是否挂载成功

在master上进入对应的容器,在被挂载的目录下创建文件:

[root@vms201 volume_practice]# kubectl exec -it podpvc -- bash
root@podpvc:/# touch /bb/test.txt

在NFS的对应卷中查看是否挂载成功:

[root@nfs ~]# ls /bb/
test.txt

可以看到,挂载已经成功。当我们删除对应PVC时,由于回收策略为recycle,所以NFS目录/bb下也就没有了文件:

[root@vms201 volume_practice]# kubectl delete pod podpvc
pod "podpvc" deleted
[root@vms201 volume_practice]# kubectl delete -f pvc1.yaml
persistentvolumeclaim "myclaim" deleted[root@nfs ~]# ls /bb/
[root@nfs ~]#

持久性存储的缺点:
虽然PV和后端存储有专人管理,但是如果我们想要创建PVC,前提是要有一个新的PV与其绑定,这时候需要专门去找PV的管理员,导致了一定的不方便。

四、动态卷供应

为了解决持久性存储的问题,可以使用动态卷供应的方式。

相关概念:

  1. 分配器:每个分配器连接到一个后端存储(NFS、LVM、AWS等)
  2. storageClass(SC):全局存在,在PVC上指定使用哪个SC,SC会根据绑定的分配器自动创建对应的PV。

因此,用户仅需要自己维护PVC,则可以链接到后存储中。

步骤1: 在NFS上创建共享目录/cc

[root@nfs ~]# mkdir /cc
[root@nfs ~]# vim /etc/exports
/cc     *(rw,async,no_root_squash)
[root@nfs ~]# exportfs -arv
exporting *:/cc
exporting *:/bb
exporting *:/aa

步骤2: 在master上下载NFS分配器相关文件

修改参数:

vim /etc/kubernetes/manifests/kube-apiserver.yaml

在command栏下添加一行:

- --feature-gates=RemoveSelfLink=false

重启服务:

[root@vms201 volume_practice]# systemctl restart kubelet

安装git并克隆项目:

 yum install git -ygit clone https://github.com/kubernetes-incubator/external-storage.git

将镜像拷贝到worker node上去:

[root@vms201 volume_practice]# scp nfs-client-provisioner.tar vms202:~
[root@vms201 volume_practice]# scp nfs-client-provisioner.tar vms203:~

在master和worker nodes上导入镜像:

[root@vms201 volume_practice]# docker load -i nfs-client-provisioner.tar
8dfad2055603: Loading layer [==================================================>]  4.284MB/4.284MB
a17ae64bae4f: Loading layer [==================================================>]  2.066MB/2.066MB
bd01fa00617b: Loading layer [==================================================>]  39.72MB/39.72MB
Loaded image: quay.io/external_storage/nfs-client-provisioner:latest

解压external-storage-master.zip文件,如果centos上没有unzip,需要通过yum安装。

yum install unzip -y
unzip external-storage-master.zip -d .

步骤3: 部署分配器

修改分配器的yaml文件:

[root@vms201 nfs-client]# cd /root/volume_practice/external-storage-master/nfs-client/deploy/
[root@vms201 deploy]# ls
class.yaml  deployment-arm.yaml  deployment.yaml  objects  rbac.yaml  test-claim.yaml  test-pod.yaml
# 可以修改存放的命名空间
[root@vms201 deploy]# kubectl create namespace 3-volume
namespace/3-volume created[root@vms201 deploy]# sed -i 's/namespace: default/namespace: 3-volume/g' rbac.yaml

应用rbac.yaml文件,创建一系列角色:

[root@vms201 deploy]# kubectl apply -f rbac.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

修改分配器的yaml文件并应用:主要是修改的NFS服务器的地址和卷的路径

[root@vms201 deploy]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: 3-volume
spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: fuseim.pri/ifs- name: NFS_SERVERvalue: 192.168.0.205- name: NFS_PATHvalue: /ccvolumes:- name: nfs-client-rootnfs:server: 192.168.0.205path: /cc[root@vms201 deploy]# kubectl apply -f deployment.yaml
deployment.apps/nfs-client-provisioner created
[root@vms201 deploy]# kubens 3-volume
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "3-volume".
[root@vms201 deploy]# kubectl get pods
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-6d969f876-npgql   1/1     Running   0          2m47s

步骤4: 创建storageClass

修改SC的文件:

[root@vms201 deploy]# cat class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: mysc
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:archiveOnDelete: "false"

注意provisioner的值和所调用的分配器的名字保持一致。分配器的名字如下:

env:- name: PROVISIONER_NAMEvalue: fuseim.pri/ifs

创建SC并查看:

root@vms201 deploy]# kubectl apply -f class.yaml
storageclass.storage.k8s.io/mysc created
[root@vms201 deploy]# kubectl get sc
NAME   PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
mysc   fuseim.pri/ifs   Delete          Immediate           false                  5s

步骤5: 创建PVC调用SC

编辑对应的yaml文件:指定SC

[root@vms201 volume_practice]# cat pvc1.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: myclaim
spec:accessModes:- ReadWriteOncevolumeMode: Filesystemresources:requests:storage: 100MistorageClassName: mysc

创建PVC并查看:

[root@vms201 volume_practice]# kubectl apply -f pvc1.yaml
persistentvolumeclaim/myclaim created
[root@vms201 volume_practice]# kubectl get pvc
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myclaim   Bound    pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab   100Mi      RWO            mysc           34s

可以看到已经自动创建了卷pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab,查看其信息:

[root@vms201 volume_practice]# kubectl describe pv  pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab
Name:            pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab
Labels:          <none>
Annotations:     pv.kubernetes.io/provisioned-by: fuseim.pri/ifs
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    mysc
Status:          Bound
Claim:           3-volume/myclaim
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        100Mi
Node Affinity:   <none>
Message:
Source:Type:      NFS (an NFS mount that lasts the lifetime of a pod)Server:    192.168.0.205Path:      /cc/3-volume-myclaim-pvc-909b896a-273f-4237-95c8-3b9dc4fb9aabReadOnly:  false
Events:        <none>

可以看到NFS的卷目录为/cc/3-volume-myclaim-pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab。

步骤6: 在master上创建pod,指定其使用的pvc,并测试:

pod的 yaml文件:

[root@vms201 volume_practice]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: podpvc
spec:terminationGracePeriodSeconds: 0# nodeName: vms203.rhce.ccvolumes:- name: v1persistentVolumeClaim:claimName: myclaimcontainers:- image: nginximagePullPolicy: IfNotPresentname: c1resources: {}volumeMounts:- name: v1mountPath: /ccdnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

创建pod,并在被挂载的目录/cc下创建文件:

[root@vms201 volume_practice]# kubectl apply -f pod1.yaml
pod/podpvc created
[root@vms201 volume_practice]# kubectl exec -it podpvc -- bash
root@podpvc:/# touch /cc/test.txt

在NFS对应的卷中查看:

[root@nfs ~]# cd /cc/3-volume-myclaim-pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab/
[root@nfs 3-volume-myclaim-pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab]# ls
test.txt

可以看到,数据已经同步了。

参考资料:
《老段CKA课程》

七、K8s volume相关操作相关推荐

  1. K8s Docker 相关操作指令

    文章目录 1 Docker镜像删除的多种方法 2 Docker常见问题 3 K8s节点驱逐 4 Centos7 修改Docker Root Dir 5 K8s 重新生成token并加入集群 6 K8s ...

  2. R语言七天入门教程六:文件相关操作

    R语言七天入门教程六:文件相关操作 一.文件的读写 R 语言作为统计学编程语言,常常需要处理大量数据,而这些数据通常会从文件中进行读取,因此文件读写在R语言中是非常重要的操作.在R语言中,用到最多的文 ...

  3. 【七】Python全栈之路--字符串_列表相关操作

    文章目录 1. format格式化_填充符号使用 1.1 format格式化 1.2 format的填充符号的使用 2. 字符串相关的方法 3. 列表的相关操作 4. 列表的相关函数 5. 深浅拷贝 ...

  4. python文件夹在哪_Python文件夹与文件的相关操作(推荐)

    最近在写的程序频繁地与文件操作打交道,这块比较弱,还好在百度上找到一篇不错的文章,这是原文传送门,我对原文稍做了些改动. 有关文件夹与文件的查找,删除等功能 在 os 模块中实现.使用时需先导入这个模 ...

  5. 【Liunx常用操作】LVM逻辑卷的介绍和相关操作(创建、删除、扩缩容)

    [Liunx常用操作]LVM逻辑卷的介绍和相关操作 提示:为保证文章的正确性和实用性,文章内容作者会不断优化改进,若您有建议或者文章存在错误请留言或评论指正. 前言 LVM(Logical Volum ...

  6. 2021年大数据HBase(五):HBase的相关操作JavaAPI方式

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 HBase的相关操作-JavaAPI方式 一.需求说明 ...

  7. 2021年大数据HBase(四):HBase的相关操作-客户端命令式!【建议收藏】

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 HBase的相关操作-客户端命令式 1.进入HBase ...

  8. Linux之用户相关操作

    Linux之用户相关操作 1. 创建用户  [创建后会立即让设置密码] 命令 说明 useradd 创建(添加)用户 useradd命令选项: 选项 说明 -m 自动创建用户主目录,主目录的名字就是用 ...

  9. T-Sql(七)用户权限操作(grant)

    原文:T-Sql(七)用户权限操作(grant) 一般数据库的权限操作我们很少用,除非一些大型的项目,需要给数据库配置不同的用户及权限,防患于未然,今天我们就来了解下t-sql中配置用户权限操作. 先 ...

  10. Python date,datetime,time等相关操作总结

    date,datetime,time等相关操作总结   by:授客 QQ:1033553122 测试环境: Python版本:Python 3.3.2 代码实践: __author__ = '授客'i ...

最新文章

  1. C++ 笔记(36)— 接收输入字符串的几种方法
  2. JFinal Nutz
  3. wxWidgets:wxMouseCaptureChangedEvent类用法
  4. 3.10 触发字检测
  5. 两种专家经验评分卡的学习
  6. linux dd copy all partitions,Linux 系统下使用dd命令备份还原MBR主引导记录
  7. Zookeeper之集群安装
  8. 传播路径图调查2013年初
  9. 《JavaScript高效图形编程(修订版)》——导读
  10. 爱心宠物诊所管理系统
  11. UAT,(user acceptance Test),用户接受度测试 标准步骤
  12. 计算机word英语词汇大全,计算机专业英语词汇缩写大全
  13. IO前哨站之##File##
  14. ReMap:人类Chip-seq数据大全
  15. IBM“移动优先”官网正式上线:苹果静候佳音
  16. python 实现大鱼吃小鱼小游戏(课程作业)
  17. 读《深入浅出MySQL数据库开发、优化与管理维护(第2版)》笔记1
  18. 互联网创业技术团队需要多少人
  19. 平板酷派Ultranote X15概述
  20. 安卓开发新手入门教程!Android学习路线指南,复习指南

热门文章

  1. Google AdSense实战宝典
  2. 21天学通JAVA:类设计的技巧
  3. 什么是数据脱敏(Data Masking)?
  4. Python模块:生成随机数模块random
  5. pytorch序列化容器
  6. python中oxf2是多少_Python学习笔记[2]
  7. 百度竞价点击器_同等预算,百度竞价托管如何让您的点击量高于您同行?
  8. Leetcode91. Decode Ways
  9. cmake相关:sudo make install后的卸载
  10. 力扣-191 位1的个数