实验环境:

在这里插入图片描述
按照图示部署好了K8s集群,一个Master,两个worker nodes。

无状态(stateless)的容器:

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

[root@vms201 volume_practice]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: pod1
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: pod1
    resources: {}
    ports:
    - name: http
      containerPort: 80
      protocol: TCP
      hostPort: 80
  dnsPolicy: ClusterFirst
  restartPolicy: 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: null
  labels:
    run: pod1
  name: pod1
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: v1
    emptyDir: {}
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /aa
      # readOnly: true
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c2
    command: ["sh", "-c", "sleep 1000"]
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /aa
  dnsPolicy: ClusterFirst
  restartPolicy: 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: null
  labels:
    run: pod1
  name: pod1
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: v1
    hostPath:
      path: /test_data
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /aa
  dnsPolicy: ClusterFirst
  restartPolicy: 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: null
  labels:
    run: pod1
  name: podnfs
spec:
  terminationGracePeriodSeconds: 0
  nodeName: vms202.rhce.cc
  volumes:
  - name: v1
    nfs:
      server: 192.168.0.205
      path: /aa
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /bb
  dnsPolicy: ClusterFirst
  restartPolicy: 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: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  #storagesClassName: xx
  nfs:
    path: /bb
    server: 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:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    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: null
  labels:
    run: pod1
  name: podpvc
spec:
  terminationGracePeriodSeconds: 0
  # nodeName: vms203.rhce.cc
  volumes:
  - name: v1
    persistentVolumeClaim:
      claimName: myclaim
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /bb
  dnsPolicy: ClusterFirst
  restartPolicy: 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 -y
 git 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-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: 3-volume
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 192.168.0.205
            - name: NFS_PATH
              value: /cc
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.0.205
            path: /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_NAME
    value: 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:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 100Mi
  storageClassName: 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.205
    Path:      /cc/3-volume-myclaim-pvc-909b896a-273f-4237-95c8-3b9dc4fb9aab
    ReadOnly:  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: null
  labels:
    run: pod1
  name: podpvc
spec:
  terminationGracePeriodSeconds: 0
  # nodeName: vms203.rhce.cc
  volumes:
  - name: v1
    persistentVolumeClaim:
      claimName: myclaim
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /cc
  dnsPolicy: ClusterFirst
  restartPolicy: 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课程》

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐