Pod数据持久化
k8s中的volume提供了在容器中挂载外部存储的能力,Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)这两个信息后
才可以使用相应的volume
官方对volume的介绍:
Docker 也有 Volume 的概念,但对它只有少量且松散的管理。 在 Docker 中,Volume 是磁盘上或者另外一个容器内的一个目录。 直到最近,Docker 才支持对基于本地磁盘的 Volume 的生存期进行管理。 虽然 Docker 现在也能提供 Volume 驱动程序,但是目前功能还非常有限(例如,截至 Docker 1.7,每个容器只允许有一个 Volume 驱动程序,并且无法将参数传递给卷)。另一方面,Kubernetes 卷具有明确的生命周期——与包裹它的 Pod 相同。 因此,卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留。 当然,当一个 Pod 不再存在时,卷也将不再存在。也许更重要的是,Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。卷的核心是包含一些数据的目录,Pod 中的容器可以访问该目录。 特定的卷类型可以决定这个目录如何形成的,并能决定它支持何种介质,以及目录中存放什么内容。使用卷时, Pod 声明中需要提供卷的类型 (.spec.volumes
字段)和卷挂载的位置 (.spec.containers.volumeMounts
字段).容器中的进程能看到由它们的 Docker 镜像和卷组成的文件系统视图。 Docker 镜像 位于文件系统层次结构的根部,并且任何 Volume 都挂载在镜像内的指定路径上。 卷不能挂载到其他卷,也不能与其他卷有硬链接。 Pod 中的每个容器必须独立地指定每个卷的挂载位置。
Kubernetes 支持下列类型的卷:
- awsElasticBlockStore
- azureDisk
- azureFile
- cephfs
- cinder
- configMap
- csi
- downwardAPI
- emptyDir
- fc (fibre channel)
- flexVolume
- flocker
- gcePersistentDisk
- gitRepo (deprecated)
- glusterfs
- hostPath
- iscsi
- local
- nfs
- persistentVolumeClaim
- projected
- portworxVolume
- quobyte
- rbd
- scaleIO
- secret
- storageos
- vsphereVolume
参考地址:https://v1-17.docs.kubernetes.io/zh/docs/concepts/storage/volumes/#volume-%E7%9A%84%E7%B1%BB%E5%9E%8B
卷类型的简单分类:
1 本地卷:只在当前节点使用,无法跨节点使用 hostPath emptyDir
2 网络卷:在任意节点都可以访问到:nfs rbd cephfs glusterfs
3 公有云卷: awsElasticBlockStore azureDisk
4 k8s资源: secret configMap
emptyDir的使用介绍
在pod的宿主机上创建目录,挂载到Pod中的容器,Pod删除该卷也会被删除。
应用场景: pod 中容器之间的数据共
环境准备:为了方便测试需要把当前环境中的所有pod删除掉
1 [root@master ~]# kubectl get pod 2 NAME READY STATUS RESTARTS AGE 3 mypod 1/1 Running 2 3d1h 4 mypod2 1/1 Running 2 3d 5 mypod3 0/1 Completed 0 2d23h 6 web-5dcb957ccc-44rdl 1/1 Running 5 10d 7 web-5dcb957ccc-qpndh 1/1 Running 5 10d 8 web1-7f87dfbd56-6lckc 1/1 Running 2 3d10h 9 web2-7585bfb769-bfr9b 1/1 Running 2 3d10h 10 [root@master ~]# 11 [root@master ~]# kubectl delete $(kubectl get deploy -o name) 12 [root@master ~]# kubectl delete $(kubectl get pod -o name)
用yaml创建一个Pod,pod中有两个容器,两个容器之间通过emptyDir来共享数据
1 root@master ~]# vim pod.yaml 2 apiVersion: v1 3 kind: Pod #定义一个Pod资源 4 metadata: 5 name: my-pod #Pod的名字是my-pod 6 spec: 7 containers: #创建两个容器,容器的名字分别是write,read 8 - name: write 9 image: centos 10 command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"] 11 volumeMounts: #在容器中挂载一个卷 12 - name: data #卷的名字是data 13 mountPath: /data #把卷挂载到容器中的/data目录下 14 15 - name: read 16 image: centos 17 command: ["bash","-c","tail -f /data/hello"] 18 volumeMounts: 19 - name: data 20 mountPath: /data 21 22 volumes: #在pod中创建一个卷,注意这个卷要与containers同级 23 - name: data #卷的名字是data 24 emptyDir: {} #卷的类型是emptyDir, "{}"可以省略 25 26 [root@master ~]# 27 [root@master ~]# kubectl apply -f pod.yaml 28 [root@master ~]# kubectl get pod 29 NAME READY STATUS RESTARTS AGE 30 my-pod 2/2 Running 0 75s 31 [root@master ~]# 32 #在pod的write容器查看写入的数据, 33 #在pod的read容器中查看是否有数据 34 [root@master ~]# kubectl exec -it my-pod -c write -- sh 35 sh-4.4# ls /data 36 hello 37 sh-4.4# tail /data 38 tail: error reading '/data': Is a directory 39 sh-4.4# tail /data/hello 40 49 41 50 42 51 43 sh-4.4# 44 [root@master ~]# kubectl exec -it my-pod -c read -- sh 45 sh-4.4# tail /data/hello 46 2 47 3 48 4 49 sh-4.4# 50 #如何查看这个共享卷在宿主机上的物理目录? 51 #首先确认这个Pod当前在哪个node上 52 [root@master ~]# kubectl get pods -o wide 53 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 54 my-pod 2/2 Running 6 17m 10.244.2.99 node2 <none> <none> 55 [root@master ~]# 56 #在node2的节点上查看kubelet的目录 57 [root@node2 ~]# cd /var/lib/kubelet/ 58 [root@node2 kubelet]# ls 59 config.yaml cpu_manager_state device-plugins kubeadm-flags.env pki plugins plugins_registry pod-resources pods 60 [root@node2 kubelet]# cd pods 61 [root@node2 pods]# ls #在这个目录下查看pod的原数据,以下数据是以podID为目录名 62 41874bad-9f46-4417-b96c-6f41fd566ce1 c563f58d-dd2e-4937-867f-66d06ccc606d 63 5b2d78d8-0782-47c9-bf3f-202105824dee c87f53c4-5cc2-4842-910d-7206e636d83f 64 [root@node2 pods]# 65 #在当前node节点上查看my-pod的PodID为k8s_read_my-pod_default_5b2d78d8-0782-47c9-bf3f-202105824dee_0 66 67 [root@node2 pods]# docker ps | grep pod 68 69 a1eb18196f87 centos "bash -c 'tail -f /d…" About an hour ago Up About an hour k8s_read_my-pod_default_5b2d78d8-0782-47c9-bf3f-202105824dee_0 70 c16f2df96115 registry.aliyuncs.com/google_containers/pause:3.2 "/pause" About an hour ago Up About an hour k8s_POD_my-pod_default_5b2d78d8-0782-47c9-bf3f-202105824dee_0 71 [root@node2 pods]# 72 #在node2这个节点上进入5b2d78d8-0782-47c9-bf3f-202105824dee目录查看 73 [root@node2 pods]# cd 5b2d78d8-0782-47c9-bf3f-202105824dee/ 74 [root@node2 5b2d78d8-0782-47c9-bf3f-202105824dee]# ls 75 containers etc-hosts plugins volumes 76 [root@node2 5b2d78d8-0782-47c9-bf3f-202105824dee]# cd volumes/ 77 [root@node2 volumes]# ls 78 kubernetes.io~empty-dir kubernetes.io~secret 79 [root@node2 volumes]# ls ./kubernetes.io~empty-dir/data/hello 80 ./kubernetes.io~empty-dir/data/hello 81 [root@node2 data]# pwd #以下目录就是my-pod中两个容器中的/data的物理目录 82 /var/lib/kubelet/pods/5b2d78d8-0782-47c9-bf3f-202105824dee/volumes/kubernetes.io~empty-dir/data
hostPath
挂载Node文件系统上文件或者目录到pod的容器中
应用场景:Pod中容器需要访问宿主机文件,只能给当前节点的pod访问使用
1 [root@master ~]# vim pod-hostpath.yaml 2 3 apiVersion: v1 4 kind: Pod 5 metadata: 6 name: my-pod 7 spec: 8 containers: 9 - name: busybox 10 image: busybox 11 args: 12 - /bin/sh 13 - -c 14 - sleep 36000 15 volumeMounts: 16 - name: data 17 mountPath: /data 18 volumes: #定义一个卷 19 - name: data #卷的名字是data 20 hostPath: 21 path: /tmp #卷在宿主机上的地址是/tmp 22 type: Directory #卷的类型是一个目录 23 24 [root@master ~]# kubectl apply -f pod-hostpath.yaml 25 pod/my-pod2 created 26 [root@master ~]# 27 [root@master ~]# kubectl get pod 28 NAME READY STATUS RESTARTS AGE 29 my-pod 2/2 Running 32 3h12m 30 my-pod2 1/1 Running 0 78s 31 [root@master ~]# #查看pod所在的node节点 32 [root@master ~]# kubectl get pod -o wide 33 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 34 my-pod 2/2 Running 44 4h35m 10.244.2.99 node2 <none> <none> 35 my-pod2 1/1 Running 0 84m 10.244.2.100 node2 <none> <none> 36 [root@master ~]# #在node2节点的/data目录下创建一个文件a.txt 37 #在my-pod2的容器中查看/data目录是否有这个文件 38 [root@node2 ~]# touch /tmp/a.txt 39 [root@node2 ~]# 40 [root@master ~]# kubectl exec -it my-pod2 -- sh 41 / # ls /data 42 a.txt 43 / #