k8s 数据管理
Kubernetes Volume
为了持久化保存容器的数据,可以使用 Kubernetes Volume。Volume 的生命周期独立于容器,Pod的容器可能被销毁和重建,但是Volume会被保留。
emptyDir
apiVersion: v1 kind: Pod metadata: name: producer-consumer spec: containers: - image: centos name: producer volumeMounts: - mountPath: /producer_dir name: shared-volume args: - /bin/sh - -c - echo "hello world" > /producer_dir/hello; sleep 30000 - image: centos name: consumer volumeMounts: - mountPath: /consumer_dir name: shared-volume args: - /bin/sh - -c - cat /consumer_dir/hello; sleep 30000 volumes: - name: shared-volume emptyDir: {}


/var/lib/kubelet/pods/b609d0d2-c47f-11e9-835c-00163e100228/volumes/kubernetes.io~empty-dir/shared-volume 就是emptyDir 在Host上的真正路径
emptyDir 是Host上创建的临时目录,其优点是能够方便地为Pod中的容器提供共享存储,不需要额外的配置。它不具备持久性,如果Pod不存在了,emptyDir 也就没有了。根据这个特性,emptyDir特别适合Pod中容器需要临时共享存储空间的场景。比如前面的生产者消费者用例。
hostPath
hostPath Volume 的作用是将Docker Host 文件系统中已经存在的目录mount给Pod的容器。大部分应用不会使用hostPath Volume,因为这实际上增加了Pod与节点的耦合,限制了Pod的使用。不过那些需要访问Kubernetes或Docker内部数据(配置文件和二进制库)的应用则需要使用hostPath,如果Pod 被销毁了,hostPath对应的目录还是会被保留,不过一旦Host崩溃,hostPath 也就无法访问了。
apiVersion: v1 kind: Pod metadata: name: producer-consumer spec: containers: - image: centos name: producer volumeMounts: - mountPath: /producer_dir name: shared-volume args: - /bin/sh - -c - echo "hello world" > /producer_dir/hello; sleep 30000 volumes: - name: shared-volume hostPath: path: /home/k8s/2019-08-30 #宿主机挂载点
外部存储
如果Kubernetes 部署在云上,那么可以直接使用云硬盘作为Volume
Kubernetes Volume 也可以使用主流的分布式存储,比如Ceph、GlustetFS 等
Ceph文件系统的/some/path/in/side/cephfs 目录被mount到容器路径/test/ceph
相当于emptyDir和hostPath,这些Volume类型的最大特点就是不依赖Kubernetes。Volume的底层基础设施由独立的存储系统管理,与Kubernetes集群是分离的。数据被持久化后,即是整个Kubernetes崩溃也不会受损。
PersistentVolume & PersistemtVolumeClaim
创建PV
下面创建一个PV ,配置文件为 nfs-pv.yaml
kind: PersistentVolume apiVersion: v1 metadata: name: mysql spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: nfs-a nfs: path: /nfsdata/mysql-pv server: 172.18.211.44
capacity : 指定PV的容量为1GB
-
ReadWriteOnce : 表示PV能以read-write模式mount到单个节点
-
ReadOnlyMany:表示PV能以read-only模式mount到多个节点
-
ReadWriteMany:表示PV能以read-write 模式mount到多个节点。
-
Retain:表示需要管理员手动回收
-
Recycle:表示清除PV中的数据,效果相当于执行 rm -rf /thevolume/*
-
Delete:表示删除StorageProvider 上对应的存储资源。
kubectl apply -f nfs-pv.yaml
STATUS 为 Available,表示 mypv1 就绪,可以被 PVC 申请。
创建PVC
接下来创建 PVC mypvc1,配置文件 nfs-pvc1.yml 如下:
PVC 就很简单了,只需要指定 PV 的容量,访问模式和 class。
执行命令创建 mypvc1:
从 kubectl get pvc 和 kubectl get pv 的输出可以看到 mypvc1 已经 Bound 到 mypv1,申请成功。
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: nfs
kubetl apply -f mypvc.yaml

从 kubectl get pvc 和 kubectl get pv 的输出可以看到 mypvc1 已经 Bound 到 mypv1,申请成功。
创建Pod
接下来就可以在Pod 中使用存储了,Pod配置文件Pod1.yml
apiVersion: v1 kind: Pod metadata: name: mypod1 spec: containers: - name: mypod1 image: busybox args: - /bin/sh - -c - sleep 300000 volumeMounts: - mountPath: "/mydata" name: mydata volumes: - name: mydata persistentVolumeClaim: claimName: mypvc1
验证
在 Pod中创建文件并写入内容,
kubectl exec -it mypod1 -- sh -c "echo 2 >> /mydata/hello"
可以看到 /mydata/hello确实已经保存在nfs的服务器目录/nfsdata中了1

PV的回收
先删pod 再删pvc 最后删pv
# kubectl apply -f mypod.yaml # kuectl apply -f mypvc.yaml
删除pvc之后pv的状态变为Available,,此时解除绑定后则可以被新的 PVC 申请。

/nfsdata文件中的文件被删除了

为 PV 的回收策略设置为 Recycle,所以数据会被清除,但这可能不是我们想要的结果。如果我们希望保留数据,可以将策略设置为 Retain。
删除pv
# kubectl apply -f nfs-pv.yaml
PV 还支持 Delete 的回收策略,会删除 PV 在 Storage Provider 上对应存储空间。NFS 的 PV 不支持 Delete,支持 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。
PV的动态供给
问题
pv 始终处于Terminating”状态,而且delete不掉。
解决方法
kubectl patch pv pvname -p '{"metadata":{"finalizers":null}}'

浙公网安备 33010602011771号