1、创建命名空间
[root@node1 statefulset-mysql]# cat mysql-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: mydb
2、provisioner授权sa账户
[root@node1 statefulset-mysql]# cat rabc.yaml
##唯一需要修改的地方只有namespace,根据实际情况定义
apiVersion: v1
kind: ServiceAccount # 创建一个账户,主要用来管理NFS provisioner在k8s集群中运行的权限
metadata:
name: nfs-client-provisioner
namespace: mydb
---
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: ["create","update","patch"]
- apiGroups: [""]
resources: ["endpoints"] #需要授权操作,否则在非默认命名空间无法动态创建PV
verbs: ["get","list","watch","create","update","patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: mydb
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 # 角色名
namespace: mydb # Role需要指定名称空间,ClusterRole 不需要
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
subjects: # 角色绑定对象
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: mydb
roleRef: # 绑定哪个角色
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
3、创建动态storageClass并配置动态PV驱动provisioner
[root@node1 statefulset-mysql]# cat mysql-sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: mysql-nfs-storage-name #PVC中的取值
provisioner: mysql-nfs-storage-pro
parameters:
archiveOndelete: "false"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-nfs-storage
namespace: mydb
labels:
app: mysql-nfs-storage
spec:
selector:
matchLabels:
app: mysql-nfs-storage
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql-nfs-storage
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: mysql-nfs-storage
image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: mysql-nfs-storage-pro #需要storageClass中的provisioner值保持一致
- name: NFS_SERVER
value: 192.168.58.130
- name: NFS_PATH
value: /opt/k8s
volumes:
- name: nfs-client-root
nfs:
server: 192.168.58.130
path: /opt/k8s
4、为statefulset创建无头服务(headless service)
[root@node1 statefulset-mysql]# cat mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: mydb
labels:
app: mysql
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: mysql
5、使用statefulset资源创建mysql
[root@node1 statefulset-mysql]# cat mysql-sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: mydb
spec:
selector:
matchLabels:
app: mysql #必须匹配 .spec.template.metadata.labels
serviceName: "mysql" #声明它属于哪个Headless Service.
replicas: 2 #副本数
template:
metadata:
labels:
app: mysql # 必须配置 .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
volumeMounts:
- name: mysql-pvc
mountPath: /var/lib/mysql
volumeClaimTemplates: #可看作pvc的模板
- metadata:
name: mysql-pvc
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "mysql-nfs-storage-name" #存储类名,改为集群中已存在的
resources:
requests:
storage: 100Mi
6、服务部署
[root@node1 statefulset-mysql]# kubectl apply -f ./
namespace/mydb created
storageclass.storage.k8s.io/mysql-nfs-storage-name created
deployment.apps/mysql-nfs-storage created
statefulset.apps/mysql created
service/mysql created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
persistentvolumeclaim/test-claim created
[root@node1 statefulset-mysql]# kubectl get all -n mydb
NAME READY STATUS RESTARTS AGE
pod/mysql-0 1/1 Running 0 35s
pod/mysql-1 1/1 Running 0 29s
pod/mysql-nfs-storage-578bb5595c-nnkr6 1/1 Running 0 35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mysql ClusterIP None <none> 3306/TCP 35s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mysql-nfs-storage 1/1 1 1 35s
NAME DESIRED CURRENT READY AGE
replicaset.apps/mysql-nfs-storage-578bb5595c 1 1 1 35s
NAME READY AGE
statefulset.apps/mysql 2/2 35s
[root@node1 statefulset-mysql]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-1288f88d-231f-4226-872d-7a7145cc5cd1 100Mi RWO Delete Bound mydb/mysql-pvc-mysql-1 mysql-nfs-storage-name 37s
pvc-a2b4585c-1548-429a-a233-bce3e6e32705 2Gi RWO Delete Terminating default/mysql-pvc-mysql-0 mysql-nfs-storage-name 81m
pvc-a876671e-8aed-4656-a319-7074f9a3db4c 100Mi RWO Delete Bound mydb/mysql-pvc-mysql-0 mysql-nfs-storage-name 40s
pvc-b6a8d86e-752c-46f4-a7a5-a9fed971e96a 2Gi RWO Delete Terminating default/mysql-pvc-mysql-1 mysql-nfs-storage-name 81m
pvc-ffb4db2d-71dd-4a71-8e58-c4016535468c 100Mi RWX Delete Bound mydb/test-claim mysql-nfs-storage-name 40s
[root@node1 statefulset-mysql]# kubectl get pvc -n mydb
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc-mysql-0 Bound pvc-a876671e-8aed-4656-a319-7074f9a3db4c 100Mi RWO mysql-nfs-storage-name 55s
mysql-pvc-mysql-1 Bound pvc-1288f88d-231f-4226-872d-7a7145cc5cd1 100Mi RWO mysql-nfs-storage-name 49s
test-claim Bound pvc-ffb4db2d-71dd-4a71-8e58-c4016535468c 100Mi RWX mysql-nfs-storage-name 55s
[root@node1 statefulset-mysql]# kubectl get pods -n mydb
NAME READY STATUS RESTARTS AGE
mysql-0 1/1 Running 0 90s
mysql-1 1/1 Running 0 84s
mysql-nfs-storage-578bb5595c-nnkr6 1/1 Running 1 (6s ago) 90s