Kubernetes K8S之存储Volume详解

 

K8S之存储Volume概述与说明,并详解经常使用Volume示例html

 

主机配置规划

服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟)
k8s-master CentOS7.7 2C/4G/20G 172.16.1.110 10.0.0.110
k8s-node01 CentOS7.7 2C/4G/20G 172.16.1.111 10.0.0.111
k8s-node02 CentOS7.7 2C/4G/20G 172.16.1.112 10.0.0.112

 

Volume概述

在容器中的文件在磁盘上是临时存放的,当容器关闭时这些临时文件也会被一并清除。这给容器中运行的特殊应用程序带来一些问题。node

首先,当容器崩溃时,kubelet 将从新启动容器,容器中的文件将会丢失——由于容器会以干净的状态重建。git

其次,当在一个 Pod 中同时运行多个容器时,经常须要在这些容器之间共享文件。docker

Kubernetes 抽象出 Volume 对象来解决这两个问题。api

Kubernetes Volume卷具备明确的生命周期——与包裹它的 Pod 相同。 所以,Volume比 Pod 中运行的任何容器的存活期都长,在容器从新启动时数据也会获得保留。 固然,当一个 Pod 再也不存在时,Volume也将再也不存在。更重要的是,Kubernetes 能够支持许多类型的Volume卷,Pod 也能同时使用任意数量的Volume卷缓存

使用卷时,Pod 声明中须要提供卷的类型 (.spec.volumes 字段)和卷挂载的位置 (.spec.containers.volumeMounts 字段).安全

 

Volume类型

Kubernetes 支持下列类型的卷:服务器

 1 awsElasticBlockStore
 2 azureDisk
 3 azureFile
 4 cephfs
 5 cinder
 6 configMap
 7 csi
 8 downwardAPI
 9 emptyDir
10 fc (fibre channel)
11 flexVolume
12 flocker
13 gcePersistentDisk
14 gitRepo (deprecated)
15 glusterfs
16 hostPath
17 iscsi
18 local
19 nfs
20 persistentVolumeClaim
21 projected
22 portworxVolume
23 quobyte
24 rbd
25 scaleIO
26 secret
27 storageos
28 vsphereVolume

 

这里咱们只介绍经常使用的存储,包括:Secret、ConfigMap、emptyDir、hostPath。app

其中Secret参考文章:「Kubernetes K8S之存储Secret详解ide

ConfigMap参考文章:「Kubernetes K8S之存储ConfigMap详解

本文只说emptyDir和hostPath存储。

 

emptyDir卷

当 Pod 指定到某个节点上时,首先建立的是一个 emptyDir 卷,而且只要 Pod 在该节点上运行,卷就一直存在。就像它的名称表示的那样,卷最初是空的。

尽管 Pod 中每一个容器挂载 emptyDir 卷的路径可能相同也可能不一样,可是这些容器均可以读写 emptyDir 卷中相同的文件。

若是Pod中有多个容器,其中某个容器重启,不会影响emptyDir 卷中的数据。当 Pod 由于某些缘由被删除时,emptyDir 卷中的数据也会永久删除

注意:容器崩溃并不会致使 Pod 被从节点上移除,所以容器崩溃时 emptyDir 卷中的数据是安全的。

 

emptyDir的一些用途:

  • 缓存空间,例如基于磁盘的归并排序
  • 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行
  • 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件

 

emptyDir示例

yaml文件

 1 [root@k8s-master emptydir]# pwd
 2 /root/k8s_practice/emptydir
 3 [root@k8s-master emptydir]# cat pod_emptydir.yaml 
 4 apiVersion: v1
 5 kind: Pod
 6 metadata:
 7   name: pod-emptydir
 8   namespace: default
 9 spec:
10   containers:
11   - name: myapp-pod
12     image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
13     imagePullPolicy: IfNotPresent
14     volumeMounts:
15     - mountPath: /cache
16       name: cache-volume
17   - name: busybox-pod
18     image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
19     imagePullPolicy: IfNotPresent
20     command: ["/bin/sh", "-c", "sleep 3600"]
21     volumeMounts:
22     - mountPath: /test/cache
23       name: cache-volume
24   volumes:
25   - name: cache-volume
26     emptyDir: {}

 

启动pod,并查看状态

 1 [root@k8s-master emptydir]# kubectl apply -f pod_emptydir.yaml 
 2 pod/pod-emptydir created
 3 [root@k8s-master emptydir]# 
 4 [root@k8s-master emptydir]# kubectl get pod -o wide
 5 NAME           READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
 6 pod-emptydir   2/2     Running   0          10s   10.244.2.166   k8s-node02   <none>           <none>
 7 [root@k8s-master emptydir]# 
 8 [root@k8s-master emptydir]# kubectl describe pod pod-emptydir
 9 Name:         pod-emptydir
10 Namespace:    default
11 Priority:     0
12 Node:         k8s-node02/172.16.1.112
13 Start Time:   Fri, 12 Jun 2020 22:49:11 +0800
14 Labels:       <none>
15 Annotations:  kubectl.kubernetes.io/last-applied-configuration:
16                 {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"pod-emptydir","namespace":"default"},"spec":{"containers":[{"image":"...
17 Status:       Running
18 IP:           10.244.2.166
19 IPs:
20   IP:  10.244.2.166
21 Containers:
22   myapp-pod:
23     Container ID:   docker://d45663776b40a24e7cfc3cf46cb08cf3ed6b98b023a5d2cb5f42bee2234c7338
24     Image:          registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
25     Image ID:       docker-pullable://10.0.0.110:5000/k8s-secret/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e
26     Port:           <none>
27     Host Port:      <none>
28     State:          Running
29       Started:      Fri, 12 Jun 2020 22:49:12 +0800
30     Ready:          True
31     Restart Count:  0
32     Environment:    <none>
33     Mounts:
34       /cache from cache-volume (rw)  ##### 挂载信息
35       /var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro)
36   busybox-pod:
37     Container ID:  docker://c2917ba30c3322fb0caead5d97476b341e691f9fb1990091264364b8cd340512
38     Image:         registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
39     Image ID:      docker-pullable://registry.cn-beijing.aliyuncs.com/ducafe/busybox@sha256:f73ae051fae52945d92ee20d62c315306c593c59a429ccbbdcba4a488ee12269
40     Port:          <none>
41     Host Port:     <none>
42     Command:
43       /bin/sh
44       -c
45       sleep 3600
46     State:          Running
47       Started:      Fri, 12 Jun 2020 22:49:12 +0800
48     Ready:          True
49     Restart Count:  0
50     Environment:    <none>
51     Mounts:
52       /test/cache from cache-volume (rw)  ##### 挂载信息
53       /var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro)
54 Conditions:
55   Type              Status
56   Initialized       True 
57   Ready             True 
58   ContainersReady   True 
59   PodScheduled      True 
60 Volumes:
61   cache-volume:
62     Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
63     Medium:     
64     SizeLimit:  <unset>
65   default-token-v48g4:
66     Type:        Secret (a volume populated by a Secret)
67     SecretName:  default-token-v48g4
68     Optional:    false
69 QoS Class:       BestEffort
70 Node-Selectors:  <none>
71 Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
72                  node.kubernetes.io/unreachable:NoExecute for 300s
73 Events:
74   Type    Reason     Age   From                 Message
75   ----    ------     ----  ----                 -------
76   Normal  Scheduled  3s    default-scheduler    Successfully assigned default/pod-emptydir to k8s-node02
77   Normal  Pulled     2s    kubelet, k8s-node02  Container image "registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1" already present on machine
78   Normal  Created    2s    kubelet, k8s-node02  Created container myapp-pod
79   Normal  Started    2s    kubelet, k8s-node02  Started container myapp-pod
80   Normal  Pulled     2s    kubelet, k8s-node02  Container image "registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24" already present on machine
81   Normal  Created    2s    kubelet, k8s-node02  Created container busybox-pod
82   Normal  Started    2s    kubelet, k8s-node02  Started container busybox-pod

 

emptyDir验证

在pod中的myapp-pod容器内操做

 1 [root@k8s-master emptydir]# kubectl exec -it pod-emptydir -c myapp-pod -- sh
 2 / # cd /cache
 3 /cache # 
 4 /cache # pwd
 5 /cache
 6 /cache # 
 7 /cache # date >> data.info
 8 /cache # ls -l
 9 total 4
10 -rw-r--r--    1 root     root            29 Jun 12 14:53 data.info
11 /cache # cat data.info 
12 Fri Jun 12 14:53:27 UTC 2020

 

在pod中的busybox-pod容器内操做

 1 [root@k8s-master emptydir]# kubectl exec -it pod-emptydir -c busybox-pod -- sh
 2 / # cd /test/cache
 3 /test/cache # ls -l
 4 total 4
 5 -rw-r--r--    1 root     root            29 Jun 12 14:53 data.info
 6 /test/cache # cat data.info 
 7 Fri Jun 12 14:53:27 UTC 2020
 8 /test/cache # 
 9 /test/cache # echo "===" >> data.info 
10 /test/cache # date >> data.info 
11 /test/cache # cat data.info 
12 Fri Jun 12 14:53:27 UTC 2020
13 ===
14 Fri Jun 12 14:56:05 UTC 2020

由上可见,一个Pod中多个容器可共享同一个emptyDir卷。

 

hostPath卷

hostPath 卷能将主机node节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 须要的,可是它为一些应用程序提供了强大的逃生舱。

 

hostPath 的一些用法有

  • 运行一个须要访问 Docker 引擎内部机制的容器;请使用 hostPath 挂载 /var/lib/docker 路径。
  • 在容器中运行 cAdvisor 时,以 hostPath 方式挂载 /sys。
  • 容许 Pod 指定给定的 hostPath 在运行 Pod 以前是否应该存在,是否应该建立以及应该以什么方式存在。

支持类型

除了必需的 path 属性以外,用户能够选择性地为 hostPath 卷指定 type。支持的 type 值以下:

取值 行为
  空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷以前不会执行任何检查
DirectoryOrCreate 若是指定的路径不存在,那么将根据须要建立空目录,权限设置为 0755,具备与 Kubelet 相同的组和全部权
Directory 给定的路径必须存在
FileOrCreate 若是给定路径的文件不存在,那么将在那里根据须要建立空文件,权限设置为 0644,具备与 Kubelet 相同的组和全部权【前提:文件所在目录必须存在;目录不存在则不能建立文件】
File 给定路径上的文件必须存在
Socket 在给定路径上必须存在的 UNIX 套接字
CharDevice 在给定路径上必须存在的字符设备
BlockDevice 在给定路径上必须存在的块设备

 

 

注意事项

当使用这种类型的卷时要当心,由于:

  • 具备相同配置(例如从 podTemplate 建立)的多个 Pod 会因为节点上文件的不一样而在不一样节点上有不一样的行为。
  • 当 Kubernetes 按照计划添加资源感知的调度时,这类调度机制将没法考虑由 hostPath 卷使用的资源。
  • 基础主机上建立的文件或目录只能由 root 用户写入。须要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器可以写入 hostPath 卷。

 

hostPath示例

yaml文件

 1 [root@k8s-master hostpath]# pwd
 2 /root/k8s_practice/hostpath
 3 [root@k8s-master hostpath]# cat pod_hostpath.yaml 
 4 apiVersion: v1
 5 kind: Pod
 6 metadata:
 7   name: pod-hostpath
 8   namespace: default
 9 spec:
10   containers:
11   - name: myapp-pod
12     image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
13     imagePullPolicy: IfNotPresent
14     volumeMounts:
15     - name: hostpath-dir-volume
16       mountPath: /test-k8s/hostpath-dir
17     - name: hostpath-file-volume
18       mountPath: /test/hostpath-file/test.conf
19   volumes:
20   - name: hostpath-dir-volume
21     hostPath:
22       # 宿主机目录
23       path: /k8s/hostpath-dir
24       # hostPath 卷指定 type,若是目录不存在则建立(可建立多层目录)
25       type: DirectoryOrCreate
26   - name: hostpath-file-volume
27     hostPath:
28       path: /k8s2/hostpath-file/test.conf
29       # 若是文件不存在则建立。 前提:文件所在目录必须存在  目录不存在则不能建立文件
30       type: FileOrCreate

 

启动pod,并查看状态

 1 [root@k8s-master hostpath]# kubectl apply -f pod_hostpath.yaml 
 2 pod/pod-hostpath created
 3 [root@k8s-master hostpath]# 
 4 [root@k8s-master hostpath]# kubectl get pod -o wide
 5 NAME           READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
 6 pod-hostpath   1/1     Running   0          17s   10.244.4.133   k8s-node01   <none>           <none>
 7 [root@k8s-master hostpath]# 
 8 [root@k8s-master hostpath]# kubectl describe pod pod-hostpath
 9 Name:         pod-hostpath
10 Namespace:    default
11 Priority:     0
12 Node:         k8s-node01/172.16.1.111
13 Start Time:   Sat, 13 Jun 2020 16:12:15 +0800
14 Labels:       <none>
15 Annotations:  kubectl.kubernetes.io/last-applied-configuration:
16                 {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"pod-hostpath","namespace":"default"},"spec":{"containers":[{"image":"...
17 Status:       Running
18 IP:           10.244.4.133
19 IPs:
20   IP:  10.244.4.133
21 Containers:
22   myapp-pod:
23     Container ID:   docker://8cc87217fb483288067fb6d227c46aa890d02f75cae85c6d110646839435ab96
24     Image:          registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
25     Image ID:       docker-pullable://registry.cn-beijing.aliyuncs.com/google_registry/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e
26     Port:           <none>
27     Host Port:      <none>
28     State:          Running
29       Started:      Sat, 13 Jun 2020 16:12:17 +0800
30     Ready:          True
31     Restart Count:  0
32     Environment:    <none>
33     Mounts:
34       /test-k8s/hostpath-dir from hostpath-dir-volume (rw)
35       /test/hostpath-file/test.conf from hostpath-file-volume (rw)
36       /var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro)
37 Conditions:
38   Type              Status
39   Initialized       True 
40   Ready             True 
41   ContainersReady   True 
42   PodScheduled      True 
43 Volumes:
44   hostpath-dir-volume:
45     Type:          HostPath (bare host directory volume)
46     Path:          /k8s/hostpath-dir
47     HostPathType:  DirectoryOrCreate
48   hostpath-file-volume:
49     Type:          HostPath (bare host directory volume)
50     Path:          /k8s2/hostpath-file/test.conf
51     HostPathType:  FileOrCreate
52   default-token-v48g4:
53     Type:        Secret (a volume populated by a Secret)
54     SecretName:  default-token-v48g4
55     Optional:    false
56 QoS Class:       BestEffort
57 Node-Selectors:  <none>
58 Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
59                  node.kubernetes.io/unreachable:NoExecute for 300s
60 Events:
61   Type    Reason     Age        From                 Message
62   ----    ------     ----       ----                 -------
63   Normal  Scheduled  <unknown>  default-scheduler    Successfully assigned default/pod-hostpath to k8s-node01
64   Normal  Pulled     12m        kubelet, k8s-node01  Container image "registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1" already present on machine
65   Normal  Created    12m        kubelet, k8s-node01  Created container myapp-pod
66   Normal  Started    12m        kubelet, k8s-node01  Started container myapp-pod

 

hostPath验证

宿主机操做

根据pod,在k8s-node01节点宿主机操做【由于Pod分配到了该节点】

 1 # 对挂载的目录操做
 2 [root@k8s-node01 hostpath-dir]# pwd
 3 /k8s/hostpath-dir
 4 [root@k8s-node01 hostpath-dir]# echo "dir" >> info
 5 [root@k8s-node01 hostpath-dir]# date >> info
 6 [root@k8s-node01 hostpath-dir]# cat info 
 7 dir
 8 Sat Jun 13 16:22:37 CST 2020
 9 # 对挂载的文件操做
10 [root@k8s-node01 hostpath-file]# pwd
11 /k8s2/hostpath-file
12 [root@k8s-node01 hostpath-file]# echo "file" >> test.conf 
13 [root@k8s-node01 hostpath-file]# date >> test.conf 
14 [root@k8s-node01 hostpath-file]# 
15 [root@k8s-node01 hostpath-file]# cat test.conf 
16 file
17 Sat Jun 13 16:23:05 CST 2020

 

在Pod 容器中操做

 1 # 进入pod 中的指定容器【若是只有一个容器,那么能够不指定容器】
 2 [root@k8s-master hostpath]# kubectl exec -it pod-hostpath -c myapp-pod -- /bin/sh
 3 ##### 对挂载的目录操做
 4 / # cd /test-k8s/hostpath-dir
 5 /test-k8s/hostpath-dir # ls -l
 6 total 4
 7 -rw-r--r--    1 root     root            33 Jun 13 08:22 info
 8 /test-k8s/hostpath-dir # cat info
 9 dir
10 Sat Jun 13 16:22:37 CST 2020
11 /test-k8s/hostpath-dir # 
12 /test-k8s/hostpath-dir # date >> info 
13 /test-k8s/hostpath-dir # cat info
14 dir
15 Sat Jun 13 16:22:37 CST 2020
16 Sat Jun 13 08:26:10 UTC 2020
17 ##### 对挂载的文件操做
18 # cd /test/hostpath-file/
19 /test/hostpath-file # cat test.conf 
20 file
21 Sat Jun 13 16:23:05 CST 2020
22 /test/hostpath-file # echo "file====" >> test.conf 
23 /test/hostpath-file # cat test.conf 
24 file
25 Sat Jun 13 16:23:05 CST 2020
26 file====

 

相关阅读

一、Kubernetes K8S之存储Secret详解

二、Kubernetes K8S之存储ConfigMap详解

三、官网Volume详解

 

 


 

 

———END———
若是以为不错就关注下呗 (-^O^-) !

相关文章
相关标签/搜索