存储卷回顾

  • 存储卷介绍

pod有生命周期,生命周期结束后pod里的数据会消失(如配置文件,业务数据等)。

解决: 我们需要将数据与pod分离,将数据放在专门的存储卷上

pod在k8s集群的节点中是可以调度的, 如果pod挂了被调度到另一个节点,那么数据和pod的联系会中断。

解决: 所以我们需要与集群节点分离的存储系统才能实现数据持久化

简单来说: volume提供了在容器上挂载外部存储的能力

存储卷分类:

  • 本地存储卷 (Volume)
    • emptyDir 宿主机目录映射(临时存储),pod删除,数据也会被清除
    • hostPath 宿主机目录映射(持久存储),pod删除,数据不会被清除
  • 网络存储卷
    • NAS类 nfs等
    • SAN类 iscsi,FC等
    • 分布式存储 glusterfs,cephfs,rbd,cinder等
    • 云存储 aws,azurefile等

  • PV(持久存储卷)与PVC(持久存储卷声明)

  1. 认识pv与pvc

persistenvolume(PV) 是配置好的一段存储(可以是任意类型的存储卷)

  • 也就是说将网络存储共享出来,配置定义成PV。

PersistentVolumeClaim(PVC)是用户pod使用PV的申请请求。

  • 用户不需要关心具体的volume实现细节,只需要关心使用需求。

  1. pv与pvc之间的关系
  • pv提供存储资源(生产者)
  • pvc使用存储资源(消费者)
  • 使用pvc绑定pv

静态供给:创建pv, 创建pvc,创建pod关联pvc

  1. 什么是动态供给

每次使用存储要提前先创建pv, 再创建pvc,比较麻烦,我们可以实现使用存储的动态供给特性。

  • 静态存储需要用户申请PVC时保证容量和读写类型与预置PV的容量及读写类型完全匹配, 而动态存储则无需如此.
  • 管理员无需预先创建大量的PV作为存储资源

Kubernetes从1.4版起引入了一个新的资源对象StorageClass(存储类),可用于将存储资源定义为具有显著特性的类(Class即模板)而不是具体的PV。

用户通过PVC直接向意向的类别发出申请,匹配由管理员事先创建的PV,或者由其按需为用户动态创建PV,这样就免去了需要先创建PV的过程。

  1. 使用NFS文件系统创建存储动态供给

PV对存储系统的支持可通过其插件来实现,

目前,官方插件是不支持NFS动态供给的,但是我们可以用第三方的插件来实现

补充:安装配置nfs服务

# 所有节点都安装nfs-utils工具包和rpc-bind服务。

     yum install nfs-utils  -y

nfs服务器的ip为192.168.10.14

[root@nfs ~]# systemctl stop firewalld

[root@nfs ~]# systemctl disable firewalld

[root@nfs ~]# setenforce 0

[root@nfs ~]# vim /etc/sysconfig/selinux

SELINUX=disabled

[root@nfs ~]# mkdir -p /data/nfs

[root@nfs ~]#  vim /etc/exports

/data/nfs *(rw,sync,no_root_squash)

[root@nfs ~]#  systemctl start nfs-server

[root@nfs ~]#  systemctl enable nfs-server

[root@nfs ~]#  showmount -e

Export list for 192.168.10.14:

/data/nfs *

[root@worker01 ~]#  showmount -e 192.168.10.14

Export list for 192.168.10.11:

/data/nfs *

[root@worker02 ~]#  showmount -e 192.168.10.14

Export list for 192.168.10.11:

/data/nfs *

  1. 下载并创建storageclass

[root@master01 ~]# wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/class.yaml

[root@master01 ~]# mv class.yaml storageclass-nfs.yml

[root@master01 ~]# cat storageclass-nfs.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass                        # 类型
metadata:
  name: nfs-client                        # 名称,要使用就需要调用此名称
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner    # 动态供给插件
parameters:
  archiveOnDelete: "false"     # 删除数据时是否存档,false表示不存档,true表示存档

[root@master01 ~]# kubectl apply -f storageclass-nfs.yml
 

[root@master01 ~]# kubectl get storageclass
NAME         PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  10s

# RECLAIMPOLICY pv回收策略,pod或pvc被删除后,pv是否删除还是保留delete表示删除,但数据保留


# VOLUMEBINDINGMODE Immediate 模式下PVC与PV立即绑定,主要是不等待相关Pod调度完成,不关心其运行节点,直接完成绑定。

  1. 下载配置清单文件,创建rbac(创建账号,并授权

因为storage自动创建pv需要经过kube-apiserver,所以需要授权。

RBAC(Role-Based Access Control):基于角色的访问控制

  • 定义:

RBAC(Role-Based Access Control,基于角色的访问控制)是一种访问控制模型,它通过将用户分配到不同的角色,并为每个角色定义权限,从而实现对资源的访问控制。用户通过其所属的角色获得相应的权限,而无需直接为每个用户分配权限。

  • 核心组件:

用户(User):需要访问系统资源的主体,如员工、客户等。

角色(Role):一组权限的集合,代表用户在系统中的职责或身份。例如,“管理员”、“普通用户”等。

权限(Permission):允许用户对资源进行的操作,如“读取”、“写入”、“删除”等。

资源(Resource):系统中需要保护的对象,如文件、数据库、网络设备等。

[root@master01 ~]# wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/rbac.yaml

[root@master01 ~]# mv rbac.yaml storageclass-nfs-rbac.yaml

[root@master01 ~]# cat storageclass-nfs-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

[root@master01 ~]# kubectl apply -f storageclass-nfs-rbac.yaml
 

  1. 创建动态供给的deployment

需要一个deployment来专门实现pv与pvc的自动创建

[root@master01 ~]# vim deploy-nfs-client-provisioner.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccount: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.10.14
            - name: NFS_PATH
              value: /data/nfs
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.10.14
            path: /data/nfs

[root@master01 ~]# kubectl apply -f deploy-nfs-client-provisioner.yml
deployment.apps/nfs-client-provisioner created

[root@master01 ~]# kubectl get pods |grep nfs-client-provisioner
nfs-client-provisioner-5b5ddcd6c8-b6zbq   1/1     Running   0          34s

  1. 测试存储动态供给是否可用


# vim nginx-sc.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      imagePullSecrets:
      - name: huoban-harbor
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:1.20
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "nfs-client"
      resources:
        requests:
          storage: 1Gi

[root@master01 nfs]# kubectl get pods
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-9c988bc46-pr55n   1/1     Running   0          95s
web-0                                    1/1     Running   0          95s
web-1                                    1/1     Running   0          61s

[root@nfs ~]# ls /data/nfs/
default-www-web-0-pvc-a78841fb-ec92-426d-a7db-a2bcb53c448e 

default-www-web-1-pvc-0f6240e7-43a2-4605-be36-aaced8b2dc5b

[root@master01 ~]# kubectl delete -f nginx-svc.yaml

[root@nfs ~]# ls /data/nfs/

default-www-web-0-pvc-a78841fb-ec92-426d-a7db-a2bcb53c448e 

default-www-web-1-pvc-0f6240e7-43a2-4605-be36-aaced8b2dc5b

更多推荐