K8s环境中部署各种开发应用服务(三)有状态服务的准备工作——StorageClass与provisioner

开始之前

上一篇我们从硬件开始打造了nfs服务
现在开始回到K8s下来继续部署使用nfs作为存储所需的其他内容

科普

之前在 K8s环境中部署各种开发应用服务(一)有状态服务的准备工作——科普 这篇提到了在K8s中要使用Statefulset来控制有状态服务类的任务

我们接下来需要做的是为Statefulset自动部署PV,PVC功能提供支持
也就是部署一个provisioner应用,并且配置通过这个provisioner来给Statefulset提供存储支持的StorageClass(存储类)

正式开始

首先我们进入到之前部署好的Rancher的Dashboard
按照之前的地址可以访问到,并且能看到前面部署好的k3s集群
https://192.168.31.82:8443/

image-20210716235102389

然后点击 raspicluster 进去就可以看到我们的4台树莓派主机了
image-20210716235203190

这里先点击上面的的项目/命名空间来创建一个新的命名空间redis来给后面的工作做准备

(此处也可以从下面的Kubernetes dashboard里面去创建,但是Rancher里就看不到了)

image-20210716235330398
可以看到我们创建好的命名空间

然后点击上面黄色的仪表盘按钮 进入到 Kubernetesdashboard 里面
image-20210716235349697

这个时候就可以通过左侧菜单提供的UI页面来部署配置我们要用的各种Deployments,StateFulSets,PV,PVC还有StorageClasses等等各种东西了

image-20210716235410278

其实在上面Rancher的页面中也是可以通过UI来可视化操作的
但是对于我们习惯了蒙眼狂奔的程序员来说,UI什么的都不重要
还有个原因就是,在具体使用这些UI界面的时候,总是会遇到各种小问题,尤其是通过UI操作之后得到的YAML内容并不是你想要的时候就会很头疼。因此与其与UI较劲(学习成本),不如直接用YAML来的方便

当然在刚起步的学习阶段,通过UI操作来生成配置文件之后再切换到YAML模式来查看内容,能够更直观的帮助理解和掌握配置的各种参数。总之按照自己喜欢的方式来就可以

我们可以通过页面最上方的导入YAML文件按钮来直接上传编辑好的YAML文件或者直接在这里编辑
image-20210716235434724

image-20210716235450356

这里就可以直接导入或者输入编辑好的YAML文件内容了

接下来先进行部署provisioner的准备工作

复制下面的内容

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
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: ["watch", "create", "update", "patch"]
   -  apiGroups: [""]
      resources: ["services", "endpoints"]
      verbs: ["get","create","list", "watch","update"]
   -  apiGroups: ["extensions"]
      resources: ["podsecuritypolicies"]
      resourceNames: ["nfs-provisioner"]
      verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: kube-system
  name: leader-locking-nfs-client-provisioner
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: kube-system
  name: leader-locking-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # 此处 namespace 要与 provisioner 的 namespace 保持一致
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

点击导入去执行

稍微说明一下
我们先给nfs服务的provisioner创建了一个Service Account以及相关的ClusterRole,让它有权限可以做后面的PV,PVC自动创建工作(其实就是读写硬盘文件) Service Account的说明请看下面从网上抄来的内容

Service Account(服务账号):是指由Kubernetes API 管理的账号,用于为Pod 之中的服务进程在访问Kubernetes API时提供身份标识( identity ) 。Service Account通常要绑定于特定的命名空间,它们由 API Server 创建,或者通过 API 调用于动创建 ,附带着一组存储为Secret的用于访问API Server的凭据。

接下来是创建provisionerStorageClass

K8s管理员可以按照自己的需求针对不同的服务去创建多个StorageClass

我们为了将不同的服务所使用的存储方案存储空间区分开,后面会使用多个StorageClass

这里先为下一章要部署的redis来创建它专用的StorageClassprovisioner

首先在NFS服务器的挂载目录下创建一个新的文件夹redis 未来redis服务启动之后生成的文件都会在这里面

 mkdir /mnt/data/nfsdata/redis

顺便赋予权限

chmod 777 -R /mnt/data/nfsdata/redis/

回到Kubernetes Dashboard去导入YAML内容

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-redis-provisioner #这个provisioner的Deployment我们专门给redis使用
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: kopkop/nfs-client-provisioner-arm64:latest
          volumeMounts:
          - name: nfs-client-root
            mountPath:  /persistentvolumes
          env:
          - name: PROVISIONER_NAME
            value: nfs-redis-provisioner #此处对应下面StorageClass的provisioner
          - name: NFS_SERVER
            value: 192.168.31.83 #之前部署好的NFS服务端地址
          - name: NFS_PATH
            value: /mnt/data/nfsdata/redis #NFS服务主机挂载到硬盘下的目录 这里给redis创建了一个目录作为redis专用
      volumes:
      - name: nfs-client-root
        nfs:
          server: 192.168.31.83 #NFS服务端地址
          path: /mnt/data/nfsdata/redis #NFS服务主机挂载到硬盘下 这里给redis创建了一个目录作为redis专用
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-redis #这个存储类专门给redis用
provisioner: nfs-redis-provisioner #和上面provisioner的PROVISIONER_NAME内容一致
reclaimPolicy: Retain

Deployment这里,这个就是真正提供服务的provisioner了,此处的image需要特别注意一下

我们要使用的是arm64版本,所以用到的是这个镜像

kopkop/nfs-client-provisioner-arm64

用错了就会出现平台不支持的报错

最下面的StorageClass就是提供给StateFulSets用的存储类

点击导入执行

image-20210716235619734

这样我们在K8s中的NFS存储工作就做好了

后面一篇会用Statefulset去部署我们的Redis集群服务

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注