kubernets可以通过emptyDir实现在同一Pod的不同容器间共享文件系统。
正如它的名字,当Pod被创建时,emptyDir卷会被创建,这个时候它是一个空的文件夹;当Pod被删除时,emptyDir卷也会被永久删除。
同一Pod上不同容器之间共享
# bash
if [ -f /tempdir/lockfile ] && ! { set -C; 2>/dev/null >/tempdir/lockfile; }; thentail -f /tempdir/lockfile
elseexec 3>/tempdir/lockfileif [ -n "$POD_NAME" ]; thenpod_name=$POD_NAMEelsepod_name="unknown_pod"fiif [ -n "$CONTAINER_NAME" ]; thencontainer_name=$CONTAINER_NAMEelsecontainer_name="unknown_container"fiwhile true; doecho "$pod_name $container_name write something to lockfile" >&3sleep 5done
fi
我们使用上面这段脚本,会检测/tempdir/lockfile文件是否存在。如果不存在则创建这个文件,并获取Pod和Container名称,然后每隔5秒钟在/tempdir/lockfile写入一句话;如果存在,则不停打印新写入这个文件的内容。
然后使用下面的清单文件创建一个deployment
# emptydir_same_pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: emptydir-deployment
spec:selector:matchLabels:app: emptydir-containerreplicas: 1template:metadata:labels:app: emptydir-containerspec:containers:- name: emptydir-container1image: busyboxcommand: ["/bin/sh", "-c", "if [ -f /tempdir/lockfile ] && ! { set -C; 2>/dev/null >/tempdir/lockfile; }; then tail -f /tempdir/lockfile; else exec 3>/tempdir/lockfile; if [ -n \"$POD_NAME\" ]; then pod_name=$POD_NAME; else pod_name=\"unknown_pod\"; fi; if [ -n \"$CONTAINER_NAME\" ]; then container_name=$CONTAINER_NAME; else container_name=\"unknown_container\"; fi; while true; do echo \"$pod_name $container_name write something to lockfile\" >&3; sleep 5; done; fi;"]volumeMounts:- name: emptydir-volumemountPath: /tempdirenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: CONTAINER_NAMEvalue: emptydir-container1- name: emptydir-container2image: busyboxcommand: ["/bin/sh", "-c" ,"if [ -f /tempdir/lockfile ] && ! { set -C; 2>/dev/null >/tempdir/lockfile; }; then tail -f /tempdir/lockfile; else exec 3>/tempdir/lockfile; if [ -n \"$POD_NAME\" ]; then pod_name=$POD_NAME; else pod_name=\"unknown_pod\"; fi; if [ -n \"$CONTAINER_NAME\" ]; then container_name=$CONTAINER_NAME; else container_name=\"unknown_container\"; fi; while true; do echo \"$pod_name $container_name write something to lockfile\" >&3; sleep 5; done; fi;"]volumeMounts:- name: emptydir-volumemountPath: /tempdirenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: CONTAINER_NAMEvalue: emptydir-container2volumes:- name: emptydir-volumeemptyDir: medium: MemorysizeLimit: 1Gi
这个Deployment会创建一个Pod,这个Pod会含有两个容器:emptydir-container1和emptydir-container2。
使用下面命令创建这个部署
kubectl create -f emptydir_same_pod.yaml
deployment.apps/emptydir-deployment created
然后登录到容器中查看/tempdir/lockfile文件的内容
kubectl exec pods/emptydir-deployment-75c6545df5-slznj --container emptydir-container1 -it -- tail -f /tempdir/lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
……
kubectl exec pods/emptydir-deployment-75c6545df5-slznj --container emptydir-container2 -it -- tail -f /tempdir/lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
……
可以看到emptydir-container1容器在持续写入内容;emptydir-container2因为检测到/tempdir/lockfile文件存在,就不会写入文件。
通过下面指令可以看到emptydir-container2的输出
kubectl logs pods/emptydir-deployment-75c6545df5-slznj --container emptydir-container2
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
emptydir-deployment-75c6545df5-slznj emptydir-container1 write something to lockfile
……
同一个Node的不同Pod间不可以共享
我们应用Pod亲和性,让Deployment在同一个Node上部署相同的Pod。
# emptydir_same_node.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: emptydir-same-node-deployment
spec:selector:matchLabels:app: emptydir-containerreplicas: 2template:metadata:labels:app: emptydir-containerspec:affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- emptydir-containertopologyKey: "kubernetes.io/hostname"containers:- name: emptydir-containerimage: busyboxcommand: ["/bin/sh", "-c", "if [ -f /tempdir/lockfile ] && ! { set -C; 2>/dev/null >/tempdir/lockfile; }; then tail -f /tempdir/lockfile; else exec 3>/tempdir/lockfile; if [ -n \"$POD_NAME\" ]; then pod_name=$POD_NAME; else pod_name=\"unknown_pod\"; fi; if [ -n \"$CONTAINER_NAME\" ]; then container_name=$CONTAINER_NAME; else container_name=\"unknown_container\"; fi; while true; do echo \"$pod_name $container_name write something to lockfile\" >&3; sleep 5; done; fi;"]volumeMounts:- name: emptydir-volumemountPath: /tempdirenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: CONTAINER_NAMEvalue: emptydir-containervolumes:- name: emptydir-volumeemptyDir: medium: MemorysizeLimit: 1Gi
创建好这个部署后,我们可以通过下面指令确认它们被部署在同一个Node(ubuntuc)上。
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
emptydir-same-node-deployment-6b6cfbb769-vhj7k 1/1 Running 0 34s 10.1.43.199 ubuntuc <none> <none>
emptydir-same-node-deployment-6b6cfbb769-mgh8h 1/1 Running 0 34s 10.1.43.198 ubuntuc <none> <none>
然后查看每个Pod上/tempdir/lockfile文件的内容
kubectl exec pods/emptydir-same-node-deployment-6b6cfbb769-mgh8h --container emptydir-container -it -- tail -f /tempdir/lockfile
emptydir-same-node-deployment-6b6cfbb769-mgh8h emptydir-container write something to lockfile
emptydir-same-node-deployment-6b6cfbb769-mgh8h emptydir-container write something to lockfile
emptydir-same-node-deployment-6b6cfbb769-mgh8h emptydir-container write something to lockfile
……
kubectl exec pods/emptydir-same-node-deployment-6b6cfbb769-vhj7k --container emptydir-container -it -- tail -f /tempdir/lockfile
emptydir-same-node-deployment-6b6cfbb769-vhj7k emptydir-container write something to lockfile
emptydir-same-node-deployment-6b6cfbb769-vhj7k emptydir-container write something to lockfile
emptydir-same-node-deployment-6b6cfbb769-vhj7k emptydir-container write something to lockfile
……
可以看到它们打印出来的Pod名称不同,即可以证明:同一个Node上不同Pod创建的emptyDir是不同的。
参考资料
- https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#emptydir