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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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
1 2 | kubectl create configmap game-config2 --from- file =.. /configMapFile/game .properties #使用文件创建configMap; kubectl get cm game-config2 -o yaml |
多次使用文件创建,与在该目录下一次性批量创建效果相同。
3、使用字面量创建configMap
1 2 | 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注入环境变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
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 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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热更新
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 | 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热更新
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 | 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案例
1 2 3 4 | 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案例
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 | 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中; |
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 | #将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案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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的认证信息<br>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服务器容器提供数据时,保存内容管理器容器提取的文件;
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 | 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卷。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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;
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | ##安装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 |
1 2 3 4 5 6 7 8 9 10 11 | ###测试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字段内容。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律