HOME / ARTICLE

Kubernetes Storage 概念

volume, PersistentVolumeClaim, PersistentVolume, StorageClass 之间的关系

Kubernetes 中的 volume 概念与 Docker 中的 volume 并不相同,不能直接替换概念,但当然,它们都是关于存储的概念。

当说到 Kubernetes 的 volume 时,指的是分配给 Pod 的存储资源。

根据存储介质的不同,Kubernetes volume 有许多类型(types),比如 emptyDir,hostPath,persistentVolumeClaim,local 等。使用不同的存储介质,在 Pod 的配置上体现在 spec.volumes 上。比如 emptyDir 类型的 volume 这样配置

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

hostPath 类型的 volume 这样配置

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data

persistentVolumeClaim 类型的 volume 这样配置

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/scaleio
parameters:
  gateway: https://192.168.99.200:443/api
  system: scaleio
  protectionDomain: default
  storagePool: default
  storageMode: ThinProvisionned
  secretRef: sio-secret
  readOnly: false
  fsType: xfs
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaimG
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}
---
kind: Pod
apiVersion: v1
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: dockerfile/nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaimG

StatefulSet 通过设置 spec.volumeClaimTemplates 字段来给 Pod 指定 volume。由于这个字段有更高的优先级,所以 Pod 内的 spec.volumes 字段就可以省略了。所以上面的 yaml 可以这样写

kind: StatefulSet
apiVersion: apps/v1beta1
metadata: 
  name: web
spec: 
  serviceName: "nginx"
  template:
    ...
  volumeClaimTemplate:
  - metadata:
      name: www
    spec:
      accessMode: ["ReadWriteOnly"]
      storageClass: nfs
      resources:
        requests:
          storage: 1Gib

Kubernetes 依靠 StorageClass 来动态置备存储卷(Dynamic Volume Provisioning)

参考

  1. https://v1-7.docs.kubernetes.io/docs/concepts/storage/volumes/
  2. https://v1-7.docs.kubernetes.io/docs/api-reference/v1.7/#volume-v1-core