• Post author:
  • Post category:Kubernetes
  • Post comments:0评论
基于 Kubernetes 1.22 版本

官方文档:

https://kubernetes.io/docs/concepts/storage/volumes/#local

一、介绍

  Local 卷表示配置的本地存储设备,如磁盘、分区或目录。Local 卷只能用作静态创建的PV,不支持动态资源调配。
  与 hostPath 卷相比,Local 卷以持久和可移植的方式使用,无需手动将 POD 调度到节点。系统通过查看 PV 上的节点关联来了解卷的节点约束。
  注意,Local 卷取决于基础节点的可用性,并不适用于所有应用程序。如果节点变得不正常,则 Pod 将无法访问本地卷,使用此卷的 Pod 无法运行。使用 Local 卷的应用程序必须能够容忍这种可用性降低以及潜在的数据丢失,这取决于底层磁盘的耐久性特征。
  以下示例显示了使用 Local 卷和 nodeAffinity 的 PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - example-node

  使用 Local 卷时必须设置 PV 的 nodeAffinity。 Kubernetes 调度程序使用 PV 的 nodeAffinity 将这些 Pod 调度到正确的节点。
  PV 的 volumeMode 可以设置为“Block”(而不是默认值“Filesystem”)以将 Local 卷公开为原始块设备。

  使用 Local 卷时,建议创建一个 StorageClass,volumeBindingMode 设置为 WaitForFirstConsumer。即延迟绑定,即创建 PVC 后,并不立刻执行绑定操作,而是要等到该 PVC 被使用时,调度器再综合考虑这个 Pod 声明的 PVC,到底应该跟哪个 PV 进行绑定。
  通过这个延迟绑定机制,原本实时发生的 PVC 和 PV 的绑定过程,就被延迟到了 Pod 第一次调度的时候在调度器中进行,从而保证了这个绑定结果不会影响 Pod 的正常调度。

二、示例演示

先创建一个 Local StorageClass:

[root@cp storageclass]# cat local.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

[root@cp storageclass]# kubectl apply -f local.yaml
[root@cp storageclass]# kubectl get sc
NAME    PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local   kubernetes.io/no-provisioner                  Delete          WaitForFirstConsumer   false                  5s

现在创建一个PV:

[root@cp storageclass]# cat test-pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-pv
spec:
  capacity:
    storage: 1Mi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local
  local:
    path: /data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - cp

[root@cp storageclass]# kubectl apply -f test-pv.yaml 
[root@cp storageclass]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
test-pv   1Mi        RWO            Retain           Available           local                   6s

  我们这里定义了一个 local 字段,表明它是一个 Local PV。path 字段,指定的正是这个 PV 对应的本地磁盘的路径。这也就意味着如果 Pod 要想使用这个 PV,那它就必须运行在 cp 节点上。所以,在这个 PV 的定义里,添加了一个节点亲和性 nodeAffinity 字段指定 cp 这个节点。这样,调度器在调度 Pod 的时候,就能够知道一个 PV 与节点的对应关系,从而做出正确的选择。
  创建一个 PVC:

[root@cp storageclass]# cat test-pvc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Mi
  storageClassName: local

[root@cp storageclass]# kubectl apply -f test-pvc.yaml 
persistentvolumeclaim/test-pvc created
[root@cp storageclass]# kubectl get pvc
NAME       STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Pending                                      local          5s

[root@cp storageclass]# kubectl describe pvc test-pvc | tail -n1
  Normal  WaitForFirstConsumer  12s (x3 over 35s)  persistentvolume-controller  waiting for first consumer to be created before binding

我们可以看到上述 PVC 处于待绑定状态,创建一个Pod 来使用这个 PVC:

[root@cp storageclass]# cat test-pod.yaml 
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: busybox:stable
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && exit 0 || exit 1"
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: test-pvc

[root@cp storageclass]# kubectl apply -f test-pod.yaml 
[root@cp storageclass]# kubectl get pvc
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    test-pv   1Mi        RWO            local          5m35s
[root@cp storageclass]# tree /data/
/data/
└── SUCCESS

发表评论