Kubernetes存储解决方案

426 阅读6分钟

临时存储-emptyDir

1. 什么是emptyDir?

当Pod的存储方案设定为emptyDir时,pod启动时就会在pod所在的节点磁盘空间开辟出一个空卷,供pod内的容器读取和写入数据。如果Pod从节点上被删除(Pod被删除或者Pod发生迁移),emptyDir也会被删除,并且永久丢失.

2. emptyDir有什么用?

主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

3. emptyDir例子

  • 创建emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-emptydir
spec:
  containers:
  - image: nginx:latest
    name: test-emptydir
    volumeMounts:
    - mountPath: /usr/share/nginx/html    #挂载到容器中的路径
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}   #指定存储方式为emptydir
  • 查看容器
kubectl get pods -o wide

image.png

  • 验证emptydir
登录节点
docker ps -a|grep empty
docker inspect 94a02ff83530
cd /var/lib/kubelet/pods/12d99fa3-8a12-46a0-86bf-fcba24d74ff6/volumes/kubernetes.io~empty-dir/cache-volume
创建文件
echo "hello" > index.html 
测试访问
curl 10.0.141.98
hello 
回收Pod
kubectl delete -f emptydir.yaml
ls /var/lib/kubelet/pods/12d99fa3-8a12-46a0-86bf-fcba24d74ff6/volumes/kubernetes.io~empty-dir/cache-volume
ls: cannot access /var/lib/kubelet/pods/12d99fa3-8a12-46a0-86bf-fcba24d74ff6/volumes/kubernetes.io~empty-dir/cache-volume: No such file or directory

image.png

本地存储-hostPath

1. 什么是hostPath

hostPath是映射节点文件系统中的文件或目录到Pod里,相当于docker -v,只不过Pod漂移到其它节点时,pod不会跨节点去读取目录。

2. hostPath有什么用?

  • 需要访问docker内部的容器:使用/var/lib/docker的hostPath
  • 在容器中运行cAdvisor;使用/dev/cgroups的hostPath
  • 一般与nodeSelector配合使用,将Pod固定在某个节点,用于一些有状态的服务,比如mysql。

3. hostPath例子

  • 创建hostpath.yaml
piVersion: v1
kind: Pod
metadata:
  name: test-hostpath
  namespace: dev
spec:
  containers:
  - name: test-hostpath
    image: nginx:latest
    hostname: test-hostpath
    volumeMounts:
    - name: test-hostpath                # 取个名字
      mountPath: /usr/share/nginx/html   # 挂载到容器中的路径,不能包含:
  volumes:
  - name: test-hostpath                  # 取个唯一名字,必须与上面volumeMounts中name的一致
    hostPath:
      path: /data                        # 节点上宿主机的路径
      type: DirectoryOrCreate            # 可选属性,默认为"",如果路径不存在,那么会创建一个空目录,权限为755

containers.volumeMounts配置项说明:

配置项名称说明取值
name必须,卷名称需要与spec.volumes下某个卷名称一致
mouthPath必须,挂载到容器中的路径
mountPropagation可选,挂载传播,提供了共享卷挂载的能力None:默认,卷在容器中以及宿主机上的后续挂载相互隔离\ \ \ \ HostToContainer: 任何在宿主机上创建的卷挂载在容器中都是可见的 Bidirectional: 在容器中创建的卷挂载都会传播到宿主机,然后传播到所有使用此挂载的pod中的容器里
readOnly可选,默认可读写
subPath可选,默认""将spec.voluems中的子目录挂载到容器中不同的位置
subPathExpr可选,默认“”与subPath类似,路径中可支持从环境变量取值:${VAR_NAME}。与subPath只能有一个出现

.hostPath.type的枚举值有:

取值说明
DirectoryOrCreate如果路径不存在,那么就创建一个755权限的空目录
Directory给定的目录路径必须存在
FileOrCreate如果文件不存在,那么就会创建一个644权限的空文件
File给定路径上必须存在对应文件
Socket给定路径上必须存在一个Unix Socket
CharDevice给定路径上必须存在字符设备
BlockDevice给定路径上必存存在块设备

持久存储-PersistentVolumes

1. 什么是PersistentVolumes

PV :PersistentVolume(持久化卷),是对底层的共享存储的一种抽象,PV由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、GlusterFS、NFS等,都是通过插件机制完成与共享存储的对接。

PV能够支持的数据存储服务类型 官方文档

  • awsElasticBlockStore - AWS Elastic Block Store (EBS)
  • azureDisk - Azure Disk
  • azureFile - Azure File
  • cephfs - CephFS volume
  • cinder - Cinder (OpenStack block storage) (deprecated)
  • csi - Container Storage Interface (CSI)
  • fc - Fibre Channel (FC) storage
  • flexVolume - FlexVolume
  • flocker - Flocker storage
  • gcePersistentDisk - GCE Persistent Disk
  • glusterfs - Glusterfs volume
  • hostPath - HostPath volume (for single node testing only; WILL NOT WORK in a multi-node cluster; consider using local volume instead)
  • iscsi - iSCSI (SCSI over IP) storage
  • local - local storage devices mounted on nodes.
  • nfs - Network File System (NFS) storage
  • photonPersistentDisk - Photon controller persistent disk. (This volume type no longer works since the removal of the corresponding cloud provider.)
  • portworxVolume - Portworx volume
  • quobyte - Quobyte volume
  • rbd - Rados Block Device (RBD) volume
  • scaleIO - ScaleIO volume (deprecated)
  • storageos - StorageOS volume
  • vsphereVolume - vSphere VMDK volume

2. 创建PV PVC验证

PV全局共享,PVC是Namespace隔离的,一个PV被PVC绑定后,不能被别的PVC绑定。

下面以AWS EBS为例子

  • 定义PV PVC

nginx-test-pv-pvc.yaml

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-test-pv
  labels:
    type: nginx-test-pv
spec:
  capacity:
    storage: 1Gi
  storageClassName: ebs-sc
  accessModes:
    - ReadWriteOnce
  awsElasticBlockStore:
    volumeID: vol-0f7f0e4a2d244201a
    fsType: xfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-test-pvc
  labels:
     type: nginx-test-pvc
spec:
  storageClassName: ebs-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      type: nginx-test-pv

  • 定义pod

nginx.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:latest
    name: test-nginx-pvc
    volumeMounts:
        - name: nginx-persistent-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nginx-persistent-storage
      persistentVolumeClaim:
        claimName: nginx-test-pvc
  • 运行查看
kubectl apply -f nginx-test-pv-pvc.yaml
kubectl apply -f nginx.yaml

kubectl get pv                                                     
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                                 STORAGECLASS   REASON   AGE
nginx-test-pv                              1Gi        RWO            Retain           Bound       default/nginx-test-pvc                ebs-sc                  4m40s

kubectl get pvc                                                                                                    
NAME             STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nginx-test-pvc   Bound    nginx-test-pv   1Gi        RWO            ebs-sc         4m45s

#进入容器
cd /usr/share/nginx/html
echo "hello" > index.html
curl 127.0.0.1
hello

#删除容器后再启动,并重新进入容器
curl 127.0.0.1
hello

PV的回收策略:

Recycle:会清除数据,自动回收。

Retain:需要手动清理回收。

Delete:云存储专用的回收空间使用命令。

2. 创建StorageClass PVC验证

Kubernetes提供了一套可以自动创建PV的机制,即:Dynamic Provisioning, 在动态资源供应模式下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV),并供Pod使用的存储管理机制。

StorageClass实现了pv的自动化,volumeClaimTemplates实现了pvc的自动化。

  • 定义storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-test
provisioner: ebs.csi.aws.com
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
  • 定义pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-test-pvc
  labels:
     type: nginx-test-pvc
spec:
  storageClassName: ebs-test
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  • 定义pod

nginx.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:latest
    name: test-nginx-pvc
    volumeMounts:
        - name: nginx-persistent-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nginx-persistent-storage
      persistentVolumeClaim:
        claimName: nginx-test-pvc
  • 运行查看
kubectl apply -f storageclass.yaml
kubectl apply -f pvc.yaml
kubectl apply -f nginx.yaml

#查看storageclass
kubectl get storageclass                                           
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
ebs-test          ebs.csi.aws.com         Delete          WaitForFirstConsumer   false                  68m

#查看pv
kubectl get pv                                                     
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                                 STORAGECLASS   REASON   AGE
pvc-9f9b0727-6bfd-4ca2-b66f-0e97a3430eea   1Gi        RWO            Retain           Bound       default/nginx-test-pvc                ebs-test                  2m41s

由StorageClass 动态创建的 PersistentVolume 会在类的reclaimPolicy字段中指定回收策略,可以是 Delete(默认) 或者 Retain。

allowVolumeExpansion 设置为true时,允许用户通过编辑相应的 PVC 对象来调整卷大小。