• K8s复习笔记2-Volume


    1. Volume

    将数据和镜像解耦,以及容器间数据共享.不将数据打包到镜像中可以减小镜像大小.
    k8s抽象出一个对象,用来保存数据.
    常用的卷有:
    emptyDir: 本地临时卷,容器删除数据跟着删除
    hostPath: 本地卷,容器删除数据不被删除
    nfs: nfs共享卷,容器删除数据不被删除
    configmap: 配置文件
    其他:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#scaling-a-deployment

    1.1 emptyDir

    当pod被创建时,会先创建emptyDir卷.只要该pod在该节点上运行,这个卷就会一直存在.被创建的时候这个卷是空的.pod中的容器可以读写该emptyDir卷中的文件.当pod被删除时,emptyDir将被永久删除.可以放一些缓存或日志等不重要的文件.

    #apiVersion: extensions/v1beta1
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels: #rs or deployment
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: nginx 
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /cache
              name: empty-volume
          volumes:
          - name: empty-volume
            emptyDir: {}
    
    • 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

    pod创建后写入文件到/cache/abc.txt
    请添加图片描述

    刚创建的时候目录是空的,写入文件后可以在node节点上读取到该文件内容.
    请添加图片描述请添加图片描述

    当pod被删除后,emptyDir一并消失
    请添加图片描述

    1.2 hostPath

    和docker的-v效果比较类似,即使容器被删除,该路径下的数据任然会被保存下来.但发生节点切换就会造成数据丢失.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: nginx 
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /data
              name: cache-volume
          volumes:
          - name: cache-volume
            hostPath:
              path: /tmp/cache
    
    • 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

    创建hostPath
    请添加图片描述
    请添加图片描述

    1.3 nfs

    1.3.1 nfs 环境准备

    apt update
    apt install nfs-server
    mkdir /data/k8s/ -p
    echo '/data/k8s *(rw,sync,no_root_squash)' >> /etc/exports
    systemctl enable --now nfs-server
    systemctl restart nfs-server
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    1.3.2 node节点测试是否可以正常访问到nfs

    root@k8s-node-1:~# apt install nfs-common
    root@k8s-node-1:~# showmount -e 192.168.31.109
    Export list for 192.168.31.109:
    /data/k8s *
    root@k8s-node-1:~# 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3.3 单个nfs的yaml

    请添加图片描述

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: nginx 
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /usr/share/nginx/html/mysite
              name: my-nfs-volume
          volumes:
          - name: my-nfs-volume
            nfs:
              server: 192.168.31.109
              path: /data/k8s
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ng-deploy-80
    spec:
      ports:
      - name: http
        port: 81
        targetPort: 80
        nodePort: 30016
        protocol: TCP
      type: NodePort
      selector:
        app: ng-deploy-80
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42

    宿主机上,nfs被挂载到容器的目录,最后被联合挂载到容器中

    请添加图片描述
    在pod内,nfs已经被挂载
    请添加图片描述

    在nfs服务器上也可以看到这个文件
    请添加图片描述

    一般这个都是放图片的,我们也放个图片试试看
    请添加图片描述

    把副本数调整成2个
    请添加图片描述

    可以看到新建的pod也自动挂载了相同的内容,数据也是完全相同的
    请添加图片描述

    1.3.3 多个nfs的yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: nginx 
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /usr/share/nginx/html/html
              name: nfs-volume-html
            - mountPath: /usr/share/nginx/html/jpg
              name: nfs-volume-jpg
            - mountPath: /usr/share/nginx/html/yml
              name: nfs-volume-yml
          volumes:
          - name: nfs-volume-html
            nfs:
              server: 192.168.31.109
              path: /data/k8s
          - name: nfs-volume-jpg
            nfs:
              server: 192.168.31.110
              path: /data/k8s
          - name: nfs-volume-yml
            nfs:
              server: 192.168.31.104
              path: /data/k8s
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ng-deploy-80
    spec:
      ports:
      - name: http
        port: 81
        targetPort: 80
        nodePort: 30016
        protocol: TCP
      type: NodePort
      selector:
        app: ng-deploy-80
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    分别在192.168.31.109,192.168.31.110,192.168.31.104创建目录,并映射到pod中不同的目录
    请添加图片描述
    请添加图片描述
    yaml被当普通文件下载
    请添加图片描述

    最后实现pod挂载3个不同的nfs路径

    1.4 Configmap

    1.4.1 configmap作为配置文件

    存在的意义:使得镜像和配置解耦,将配置信息放入configmap,在pod的对象中导入configmap,实现配置导入

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
    data:
     default: |
        server {
           listen       80;
           server_name  www.mysite.com;
           index        index.html;
           location / {
               root /data/nginx/html;
               if (!-e $request_filename) {
                   rewrite ^/(.*) /index.html last;
               }
           }
        }
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /data/nginx/html
              name: my-nfs-volume
            - name: nginx-config
              mountPath:  /etc/nginx/conf.d/
          volumes:
          - name: nginx-config
            configMap:
              name: nginx-config
              items:
                 - key: default
                   path: mysite.conf
          - name: my-nfs-volume
            nfs:
              server: 192.168.31.109
              path: /data/k8sdata
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ng-deploy-80
    spec:
      ports:
      - name: http
        port: 81
        targetPort: 80
        nodePort: 30019
        protocol: TCP
      type: NodePort
      selector:
        app: ng-deploy-80
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    此时访问不存在的页面,会直接将首页返回.
    明显configmap配置已经生效

    root@k8s-master-01:~/yml# curl 192.168.31.113:30019
    in nfs node
    root@k8s-master-01:~/yml# curl 192.168.31.113:30019/dak.dkaj
    in nfs node
    root@k8s-master-01:~/yml# curl 192.168.31.113:30019/dak.jpg
    in nfs node
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    再看下pod下文件,可以看到/etc/nginx/conf.d/mysite.conf的内容正是configmap中default的内容

    root@k8s-master-01:~/yml# kubectl exec -it nginx-deployment-7c94b5fcb7-rnj7g sh
    kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
    # cat /etc/nginx/nginx.conf
    
    user  nginx;
    worker_processes  auto;
    
    error_log  /var/log/nginx/error.log notice;
    pid        /var/run/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
    
        include /etc/nginx/conf.d/*.conf;
    }
    # cat /etc/nginx/conf.d/mysite.conf
    server {
       listen       80;
       server_name  www.mysite.com;
       index        index.html;
       location / {
           root /data/nginx/html;
           if (!-e $request_filename) {
               rewrite ^/(.*) /index.html last;
           }
       }
    }
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    1.4.2 configmap作为变量传递参数

    configMap的data中
    创建key:username,val:user1
    通过env将来源就是来源名为nginx-config的configMap,key为username的值至传递给容器的MY_USERNAME变量,
    yaml部分详见下:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
    data:
      username: user1
    
    ---
    #apiVersion: extensions/v1beta1
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: nginx 
            env:
            - name: "mykey"
              value: "myvalue"
            - name: MY_USERNAME
              valueFrom:
                configMapKeyRef:
                  name: nginx-config
                  key: username
            ports:
            - containerPort: 80
    
    • 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

    可以看到MY_USERNAME,mykey值就是我们传入的value

    root@k8s-master-01:~/yml# kubectl apply -f 8-2-configmap.yaml 
    root@k8s-master-01:~/yml# kubectl get pods
    NAME                                READY   STATUS    RESTARTS   AGE
    net-test1                           1/1     Running   6          102d
    net-test2                           1/1     Running   6          102d
    nginx-deployment-6fb568ff7f-gdjqq   1/1     Running   0          35s
    root@k8s-master-01:~/yml# kubectl exec -it nginx-deployment-6fb568ff7f-gdjqq sh
    kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
    # echo $MY_USERNAME
    user1
    # echo $mykey
    myvalue
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.5 pv/pvc

    持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

    持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。

    pv是对底层网络存储的抽象,将存储定义为一种资源,将一个整体的存储资源拆分成多份后给不同的业务使用.
    pvc是对pv资源的申请调用.就像POD消费NODE节点一样,POD通过PVC将数据保存至PV,PV在保存数据至存储.

    pv和存储对接,全局资源,不需要指定namespace.
    pvc和pod对接,需要指定namespace
    https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

    1.5.1 PV 持久卷类型

    PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插件:

    持久卷类型含义
    awsElasticBlockStoreAWS 弹性块存储(EBS)
    azureDiskAzure Disk
    azureFileAzure File
    cephfsCephFS volume
    csi容器存储接口 (CSI)
    fcFibre Channel (FC) 存储
    gcePersistentDiskGCE 持久化盘
    glusterfsGlusterfs 卷
    hostPathHostPath 卷 (仅供单节点测试使用;不适用于多节点集群;请尝试使用 local 卷作为替代)
    iscsiiSCSI (SCSI over IP) 存储
    local节点上挂载的本地存储设备
    nfs网络文件系统 (NFS) 存储
    portworxVolumePortworx 卷
    rbdRados 块设备 (RBD) 卷
    vsphereVolumevSphere VMDK 卷

    1.5.2 访问模式

    PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器上以只读的方式导出。 每个 PV 卷都会获得自身的访问模式集合,描述的是特定 PV 卷的能力。

    访问模式有:

    • ReadWriteOnce

      卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。

    • ReadOnlyMany

      卷可以被多个节点以只读方式挂载。

    • ReadWriteMany

      卷可以被多个节点以读写方式挂载。

    • ReadWriteOncePod

      卷可以被单个 Pod 以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用 ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。

      在命令行接口(CLI)中,访问模式也使用以下缩写形式:

      • RWO - ReadWriteOnce 卷可以被一个节点以读写方式挂载
      • ROX - ReadOnlyMany 卷可以被多个节点以只读方式挂载
      • RWX - ReadWriteMany 卷可以被多个节点以读写方式挂载
      • RWOP - ReadWriteOncePod 卷可以被单个 Pod 以读写方式挂载
    卷插件ReadWriteOnceReadOnlyManyReadWriteManyReadWriteOncePod
    AWSElasticBlockStore---
    AzureFile-
    AzureDisk---
    CephFS-
    Cinder-(如果多次挂接卷可用)-
    CSI取决于驱动取决于驱动取决于驱动取决于驱动
    FC--
    FlexVolume取决于驱动-
    Flocker---
    GCEPersistentDisk--
    Glusterfs-
    HostPath---
    iSCSI--
    Quobyte-
    NFS-
    RBD--
    VsphereVolume-- (Pod 运行于同一节点上时可行)-
    PortworxVolume--
    StorageOS---

    1.5.3 PV创建方式

    1. 自动创建
      1.1 管理员创建存储类(StorageClass)
      1.2 用户创建持久化存储卷声明
      1.3 调用存储类,通知系统使用存储类创建PV
      1.4 获取存储类信息
      1.5 基于存储类创建PV
      1.6 用户创建使用PVC的POD
      1.7 指定POD使用哪个PVC
      1.8 PVC使用PV存储数据
    2. 手动创建

    1.5.4 pv参数

    PersistentVolume参数:

    Capacity: 当前pv空间大小
    accessModes: 访问模式
      ReadWriteOnce	PV可以被一个节点以读写方式挂载
      ReadOnlyMany      PV可以被多个节点以只读方式挂载
      ReadWriteMany   PV可以被多个节点以读写方式挂载
    persistentVolumeReclaimPolicy 删除机制删除数据存储的时候,已经创建好的卷由以下删除操作.
       Retain -- 手动回收
       Recycle -- 基本擦除 (`rm -rf /thevolume/*`) 仅支持NFS和HostPath
       Delete -- 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除
    volumeMode	#卷类型
      定义存储卷使用的文件系统是块设备还是文件系统,默认文件系统
    mountOptions  附加的挂载选项列表,实现更精细的权限控制
      ro 等
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.5.5 回收策略

    当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除, 从而允许该资源被回收再利用。PersistentVolume 对象的回收策略告诉集群, 当其被从申领中释放时如何处理该数据卷。 目前,数据卷可以被 Retained(保留)、Recycled(回收)或 Deleted(删除)。

    目前的回收策略有:

    • Retain – 手动回收
    • Recycle – 基本擦除 (rm -rf /thevolume/*) 仅支持NFS和HostPath
    • Delete – 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除

    每个卷会处于以下阶段(Phase)之一:
    Available(可用)-- 卷是一个空闲资源,尚未绑定到任何申领;
    Bound(已绑定)-- 该卷已经绑定到某申领;
    Released(已释放)-- 所绑定的申领已被删除,但是资源尚未被集群回收;
    Failed(失败)-- 卷的自动回收操作失败。

    1.5.6 PersistentVolumeClaims

    pvc的访问模式:

    • RWO - ReadWriteOnce PVC可以被一个节点以读写方式挂载
    • ROX - ReadOnlyMany PVC可以被多个节点以只读方式挂载
    • RWX - ReadWriteMany PVC可以被多个节点以读写方式挂载

    pvc创建参数

    accessModes:
      ReadWriteOnce	PVC可以被一个节点以读写方式挂载
      ReadOnlyMany      PVC可以被多个节点以只读方式挂载
      ReadWriteMany   PVC可以被多个节点以读写方式挂载
    
    resources:  定义pvc创建存储卷的空间大小
    
    selector: 标签选择器,选择要绑定的pv
      matchLables  匹配标签名称
      matchExpressions  基于正则匹配
    volumeName  要绑定的pv名称
    volumeMode  卷类型
    	定义pvc使用文件系统是块设备还是文件系统,默认是文件系统
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    【题解】同济线代习题一.8.3
    【C++基础】【集成编译环境04】Visual Station 2022 项目集成【2】 Opencv 的库的项目集成和遇到的坑
    【LMKD】十 有问有答 - FAQ
    网络安全入门必知的靶场!
    Pytorch安装20221029
    Day 83
    第14课 形变之城--故事卡--听ChatGPT说
    轧钢切头飞剪机设计及有限元分析
    Shell脚本学习指南(二)——查找与替换
    无人注意,新安装的 Ubuntu 23.04 不支持安装 32 位应用
  • 原文地址:https://blog.csdn.net/qq_29974229/article/details/126180759