K8S 之 存储卷 emptyDir

摘要

存储卷 emptyDir 介绍

  • emptyDir 是 Kubernetes 中最简单的一种 Pod 级别的临时存储卷。它的核心特点是:Pod 生命周期内共享临时存储,Pod 删除后数据自动丢弃。

  • 同一个 Pod 内的多个容器可以通过 emptyDir 共享数据。跨 Pod 不共享,适用于临时数据。

  • emptyDir 只能挂载目录。

示例

  • 两个容器 app 和 sidecar 通过 /data 共享一个 emptyDir 卷。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# shared-emptydir-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: shared-emptydir-pod
labels:
app.sto: emptydir
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo Hello > /data1/hello; sleep 3600"]
volumeMounts: # 存储卷挂载点
- name: shared-data # 挂载点名称,与下面 volumes 中定义的 volume 名称一致
mountPath: /data1 # 挂载点路径,挂载到容器的 /data1 目录
- name: sidecar
image: busybox
command: ["sh", "-c", "sleep 3600"]
volumeMounts: # 存储卷挂载点
- name: shared-data # 挂载点名称,与上面容器中的 volume 配置名称一致
mountPath: /data2 # 挂载点路径,挂载到容器的 /data2 目录
volumes: # 存储卷声明
- name: shared-data # 存储卷名称
emptyDir: {} # 声明为 emptyDir 存储卷
  • 创建

1
2
3
4
5
6
7
8
k apply -f shared-emptydir-pod.yaml
# 查看pod所在节点
$ k get pod -l app.sto=emptydir
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
shared-emptydir-pod 2/2 Running 0 22m 10.244.126.59 k8s-worker2 <none> <none>
# 查看 pod-uid
$ kubectl get pod shared-emptydir-pod -o jsonpath='{.metadata.uid}'
d597b4d7-e6b6-4522-887e-73d3f4c01006
  • emptyDir 存储卷 默认使用节点本地磁盘,路径为 /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~empty-dir/<volume-name>

1
2
3
4
5
6
7
8
9
# 登录 k8s-worker2 节点
export POD_UID=d597b4d7-e6b6-4522-887e-73d3f4c01006
export POD_UID=6ea6636c-4a24-4dc5-af2a-2448825913b6
export VOLUME_NAME=shared-data
cd /var/lib/kubelet/pods/$POD_UID/volumes/kubernetes.io~empty-dir/$VOLUME_NAME
$ ls
hello
$ cat hello
Hello
  • 进入容器查看存储卷内容

1
2
3
4
5
6
7
8
9
$ kubectl exec -it shared-emptydir-pod -c app -- cat /data1/hello
Hello
$ kubectl exec -it shared-emptydir-pod -c sidecar -- cat /data2/hello
Hello

# 修改内容,实际上在容器内部和外部都可以修改存储卷内容,修改后立刻生效
$ kubectl exec -it shared-emptydir-pod -c sidecar -- sh -c "echo 'Hello World' > /data2/hello"
$ kubectl exec -it shared-emptydir-pod -c app -- cat /data1/hello
Hello World
  • 删除POD后emptydir存储卷会立刻删除

1
2
3
4
5
kubectl delete pod shared-emptydir-pod

# 登录 k8s-worker2 节点查看 emptydir 存储卷
$ ls /var/lib/kubelet/pods/$POD_UID
ls: cannot access '/var/lib/kubelet/pods/d597b4d7-e6b6-4522-887e-73d3f4c01006': No such file or directory

将 emptydir 存储卷改用 内存 存储

1
2
3
emptyDir:
medium: Memory # 使用 内存 存储(tmpfs),适合高 IO 临时缓存
sizeLimit: 512Mi # 限制存储大小
  • 这里要注意,即使这里使用内存存储,但是 /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~empty-dir/<volume-name> 依然存在,但它挂载的是 tmpfs 文件系统

1
2
3
4
# 登录pod所在节点查看挂载点
$ mount | grep $POD_UID
tmpfs on /var/lib/kubelet/pods/6ea6636c-4a24-4dc5-af2a-2448825913b6/volumes/kubernetes.io~empty-dir/shared-data type tmpfs (rw,relatime,size=524288k)
tmpfs on /var/lib/kubelet/pods/6ea6636c-4a24-4dc5-af2a-2448825913b6/volumes/kubernetes.io~projected/kube-api-access-5nk7d type tmpfs (rw,relatime,size=3903212k)
卷类型 来源 挂载路径 作用
emptyDir 你配置的 /data1, /data2 Pod 内部容器共享临时内存存储
projected 系统自动 /var/run/secrets/kubernetes.io/serviceaccount/ 挂载 serviceaccount token,CA 证书
  • 查看容器内挂载点

1
2
3
4
$ kubectl exec shared-emptydir-pod -c app -- mount | grep /data1
tmpfs on /data1 type tmpfs (rw,relatime,size=524288k)
$ kubectl exec shared-emptydir-pod -c app -- mount | grep serviceaccount
tmpfs on /var/run/secrets/kubernetes.io/serviceaccount type tmpfs (ro,relatime,size=3903212k)