一、为什么需要 volume(数据卷)?
容器中的文件在磁盘上是临时存放的,这给容器中运行比较重要的应用程序带来一些问题。
- 问题1:当容器升级或者崩溃时,kubelet会重建容器,容器内文件会丢失
- 问题2:一个Pod中运行多个容器需要共享文件。
Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。
二、常用数据卷
- 本地(emptyDir,hostPath)
- 网络(NFS,Ceph,GlusterFS)
- 公有云(AWS EBS)
- K8S资源(configmap,secret)
三、empryDir
emptyDir卷: 是一个自动创建的、 Pod 所在node主机上的临时目录(node上预设定好的存储位置),与Pod生命周期绑定在一起,如果Pod删除了,emptyDir卷也会被删除。
应用场景: Pod中容器之间数据共享,常用于同一个pod内容器(container)之间直接的数据传输。
例子
# 做一个测试yaml
vi emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: write # 业务容器(写数据)
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /data
- name: read # 辅助容器(读数据)
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
kubectl apply -f emptydir.yaml
执行后,可以看到两个文件data是共享的,测试可以看到两个文件是共享的。
empryDir在k8s中的存储位置
一般在 /var/lib/kubelet/pods/{pod-id}/volumes/kubernetes.io~empty-dir
下。
四、hostPath
hostPath卷: 挂载Node文件系统(Pod所在节点)上文件或者目录到Pod中的容器。
应用场景: Pod中容器需要访问宿主机文件。但不适合做持久化。
示例
vi hostPath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- name: write # 业务容器(写数据)
image: centos
command: ["bash","-c","for i in {1..1000};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /ttt
volumes:
- name: data
hostPath:
path: /tmp
type: Directory # 文件类型:定义node主机上的 /tmp 是文件夹还是文件。
测试,在 pod 的 /ttt
目录下写入一个123文件后,查看此pod所处节点
# 查看 pod 所在的 node
kubectl get pods -o wide
进入node1节点tmp下查看
成功
五、emptyDir 与 hostPath 的区别
相同点
- emptyDir 和 hostPath 类型都可用于 container 之间数据共享。
区别
-
emptyDir 是 pod 级别的。pod 销毁后, emptyDir 也会销毁。
-
emptyDir 被初始化后里面是空的。所有在同一个 pod 中的 container 都可以通过挂载emptyDir后对其进行读写操作。
-
emptyDir 主要用于同一个 pod 中的 container 之间共享数据。(如:log 日志目录)
-
emptyDir 使用 emptyDir 这种 volume 时,一个pod中一般会有2个以上的 container。
-
hostPath 是 node 级别的,node 是持久化的。一个 node 可以创建 N 个 pod 。
emptyDir
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-app
image: my-app-image
volumeMounts:
- mountPath: /cache
name: cache-volume
- name: sidecar
image: busybox
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
hostPath
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-app
image: my-app-image
volumeMounts:
- name: test-volume
mountPath: /test-pd
volumes:
- name: test-volume
hostPath:
path: /data # directory on host
type: Directory # optional
# type:
# Other values for type are 'DirectoryOrCreate', 'File', 'FileOrCreate'.
- ref:
https://blog.csdn.net/huahua1999/article/details/124375310
https://dev.to/techworld_with_nana/difference-between-emptydir-and-hostpath-volume-types-in-kubernetes-286g