kubernetes.io > Documentation > Tasks > Configure Pods and Containers > Configure a Pod to Use a Volume for Storage
kubernetes.io > Documentation > Tasks > Configure Pods and Containers > Configure a Pod to Use a PersistentVolume for Storage
This question is probably a better fit for the ‘Multi-container-pods’ section but I’m keeping it here as it will help you get acquainted with state
Easiest way to do this is to create a template pod with:
kubectl run busybox --image=busybox --restart=Never -o yaml --dry-run=client -- /bin/sh -c 'sleep 3600' > pod.yaml
vi pod.yaml
Copy paste the container definition and type the lines that have a comment in the end:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: busybox
name: busybox
spec:
dnsPolicy: ClusterFirst
restartPolicy: Never
containers:
- args:
- /bin/sh
- -c
- sleep 3600
image: busybox
imagePullPolicy: IfNotPresent
name: busybox
resources: {}
volumeMounts: #
- name: myvolume #
mountPath: /etc/foo #
- args:
- /bin/sh
- -c
- sleep 3600
image: busybox
name: busybox2 # don't forget to change the name during copy paste, must be different from the first container's name!
volumeMounts: #
- name: myvolume #
mountPath: /etc/foo #
volumes: #
- name: myvolume #
emptyDir: {} #
In case you forget to add bash -- /bin/sh -c 'sleep 3600'
in template pod create command, you can include command field in config file
spec:
containers:
- image: busybox
name: busybox
command: ["/bin/sh", "-c", "sleep 3600"]
Connect to the second container:
kubectl exec -it busybox -c busybox2 -- /bin/sh
cat /etc/passwd | cut -f 1 -d ':' > /etc/foo/passwd # instead of cut command you can use awk -F ":" '{print $1}'
cat /etc/foo/passwd # confirm that stuff has been written successfully
exit
Connect to the first container:
kubectl exec -it busybox -c busybox -- /bin/sh
mount | grep foo # confirm the mounting
cat /etc/foo/passwd
exit
kubectl delete po busybox
vi pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: myvolume
spec:
storageClassName: normal
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
- ReadWriteMany
hostPath:
path: /etc/foo
Show the PersistentVolumes:
kubectl create -f pv.yaml
# will have status 'Available'
kubectl get pv
vi pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mypvc
spec:
storageClassName: normal
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
Create it on the cluster:
kubectl create -f pvc.yaml
Show the PersistentVolumeClaims and PersistentVolumes:
kubectl get pvc # will show as 'Bound'
kubectl get pv # will show as 'Bound' as well
Create a skeleton pod:
kubectl run busybox --image=busybox --restart=Never -o yaml --dry-run=client -- /bin/sh -c 'sleep 3600' > pod.yaml
vi pod.yaml
Add the lines that finish with a comment:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: busybox
name: busybox
spec:
containers:
- args:
- /bin/sh
- -c
- sleep 3600
image: busybox
imagePullPolicy: IfNotPresent
name: busybox
resources: {}
volumeMounts: #
- name: myvolume #
mountPath: /etc/foo #
dnsPolicy: ClusterFirst
restartPolicy: Never
volumes: #
- name: myvolume #
persistentVolumeClaim: #
claimName: mypvc #
status: {}
Create the pod:
kubectl create -f pod.yaml
Connect to the pod and copy ‘/etc/passwd’ to ‘/etc/foo/passwd’:
kubectl exec busybox -it -- cp /etc/passwd /etc/foo/passwd
Create the second pod, called busybox2:
vim pod.yaml
# change 'metadata.name: busybox' to 'metadata.name: busybox2'
kubectl create -f pod.yaml
kubectl exec busybox2 -- ls /etc/foo # will show 'passwd'
# cleanup
kubectl delete po busybox busybox2
kubectl delete pvc mypvc
kubectl delete pv myvolume
If the file doesn’t show on the second pod but it shows on the first, it has most likely been scheduled on a different node.
# check which nodes the pods are on
kubectl get po busybox -o wide
kubectl get po busybox2 -o wide
If they are on different nodes, you won’t see the file, because we used the hostPath
volume type.
If you need to access the same files in a multi-node cluster, you need a volume type that is independent of a specific node.
There are lots of different types per cloud provider (see here), a general solution could be to use NFS.
kubectl run busybox --image=busybox --restart=Never -- sleep 3600
kubectl cp busybox:/etc/passwd ./passwd # kubectl cp command
# previous command might report an error, feel free to ignore it since copy command works
cat passwd