Volume: 数据卷,实现数据本地存储                         

PV: PersistenVolume持久卷,实现数据网络存储

-------------------------------------------    

Volume简介:

Volumekubernetes Pod中多个容器访问的共享目录。

volume被定义在pod上,被这个pod的多个容器挂载到相同或不同的路径下。

volume的生命周期与pod的生命周期相同,pod内的容器停止和重启时一般不会影响volume中的数据(数据存储在宿主机目录)。

volume一般被用于持久化,保存pod产生的数据。

volume类型:

        emptyDir(临时)

        hostPath(持久)

  • emptyDir:

    1. emptyDir数据卷的特点:

  1. emptyDir的生命周期与所属的pod相同,pod删除时,emptyDir中的数据也会被删除
  2. emptyDir类型需要在volums字段中定义,用volumsMounts字段挂载使用
  3. kubernetes会node上自动创建一个目录,无需提前创建
  4. emptyDir Volume主要用于某些应用程序无需永久保存数据,多个容器的共享目录等

    1. 示例:多个容器共享数据

[root@master01 ~]# vim emptyDir.yaml

kind: Pod

apiVersion: v1

metadata:

  name: auth-vol

spec:

  containers:

  - name: vol1

    image: busybox

    imagePullPolicy: IfNotPresent

    volumeMounts:

    - mountPath: /vol1_dir

      name: shared-volume

    args:

    - /bin/sh

    - -c

    - echo "hello world" > /vol1_dir/hello.txt ; sleep 30000

  - name: vol2

    image: busybox

    imagePullPolicy: IfNotPresent

    volumeMounts:

      - mountPath: /vol2_dir

        name: shared-volume

    args:

    - /bin/sh

    - -c

    - cat /vol2_dir/hello.txt ;sleep 30000

  volumes:

  - name: shared-volume

    emptyDir: {}

分析:

volumes是指k8s的存储方案,容器内volumeMounts使用的是volumes内定义的存储,

volumes定义的宿主机上的目录或文件,分别挂载到了vol1(/vol1_dir)和vol2(/vol2_dir)这个两个容器的对应目录

在vol1容器的/vol1_dir目录下创建的文件,在vol2容器的/vol2_dir目录下,同样可以看到

    1. 验证:

      1. 应用emptyDir.yaml

[root@master01 ~]# kubectl apply -f emptyDir.yaml

      1. 查看vol2容器的日志

[root@master01 ~]# kubectl logs auth-vol vol2

hello world

      1. 查看一个Pod运行在了哪个Node节点上

[root@master01 ~]# kubectl get pod -o wide

      1. 到对应Node节点上(此处为worker01)查看该容器的详细信息(Mounts

注:pause 容器,用于管理 Pod 的网络和存储资源的基础容器。

查看容器19abea5a4291 详细信息中Mounts区域中内容,确定数据源目录

      1. 查看宿主机数据源目录中的文件

      1. 删除pod,宿主机中的数据被删除

[root@master01 ~]# kubectl delete -f emptyDir.yaml

worker01上查看文件:

注:emptyDir的使用场景:

如果Pod被删除,那么数据也会被删除,不具备持久化。

Pod内的容器,需要共享数据卷的时候,使用的是临时数据卷。

  • HostPath 数据卷

    1. Hostpath数据卷的特点:

hostPath卷将主机节点中的文件或目录挂载到集群中

hostPath就等于运行容器时使用的命令:

    docker run -v /host/path:/container/path

除了path属性之外,用户还可以指定type:

   

    DirectoryOrCreate  如果指定的位置没有目录,将创建,权限755,与kubelet具有相同的所有权

    Directory             指定的位置必须存在目录

    FileOrCreate       如果指定的位置没有文件,将创建,权限644,与kubelet具有相同的所有权

    File                  指定的位置必须存在文件

[root@master01 ~]#  kubectl delete all --all

[root@master01 ~]#  vim hostPath.yaml

kind: Pod

apiVersion: v1

metadata:

  name: auth-vol

spec:

  containers:

  - name: vol1

    image: busybox

    imagePullPolicy: IfNotPresent

    volumeMounts:

    - mountPath: /vol1_dir

      name: shared-volume

    args:

    - /bin/sh

    - -c

    - echo "hello world" > /vol1_dir/hello.txt ; sleep 30000

  - name: vol2

    image: busybox

    imagePullPolicy: IfNotPresent

    volumeMounts:

      - mountPath: /vol2_dir

        name: shared-volume

    args:

    - /bin/sh

    - -c

    - cat /vol2_dir/hello.txt ;sleep 30000

  volumes:

  - name: shared-volume

    hostPath:

      path: "/data/hostPath"

      type: DirectoryOrCreate

[root@master01 ~]# kubectl apply -f hostPath.yaml

[root@master01 ~]# kubectl get pod -o wide                         #查看pod节点(此处在worker02上)

[root@worker02 ~]# ls /data/hostPath/                          #查看数据存储位置

hello.txt

[root@master01 ~]# kubectl logs auth-vol vol2

hello world

[root@master01 ~]#  kubectl delete all --all                 #删除pod

[root@worker02 ~]# ls /data/hostPath/                          #查看数据存储位置

hello.txt

  • PV持久卷(PersistenVolume

    1. PVPVC简介:

      1. PV:

PersistentVolume ( PV )是集群之中的一块网络存储

跟 Node 一样,也是集群的资源。

      1. PVC:

PV 是存储资源,而 PersistentVolumeClaim (PVC) 是对 PV 的请求。

    1. 实现过程:

  1. 准备存储设备
  2. 创建pv(关联到存储)
  3. 创建pvc(向pv申请资源)
  4. 创建pod(连接pvc)

      1. 准备存储设备:此处使用NFS

# 所有节点都安装nfs-utils工具包和rpc-bind服务。

         yum install nfs-utils  -y

# 这里准备将NFS服务部署在master01节点上,需要在master01节点上提前规划好共享的目录

生产环境下网络存储是独立存在的

[root@master01 ~]# mkdir /nfsdata

[root@master01 ~]#  vim /etc/exports

/nfsdata *(rw,sync,no_root_squash)

[root@master01 ~]#  systemctl start nfs-server

[root@master01 ~]#  systemctl enable nfs-server

[root@master01 ~]#  showmount -e

      1. 创建PV(关联到存储)

[root@master01 ~]# vim pv1.yaml

kind: PersistentVolume

apiVersion: v1

metadata:

  name: pv1

spec:

  capacity:

    storage: 1Gi

  accessModes: 

    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  storageClassName: nfs

  nfs:

    path: /nfsdata

    server: 192.168.10.11

[root@master01 ~]# kubectl apply -f pv1.yaml

[root@master01 ~]# kubectl get pv

NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM   STORAGECLASS   REASON   AGE

pv1    1Gi        RWO            Retain          Available             nfs                     58s

PV所支持的访问模式:

        ReadWriteOnce:PV能以read-write的模式mount到单个节点。(命令模式:RWO)

        ReadOnlyMany:  PV能以read-only 的模式mount到多个节点。(命令模式:ROX)

        ReadWriteMany:     PV能以read-write的模式Mount到多个节点。(命令模式:RWX)

PV状态:

        Available(可用):一块空闲资源还没有被任何声明绑定

        Bound(绑定):卷已经被声明绑定

        Released(已释放):声明被删除,但是资源还未被集群重新声明

        Failed(失败):该卷的自动回收失败

PV空间的回收策略:persistentVolumeReclaimPolicy

        Recycle: 回收,会清除数据,自动回收(新k8s版本已不支持)。

        Retain: 保留,需要手动清理回收。

        Delete: 删除,(自动删除pv,网络存储数据仍保留,一般在动态供给中使用)

      1. 创建一个PVC(向pv申请资源)

PV与PVC的绑定,通过storageClassName和accessModes这两个字段共同决定。

[root@master01 ~]# vim pvc1.yaml

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: pvc1

spec:

  accessModes:

    - ReadWriteOnce

  storageClassName: nfs

  resources:

    requests:

      storage: 1Gi

[root@master01 ~]# kubectl apply -f pvc1.yaml

[root@master01 ~]# kubectl get pv,pvc

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM     STORAGECLASS   REASON   AGE

persistentvolume/pv1   1Gi        RWO      Retain     Bound    default/pvc1   nfs              6h1m

NAME                              STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE

persistentvolumeclaim/pvc1   Bound    pv1      1Gi        RWO            nfs            4m40s

再次查看pv,状态status由Available换成了Bound,CLAIM(宣称)换成了default/pvc1占用

   

总结:

        1. RWO模式:当系统中的pv被绑定之后,就不会被其他的PVC绑定了。

        2. 如果系统中有多个能够满足pvc要求的pv,那么,系统会自动选择一个符合pvc申请空间大小的PV,进行绑定,尽量不浪费存储空间。

      1. 创建pod(连接pvc

        • 创建pod1

[root@master01 ~]# vim pod1.yaml

kind: Pod

apiVersion: v1

metadata:

  name: pod1

spec:

  containers:

  - name: pod1

    image: busybox

    imagePullPolicy: IfNotPresent

    args:

    - /bin/sh

    - -c

    - sleep 30000

    volumeMounts:

    - mountPath: "/data"

      name: mydata

  volumes:

  - name: mydata

    persistentVolumeClaim:

      claimName: pvc1

[root@master01 ~]# kubectl apply -f pod1.yaml

[root@master01 ~]# kubectl get pod -o wide

NAME   READY   STATUS    RESTARTS   AGE   IP   NODE     NOMINATED NODE   READINESS GATES

pod1   1/1     Running   0          31s   10.244.2.4   worker02   <none>           <none>

在pod1的容器中,创建一个文件

[root@master01 ~]# kubectl exec -it pod1  --  touch /data/auth.txt

nfs服务器上查看:

[root@master01 ~]# ls /nfsdata/

auth.txt

        • 再创建pod2,连接相同的pvc

[root@master01 ~]# vim pod2.yaml

kind: Pod

apiVersion: v1

metadata:

  name: pod2

spec:

  containers:

  - name: pod2

    image: busybox

    imagePullPolicy: IfNotPresent

    args:

    - /bin/sh

    - -c

    - sleep 30000

    volumeMounts:

    - mountPath: "/data"

      name: mydata

  volumes:

  - name: mydata

    persistentVolumeClaim:

      claimName: pvc1

查看相应容器/data目录内容为nfs共享数据

[root@master01 ~]# kubectl apply -f pod2.yaml

[root@master01 ~]# kubectl exec -it pod2 -- ls /data

auth.txt

      1. PV的空间回收

当pv中回收策略为:Retain

[root@master01 ~]# kubectl get pv,pvc

NAME                   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM          STORAGECLASS   REASON   AGE

persistentvolume/pv1         1Gi        RWO            Retain           Bound    default/pvc1       nfs                     4m4s

        • 验证dockerhostPV上存放的数据

[root@master01 ~]# ls /nfsdata/

auth.txt

        • 删除PodPVCPV

[root@master01 ~]# kubectl delete pod,pv,pvc --all

        • 查看数据

[root@master01 ~]# ls /nfsdata

auth.txt

可重复实验测试

[root@master01 ~]# rm -rf /nfsdata/*

[root@master01 ~]# kubectl apply -f pv1.yaml

[root@master01 ~]# kubectl apply -f pvc1.yaml

[root@master01 ~]# kubectl apply -f pod1.yaml

[root@master01 ~]# kubectl apply -f pod2.yaml

[root@master01 ~]# kubectl exec pod1 -- touch /data/auth2.txt

[root@master01 ~]# ls /nfsdata/

auth2.txt

//再次删除Pod,PVC,验证PV目录下存放的数据

[root@master01 ~]# kubectl delete pod,pvc,pv --all

[root@master01 ~]# ls /nfsdata/

auth2.txt

================================================

    1. PVPVC的运用

现在部署一个MySQL服务,并且将MySQL的数据进行持久化存储。

      1. 创建PVPVC

[root@master01 ~]# vim mysql-pv.yaml

kind: PersistentVolume

apiVersion: v1

metadata:

  name: mysql-pv

spec:

  accessModes:

    - ReadWriteOnce

  capacity:

    storage: 1Gi

  persistentVolumeReclaimPolicy: Retain

  storageClassName: nfs

  nfs:

    path: /nfsdata/mysql-pv

    server: 192.168.10.11

[root@master01 ~]# vim mysql-pvc.yaml

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: mysql-pvc

spec:

  accessModes:

    - ReadWriteOnce

  storageClassName: nfs

  resources:

    requests:

      storage: 1Gi

   

[root@master01 ~]# mkdir /nfsdata/mysql-pv

[root@master01 ~]# kubectl apply -f mysql-pv.yaml

[root@master01 ~]# kubectl apply -f mysql-pvc.yaml

[root@master01 ~]# kubectl get pv,pvc

NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE

persistentvolume/mysql-pv   1Gi        R    Retain    Bound    default/mysql-pvc                    nfs                   44s

NAME                                                           STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE

persistentvolumeclaim/mysql-pvc   Bound    mysql-pv     1Gi        RWO            nfs            4s

      1. 部署MySQL

[root@master01 ~]# vim mysql.yaml

kind: Deployment

apiVersion: apps/v1

metadata:

  name: mysql

spec:

  selector:

    matchLabels:

      app: mysql

  template:

    metadata:

      labels:

        app: mysql

    spec:

      containers:

      - name: mysql

        image: mysql:5.7

        imagePullPolicy: IfNotPresent

        env:

        - name: MYSQL_ROOT_PASSWORD

          value: 123.com

        volumeMounts:

        - name: mysql-storage

          mountPath: /var/lib/mysql

      volumes:

      - name: mysql-storage

        persistentVolumeClaim:

          claimName: mysql-pvc

---

kind: Service

apiVersion: v1

metadata:

  name: mysql

spec:

  type: NodePort

  selector:

    app: mysql

  ports:

    - port: 3306

      targetPort: 3306

      nodePort: 31306

[root@master01 ~]# kubectl apply -f mysql.yaml

      1. MySQL数据库中添加数据

[root@master01 ~]# kubectl get pod

NAME                     READY   STATUS    RESTARTS   AGE

mysql-5d86c64fc9-5krvs   1/1     Running   0          56s

[root@master01 ~]# kubectl exec -it mysql-5d86c64fc9-5krvs -- mysql -uroot -p123.com

mysql> SHOW DATABASES;                                      //查看当前的库。

mysql> CREATE DATABASE auth;                            //创建auth库。

mysql> USE auth;                                                     //选择使用auth库。

mysql> CREATE TABLE users(user_name char(10),user_passwd char(40));         //创建my_id表

mysql> INSERT users values ('zhangsan','123');                                       //往my_id表中,插入数据。

mysql> SELECT * FROM users;                                                                  //查看my_id表中所有数据

      1. 模拟MySQ服务器节点故障

删除pod,k8s集群会产生一个新的Pod,验证这个Pod内是否有之前数据。

[root@master01 ~]# kubectl get pod -o wide

。。。。

[root@master01 ~]# kubectl exec -it  pod  -- mysql -u root -p123.com

mysql> show databases;

mysql> use auth;

mysql> show tables;

mysql> select * from users;

验证数据还在

Nfs服务器上查看:

[root@master01 ~]# ls /nfsdata/mysql-pv

Mysql数据

更多推荐