Container中的文件在磁盘上是临时存放的,这给 Container中运行的较重要的应用程序带来一些问题:
1,当容器崩溃时文件丢失。kubelet 会重新启动容器。
2,同一 Pod 中运行多个容器的情况下有共享文件需求。
Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。本文主要介绍k8s主流的集中卷,本文测试数据来自源Kubernetes 1.18版本。
emptyDir
当 Pod 分派到某个 Node 上时,emptyDir 卷在node上会被创建,并且在 Pod 在该节点上运行期间,卷一直存在。 就像其名称表示的那样,卷最初是空的。 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,这些容器都可以读写 emptyDir 卷中相同的文件。当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。
生命周期
从pod被在node上创建到pod从node中删除
使用场景
应用的临时数据大的时候,存放应用的缓存数据。如果想要提高读写速度,可以在node上使用ssd或者tmpfs来满足需求。
创建一个挂载emptyDir的Pod
# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
# kubectl apply -f test.yaml
查看emptyDir卷在node中的位置
先查看pod被调度的node
# kubectl get pods -o wide|grep test-pd
test-pd 1/1 Running 0 3m41s 10.101.26.7 work4 <none> <none>
登陆work4,找到对应的容器id
# docker container ls|grep test-pd
902cb30eb240 busybox "/bin/sh -c 'sleep 9…" 5 minutes ago Up 5 minutes k8s_test-container_test-pd_default_ad83c596-a2b2-4c76-9a0c-a6da7305d5cd_0
找到存储对应容器配置信息的配置文件,此文件中存放了存储卷和容器挂载点的映射信息
# cat /var/lib/docker/containers/902cb30eb240a55b1e4c8c222e8c6f8b15a3f950b34084c0963909479986bfc9/config.v2.json|jq '.MountPoints'
{
"/cache": {
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/volumes/kubernetes.io~empty-dir/cache-volume",
"Destination": "/cache",
"RW": true,
"Name": "",
"Driver": "",
"Type": "bind",
"Relabel": "Z",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/volumes/kubernetes.io~empty-dir/cache-volume",
"Target": "/cache"
},
"SkipMountpointCreation": false
},
"/dev/termination-log": {
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/containers/test-container/957c3416",
"Destination": "/dev/termination-log",
"RW": true,
"Name": "",
"Driver": "",
"Type": "bind",
"Relabel": "Z",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/containers/test-container/957c3416",
"Target": "/dev/termination-log"
},
"SkipMountpointCreation": false
},
"/etc/hosts": {
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/etc-hosts",
"Destination": "/etc/hosts",
"RW": true,
"Name": "",
"Driver": "",
"Type": "bind",
"Relabel": "Z",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/etc-hosts",
"Target": "/etc/hosts"
},
"SkipMountpointCreation": false
},
"/var/run/secrets/kubernetes.io/serviceaccount": {
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/volumes/kubernetes.io~secret/default-token-tlsjd",
"Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
"RW": false,
"Name": "",
"Driver": "",
"Type": "bind",
"Relabel": "ro,Z",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/volumes/kubernetes.io~secret/default-token-tlsjd",
"Target": "/var/run/secrets/kubernetes.io/serviceaccount",
"ReadOnly": true
},
"SkipMountpointCreation": false
}
}
卷写入测试(实际上容器直接写到了node对应的目录)
[root@master1 t]# kubectl exec -it test-pd sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
/ # echo test > /cache/1.txt
[root@work4 ~]# cat /var/lib/kubelet/pods/ad83c596-a2b2-4c76-9a0c-a6da7305d5cd/volumes/kubernetes.io~empty-dir/cache-volume/1.txt
test
hostPath
hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱。
除了必需的 path 属性之外,用户可以选择性地为 hostPath 卷指定 type, type 值如下:
- 空字符串(默认):用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
- DirectoryOrCreate: 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
- Directory: 在给定路径上必须存在的目录。
- FileOrCreate: 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
- File: 在给定路径上必须存在的文件。
- Socket: 在给定路径上必须存在的 UNIX 套接字。
- CharDevice: 在给定路径上必须存在的字符设备。
- BlockDevice: 在给定路径上必须存在的块设备。
生命周期
hostPath卷默认不会因为Pod的删除而数据删除丢失
使用场景
1,运行一个需要访问 Docker 内部机制的容器;可使用 hostPath 挂载 /var/lib/docker 路径。
2,在容器中运行 cAdvisor 时,以 hostPath 方式挂载 /sys。
3,允许 Pod 指定给定的 hostPath 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。
查看hostPath卷在node中的位置
同emptyDir卷
gitRepo(废弃)
Kubernetes 1.12开始,gitRepo 卷类型已经被废弃。如果需要在容器中提供 git 仓库,请将一个 EmptyDir 卷挂载到 InitContainer 中,使用 git 命令完成仓库的克隆操作, 然后将 EmptyDir 卷挂载到 Pod 的容器中。
configMap
k8s允许应用的配置分离到单独的资源对象configMap中,它本质上是一个键值对。应用无需要读取configMap,其中存放的配置可以通过环境变量或者卷文件的形式传递给容器,然后被 Pod 中运行的容器化应用使用。
使用configMap的注意事项为:
1,在使用 ConfigMap 之前你首先要创建它。
2,容器以 subPath 卷挂载方式使用 ConfigMap 时,将无法接收 ConfigMap 的更新。
3,文本数据挂载成文件时采用 UTF-8 字符编码。如果使用其他字符编码形式,可使用 binaryData 字段。
生命周期
configMap是单独的资源,故和Pod的生命周期没有关系
使用场景
存放应用的配置
创建configMap和使用它的Pod
创建configMap
# cat cf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: log-config
data:
log_level: |-
listen: 0.0.0.0
port: 9999
accessLog: /var/log/test.log
# kubectl apply -f cf.yaml
创建使用如上configMap的Pod
# cat cf-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox
args: [/bin/sh, -c, 'sleep 99999']
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
# kubectl apply -f cf-pod.yaml
查看Pod中容器通过configMap映射的配置
# kubectl exec -it configmap-pod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
/ # cat /etc/config/log_level
listen: 0.0.0.0
port: 9999
accessLog: /var/log/test.log/
#
查看configMap卷在node中的位置
同emptyDir卷
secret
secret存储结构与configMap类似,都是键值对存储。但是secret 卷用来给 Pod 传递敏感信息,例如密码,证书和密钥等。k8s 通过仅仅将 secret 分发到需要访问 secret 的 pod 所在的机器节点来
保障其安全性。 另外, secret 只会存储在节点的内存中, 永不写入物理存储, 这样从节点上删除 secret 时就不需要擦除磁盘了。
要使用 Secret,Pod 需要引用 Secret。 Pod 可以用三种方式之一来使用 Secret:
1,作为挂载到一个或多个容器上的 卷 中的文件。
2,作为容器的环境变量
3,由 kubelet 在为 Pod 拉取镜像时使用
注意事项:
1,使用secret前必须已经创建
2,容器以 subPath 卷挂载方式挂载 secret 时,将感知不到 secret 的更新。
生命周期
单独的资源,故和Pod的生命周期没有关系
使用场景
存储敏感数据,例如密码,证书和密钥等。
使用样例
https://kubernetes.io/zh/docs/concepts/configuration/secret/
查看secret卷在node中的位置
同emptyDir卷
其它存储卷
- 网络或者共享存储:nfs,ceph,cephfs,cinder,glusterfs,iscsi等
- 主流云存储:awsElasticBlockStore,azureDisk,gcePersistentDisk
备注:
k8s对接ceph rbd存储见:https://blog.51cto.com/leejia/2501080
参考
https://kubernetes.io/zh/docs/concepts/configuration/secret/
https://kubernetes.io/zh/docs/concepts/storage/volumes/
来源:oschina
链接:https://my.oschina.net/u/4373790/blog/4782909