准备工作
在kubernetes集群中部署单实例MySQL参考运行一个单实例有状态应用 | Kubernetes。但在操作的时候将PV卷的类型由hostPath改为nfs。
Persistent Volumes
PV是集群的存储资源,Pod可以像使用其他Vloume资源那样使用PV。不同点在于PV的生命周期独立于使用的Pod。
PersistentVolumeClaims
PVC类似于声明,描述的是对象对存储的请求。在Pod对象中描述的PVC将为Pod匹配一个可用的PV,然后Pod就可以挂载使用这个PV,就像操作本地文件系统那样。
StorageClass
StorageClass可描述PVC与PV之间的匹配关系,多用于动态PV分配。本次操作中由于PV是静态制备的,StorageClassName似乎只起到了一个对应PVC和PV的作用,并不会检查对应的StorageClass是否实际存在。
Network File System(NFS)
NFS允许操作系统通过网络共享文件夹或者文件。
搭建自己的NFS服务器
根据unbuntu文档的指导,安装并启动一个NFS服务并不需要太复杂的步骤。安装只需执行该命令:
sudo apt install nfs-kernel-server
安装之后还需要修改/etc/exports配置NFS要暴露的路径,这里暴露/srv/mysql目录。
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/srv/mysql *(rw,async,no_subtree_check,no_root_squash)
其中:
*:表示允许所有客户端访问此共享。
rw:允许客户端读写该目录。
async:数据异步写入,性能较高,崩溃时可能导致数据丢失。
no_subtree_check:禁用子目录检查,提升性能,可能降低安全性。
no_root_squash:允许客户端以root用户的权限访问该目录。
修改之后重新加载NFS配置。
sudo exportfs -ra
部署MySQL
首先用NFS服务器暴露的路径创建一个如下的PV。其中storageClassName字段填写的并不是实际存在的storageClass,只是为了与之后的PVC匹配。
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
nfs:
path: /srv/mysql
server: 192.168.50.60
接下来声明如下的PVC。这将为该PVC绑定一个访问权限为ReadWriteOnce,大小为20Gi且storageClassName为manual的PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
最后在创建的MySQL中使用这个PVC。其中MYSQL_ROOT_PASSWORD是MySQL中root用户的密码,这一般是存储在Secret中的。另外,还需要确保PV中NFS服务器暴露的路径必须是空的,否则会导致MySQL容器启动失败。
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-pod
spec:
selector:
matchLabels:
app: mysql-pod
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql-pod
spec:
containers:
- name: mysql-container
image: mysql:8.4
resources:
limits:
memory: "1Gi"
cpu: "1000m"
env:
- name: MYSQL_ROOT_PASSWORD
value: "mysqlpassword"
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
创建后效果如下:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
mysql-pv-volume 20Gi RWO Retain Bound default/mysql-pv-claim manual <unset> 11m
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
mysql-pv-claim Bound mysql-pv-volume 20Gi RWO manual <unset> 11m
$ kubectl get pod | grep mysql
mysql-pod-66f9d485fc-8xkrl 1/1 Running 0 2m47s
随后创建MySQL服务共集群内部访问。
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql-pod
ports:
- port: 3306
targetPort: mysql
最后检查所创建的服务是可用的:
$ kubectl run -it --rm --image=mysql:8.4 mysql -- mysql -hmysql-service -pmysqlpassword
If you don't see a command prompt, try pressing enter.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> exit
Bye
Session ended, resume using 'kubectl attach mysql -c mysql -i -t' command when the pod is running
pod "mysql" deleted
参考资料
持久卷 | Kubernetes
运行一个单实例有状态应用 | Kubernetes
Network File System (NFS) - Ubuntu Server documentation
存储类 | Kubernetes