Kubernetes存储管理

TOC

Volume挂载

Volume是kubernetes Pod中多个容器访问的共享目录,Kubernetes提供了众多的volume类型,包括emptyDir、hostPath、nfs、glusterfs、cephfs、ceph rbd等。
下面主要介绍emptyDirhostPath两类。

emptyDir

emptyDir类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配 一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当Pod从node上移除时,emptyDir中的数据会被永久删除。
资源清单编写如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
      - name: vol-logs
        emptyDir: {}
      containers:
      - name: nginx
        image: nginx:1.23.1
        ports:
        - containerPort: 80
        volumeMounts:
        - name: vol-logs
          mountPath: /var/logs

其他配置不变,主要核心配置项如下:

#定义挂载的类型和名字
volumes:
- name: vol-logs
  emptyDir: {} #该模式不用定义路径
#挂载到容器里面的目录
volumeMounts:
- name: vol-logs
  mountPath: /var/logs

hostPath

hostPath Volume为pod挂载宿主机上的目录或文件,使得容器可以使用宿主机的高速文件系统进行存储。但是在k8s中pod都是动态在各node节点上调度。如果下次调度不在同一节点上,则无法正常使用。
资源清单编写如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
      - name: vol-logs
        hostPath:
          path: /data/logs
      containers:
      - name: nginx
        image: nginx:1.23.1
        ports:
        - containerPort: 80
        volumeMounts:
        - name: vol-logs
          mountPath: /var/logs

其他配置不变,主要核心配置项如下:

#定义挂载的类型和名字以及节点本地的目录
volumes:
- name: vol-logs
  hostPath:
    path: /data/logs
#挂载到容器里面的目录
volumeMounts:
- name: vol-logs
  mountPath: /var/logs

PV和PVC

PV和PVC的概念

PV:全称PersistentVolum(持久化卷),是对底层共享存储的一种抽象,比如 Ceph、GlusterFS、NFS、hostPath等,都是通过插件机制完成与共享存储的对接。

PVC:全称PersistentVolumeClaim(持久化卷声明),PVC是用户存储的一种声明,PVC和Pod 比较类似,Pod消耗的是节点,PVC消耗的是PV资源
除了PVC,Kubernetes又为我们引入了一个新的资源对象:StorageClass,通过StorageClass的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据StorageClass的描述就可以非常直观的知道各种存储资源的具体特性了,此外StorageClass还可以为我们自动生成PV。

hostPath

创建PV和PVC,使用hostPath的方式,资源清单编写如下:

# pv-hostpath.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-hostpath
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: '/data/k8s/test/hostpath'
---
# pvc-hostpath.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-hostpath
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

关于配置文件中属性说明:
Capacity(存储能力):一般来说,一个 PV 对象都要指定一个存储能力,通过 PV 的 capacity 属性来设置的,目前只支持存储空间的设置,就是我们这里的 storage=10Gi,不过未来可能会加入 IOPS、吞吐量等指标的配置。

AccessModes(访问模式):用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:

  • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
  • ReadWriteMany(RW):读写权限,可以被多个节点挂载

RECLAIM POLICY(回收策略属性):

  • Retain(保留):保留数据,需要管理员手工清理数据
  • Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /thevoluem/*
  • Delete(删除):与 PV 相连的后端存储完成 volume 的删除操作,当然这常见于云服务商的存储服务,比如 ASW EBS。

STATUS(PV状态):

  • Available(可用):表示可用状态,还未被任何 PVC 绑定
  • Bound(已绑定):表示 PV 已经被 PVC 绑定
  • Released(已释放):PVC 被删除,但是资源还未被集群重新声明
  • Failed(失败): 表示该 PV 的自动回收失败

查看pv和pvc的状态:

#查看PV的状态
[root@master ~]# kubectl get pv -l type=local
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE
pv-hostpath   10Gi       RWO            Retain           Bound    default/pvc-hostpath   manual 81m
#查看PVC的信息
[root@master ~]# kubectl get pvc pvc-hostpath
NAME           STATUS   VOLUME        CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-hostpath   Bound    pv-hostpath   10Gi       RWO            manual         6m47s

接下来就是挂载到pod容器上使用,资源清单编写如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
         - name: pv-hostpath
           persistentVolumeClaim:
             claimName: pvc-hostpath
      nodeSelector:
        kubernetes.io/hostname: node1
      containers:
      - name: nginx
        image: nginx:1.23.1
        ports:
        - containerPort: 80
        volumeMounts:
          - name: pv-hostpath
            mountPath: '/usr/share/nginx/html'   

注意:由于我们创建的 PV 真正的存储在节点 node1 上面,所以我们这里必须把 Pod 固定在这个节点下面

NFS共享存储

NFS共享存储故名思义就是使用nfs服务来创建PV和PVC对象来给pod使用,这样可以不用将pod调度到对应的node节点上才能使用了。
首先我们得先搭建NFS服务,这里我们的NFS服务地址为:192.168.31.110

开始创建PV和PVC,资源清单编写如下:

# nfs-pv-pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /var/lib/k8s/data/
    server: 192.168.31.110
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

接下来就是挂载到pod容器上使用,资源清单编写如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
         - name: nfs
           persistentVolumeClaim:
             claimName: nfs-pvc
      nodeSelector:
        kubernetes.io/hostname: node1
      containers:
      - name: nginx
        image: nginx:1.23.1
        ports:
        - containerPort: 80
        volumeMounts:
          - name: nfs
            subPath: test-volumes
            mountPath: '/usr/share/nginx/html'