【kubernetes学习笔记】部署一个单实例MySQL

119 阅读3分钟

准备工作

在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