多应用+插件架构,代码干净,支持一键云编译,码云点赞13K star,4.8-4.12 预售价格198元 广告
[TOC] 参考连接:[https://feisky.gitbooks.io/kubernetes/content/concepts/persistent-volume.html](https://feisky.gitbooks.io/kubernetes/content/concepts/persistent-volume.html) ## 缘由 在看statefluset[基础教程]([https://kubernetes.io/zh/docs/tutorials/stateful-application/basic-stateful-set/](https://kubernetes.io/zh/docs/tutorials/stateful-application/basic-stateful-set/))的时候遇到pod状态为pending ``` kubectl describe pod web-0 ``` 日志内容是 ``` pod has unbound immediate PersistentVolumeClaims ``` 于是就对PV和PVC进行研究。 具体内容查看[statefulset详解](statefulset%E8%AF%A6%E8%A7%A3.md),有给出完整的 web.yaml。但是我建议先把PV和PVC的概念弄懂了,自然就知晓怎么处理pod的状态为pending的问题了。 ## PV PersistentVolume(PV)是集群之中的一块网络存储。跟 Node 一样,也是集群的资源。PV 跟 Volume (卷) 类似,不过会有独立于 Pod 的生命周期。比如一个 NFS 的 PV 可以定义为 ``` apiVersion: v1 kind: PersistentVolume metadata: name: "www-data-pv" labels: name: www-data-pv release: stable spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle nfs: path: /nfs/www/data server: 192.168.84.75 ``` PV 的访问模式(accessModes)有三种: * ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个节点挂载。 * ReadOnlyMany(ROX):可以以只读的方式被多个节点挂载。 * ReadWriteMany(RWX):这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。 PV 的回收策略(persistentVolumeReclaimPolicy,即 PVC 释放卷的时候 PV 该如何操作)也有三种 * Retain,不清理, 保留 Volume(需要手动清理) * Recycle,删除数据,即`rm -rf /thevolume/*`(只有 NFS 和 HostPath 支持) * Delete,删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持) ## PVC PV 是存储资源,而 PersistentVolumeClaim (PVC) 是对 PV 的请求。PVC 跟 Pod 类似:Pod 消费 Node 资源,而 PVC 消费 PV 资源;Pod 能够请求 CPU 和内存资源,而 PVC 请求特定大小和访问模式的数据卷。 ``` apiVersion: v1 kind: PersistentVolumeClaim metadata: name: www-data-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi selector: matchLabels: name: www-data-pv release: stable ``` PVC 可以直接挂载到 Pod/StatefulSet 中: ``` apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumes: - name: www persistentVolumeClaim: claimName: www-data-pvc ``` ## 完整示例 ``` apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: v1 kind: PersistentVolume metadata: name: "www-data-pv" labels: name: www-data-pv release: stable spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle nfs: path: /nfs/www/data server: 192.168.84.75 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: www-data-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi selector: matchLabels: name: www-data-pv release: stable --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumes: - name: www persistentVolumeClaim: claimName: www-data-pvc ``` nfs是需要另外安装的 ``` sudo apt install nfs-kernel-server ``` 需要手动创建一个NFS Volume,具体细节看这里:[nfs的安装和使用](nfs%E7%9A%84%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8.md) ## StorageClass 上面通过手动的方式创建了一个 NFS Volume,这在管理很多 Volume 的时候不太方便。Kubernetes 还提供了[StorageClass](https://kubernetes.io/docs/user-guide/persistent-volumes/#storageclasses)来动态创建 PV,不仅节省了管理员的时间,还可以封装不同类型的存储供 PVC 选用。 StorageClass 包括四个部分 * provisioner:指定 Volume 插件的类型,包括内置插件(如`kubernetes.io/glusterfs`)和外部插件(如[external-storage](https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/cephfs)提供的`ceph.com/cephfs`)。 * mountOptions:指定挂载选项,当 PV 不支持指定的选项时会直接失败。比如 NFS 支持`hard`和`nfsvers=4.1`等选项。 * parameters:指定 provisioner 的选项,比如`kubernetes.io/aws-ebs`支持`type`、`zone`、`iopsPerGB`等参数。 * reclaimPolicy:指定回收策略,同 PV 的回收策略。 在使用 PVC 时,可以通过`DefaultStorageClass`准入控制设置默认 StorageClass, 即给未设置 storageClassName 的 PVC 自动添加默认的 StorageClass。而默认的 StorageClass 带有 annotation`storageclass.kubernetes.io/is-default-class=true`。 ## 技巧:Kuberntes 中无法删除 PV 的解决方法 系统内有一个已经不再使用的 PV ,已经删除了与其关联的 Pod 及 PVC ,并对其执行了删除命令,但是无法正常删除,一直出于如下状态: ``` $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-nfs-gysl 1Gi RWO Recycle Terminating default/www-vct-statefulset-pvc-gysl-0 managed-nfs-storage 22h ``` 解决方法 ``` $ kubectl patch pv pv-nfs-gysl -p '{"metadata":{"finalizers":null}}' persistentvolume/pv-nfs-gysl patched $ kubectl get pv No resources found. ``` 通过系统帮助信息,我们可以获取patch的简要使用说明: ``` patch: 使用 strategic merge patch 更新一个资源的 field(s) ```