动态PV

静态 PV 最大的问题就是使用起来不够方便,都是管理员提前创建好一批指定规格的 PV,无法做到按需创建。使用过程中,经常会遇到由于资源大小不匹配,规格不对等,造成 PVC 无法绑定 PV 的情况。同时还会造成资源浪费,比如一个只需要 1G 空间的 Pod,绑定了 10G 的 PV。这些问题,都可以通过动态 PV 来解决。

动态PV, 用StorageClass这个对象来描述

  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4. name: fast-rbd-sc
  5. annotation:
  6. storageclass.kubernetes.io/is-default-class: "true"
  7. provisioner: kubernetes.io/rbd # 必填项,用来指定volume plugin来创建PV的物理资源
  8. parameters: # 一些参数
  9. monitors: 10.16.153.105:6789
  10. adminId: kube
  11. adminSecretName: ceph-secret
  12. adminSecretNamespace: kube-system
  13. pool: kube
  14. userId: kube
  15. userSecretName: ceph-secret-user
  16. userSecretNamespace: default
  17. fsType: ext4
  18. imageFormat: "2"
  19. imageFeatures: "layering"

首先我们定义了一个 StorageClass。当用户创建好 Pod 以后,指定了 PVC,这个时候 Kubernetes 就会根据 StorageClass 中定义的 Provisioner 来调用对应的 plugin 来创建 PV。PV 创建成功后,跟 PVC 进行绑定,挂载到 Pod 中使用。

StatefulSet 中怎么使用 PV 和 PVC

我们在 StatefulSet 中使用volumeClaimTemplate,有了这个 template 我们就可以为每一个 Pod 生成一个单独的 PVC,并且绑定 PV 了,从而实现有状态服务各个 Pod 都有自己专属的存储

  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4. name: web
  5. spec:
  6. serviceName: "nginx"
  7. replicas: 2
  8. selector:
  9. matchLabels:
  10. app: nginx
  11. template:
  12. metadata:
  13. labels:
  14. app: nginx
  15. spec:
  16. containers:
  17. - name: nginx
  18. image: k8s.gcr.io/nginx-slim:0.8
  19. ports:
  20. - containerPort: 80
  21. name: web
  22. volumeMounts:
  23. - name: www
  24. mountPath: /usr/share/nginx/html
  25. volumeClaimTemplates:
  26. - metadata:
  27. name: www
  28. spec:
  29. accessModes: [ "ReadWriteOnce" ]
  30. resources:
  31. requests:
  32. storage: 1Gi