目录

    之前通过 Kubernetes 之 Volumes ,对 Volumes 有了一定的了解。本篇主要侧重实践,学习如何使用 emptydir、hostpath、localvolume 三种本地存储方案。

    1. PV 的基本属性

    1.1 PV 的生命周期

    PV 的状态:

    • Available:可用,还未被任何 PVC 绑定
    • Bound:已经被 PVC 绑定
    • Released:PVC 被删除,但是资源还未被重新声明
    • Failed:自动回收失败

    1.2 PV 的回收策略

    PersistentVolumeReclaimPolicy,即 PV 的回收策略。

    当 Pod 不需要 PV 时,如何处理:

    • Retain:保留数据,需要管理员手工清理数据
    • Recycle:资源回收,清除 PV 中的数据
    • Delete:直接删除 PV

    目前只有 NFS 和 HostPath 类型卷支持回收策略,AWS EBS、GCE PD、Azure Disk 和 Cinder 支持 Delete 策略。

    1.3 PV 的访问模式

    PV 的访问模式(accessModes):

    • ReadWriteOnce:PV 以 read-write 挂载到一个 Pod
    • ReadWriteMany:PV 以 read-write 方式挂载到多个 Pod
    • ReadOnlyMany:PV 以 read-only 方式挂载到多个 Pod

    2. emptyDir

    使用 emptyDir 时,Kubernetes 在 Node 上自动分配一个目录给 Pod。此目录中,初始内容为空,当 Pod 从 Node 上移除时,emptyDir 中的数据也被移除。

    主要用于无需永久保存的临时目录,多个容器的共享目录等场景。

    创建文件 emptydir.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: emptydir
    spec:
      containers:
      - image: busybox
        name: app
        volumeMounts:
        - mountPath: /logs
          name: shared-dir
        args:
        - /bin/sh
        - -c
        - echo emptydir >> /logs/app.log; sleep 60000
      - image: busybox
        name: log-collector
        volumeMounts:
        - mountPath: /app_logs
          name: shared-dir
        args:
        - /bin/sh
        - -c
        - cat /app_logs/app.log; sleep 60000
      volumes:
      - name: shared-dir
        emptyDir: {}
    

    执行命令:

    kubectl apply -f emptydir.yaml
    kubectl exec emptydir -c log-collector cat /app_logs/app.log
    emptydir
    

    可以看到两个容器之间,实现了文件共享的功能。

    3. hostPath

    hostPath 类型是映射 Node 文件系统中的文件或者目录到 Pod 。支持的类型有文件、目录、File、Socket、CharDevice 和 BlockDevice。

    创建文件 hostpath.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-hostpath
    spec:
      nodeSelector:
        kubernetes.io/hostname: i-6fns0nua
      containers:
      - image: busybox
        name: app
        volumeMounts:
        - mountPath: /logs
          name: shared-dir
        args:
        - /bin/sh
        - -c
        - echo hostpath >> /logs/app.log; sleep 60000
      volumes:
      - name: shared-dir
        hostPath:
          path: /data/logs
    
    1. 登陆主机 i-6fns0nua ,创建目录
    mkdir -p /data/logs
    
    1. 创建 hostpath
    kubectl apply -f pod.yaml
    
    1. 登陆主机 i-6fns0nua ,查看共享文件
    cat /data/logs/app.log
    hostpath
    

    4. local volume

    local volume 适合的场景:

    • 数据缓存,应用可以就近访问数据,快速处理。
    • 分布式存储系统,如分布式数据库,分布式文件系统。

    4.1 创建静态存储

    创建文件 sc.yaml

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: local
    provisioner: kubernetes.io/no-provisioner
    volumeBindingMode: WaitForFirstConsumer
    

    pv.yaml

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: local1
    spec:
      capacity:
        storage: 30Gi 
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: local
      local:
        path: /data/local1
      nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - i-6fns0nua
    

    4.2 Pod 使用

    创建文件 pvc.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc1
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 30Gi
    

    Kubernetes 会自动对 PV 和 PVC 进行匹配。下面是在 Pod 中通过 PVC 使用存储。

    pod.yaml

    kind: Pod
    apiVersion: v1
    metadata:
      name: pod1
    spec:
      containers:
        - name: nginx1
          image: nginx
          volumeMounts:
          - mountPath: "/var/www/html"
            name: pod1
      volumes:
        - name: pod1
          persistentVolumeClaim:
            claimName: pvc1