K8s中Volume
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃
时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在
Pod 中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的 Volume 抽象就很好的解决了这些问题
背景
Kubernetes 中的卷有明确的寿命 —— 与封装它的 Pod 相同。所f以,卷的生命比 Pod 中的所有容器都长,当这
个容器重启时数据仍然得以保存。当然,当 Pod 不再存在时,卷也将不复存在。也许更重要的是,Kubernetes
支持多种类型的卷,Pod 可以同时使用任意数量的卷卷的类型。
emptyDir
一个emptyDir 第一次创建是在一个pod被指定到具体node的时候,并且会一直存在在pod的生命周期当中,正如它的名字一样,它初始化是一个空的目录,pod中的容器都可以读写这个目录,这个目录可以被挂在到各个容器相同或者不相同的的路径下。当一个pod因为任何原因被移除的时候,这些数据会被永久删除。注意:一个容器崩溃了不会导致数据的丢失,因为容器的崩溃并不移除pod.
emptyDir 磁盘的作用:
scratch space, such as for a disk-based mergesortcw
checkpointing a long computation for recovery from crashes
holding files that a content-manager container fetches while a webserver container serves the data
- 普通空间,基于磁盘的数据存储
- 作为从崩溃中恢复的备份点
- 存储那些那些需要长久保存的数据,例web服务中的数据
默认的,emptyDir 磁盘会存储在主机所使用的媒介上,可能是SSD,或者网络硬盘,这主要取决于你的环境。当然,我们也可以将emptyDir.medium的值设置为Memory来告诉Kubernetes 来挂在一个基于内存的目录tmpfs,因为
tmpfs速度会比硬盘块度了,但是,当主机重启的时候所有的数据都会丢失
[ mnt]# cat volume.yaml apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: wangyanglinux/myapp:v2 name: test-container volumeMounts: - mountPath: /cache name: cache-volume - name: liveness-exec-container image: busybox imagePullPolicy: IfNotPresent command: ["/bin/sh","-c","sleep 6000s"] volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {} [root@k8s-master mnt]#
执行:
[ mnt]# vim volume.yaml [ mnt]# kubectl create -f volume.yaml pod/test-pd created [root@k8s-master mnt]# kubectl describe pod test-pd Name: test-pd Namespace: default Priority: 0 Node: k8s-node02/192.168.180.136 Start Time: Fri, 27 Dec 2019 13:44:38 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.1.49 IPs: IP: 10.244.1.49 Containers: test-container: Container ID: docker://236b2b8c29ed6d42b74aaef24bc1d43d21863598c7c5a5cd19b9fc953993c7c0 Image: wangyanglinux/myapp:v2 Image ID: docker-pullable://wangyanglinux/sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358 Port: <none> Host Port: <none> State: Running Started: Fri, 27 Dec 2019 13:44:40 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /cache from cache-volume (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro) liveness-exec-container: Container ID: docker://304943afd2171d58d2b36d93f3833405f7e2651ffb67ad807adaf80c8a6fd330 Image: busybox Image ID: docker-pullable://sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084 Port: <none> Host Port: <none> Command: /bin/sh -c sleep 6000s State: Running Started: Fri, 27 Dec 2019 13:44:40 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /cache from cache-volume (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: cache-volume: Type: EmptyDir (a temporary directory that shares a pod‘s lifetime) Medium: SizeLimit: <unset> default-token-6wcrh: Type: Secret (a volume populated by a Secret) SecretName: default-token-6wcrh Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/test-pd to k8s-node02 Normal Pulled 8s kubelet, k8s-node02 Container image "wangyanglinux/myapp:v2" already present on machine Normal Created 8s kubelet, k8s-node02 Created container test-container Normal Started 7s kubelet, k8s-node02 Started container test-container Normal Pulled 7s kubelet, k8s-node02 Container image "busybox" already present on machine Normal Created 7s kubelet, k8s-node02 Created container liveness-exec-container Normal Started 7s kubelet, k8s-node02 Started container liveness-exec-container [root@k8s-master mnt]# kubectl get pod NAME READY STATUS RESTARTS AGE test-pd 2/2 Running 0 107s [root@k8s-master mnt]# !711 kubectl exec test-pd -it -- /bin/sh Defaulting container name to test-container. Use ‘kubectl describe pod/test-pd -n default‘ to see all of the containers in this pod. / # ls bin cache dev etc home lib media mnt proc root run sbin srv sys tmp usr var / # exit
看来里面有这个文件夹
hostPath
hostPath 卷将主机节点的文件系统中的文件或目录挂载到集群中
hostPath 的用途如下:
运行需要访问 Docker 内部的容器;使用 /var/lib/docker 的 hostPath
在容器中运行 cAdvisor;使用 /dev/cgroups 的 hostPath
允许 pod 指定给定的 hostPath 是否应该在 pod 运行之前存在,是否应该创建,以及它应该以什么形式存在
除了所需的 path 属性之外,用户还可以为 hostPath 卷指定 type
使用这种卷类型是请注意,因为:
由于每个节点上的文件都不同,具有相同配置(例如从 podTemplate 创建的)的 pod 在不同节点上的行为可能会有所不同。
当 Kubernetes 按照计划添加资源感知调度时,将无法考虑 hostPath 使用的资源
在底层主机上创建的文件或目录只能由 root 写入。您需要在特权容器中以 root 身份运行进程,或修改主机上的文件权限以便写入 hostPath 卷。
[ mnt]# cat pod1.yaml apiVersion: v1 kind: Pod metadata: name: test-pd1 spec: containers: - image: wangyanglinux/myapp:v2 name: test-container volumeMounts: - mountPath: /test-pd1 name: test-volume1 volumes: - name: test-volume1 hostPath: path: /data type: Directory [root@k8s-master mnt]#
[ mnt]# vim pod1.yaml [ mnt]# kubectl create -f pod1.yaml pod/test-pd1 created [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 101m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 9s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 102m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 23s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 102m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 25s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 102m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 48s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 102m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 50s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 103m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 79s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 103m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 81s <none> k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 104m 10.244.1.49 k8s-node02 <none> <none> test-pd1 0/1 ContainerCreating 0 3m2s <none> k8s-node01 <none> <none>
假如子节点没有data文件夹
[ mnt]# kubectl describe pod test-pd1 Name: test-pd1 Namespace: default Priority: 0 Node: k8s-node01/192.168.180.135 Start Time: Fri, 27 Dec 2019 15:31:19 +0800 Labels: <none> Annotations: <none> Status: Pending IP: IPs: <none> Containers: test-container: Container ID: Image: wangyanglinux/myapp:v2 Image ID: Port: <none> Host Port: <none> State: Waiting Reason: ContainerCreating Ready: False Restart Count: 0 Environment: <none> Mounts: /test-pd1 from test-volume1 (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro) Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: test-volume1: Type: HostPath (bare host directory volume) Path: /data HostPathType: Directory default-token-6wcrh: Type: Secret (a volume populated by a Secret) SecretName: default-token-6wcrh Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/test-pd1 to k8s-node01 Warning FailedMount 21s (x6 over 36s) kubelet, k8s-node01 MountVolume.SetUp failed for volume "test-volume1" : hostPath type check failed: /data is not a directory
[ mnt]# kubectl describe pod test-pd1 Name: test-pd1 Namespace: default Priority: 0 Node: k8s-node01/192.168.180.135 Start Time: Fri, 27 Dec 2019 15:31:19 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.2.55 IPs: IP: 10.244.2.55 Containers: test-container: Container ID: docker://5a8696561897043c9c141acae2f66eea2ca6d4b834a15c143c953a269113e25b Image: wangyanglinux/myapp:v2 Image ID: docker-pullable://wangyanglinux/sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358 Port: <none> Host Port: <none> State: Running Started: Fri, 27 Dec 2019 15:32:04 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /test-pd1 from test-volume1 (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: test-volume1: Type: HostPath (bare host directory volume) Path: /data HostPathType: Directory default-token-6wcrh: Type: Secret (a volume populated by a Secret) SecretName: default-token-6wcrh Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/test-pd1 to k8s-node01 Warning FailedMount 106s (x6 over 2m1s) kubelet, k8s-node01 MountVolume.SetUp failed for volume "test-volume1" : hostPath type check failed: /data is not a directory Normal Pulled 77s kubelet, k8s-node01 Container image "wangyanglinux/myapp:v2" already present on machine Normal Created 77s kubelet, k8s-node01 Created container test-container Normal Started 77s kubelet, k8s-node01 Started container test-container [root@k8s-master mnt]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-pd 2/2 Running 1 109m 10.244.1.49 k8s-node02 <none> <none> test-pd1 1/1 Running 0 3m9s 10.244.2.55 k8s-node01 <none> <none> [root@k8s-master mnt]# kubectl exec test-pd1 -it -- /bin/sh / # ls bin etc lib mnt root sbin sys tmp var dev home media proc run srv test-pd1 usr / # cd test-pd1 /test-pd1 # date > index.html /test-pd1 # ls -l total 4 -rw-r--r-- 1 root root 29 Dec 27 07:35 index.html /test-pd1 #
在子节点查看
[ /]# mkdir /data [ /]# cd /data [ data]# ll 总用量 4 -rw-r--r-- 1 root root 29 12月 27 15:35 index.html [root@k8s-node01 data]# cat index.html Fri Dec 27 07:35:52 UTC 2019 [root@k8s-node01 data]#