zoukankan      html  css  js  c++  java
  • kubernetes集群系列资料13--存储机制介绍

    一、K8S存储机制介绍  

      k8s的stateful控制组件是为有状态服务而设计的,有状态服务需要对数据进行存储;k8s有4种存储机制,主要为:

      1)configMap:为K8S存储配置文件而设计的,configMap可以用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
      2)secret:为了解决密码、token、密钥等敏感数据的配置加密而设计,而不需要将这些敏感数据暴露到镜像或pod.spec中,可以volume或环境变量的方式使用。
      3)volume:为容器提供共享存储卷,避免发生容器崩溃重启后容器中文件丢失的问题。当pod不存在时,volume也不复存在;k8s支持多种类型的卷,pod可使用任意数量的卷。
      4)persistentVolume/persistentVolumeClai:

    二、configMap介绍

      许多应用程序从配置文件、命令行参数或环境变量中读取配置信息,而configMap API给我们提供了向容器注入配置信息的机制。
      传统生成环境中,配置文件注册中心负责向n个集群n个节点应用程序的提供配置信息,该中心需要自行构建,没有较好的开源方案。应用程序向配置文件注册中心提供本节点的信息(如:IP、hostname),配置文件注册中心根据规则为该节点应用程序更新配置,应用程序按照新配置进行重载后运行。
      k8s集群中,configMap充当了配置文件注册中心的作用。pod向configMap申请配置,configMap为各pod下发不同的配置。
      configMap创建配置有3中方式:使用目录创建、使用文件创建、使用字面值创建。

    1、使用目录创建configMap

    mkdir configMapFile;cd configMapFile
    cat > game.properties <<eof
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    enemies.code.passphrase=UUDDLRLRBABAS
    enemies.code.allowed=true
    enemies.code.lives=30
    eof
    
    cat >ui.properties<<eof
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
    eof
    
    kubectl create configmap game-config --from-file=../configMapFile #创建configMap;
    kubectl get configmap               #查看configMap;
    kubectl get cm game-config -o yaml  #以yaml格式输出game-config配置;
    kubectl get cm game-config -o json    #以yaml格式输出game-config配置;
    

     2、使用文件创建configMap

    kubectl create configmap game-config2 --from-file=../configMapFile/game.properties #使用文件创建configMap;
    kubectl get cm game-config2 -o yaml
    

      多次使用文件创建,与在该目录下一次性批量创建效果相同。

    3、使用字面量创建configMap

    kubectl create configmap game-config3 --from-literal=special.how=very --from-literal=special.type=charm #使用字面量创建configMap;
    kubectl get cm game-config3 -o yaml
    

    4、案例:使用configMap向pod注入环境变量

    cat >special-config.yaml<<eof
    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: special-config
        namespace: default
    data:
        special.how: very
        special.type: charm
    eof
    kubectl apply -f special-config.yaml #使用yaml文件创建configMap;
    
    cat >env-config.yaml<<eof
    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: env-config
        namespace: default
    data:
        log_level: INFO
    eof
    kubectl apply -f env-config.yaml
    

    cat >pod_configMapTest.yaml<<eof
    apiVersion: v1
    kind: Pod
    metadata:
        name: dapi-test-pod
        namespace: default
    spec:
        containers:
            - name: test-container
              image: hub.atguigu.com/library/nginx:latest
              command: ["/bin/sh","-c","env"]
              env:                              #设置pod环境变量;
                - name: SPECIAL_LEVEL_KEY
                  valueFrom:                    #向pod环境变量注入special-config配置中某个键的值;
                    configMapKeyRef:
                        name: special-config
                        key: special.how
                - name: SPECIAL_TYPE_KEY
                  valueFrom:
                    configMapKeyRef:
                        name: special-config
                        key: special.type
              envFrom:                          #向pod注入env.config配置中所有键值对;
                - configMapRef:
                    name: env-config
        restartPolicy: Never
    eof
    kubectl apply -f pod_configMapTest.yaml
    

    验证结果显示:环境变量包含导入的变量SPECIAL_LEVEL_KEY、SPECIAL_TYPE_KEY、log_level。

     5、案例:通过volume来使用configMap

    cat >pod_configMapTest_1.yaml<<eof
    apiVersion: v1
    kind: Pod
    metadata:
        name: dapi-test-pod-1
        namespace: default
    spec:
        containers:
        - name: test-container
          image: hub.atguigu.com/library/nginx:latest
          command: ["/bin/sh","-c","ls /etc/config/"]
          volumeMounts:                     #指定挂载卷;
            - name: config-volume           #指定挂载卷名称;
              mountPath: /etc/config        #指定挂载卷挂载点;
        volumes:
            - name: config-volume
              configMap:
                name: special-config        #将configMap导入pod的volume中,有不同的选型。基本方式为:将文件填入volume,键以文件名显示,值以内容显示;
        restartPolicy: Never
    eof
    kubectl apply -f pod_configMapTest_1.yaml
    

    5、案例:configMap热更新

    cat >config_update_test.yaml<<eof
    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: log-config
        namespace: default
    data:
        log_level: INFO
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
        name: my-nginx
        namespace: default
    spec:
        replicas: 1
        template:
            metadata:
                labels:
                    run: my-nginx
            spec:
                containers:
                - name: my-nginx
                  image: hub.atguigu.com/library/nginx:latest
                  ports:
                  - containerPort: 80
                  volumeMounts:                     #指定挂载卷;
                    - name: config-volume           #指定挂载卷名称;
                      mountPath: /etc/config        #指定挂载卷挂载点;
                volumes:
                    - name: config-volume
                      configMap:
                        name: log-config        #将configMap导入pod的volume中,有不同的选型。基本方式为:将文件填入volume,键以文件名显示,值以内容显示;
                restartPolicy: Always
    eof
    kubectl apply -f config_update_test.yaml
    kubectl exec $(kubectl get pod -l run=my-nginx -o=name |cut -d "/" -f2) -it -- cat /etc/config/log_level #查看导入pod的configMap配置,该值以volume文件存在;

    验证结果:配置写入volume的log_level文件。

     

    6、案例:configMap热更新

    cat >config_update_test.yaml<<eof
    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: log-config
        namespace: default
    data:
        log_level: INFO
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
        name: my-nginx
        namespace: default
    spec:
        replicas: 1
        template:
            metadata:
                labels:
                    run: my-nginx
            spec:
                containers:
                - name: my-nginx
                  image: hub.atguigu.com/library/nginx:latest
                  ports:
                  - containerPort: 80
                  volumeMounts:                     #指定挂载卷;
                    - name: config-volume           #指定挂载卷名称;
                      mountPath: /etc/config        #指定挂载卷挂载点;
                volumes:
                    - name: config-volume
                      configMap:
                        name: log-config        #将configMap导入pod的volume中,有不同的选型。基本方式为:将文件填入volume,键以文件名显示,值以内容显示;
                restartPolicy: Always
    eof
    kubectl apply -f config_update_test.yaml
    kubectl exec $(kubectl get pod -l run=my-nginx -o=name |cut -d "/" -f2) -it -- cat /etc/config/log_level #查看导入pod的configMap配置,该值以volume文件存在;
    kubectl edit configmap log-config #修改configMap配置log_level值改为DEBUG;
    kubectl patch deployment my-nginx --patch '{"spec":{"template":{"metadata":{"annotations":{"version/config":"20210618 14:53:00"}}}}}' #手动指定20210618 14:53:00重新加载配置文件,以便配置文件生效;
    kubectl exec $(kubectl get pod -l run=my-nginx -o=name |cut -d "/" -f2) -it -- cat /etc/config/log_level #查看log_level值是否修改;
    

    验证结果:configMap配置已热更新。

     三、secret介绍 

    service Account:用来访问K8S API,由K8S自动创建,并且会自动挂载到pod的/run/secrets/kubernetes.io/serviceaccount目录中;对于有些pod(如coreDNS、flannel)来说,需要与K8S API进行交互,K8S API不是谁都可以访问的,必须通过挂载SA后pod才能访问K8S API;

    opaque:base64编码格式的secret,用来存储密码、密钥等;opaque类型的数据是一个map类型,要求value是base64编码格式;
    kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息;

    1、SA案例

    kubectl run nginx --image nginx #创建名为nginx的depoloyment及pod;
    kubectl get deployment;kubectl get pods
    kubectl exec nginx-7bb7cd8db5-czg6s ls /run/secrets/kubernetes.io/serviceaccount #查看sa的默认挂载的目录;
    kubectl get secret -n kube-system #查看集群自动创建的secret;
    

     2、opaque案例

     

    echo -n 'admin' |base64 	#输出以base64加密结果为YWRtaW4=;
    echo -n '1qaz@WSX' |base64 	#输出以base64加密结果为MXFhekBXU1g=;
    echo -n 'YWRtaW4=' |base64 -d  #输出YWRtaW4=的解密结果为admin;
    cat >secret.yml<<eof
    apiVersion: v1
    kind: Secret
    metadata:
        name: mysecret
    data:
        username: YWRtaW4=
        password: MXFhekBXU1g=
    eof
    kubectl apply -f secret.yml
    kubectl get secret
    #将secret挂载到volume中
    cat >secret-pod.yml<<eof
    apiVersion: v1
    kind: Pod
    metadata:
        labels:
            name: secret-test
        name: secret-test
    spec:
        volumes:
        - name: secrets
          secret:
            secretName: mysecret
        containers:
        - image: hub.atguigu.com/library/nginx:latest
          name: db
          volumeMounts:
          - name: secrets
            mountPath: '/etc/secrets'
            readOnly: true
    eof
    kubectl apply -f secret-pod.yml
    kubectl get pod
    kubectl exec secret-test -it -- cat /etc/secrets/username #验证secret是否导入volume中;
    

    #将secret导出到pod的环境变量中
    cat >secret-pod-out.yml<<eof
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
        name: secret-pod-out-deployment
    spec:
        replicas: 2
        template:
            metadata:
                labels:
                    app: secret-pod-out-deployment
            spec:
                containers:
                - image: hub.atguigu.com/library/nginx:latest
                  name: pod-1
                  ports:
                  - containerPort: 80
                  env:
                  - name: TEST_USER
                    valueFrom:
                        secretKeyRef:
                            name: mysecret
                            key: username
                  - name: TEST_PASSWORD
                    valueFrom:
                        secretKeyRef:
                            name: mysecret
                            key: password
    eof
    kubectl apply -f secret-pod-out.yml
    kubectl get pod
    kubectl exec secret-pod-out-deployment-7b8f585846-2cvj6 -it -- echo $TEST_PASSWORD #验证secret是否导入pod中;
    

    3、kubernetes.io/dockerconfigjson案例

    kubectl create secret docker-registry myregistrykey --docker-server=hub.atguigu.com --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@example.com #创建docker registry认证的secret;私有仓库不进行认证就无法下载镜像,因此需要创建该secret来存储私有docker registry的认证信息
    cat >myregistry-secret.yml<<eof apiVersion: v1 kind: Pod metadata: name: foo spec: containers: - image: hub.atguigu.com/library/nginx:latest name: foo imagePullSecrets: - name: myregistrykey eof kubectl apply -f myregistry-secret.yml kubectl get pod

     四、volume介绍

    docker中,容器崩溃后重启时数据不会丢失;但K8S中,容器崩溃时,该容器的文件会丢失,kubelet重启该容器,容器以镜像最初状态重新启动;POD中同时运行的多个容器需要共享文件。
    k8s支持以下类型的卷:emptyDir;hostPath;iscsi;local;nfs;awsElasticBlockStore;azureDisk;azureFile;cephfs;csi;downwardAPI;fc;flocker;gcePersistentDisk;gitRepo;glusterfs;persistentVolumeClaim;projected;portworxVolume;quobyte;rbd;scaleIO;secret;storageos;vsphereVolume;

    1、emptyDir介绍  

    当pod被分配给节点时,首先创建emptyDir卷,并且只要该pod在该节点上运行,该卷就会存在。该卷最初时空的,pod中容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同的路径上。当处于任何原因从节点中删除pod时,emptyDir中数据将被永久删除。
    empty的用法有:
      暂存空间,如:用于基于磁盘的合并排序;
      用作长时间计算崩溃恢复时的检查点;
      web服务器容器提供数据时,保存内容管理器容器提取的文件;

    cat >volume-emptyDir.yml<<eof
    apiVersion: v1
    kind: Pod
    metadata:
        name: volume-test-pod
    spec:
        containers:
        - image: hub.atguigu.com/library/nginx:latest
          name: volume-test-container
          volumeMounts:
          - mountPath: /cache
            name: cache-volume
        - image: hub.atguigu.com/library/busybox:latest
          name: liveness-exec-container
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh","-c","touch /tmp/live;sleep 6000s"]
          volumeMounts:
          - mountPath: /test
            name: cache-volume      
        volumes:
        - name: cache-volume
          emptyDir: {}
    eof
    kubectl apply -f volume-emptyDir.yml
    kubectl get pod
    kubectl exec volume-test-pod -c volume-test-container -it -- touch /cache/test.txt
    kubectl exec volume-test-pod -c volume-test-container -it -- ls /cache
    kubectl exec volume-test-pod -c liveness-exec-container -it -- ls /test
    

    2、hostPath介绍  

    hostPath卷:将主机节点的文件系统中文件或目录挂载到集群中;用途如下:
      运行需要访问docker内部的容器;使用/var/lib/docker的hostPath;
      在容器中运行cAdvisor(K8S中一个用于监控docker的组件);使用/dev/cgroups的hostPath;
      允许pod指定给定的hostPath是否应该在pod运行之前存在,是否应该创建,以及它应该以什么形式存在;
    hostPath卷属性有path,type;
      type: #type默认值为空,用于向后兼容,意味着在挂载hostPath卷之前不会执行任何检查。
      type:DirectoryOrCreate #如果在给定的路径上没有任何东西存在,则根据需要创建一个空目录,权限为0755,与kubelet具有相同的组和所有权;
      type:Directory #给定的路径上必须存在目录;
      type:FileOrCreate #如果在给定的路径上没有任何东西存在,则根据需要创建一个空文件,权限为0644,与kubelet具有相同的组和所有权;
      type:File #给定的路径上必须存在文件;
      type:Socket #给定的路径上必须存在UNIX套接字;
      type:CharDevice #给定的路径上必须存在字符设备;
      type:BlockDevice #给定的路径上必须存在块设备;
    使用hostPath卷注意事项:
      由于每个节点上的文件都不同,具有相同配置的pod在不同节点上的行为可能会有所不同;
      当K8S按照计划添加资源感知调度时,将无法考虑hostPath使用的资源;
      在底层主机上创建的文件或目录只能由root写入。您需要在特权容器中以root身份运行进程,或修改主机上文件权限以便写入hostPath卷。

    cat >volume-hostPath.yml<<eof
    apiVersion: v1
    kind: Pod
    metadata:
        name: hostpath-volume-pod
    spec:
        containers:
        - image: hub.atguigu.com/library/nginx:latest
          name: hostPath-volume--container
          volumeMounts:
          - mountPath: /cache
            name: cache-volume
        volumes:
        - name: cache-volume
          hostPath: 
            path: /data
            type: Directory
    eof
    kubectl apply -f volume-hostPath.yml  #确保调度节点存在/data/目录;
    kubectl get pod
    kubectl exec volume-test-pod -c volume-test-container -it -- touch /cache/test.txt
    

    五、PV及PVC介绍

     PV(persistentVolume)

      是由管理设置的存储,它是集群的一部分。就像节点是集群中的资源一样,PV也是集群中的资源。PV是volume之类的卷插件,但居于哦独立于使用PV的pod的生命周期。此API对象包含存储实现的细节,接NFS,iSCSI或特定于云供应商的存储系统。

    PVC(persistentVolumeClaim)
      是用户存储的请求。它与pod相似。pod消耗节点资源,PVC消耗PV资源。pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(如:可以读/写一次或只读多次模式挂载);

    静态PV
      集群管理员创建一些PV。他们带有可供集群用户使用的实际存储的细节他们存在于K8S API中,可用于消费;

    动态PV(实现方式复杂,价格昂贵,不太成熟,但是是未来的趋势)
      当管理员创建静态PV都不匹配用户的persistentVolumeClaim时,集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses:PVC必须请求[存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为“”可以有效地金庸其动态配置。
      要启用基于存储级别的动态存储配置,集群管理员需要启用API server上的DefaultStorageClass【准入控制器】。例如,通过确保DefaultStorageClass位于API server组件的--admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作。

    绑定
      master中的控制环路监视新的PVC,寻找匹配的PV(如果可能),并将它们绑定在一起。如果为新的PVC动态调配PV,则该环路将始终将PV绑定到PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦PV和PVC绑定后,PersistentVolumeClaimbanging是排他性的,不管它们是如何绑定的。PVC跟PV绑定是一对一的映射。一般情况下,PVC规定容量一般小于PV容量,很少情况会出现近似相等。

    持久化卷声明的保护
      PVC保护的目的是确保由POD正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失。当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,指导PVC不再被任何pod使用。注意:当pod状态为pending并且pod已经分配给节点或pod为running状态时,PVC处于活动状态。

    PV类型以插件形式实现。K8S目前支持以下插件类型:
      awsElasticBlockStore;azureDisk;azureFile;FC(fiber channel);
      FlexVolume;Flocker;NFS;iSCSI;RBD(ceph block device);cephFS;
      cinder(openstack block storage);glusterfs;vshpereVolume;quobyte volumes;
      HostPath;VMware Photon;portworx Volumes;scaleIO volumes;storageOS;

    PV访问模式:
      persistentVolume可以资源提供者支持的任何方式挂载到主机上。供应商具有不同的功能,每个PV的访问模式都将被设置为怪卷支持的特定模式;如:NFS可支持多个读/写客户端,但特定的NFS PV可能以只读方式导出到服务器。每  个PV都有一套自己的用来描述特定功能的访问模式。一个卷只能使用一种访问模式挂载,即使它支持很多访问模式。
      ReadWriteOnce(RWO)---该卷可以被单个节点以读/写模式挂载;
      ReadOnlyMany(ROX)---该卷可以被多个节点以只读模式挂载;
      ReadWriteMany(RWX)---该卷可以被多个节点以读/写模式挂载;

    回收策略:
      retain(保留)---手动回收;PV不再被pod使用,但也不允许其他pod使用,等待管理员去手动释放数据。
      recycle(回收)---基本擦除(rm -rf /thevolume/*);最新版K8S不支持。
      delete(删除)---关联的存储资产(如AWS EBS|GCE PD|AZURE DISK|OPENSTACK CINDER)将被删除;
      当前只有NFS和hostPath支持回收策略。AWS EBS|GCE PD|AZURE DISK|OPENSTACK CINDER支持删除策略。

    卷可以处于以下某种状态:
      available(可用)---一块空闲资源还没有被任何声明绑定;
      bound(已绑定)---卷已经被声明绑定;
      released(已释放)---声明被删除,但是资源还未被集群重新声明。
      failed(失败)---该卷的自动回收失败。
    命令行会显示绑定到PV的PVC的名称。

    创建statefuSet前必须要创建要给SVC;

    ##安装NFS服务器(选定K8S集群之外的主机部署,IP为192.168.66.100)
    yum install -y nfs-common nfs-utils rpcbind
    mkdir /nfsdata
    chmod 777 /nfsdata          #慎用权限;
    chown nfsnobody /nfsdata
    cat >>/etc/exports<<eof  
    /nfsdata *(rw,no_root_squash,no_all_squash,sync) #创建一个nfs文件系统;
    eof
    systemctl enable rpcbind;systemctl start rpcbind;systemctl status rpcbind
    systemctl enable nfs;systemctl start nfs;systemctl status nfs
    mkdir /nfs{1..3}            #在nfs服务器创建3个空目录;
    chmod 777 /nfs{1..3}         
    chown nfsnobody /nfs{1..3} 
    
    cat >>/etc/exports<<eof     #在创建3个nfs文件系统;
    /nfs1 *(rw,no_root_squash,no_all_squash,sync) 
    /nfs2 *(rw,no_root_squash,no_all_squash,sync) 
    /nfs3 *(rw,no_root_squash,no_all_squash,sync) 
    eof
    systemctl restart rpcbind nfs
    ##所有K8S集群节点安装工具
    yum install -y nfs-utils rpcbind
    mkdir /nfs_test/
    showmount -e 192.168.66.100
    mount -t nfs 192.168.66.100:/nfsdata /nfs_test/ #将nfs服务器192.168.66.100的/nfsdata挂载至本机/nfs_test目录下;
    cd /nfs_test/
    echo "nfs_test" >test.txt #在nfs服务器192.168.66.100的/nfsdata与本机/nfs_test目录下都可看见创建的test.txt;
    umount /nfs_test/ #卸载挂载的nfs服务器192.168.66.100的/nfsdata;
    
    ##部署PV
    cat >PV.yml<<eof
    apiVersion: v1
    kind: PersistentVolume
    metadata:
        name: nfspv1
    spec:
        capacity:
            storage: 10Gi                       #声明卷的容量;
        accessModes:
            - ReadWriteOnce                     #声明访问方式;
        persistentVolumeReclaimPolicy: Retain   #声明回收策略;
        storageClassName: nfs                   #指定要绑定PV的类;非常重要的一个指标;
        nfs:
            path: /nfsdata
            server: 192.168.66.100
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
        name: nfspv01
    spec:
        capacity:
            storage: 5Gi                       #声明卷的容量;
        accessModes:
            - ReadWriteMany                     #声明访问方式;
        persistentVolumeReclaimPolicy: Retain   #声明回收策略;
        storageClassName: slow                   #指定要绑定PV的类;非常重要的一个指标;
        nfs:
            path: /nfs1
            server: 192.168.66.100
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
        name: nfspv02
    spec:
        capacity:
            storage: 5Gi                       #声明卷的容量;
        accessModes:
            - ReadWriteOnce                     #声明访问方式;
        persistentVolumeReclaimPolicy: Retain   #声明回收策略;
        storageClassName: nfs                   #指定要绑定PV的类;非常重要的一个指标;
        nfs:
            path: /nfs2
            server: 192.168.66.100
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
        name: nfspv03
    spec:
        capacity:
            storage: 1Gi                       #声明卷的容量;
        accessModes:
            - ReadWriteOnce                     #声明访问方式;
        persistentVolumeReclaimPolicy: Retain   #声明回收策略;
        storageClassName: nfs                   #指定要绑定PV的类;非常重要的一个指标;
        nfs:
            path: /nfs3
            server: 192.168.66.100
    eof
    kubectl apply -f PV.yml
    kubectl get pv          #此时pv可以直接挂载至pod使用了;但正常情况下,使用PVC来调用PV;
    ##创建服务并使用PVC
    cat >PVC.yml<<eof
    apiVersion: v1
    kind: Service
    metadata:
        name: nginx
        labels:
            app: nginx
    spec:
        ports:
        - port: 80
          name: web
        clusterIP: None
        selector:
            app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet       #创建statefuSet前必须要创建要给SVC;
    metadata:
        name: web
    spec:
        selector:
            matchLabels:
                app: nginx
        serviceName: "nginx"  #必须为无头服务(即该服务必须为clusterIP: None)才行;
        replicas: 3
        template:
            metadata:
                labels:
                    app: nginx
            spec:
                containers:
                - name: nginx
                  image: hub.atguigu.com/library/nginx:latest
                  ports:
                  - containerPort: 80
                    name: web
                  volumeMounts:
                  - name: www
                    mountPath: /usr/share/nginx/html
        volumeClaimTemplates:                           #声明卷的请求;
        - metadata:
            name: www
          spec:
            accessModes: ["ReadWriteOnce"]
            storageClassName: "nfs"
            resources:
                requests:
                    storage: 1Gi
    eof
    kubectl apply -f PVC.yml
    kubectl get pv
    kubectl get pvc
    kubectl get pod
    kubectl get statefulset
    

    ###测试NFS卷的使用
    ##在NFS服务器操作
    cd /nfs3        #根据实际pv确定目录;
    echo "hello world" >index.html
    chmod 777 index.html
    chown nfsnobody index.html
    ##在K8S master操作
    curl 10.244.2.157           #该IP为名为web-0的pod调度节点的IP;
    kubectl delete pod web-0    
    kubectl get pod -o wide
    curl 10.244.2.159           #访问新pod,其pv内容不会变化。
    

     1、PV手动回收

     

     

     删除statefulset、pod、pvc后,需要手动释放pv时,需要至NFS服务器删除对应目录下的文件及pv下的claimRef字段内容。

     

     

      

      

      

      

      

      

     

  • 相关阅读:
    wpf 获取datagrid中模板中控件
    WPF DataGrid DataGridTemplateColumn 控制模板中控件
    ztree实现拖拽移动和复制
    layui的select监听
    layui父页面获取子页面数据
    win10安装网络适配器
    bat启动OpenOffice4
    java注解简单使用
    win7安装IIS
    java的Array和List相互转换
  • 原文地址:https://www.cnblogs.com/chalon/p/14898159.html
Copyright © 2011-2022 走看看