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/
然后点击 raspicluster 进去就可以看到我们的4台树莓派主机了
这里先点击上面的的项目/命名空间来创建一个新的命名空间redis来给后面的工作做准备
(此处也可以从下面的Kubernetes dashboard里面去创建,但是Rancher里就看不到了)
可以看到我们创建好的命名空间
然后点击上面黄色的仪表盘按钮 进入到 Kubernetes 的 dashboard 里面
这个时候就可以通过左侧菜单提供的UI页面来部署配置我们要用的各种Deployments,StateFulSets,PV,PVC还有StorageClasses等等各种东西了
其实在上面Rancher的页面中也是可以通过UI来可视化操作的
但是对于我们习惯了蒙眼狂奔的程序员来说,UI什么的都不重要
还有个原因就是,在具体使用这些UI界面的时候,总是会遇到各种小问题,尤其是通过UI操作之后得到的YAML内容并不是你想要的时候就会很头疼。因此与其与UI较劲(学习成本),不如直接用YAML来的方便
当然在刚起步的学习阶段,通过UI操作来生成配置文件之后再切换到YAML模式来查看内容,能够更直观的帮助理解和掌握配置的各种参数。总之按照自己喜欢的方式来就可以
我们可以通过页面最上方的导入YAML文件按钮来直接上传编辑好的YAML文件或者直接在这里编辑
这里就可以直接导入或者输入编辑好的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的凭据。
接下来是创建provisioner和StorageClass
K8s管理员可以按照自己的需求针对不同的服务去创建多个StorageClass
我们为了将不同的服务所使用的存储方案和存储空间区分开,后面会使用多个StorageClass
这里先为下一章要部署的redis来创建它专用的StorageClass和provisioner
首先在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用的存储类了
点击导入执行
这样我们在K8s中的NFS存储工作就做好了
后面一篇会用Statefulset去部署我们的Redis集群服务