关于 Kubernetes中Volume的一些笔记(一)
写在前面
学习K8s,刚把这一块学完,整理笔记,理论很少,偏实战,适合温习
博文内容涉及:
常见nfs,hostPath,emptyDir数据卷类型
PV+PVC的创建
持久性存储及动态卷供应
男女情事,谁先动心谁吃亏,越吃亏越难忘,到最后,到底是喜欢对方呢,还是喜欢自己,都搞不清楚了,答案偏偏在对方身上,所以才说,由爱故生忧。--------《剑来》
数据卷(Volume)管理
Volume是Pod中能够被多个容器访问的共享目录。Kuberetes的Volume概念、用途和目的与Docker的Volume比较类似,但两者不能等价。
Volume的使用也比较简单,在大多数情况下,我们先在Pod上声明一个Volume,然后在容器里引用该Volume并Mount到容器里的某个目录上。举例来说,我们要给之前的Tomcat Pod增加一个名字为datavol的Volume,并且Mount到容器的/mydata-data目录上,则只要对Pod的定义文件做如下修正即可(注意黑体字部分):
template: metadata: labels: app: app-demo tier: frontend spec: volumes: - name: datavol emptyDir: {} containers: - name: tomcat-demo image: tomcat volumeMounts: - mountPath: /myddata-data name: datavol imagePullPolicy: IfNotPresent
除了可以让一个Pod里的多个容器共享文件、让容器的数据写到宿主机的磁盘上或者写文件到网络存储中, Kubernetes的Volume还扩展出了一种非常有实用价值的功能,即
:
容器配置文件集中化定义与管理
,这是通过ConfigMap这个新的资源对象来实现的.
Kubernetes提供了非常丰富的Volume类型
学习环境准备
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$mkdir k8s-volume-create;cd k8s-volume-create ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl get ns NAME STATUS AGE default Active 49d kube-node-lease Active 49d kube-public Active 49d kube-system Active 49d liruilong Active 49d liruilong-pod-create Active 41d
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl create ns liruilong-volume-create namespace/liruilong-volume-create created ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl config set-context $(kubectl config current-context) --namespace=liruilong-volume-create Context "context1" modified. ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE cluster1 default * context1 cluster1 kubernetes-admin1 liruilong-volume-create context2 kube-system
emptyDir
一个emptyDir Volume是在Pod分配到Node时创建的
。
从它的名称就可以看出,它的初始内容为空,并且无须指定宿主机上对应的目录文件
,因为这是
Kubernetes自动分配的一个目录
,而且这个目录实际是挂载中物理机内存中的的,当Pod从Node上移除时, emptyDir中的数据也会被永久删除。
emptyDir的一些用途如下:
创建一个Pod,声明volume卷
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolume name: podvolume spec: volumes: - name: volume1 emptyDir: {} - name: volume2 emptyDir: {} containers: - image: busybox imagePullPolicy: IfNotPresent command: ['sh','-c','sleep 5000'] resources: {} name: podvolume1 volumeMounts: - mountPath: /liruilong name: volume1 - image: busybox imagePullPolicy: IfNotPresent name: podvolume2 volumeMounts: - mountPath: /liruilong name: volume2 command: ['sh','-c','sleep 5000'] dnsPolicy: ClusterFirst restartPolicy: Always status: {}
创建pod,查看运行状态
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl apply -f pod_volume.yaml pod/podvolume configured ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES podvolume 0/2 CrashLoopBackOff 164 (117s ago) 37h 10.244.70.14 vms83.liruilongs.github.io
查看pod的数据卷类型
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl describe pod podvolume | grep -A2 Volumes Volumes: volume1: Type: EmptyDir (a temporary directory that shares a pod's lifetime)
通过docker命令来查看对应的宿主机容器
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible 192.168.26.83 -m shell -a "docker ps | grep podvolume" 192.168.26.83 | CHANGED | rc=0 >> bbb287afc518 cabb9f684f8b "sh -c 'sleep 5000'" 12 minutes ago Up 12 minutes k8s_podvolume2_podvolume_liruilong-volume-create_76b518f6-9575-4412-b161-f590ab3c3135_0 dcbf5c63263f cabb9f684f8b "sh -c 'sleep 5000'" 12 minutes ago Up 12 minutes k8s_podvolume1_podvolume_liruilong-volume-create_76b518f6-9575-4412-b161-f590ab3c3135_0 5bb9ee2ed134 registry.aliyuncs.com/google_containers/pause:3.4.1 "/pause" 12 minutes ago Up 12 minutes k8s_POD_podvolume_liruilong-volume-create_76b518f6-9575-4412-b161-f590ab3c3135_0 ┌──[root@vms81.liruilongs.github.io]-[~/ansible]
通过inspect查看映射的宿主机信息
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible 192.168.26.83 -m shell -a "docker inspect dcbf5c63263f | grep -A5 Mounts" 192.168.26.83 | CHANGED | rc=0 >> "Mounts": [ { "Type": "bind", "Source": "/var/lib/kubelet/pods/76b518f6-9575-4412-b161-f590ab3c3135/volumes/kubernetes.io~empty-dir/volume1", "Destination": "/liruilong", "Mode": "", ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible 192.168.26.83 -m shell -a "docker inspect bbb287afc518 | grep -A5 Mounts" 192.168.26.83 | CHANGED | rc=0 >> "Mounts": [ { "Type": "bind", "Source": "/var/lib/kubelet/pods/76b518f6-9575-4412-b161-f590ab3c3135/volumes/kubernetes.io~empty-dir/volume2", "Destination": "/liruilong", "Mode": "", ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$
pod内多容器数据卷共享
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$sed 's/podvolume/podvolumes/' pod_volume.yaml >pod_volumes.yaml ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$vim pod_volumes.yaml
编写pod_volumes.yaml文件
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolumes name: podvolumes spec: volumes: - name: volume1 emptyDir: {} containers: - image: busybox imagePullPolicy: IfNotPresent command: ['sh','-c','sleep 5000'] resources: {} name: podvolumes1 volumeMounts: - mountPath: /liruilong name: volume1 - image: busybox imagePullPolicy: IfNotPresent name: podvolumes2 volumeMounts: - mountPath: /liruilong name: volume1 command: ['sh','-c','sleep 5000'] dnsPolicy: ClusterFirst restartPolicy: Always status: {}
新建的文件夹中两个pod中同时存在
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl apply -f pod_volumes.yaml pod/podvolumes created ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl exec -it podvolumes -c podvolumes1 -- sh / # mkdir -p /liruilong/$(date +"%Y%m%d%H%M%S");cd /liruilong/;ls 20211127080726 /liruilong # /liruilong # exit ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl exec -it podvolumes -c podvolumes2 -- sh / # cd /liruilong/;ls 20211127080726 /liruilong #
设置数据卷的读写权限
pod_volume_r.yaml:设置数据卷pod1只读
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolume name: podvolume spec: volumes: - name: volume1 emptyDir: {} - name: volume2 emptyDir: {} containers: - image: busybox imagePullPolicy: IfNotPresent command: ['sh','-c','sleep 5000'] resources: {} name: podvolume1 volumeMounts: - mountPath: /liruilong name: volume1 readOnly: true # 设置数据卷pod1只读 - image: busybox imagePullPolicy: IfNotPresent name: podvolume2 volumeMounts: - mountPath: /liruilong name: volume2 command: ['sh','-c','sleep 5000'] dnsPolicy: ClusterFirst restartPolicy: Always status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl exec -it podvolume -c podvolume1 -- sh / # cd liruilong/;touch lrl.txt touch: lrl.txt: Read-only file system /liruilong # /liruilong # exit command terminated with exit code 1 ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl exec -it podvolume -c podvolume2 -- sh / # cd liruilong/;touch lrl.txt /liruilong # ls lrl.txt /liruilong #
hostPath
hostPath为在Pod上挂载宿主机上的文件或目录,它通常可以用于以下几方面。
在使用这种类型的Volume时,需要注意以下几点。
在不同的Node上具有相同配置的Pod可能会因为宿主机上的目录和文件不同而导致对Volume上目录和文件的访问结果不一致。
如果使用了资源配额管理,则Kubernetes无法将hostPath在宿主机上使用的资源纳入管理cgroup。在下面的例子中使用宿主机的/data目录定义了一个
hostPath类型的Volume:
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolumehostpath name: podvolumehostpath spec: volumes: - name: volumes1 hostPath: path: /data containers: - image: busybox name: podvolumehostpath command: ['sh','-c','sleep 5000'] resources: {} volumeMounts: - mountPath: /liruilong name: volumes1 dnsPolicy: ClusterFirst restartPolicy: Always status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl apply -f PodVolumeHostPath.yaml pod/podvolumehostpath created
宿主机创建一个文件
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create] └─$kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES podvolumehostpath 1/1 Running 0 5m44s 10.244.70.9 vms83.liruilongs.github.io
pod容器内同样存在
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$kubectl exec -it podvolumehostpath -- sh / # ls bin dev etc home liruilong proc root sys tmp usr var / # cd liruilong/;ls liruilong /liruilong #
NFS
不管是emptyDir还是hostPath,数据都是存放到宿主机,但是如某个pod出现了问题,通过控制器重启时,会通过调度生产一个新的Pod,如果调度的节点不是原来的节点,那么数据就会丢失。这里的话,使用网路存储就很方便。
部署一个NFSServer
使用NFS网络文件系统提供的共享目录存储数据时,我们需要在系统中部署一个NFSServer
┌──[root@vms81.liruilongs.github.io]-[~] └─$yum -y install nfs-utils.x86_64 ┌──[root@vms81.liruilongs.github.io]-[~] └─$systemctl enable nfs-server.service --now ┌──[root@vms81.liruilongs.github.io]-[~] └─$mkdir -p /liruilong ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$cd /liruilong/;echo `date` > liruilong.txt ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$cd /liruilong/;cat liruilong.txt 2021年 11月 27日 星期六 21:57:10 CST ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$cat /etc/exports ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$echo "/liruilong *(rw,sync,no_root_squash)" > /etc/exports ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$exportfs -arv exporting *:/liruilong ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$showmount -e Export list for vms81.liruilongs.github.io: /liruilong * ┌──[root@vms81.liruilongs.github.io]-[/liruilong] └─$
然后我们需要在所有的工作节点安装nfs-utils,然后挂载
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "yum -y install nfs-utils" ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "systemctl enable nfs-server.service --now"
nfs共享文件测试
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "showmount -e vms81.liruilongs.github.io" 192.168.26.83 | CHANGED | rc=0 >> Export list for vms81.liruilongs.github.io: /liruilong * 192.168.26.82 | CHANGED | rc=0 >> Export list for vms81.liruilongs.github.io: /liruilong * ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$
挂载测试
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "mount vms81.liruilongs.github.io:/liruilong /mnt" 192.168.26.82 | CHANGED | rc=0 >> 192.168.26.83 | CHANGED | rc=0 >> ┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "cd /mnt/;ls" 192.168.26.83 | CHANGED | rc=0 >> liruilong.txt 192.168.26.82 | CHANGED | rc=0 >> liruilong.txt
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "df -h | grep liruilong" 192.168.26.82 | CHANGED | rc=0 >> vms81.liruilongs.github.io:/liruilong 150G 8.3G 142G 6% /mnt 192.168.26.83 | CHANGED | rc=0 >> vms81.liruilongs.github.io:/liruilong 150G 8.3G 142G 6% /mnt
取消挂载
┌──[root@vms81.liruilongs.github.io]-[~/ansible] └─$ansible node -m shell -a "umount /mnt"
使用nfs数据卷pod资源yaml文件
podvolumenfs.yaml
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolumehostpath name: podvolumehostpath spec: volumes: - name: volumes1 nfs: server: vms81.liruilongs.github.io path: /liruilong containers: - image: busybox name: podvolumehostpath command: ['sh','-c','sleep 5000'] resources: {} volumeMounts: - mountPath: /liruilong name: volumes1 dnsPolicy: ClusterFirst restartPolicy: Always status: {}
Kubernetes
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。