• k8s快速入门教程-----7 数据管理


       首先我们会学习Volume, 以及Kubernetes如何通过Volume 为集群中的容器提供存储;然后我们会实践几种常用的Volume 类型并理解它们各自的应用场景;最后,我们会讨论Kubernetes如何通过Persistent Volume和Persistent Volume Claim分离集群管理员与集群用户的职责,并实践Volume的静态供给和动态供给。
    
    • 1

    7.1 volume

    7.1.1 emptyDir

        emptyDir是最基础的Volume类型。正如其名字所示,一个emptyDir Volume是Host上的一个空目录。emptyDir Volume 对于容器来说是持久的,对于Pod则不是。当Pod从节点删除时,Volume的内容也会被删除。但如果只是容器被销毁而Pod还在,则Volume不受影响。也就是说: emptyDir Volume的生命周期与Pod-致。
        Pod中的所有容器都可以共享Volume, 它们可以指定各自的mount 路径。
    
    • 1
    • 2
    apiVersion: v1
    kind: Pod
    metadata:
      name: producer-consumer
    spec:
      containers:
      - name: producer
        image: wangjinxiong/nginx:tools
        volumeMounts:
        - name: shared-volume
          mountPath: /usr/share/nginx/html   # (2)
      volumes:
      - name: shared-volume   # (1)
        emptyDir: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    (1) 文件最底部volumes 定义了一个emptyDir 类型的Volume shared-volume
    (2 ) 将volume shared-volume 挂载到容器producer的/usr/share/nginx/html

    通过docker命令可以查看,可以看到shared-volume的保存目录。

    docker inspect d30522745908  # 通过docker ps | grep  producer-consumer查看ID 
    ........
    "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/var/lib/kubelet/pods/02c1e853-e863-4dc6-8b5a-91e08a8592f4/volumes/kubernetes.io~empty-dir/shared-volume",
                    "Destination": "/usr/share/nginx/html",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
       emptyDir是Host上创建的临时目录,其优点是能够方便地为Pod中的容器提供共享存储,不需要额外的配置。它不具备持久性,如果Pod 不存在了,emptyDir 也就没有了。根据这个特性,emptyDir特别适合Pod中的容器需要临时共享存储空间的场景,比如前面的生产者消费者用例。
    
    • 1

    7.1.2 hostpath

       hostPathVolume的作用是将DockerHost文件系统中已经存在的目录mount给Pod的容器。大部分应用都不会使用hostPath Volume,因为这实际上增加了Pod 与节点的耦合,限制了Pod 的使用。不过那些需要访问Kubernetes 或Docker 内部数据(配置文件和二进制库)的应用则需要使用hostPath。比如kube- apiserver和kube- controller-manager就是这样的应用,通过kubectl edit --namespace=kube -system pod kube- apiserver- k8s-master查看kube-apiserver Pod的配置,Volume的相关部分如图9-5所示。
    
    • 1
     volumeMounts:
        - mountPath: /etc/ssl/certs
          name: ca-certs
          readOnly: true
        - mountPath: /etc/pki
          name: etc-pki
          readOnly: true
        - mountPath: /etc/kubernetes/pki
          name: k8s-certs
          readOnly: true
      dnsPolicy: ClusterFirst
      enableServiceLinks: true
      hostNetwork: true
      nodeName: k8s-master
      preemptionPolicy: PreemptLowerPriority
      priority: 2000001000
      priorityClassName: system-node-critical
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      tolerations:
      - effect: NoExecute
        operator: Exists
      volumes:
      - hostPath:
          path: /etc/ssl/certs
          type: DirectoryOrCreate
        name: ca-certs
      - hostPath:
          path: /etc/pki
          type: DirectoryOrCreate
        name: etc-pki
      - hostPath:
          path: /etc/kubernetes/pki
          type: DirectoryOrCreate
        name: k8s-certs
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    这里定义了三个hostPath: volume k8s、 certs 和pki, 分别对应Host目录/etc/kubermetes、/etc/ssl/certs和/etc/pki. 如果Pod被销毁了,hostPath 对应的目录还是会被保留,从这一.点来看,hostPath 的持久性比emptyDir 强。不过- -旦Host 崩溃,hostPath 也就无法访问了。

       hostpath 宿主机本地目录保存,pod删除时不会删除数据,但宿主机故障不能迁移到其他nodes节点。
    
    • 1
    apiVersion: v1
    kind: Pod
    metadata:
      name: producer-consumer
    spec:
      containers:
      - name: producer
        image: wangjinxiong/nginx:tools
        volumeMounts:
        - name: shared-volume
          mountPath: /usr/share/nginx/html   # (2)
      volumes:
      - name: shared-volume
        hostPath:
          path: /tmp    #(1)
          type: Directory
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    (1) 文件最底部volumes 定义了一个hostpath 类型的Volume shared-volume
    (2 ) 将volume shared-volume 挂载到容器producer的/usr/share/nginx/html

    通过docker命令可以查看,可以看到shared-volume的保存目录。

    docker inspect 8ab46de51ba2   # 通过docker ps | grep  producer-consumer查看ID 
    "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/var/lib/kubelet/pods/03aa0d37-c68f-46a6-8353-f275b0101a57/etc-hosts",
                    "Destination": "/etc/hosts",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
                    "Type": "bind",
                    "Source": "/var/lib/kubelet/pods/03aa0d37-c68f-46a6-8353-f275b0101a57/containers/producer/95e21b36",
                    "Destination": "/dev/termination-log",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
                    "Type": "bind",
                    "Source": "/tmp",
                    "Destination": "/usr/share/nginx/html",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    7.2 PV && PVC

       PersistentVolumeClaim (PVC) 是对 PV的申请(Claim) 。PVC通常由普通用户创建和维护。需要为Pod分配存储资源时,用户可以创建一个PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的PV。有了PersistentVolumeClaim, 用户只需要告诉Kubernetes 需要什么样的存储资源,而不
    
    • 1

    必关心真正的空间从哪里分配、如何访问等底层细节信息。这些Storage Provider的底层信息交给管理员来处理,只有管理员才应该关心创建PersistentVolume 的细节信息。

    7.2.1 PV/PVC静态供给

    作为准备工作,我们已经在k8s-master 节点上搭建了一个NFS服务器,目录为/nfsdata。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv0908
    spec:
      capacity:
        storage: 5Gi
      accessModes:
        - ReadWriteMany
      nfs:
        path: /nfsdata
        server: 10.0.12.16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    7.2.1.1 创建pv

    # kubectl apply -f pv0908.yaml 
    persistentvolume/pv0908 created
    # kubectl get pv
    NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
    pv0908   5Gi        RWX            Retain           Available                                   7s
    
    • 1
    • 2
    • 3
    • 4
    • 5

    STATUS为Available, 表示pv0908就绪,可以被PVC申请。
    pvc的yaml文件:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc0908
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7.2.1.2 创建pvc

    [root@k8s-master ~]# kubectl apply -f pvc0908.yaml 
    persistentvolumeclaim/pvc0908 created
    [root@k8s-master ~]# kubectl apply -f pvc0908.yaml ^C
    [root@k8s-master ~]# kubectl get pvc
    NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    pvc0908   Bound    pv0908   5Gi        RWX                           5s
    [root@k8s-master ~]# kubectl get pv
    NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
    pv0908   5Gi        RWX            Retain           Bound    default/pvc0908                           7m18s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    从kubectl get pvc和kubectl get pv的输出可以看到pv0908已经Bound到pv0908,申请成功。

    7.2.1.3 pvc应用到pod

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx0908
    spec:
      containers: 
      - name: nginx
        image: wangjinxiong/nginx:tools
        ports:
        - containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
      - name: www
        persistentVolumeClaim:
          claimName: pvc0908
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    进入容器:

    # kubectl exec -it nginx0908 -- /bin/bash
    root@nginx0908:/# cd /usr/share/nginx/html/
    root@nginx0908:/usr/share/nginx/html# echo "wangjinxiong" > index.html
    
    • 1
    • 2
    • 3

    访问pod的主页:

    # kubectl get pod -o wide | grep nginx0908
    nginx0908                        1/1     Running   0          5m53s   172.18.235.197   k8s-master   <none>           <none>
    # curl 172.18.235.197
    wangjinxiong
    
    • 1
    • 2
    • 3
    • 4

    查看后端存储:

    # kubectl describe pv pv0908
    Name:            pv0908
    Labels:          <none>
    Annotations:     pv.kubernetes.io/bound-by-controller: yes
    Finalizers:      [kubernetes.io/pv-protection]
    StorageClass:    
    Status:          Bound
    Claim:           default/pvc0908
    Reclaim Policy:  Retain
    Access Modes:    RWX
    VolumeMode:      Filesystem
    Capacity:        5Gi
    Node Affinity:   <none>
    Message:         
    Source:
        Type:      NFS (an NFS mount that lasts the lifetime of a pod)
        Server:    10.0.12.16
        Path:      /nfsdata
        ReadOnly:  false
    Events:        <none>
    # 查看nfs文件
    # cd /nfsdata/
    [root@k8s-master nfsdata]# ls
    index.html
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    7.2.2 PV生命周期

    **AccessModes(访问模式): **
    AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
    • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
    • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
    • ReadWriteMany(RWX):读写权限,可以被多个节点挂载
    *RECLAIM POLICY(回收策略): **
    目前 PV 支持的策略有三种:
    • Retain(保留): 保留数据,需要管理员手工清理数据 , 默认。
    • Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/

    • Delete(删除):与 PV 相连的后端存储同时删除
    **STATUS(状态): **
    一个 PV 的生命周期中,可能会处于4中不同的阶段:
    • Available(可用):表示可用状态,还未被任何 PVC 绑定
    • Bound(已绑定):表示 PV 已经被 PVC 绑定
    • Released(已释放):PVC 被删除,但是资源还未被集群重新声明
    • Failed(失败): 表示该 PV 的自动回收失败

    7.2.3 PV 动态供给(StorageClass)

    在前面的例子中,我们提前创建了PV, 然后通过PVC申请PV并在Pod中使用,这种方式叫作静态供给( Static Provision)。与之对应的是动态供给(Dynamical Provision),即如果没有满足PVC 条件的PV,会动态创建PV。 相比静态供给,动态供给有明显的优势:不需要提前创建PV,减少了管理员的工作量,效率高。动态供给是通过StorageClass 实现的,StorageClass 定义了如何创建PV,下面给出两个例子。

    7.2.3.1 创建pvc

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc0908-nfs
      annotations:
        volume.beta.kubernetes.io/storage-provisioner: nfs-provisioner-01
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 2Gi
      storageClassName: nfs-server
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    7.2.3.2 pvc应用到deployment

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx0908
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx0908
      template:
        metadata:
          labels:
            app: nginx0908
        spec:
          volumes:
            - name: host-time
              hostPath:
                path: /etc/localtime
                type: ''
            - name: pvc0908-nfs
              persistentVolumeClaim:
                claimName: pvc0908-nfs
          containers:
          - image: wangjinxiong/nginx:tools
            name: nginx
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 80
              name: web80
            volumeMounts:
            - mountPath: /etc/localtime
              name: host-time
              readOnly: true
            - name: pvc0908-nfs
              mountPath: /usr/share/nginx/html
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    查看pvc相关情况:

    # kubectl get pvc
    NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    pvc0908-nfs   Bound    pvc-fab208e9-ca70-4129-8d67-78d89011e726   2Gi        RWX            nfs-server     18m
    # kubectl describe pv pvc-fab208e9-ca70-4129-8d67-78d89011e726
    Name:            pvc-fab208e9-ca70-4129-8d67-78d89011e726
    Labels:          <none>
    Annotations:     pv.kubernetes.io/provisioned-by: nfs-provisioner-01
    Finalizers:      [kubernetes.io/pv-protection]
    StorageClass:    nfs-server
    Status:          Bound
    Claim:           default/pvc0908-nfs
    Reclaim Policy:  Delete
    Access Modes:    RWX
    VolumeMode:      Filesystem
    Capacity:        2Gi
    Node Affinity:   <none>
    Message:         
    Source:
        Type:      NFS (an NFS mount that lasts the lifetime of a pod)
        Server:    10.0.12.16
        Path:      /nfsdata/default-pvc0908-nfs-pvc-fab208e9-ca70-4129-8d67-78d89011e726
        ReadOnly:  false
    Events:        <none>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    nfs server情况:

    # cd /nfsdata/
    # ls 
    default-pvc0908-nfs-pvc-fab208e9-ca70-4129-8d67-78d89011e726
    # 
    
    • 1
    • 2
    • 3
    • 4

    下一篇:8 secret and configmap

  • 相关阅读:
    Flask框架-1-[群聊]: flask-socketio实现websocket的功能
    Embind进阶用法(vector)
    Qt EventFilter 事件过滤器 及传递 鼠标键盘事件捕捉
    C# 替换字符串最后一个逗号为分号
    西门子S7-200 SMART如何实现远程监控并通过手机自动报警
    vue实战项目之vue-cli脚手架搭建过程详解
    RK3588 实现温控风扇之pwm驱动调试(二)
    在Go中处理异常
    Http请求类型GET, POST, PUT
    技术书籍超级阅读法
  • 原文地址:https://blog.csdn.net/cloud_engineer/article/details/126769255