Volume
Volume的生命周期独立于容器,Pod的容器可能被销毁和重建,但Volume会被保留
emptyDir
emptyDir是最基础的Volume类型,一个emptyDir Volume是Host上的一个空目录
emptyDir Volume的生命周期和Pod一致。
模拟场景
apiVersion: v1
kind: Pod
metadata:
name: producer-consumer
spec:
containers:
- image: busybox
name: producer
volumeMounts:
- mountPath: /producer_dir # mount到指定目录
name: shared-volume
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello; sleep 30000
- image: busybox
name: consumer
volumeMounts:
- mountPath: /consumer_dir # mount到指定目录
name: shared-volume
args:
- /bin/sh
- -c
- cat /consumer_dir/hello; sleep 30000
volumes:
- name: shared-volume # 定义 `emptyDir` 类型的 Volume
emptyDir: {}
- 创建Pod
ubuntu2@root ~ kubectl apply -f emptyDir.yml
pod/producer-consumer created
ubuntu2@root ~ kubectl get pod
NAME READY STATUS RESTARTS AGE
producer-consumer 2/2 Running 0 79s
ubuntu2@root ~ kubectl logs producer-consumer consumer
hello world
ubuntu2@root ~
小结
emptyDir 是 Host 上创建的临时目录,其优点是能够方便地为 Pod 中的容器提供共享存储,不需要额外的配置。但它不具备持久性,如果 Pod 不存在了,emptyDir 也就没有了。根据这个特性,emptyDir 特别适合 Pod 中的容器需要临时共享存储空间的场景
hostPath Volume
hostPath Volume 的作用是将 Docker Host 文件系统中已经存在的目录 mount 给 Pod 的容器。大部分应用都不会使用 hostPath Volume,因为这实际上增加了 Pod 与节点的耦合,限制了 Pod 的使用。不过那些需要访问 Kubernetes 或 Docker 内部数据(配置文件和二进制库)的应用则需要使用 hostPath。
PV & PVC
PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。
PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。
NFS PersistentVolume
- ububtu2 安装nfs
无特殊说明则只在 ubuntun2(Master) 节点上执行
# Master、Node节点都安装nfs
sudo apt-get install -y nfs-kernel-server nfs-common
mkdir -p /nfsdata/pv1
echo -n "/nfsdata *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
# 配置生效
exportfs -r
# Master、Node节点都启动rpcbind、nfs服务
/etc/init.d/rpcbind restart && /etc/init.d/nfs-kernel-server restart
# 查看 RPC 服务的注册状况
rpcinfo -p localhost
# showmount测试
showmount -e localhost
# node节点查看NFS服务器共享目录
showmount -e x.x.x.x
- 编写 nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.1.8
accessModes
支持的访问模式有:
ReadWriteOnce – PV 能以 read-write 模式 mount 到单个节点。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多个节点。
ReadWriteMany – PV 能以 read-write 模式 mount 到多个节点。
persistentVolumeReclaimPolicy
支持的策略有
Retain – 需要管理员手工回收。
Recycle – 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*。
Delete – 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。
- 创建pv
ubuntu2@root ~ kubectl apply -f nfs-pv1.yml
persistentvolume/mypv1 created
ubuntu2@root ~ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mypv1 1Gi RWO Recycle Available nfs 56s
- 编写 nfs-pvc1.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mypvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
- 创建pvc
ubuntu2@root ~ kubectl apply -f nfs-pvc1.yml
persistentvolumeclaim/mypvc1 created
ubuntu2@root ~ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc1 Bound mypv1 1Gi RWO nfs 7s
- Pod使用存储
kind: Pod
apiVersion: v1
metadata:
name: mypod1
spec:
containers:
- name: mypod1
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/mydata"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: mypvc1
- 创建pod
ubuntu2@root k8s-learn kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mypod1 1/1 Running 0 21s 10.40.0.0 ubuntu3 <none> <none>
ubuntu2@root k8s-learn kubectl exec mypod1 touch /mydata/hello
ubuntu2@root k8s-learn ls -l /nfsdata/pv1
total 0
-rw-r--r-- 1 root root 0 Mar 12 22:27 hello
回收PV
kubectl delete pvc mypvc1
# 遇到了pvc一直无法删除,直接删除k8s中的记录
kubectl patch pvc mypvc1 -p '{"metadata":{"finalizers":null}}'
kubectl patch pv mypv1 -p '{"metadata":{"finalizers":null}}'