ConfigMap、Secret、emptyDir、hostPath等属于临时性存储,当pod被调度到某个节点上时,它们随pod的创建而创建,临时占用节点存储资源,当pod离开节点时,存储资源被交还给节点,pod一旦离开它们就失效,不具备持久化存储数据的能力。与此相反,持久化存储拥有独立的生命周期,具备持久化存储能力,其后端一般是独立的存储系统如NFS、iSCSI、cephfs、glusterfs等

kubernetes存储卷

  • 我们知道默认情况下容器的数据都是非持久化的,在容器消亡以后数据也跟着丢失,所以Docker提供了Volume机制以便将数据持久化存储。类似的。
  • Kubernetes提供了更强大的Volume机制和丰富的插件,解决了容器数据持久化和容器间共享数据的问题。
  • 与Docker不同,Kubernetes Volume的生命周期与Pod绑定
  • 容器挂掉后Kubelet再次重启容器时,Volume的数据依然还在
  • 而Pod删除时,Volume才会清理。数据是否丢失取决于具体的Volume类型,比如emptyDir的数据会丢失,而PV的数据则不会丢

NFS

NFS 是Network File System的缩写,即网络文件系统。Kubernetes中通过简单地配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持同时写操作。

  • NFS安装,所有节点都需要安装
# 安装nfs
yum install -y nfs-utils
# 创建共享目录
mkdir -p /data/nfs
# 赋予权限
chmod 777 -R /data/nfs
  • NFS配置-只在共享目录节点设置
# 编辑配置文件
vim /etc/exports
# 新增如下内容
/data/nfs *(rw,no_root_squash)
# 启动nfs
systemctl enable nfs
systemctl restart nfs

PV与PVC

  • pv: persistentVolume # 持久卷
  • 是集群中由系统管理员配置的一段网络存储。它是集群中的资源,就像node是集群资源一样。PV也是像是Volumes一样的存储插件,但其生命周期独立于使用PV的任何单个Pod。PV配置存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统。PV属于集群级别资源,不属于任何的Namespace
  • pvc: persistentVolumeClaim # 持久卷声明
  • 是使用存储的请求,属于Namespace中的资源。PVC类似于Pod,Pod消耗node资源,PVC消耗PV资源。Pod可以请求特定级别的计算资源(CPU和内存),PVC可以请求特定大小和访问模式的存储资源。
  • persistentVolume (PV) 和 PersistentVolumeClaim (PVC) 提供了方便的持久化卷:PV提供网络存储资源,而 PVC 请求存储资源。这样,设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷PV、最后创建 PVC 来将 Pod 跟数据卷关联起来PV和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。
  • pv和pvc是一对一绑定的,一旦一个pv和一个pvc完成绑定,除非pvc被删除,否则pv是不可以再被别的pvc绑定使用的
  • PV和PVC模式是需要运维人员先创建好PV,然后开发人员定义好PVC进行一对一的Bond

简述Kubernetes如何实现集群管理 kubernetes集群数据存储在哪_Pod


简述Kubernetes如何实现集群管理 kubernetes集群数据存储在哪_mysql_02

PV【persistentVolume 】持久卷

创建PV

apiVersion: v1
kind: PersistentVolume
# metadata
metadata:
  name: mypv
  labels:
    release: "stable"
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /data/nfs/mysql
    server: 192.168.0.180
  persistentVolumeReclaimPolicy: Recycle
  mountOptions:
    - hard
    - nfsvers=4.1
    - tcp

PV的生命周期

PV的生命周期包括5个阶段

  • Provisioning,即PV的创建,可以直接创建PV(静态方式),也可以使用StorageClass动态创建
  • Binding,将PV分配给PVC
  • Using,Pod通过PVC使用该Volume
  • Releasing,Pod释放Volume并删除PVC
  • Reclaiming,回收PV,可以保留PV以便下次使用,也可以直接从存储中删除

PV的状态

根据PV生命周期5个阶段,PV的状态有以下4种

  • Available:可用
  • Bound:已经分配给PVC
  • Released:PVC解绑但还未执行回收策略
  • Failed:发生错误

PV的访问模式

PV的访问模式(accessModes)有三种:

  • ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个Pod挂载
  • ReadOnlyMany(ROX):可以以只读的方式被多个Pod挂载共享
  • ReadWriteMany(RWX):这种存储可以以读写的方式被多个Pod挂载共享

不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

PV的回收状态

PV的回收策略(persistentVolumeReclaimPolicy,即PVC释放卷的时候PV该如何操作)也有三种

  • Retain,不清理, 保留Volume(需要手动清理)【比较常用】【缺省配置】
  • Recycle,删除数据,即rm -rf /thevolume/*(只有NFS和HostPath支持)
  • Delete,删除存储资源,比如删除AWS EBS卷(只有AWS EBS, GCE PD, Azure Disk和Cinder支持)

PVC [persistentVolumeClaim] 持久卷声明

创建pvc

# gvk
apiVersion: v1
kind: PersistentVolumeClaim
# metadata
metadata:
  name: db-data
spec:
  # 访问模式
  accessModes:
    - ReadWriteOnce
  # 存储类型
  volumeMode: Filesystem
  # 存储大小
  resources:
    requests:
      storage: 2Gi

PV与PVC绑定

  • master 中的控制环路监视新的 PVC,寻找匹配的 PV(如果可能),并将它们绑定在一起。如果为新的 PVC 动态 调配 PV,则该环路将始终将该 PV 绑定到 PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求 的数量。一旦 PV 和 PVC 绑定后, PersistentVolumeClaim 绑定是排他性的,不管它们是如何绑定的。 PVC 跟 PV 绑定是一对一的映射
  • 用户创建包含容量、访问模式等信息的PVC,向系统请求存储资源。系统查找已存在PV或者监控新创建PV,如果与PVC匹配则将两者绑定。如果PVC创建动态PV,则系统将一直将两者绑定。PV与PVC的绑定是一一对应关系,不能重复绑定与被绑定。如果系统一直没有为PVC找到匹配PV,则PVC无限期维持在"unbound"状态,直到系统找到匹配PV。实际绑定的PV容量可能大于PVC中申请的容量

简述Kubernetes如何实现集群管理 kubernetes集群数据存储在哪_Pod_03

在POD中使用PVC

  • 示例
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dbserver
  name: dbserver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dbserver
  strategy: {}
  template:
    metadata:
      labels:
        app: dbserver
    spec:
      volumes:
      - name: datadir
        persistentVolumeClaim:
          claimName: db-data
        #nfs:
        #  server: 192.168.0.180
        #  path: /data/nfs/mysql
      #nodeSelector:
      #  kubernetes.io/hostname: k8s03
      containers:
      - image: registry.cn-zhangjiakou.aliyuncs.com/breezey/mysql:5.7
        name: mysql
        volumeMounts:
        - name: datadir
          mountPath: /var/lib/mysql
        ports:
        - name: mysql
          containerPort: 3306
        env: 
        - name: MYSQL_ROOT_PASSWORD
          value: cka123
        - name: MYSQL_DATABASE
          value: wordpress
        resources: {}

storageClass

  • 监视集群当中的pvc,然后根据pvc的需求,自动的创建满足pvc类型的pv
  • PV和PVC模式是需要运维人员先创建好PV,然后开发人员定义好PVC进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,**Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板 **
  • StorageClass还可以封装不同类型的存储供PVC选用

StorageClass结构

StorageClass包括四个部分

  • provisioner:指定Volume插件的类型,包括内置插件(如kubernetes.io/glusterfs)和外部插件(如external-storage提供的ceph.com/cephfs)。
  • mountOptions:指定挂载选项,当PV不支持指定的选项时会直接失败。比如NFS支持hard和nfsvers=4.1等选项。
  • parameters:指定provisioner的选项,比如kubernetes.io/aws-ebs支持type、zone、iopsPerGB等参数。
  • reclaimPolicy:指定回收策略,同PV的回收策略。

在使用PVC时,可以通过DefaultStorageClass准入控制设置默认StorageClass, 即给未设置storageClassName的PVC自动添加默认的StorageClass

要使用 StorageClass,我们就得安装对应的自动配置程序,比如这里我们存储后端使用的是 nfs,那么我们就需要使用到⼀个 nfs-client 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

  • 存储卷绑定模式 Volume Binding Mode: StorageClass 根据存储卷绑定模式的选项,确定何时执行 存储卷与存储卷声明的绑定、何时执行动态存储卷提供(动态创建存储卷)。可选项有
  • Immediate: 即刻绑定 , 存储卷声明创建后,立刻动态创建存储卷并将其绑定到存储卷声明
  • WaitForFirstConsumer : 首次使用时绑定 , 直到存储卷声明第一次被容器组使用时,才创建存储卷,并将其绑定到存储卷声明 ** **

CSI 【Container Storage Interface】 容器存储接口

  • Container Storage Interface是由来自Kubernetes、Mesos、Docker等社区member联合制定的一个行业标准接口规范,旨在将任意存储系统暴露给容器化应用程序。
  • CSI规范定义了存储提供商实现CSI兼容的Volume Plugin的最小操作集和部署建议。CSI规范的主要焦点是声明Volume Plugin必须实现的接口。

简述Kubernetes如何实现集群管理 kubernetes集群数据存储在哪_数据_04

基于NFS的storageClass

storageclass --> nfs-csi --> nfs

部署nfs-csi

简述Kubernetes如何实现集群管理 kubernetes集群数据存储在哪_Pod_05

  • 部署 kubectl app -f **.yaml

创建StorageClass

# gvk
apiVersion: storage.k8s.io/v1
kind: StorageClass
# metadata   # global
metadata:
  name: nfs-sc
# 提供商
provisioner: nfs.csi.k8s.io
parameters:
  server: 192.168.0.180
  share: /data/nfs
reclaimPolicy: Retain  # only retain is supported
volumeBindingMode: Immediate
mountOptions:
  - hard
  - nfsvers=4.1

创建pvc

# gvk
apiVersion: v1
kind: PersistentVolumeClaim
# metadata
metadata:
  name: db-data2
spec:
  # 访问模式
  accessModes:
    - ReadWriteOnce
  # 存储类型
  volumeMode: Filesystem
  # 存储大小
  resources:
    requests:
      storage: 2Gi
  storageClassName: nfs-sc

创建Pod使用基于StorageClass的PVC

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dbserver
  name: dbserver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dbserver
  strategy: {}
  template:
    metadata:
      labels:
        app: dbserver
    spec:
      volumes:
      - name: datadir
        persistentVolumeClaim:
          claimName: db-data2
        #nfs:
        #  server: 192.168.0.180
        #  path: /data/nfs/mysql
      #nodeSelector:
      #  kubernetes.io/hostname: k8s03
      containers:
      - image: registry.cn-zhangjiakou.aliyuncs.com/breezey/mysql:5.7
        name: mysql
        volumeMounts:
        - name: datadir
          mountPath: /var/lib/mysql
        ports:
        - name: mysql
          containerPort: 3306
        env: 
        - name: MYSQL_ROOT_PASSWORD
          value: cka123
        - name: MYSQL_DATABASE
          value: wordpress
        resources: {}