在Kubernetes 1.26 上使用 StatefulSet 部署 MySQL8
本文将详细介绍如何在 Kubernetes 1.26 上使用 StatefulSet 部署 MySQL 8,并使用 nfs-client
存储类。同时,我们将通过 ConfigMap 管理 MySQL 的配置文件,并为其添加一些优化参数。最后,我们还会配置一个 NodePort
类型的 Service,以便外部访问 MySQL 服务。
前提条件
-
已安装 Kubernetes 1.26 集群。
-
已安装 Helm。
-
已配置 NFS 服务器,并确保 Kubernetes 集群可以访问。
步骤 1: 安装 NFS 客户端 Provisioner
首先,我们需要安装 NFS 客户端 Provisioner,以便 Kubernetes 能够动态创建 NFS 存储卷。
安装 NFS 客户端 Provisioner
运行以下命令:
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ --set nfs.server=<NFS_SERVER_IP> \ --set nfs.path=<NFS_SHARE_PATH>
将 <NFS_SERVER_IP>
替换为你的 NFS 服务器 IP 地址,将 <NFS_SHARE_PATH>
替换为 NFS 共享路径。
验证 StorageClass
安装完成后,验证 nfs-client
StorageClass 是否创建成功:
kubectl get storageclass
步骤 2: 创建 ConfigMap 保存 MySQL 配置文件
我们将使用 ConfigMap 来管理 MySQL 的配置文件,并为其添加一些优化参数。
创建 ConfigMap
创建一个名为 mysql-config.yaml
的文件,内容如下:
apiVersion: v1 kind: ConfigMap metadata: name: mysql8-config labels: app: mysql8 data: my.cnf: | [mysqld] # Basic Settings bind-address = 0.0.0.0 port = 3306 datadir = /var/lib/mysql socket = /var/run/mysqld/mysqld.sock # Character Set character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # Connection Settings max_connections = 1000 max_user_connections = 500 wait_timeout = 600 interactive_timeout = 600 # Buffer Settings innodb_buffer_pool_size = 1G # Adjust based on available memory (e.g., 70% of total RAM) innodb_buffer_pool_instances = 8 # Recommended for high-concurrency workloads innodb_log_file_size = 512M # Larger log files improve write performance innodb_log_buffer_size = 64M # Query Cache (Disabled by default in MySQL 8) query_cache_type = 0 query_cache_size = 0 # Table Open Cache table_open_cache = 4000 table_definition_cache = 2000 # Threading thread_cache_size = 100 thread_stack = 256K # Logging log_error = /var/log/mysql/error.log slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # Binary Logging (Enable for replication and point-in-time recovery) log_bin = /var/lib/mysql/mysql-bin expire_logs_days = 7 binlog_format = ROW # InnoDB Settings innodb_file_per_table = 1 # Store each table in a separate file innodb_flush_log_at_trx_commit = 1 # Full ACID compliance (set to 2 for better performance) innodb_flush_method = O_DIRECT # Avoid double buffering innodb_io_capacity = 2000 # Adjust based on disk performance innodb_io_capacity_max = 4000 # Security skip_symbolic_links = 1 local_infile = 0 [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4
应用 ConfigMap:
kubectl apply -f mysql-config.yaml
步骤 3: 编写 StatefulSet 和 Service 的 YAML 文件
接下来,我们编写 StatefulSet 和 Service 的 YAML 文件。
创建 YAML 文件
创建一个名为 mysql-statefulset-nodeport-configmap.yaml
的文件,内容如下:
--- # Service for MySQL (NodePort) apiVersion: v1 kind: Service metadata: name: mysql8 labels: app: mysql8 spec: type: NodePort ports: - port: 3306 targetPort: 3306 nodePort: 31036 # Optional: Specify a NodePort between 30000-32767 selector: app: mysql8 --- # StatefulSet for MySQL apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql8 labels: app: mysql8 spec: serviceName: mysql8 replicas: 1 selector: matchLabels: app: mysql8 template: metadata: labels: app: mysql8 spec: containers: - name: mysql image: mysql:8.0 env: - name: MYSQL_ROOT_PASSWORD value: "your-root-password" # Replace with your desired root password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql8-data mountPath: /var/lib/mysql - name: mysql8-config mountPath: /etc/mysql/conf.d volumes: - name: mysql8-config configMap: name: mysql8-config volumeClaimTemplates: - metadata: name: mysql8-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "nfs-client" resources: requests: storage: 100Gi
步骤 4: 部署 MySQL StatefulSet 和 Service
部署 YAML 文件
运行以下命令部署 MySQL:
kubectl apply -f mysql-statefulset-nodeport-configmap.yaml
验证部署
-
检查 StatefulSet 和 Pod:
kubectl get statefulset kubectl get pods -l app=mysql8
你应该会看到一个名为
mysql8-0
的 Pod 正在运行。 -
检查 Service:
kubectl get svc -l app=mysql8
你应该会看到一个名为
mysql8
的 Service,类型为NodePort
,并且有一个分配的 NodePort(例如31306
)。
步骤 5: 验证 MySQL 服务
获取节点 IP
运行以下命令获取 Kubernetes 节点的 IP 地址:
kubectl get nodes -o wide
记录下其中一个节点的 INTERNAL-IP
或 EXTERNAL-IP
。
连接 MySQL
使用 MySQL 客户端连接到 MySQL 服务:
mysql -h <NODE_IP> -P 30036 -u root -p
将 <NODE_IP>
替换为你的节点 IP 地址,输入你在 YAML 文件中设置的 MYSQL_ROOT_PASSWORD
。
步骤 6: 验证配置文件
进入 Pod
进入 MySQL Pod:
kubectl exec -it mysql8-0 -- bash
查看配置文件
查看配置文件是否挂载到 /etc/mysql/conf.d
:
cat /etc/mysql/conf.d/my.cnf
你应该会看到 ConfigMap 中定义的 my.cnf
内容。
步骤 7: 清理资源(可选)
如果需要删除部署的资源,可以运行以下命令:
kubectl delete -f mysql-statefulset-nodeport-configmap.yaml kubectl delete configmap mysql-config
总结
通过以上步骤,我们成功在 Kubernetes 1.26 上使用 StatefulSet 部署了 MySQL 8,并通过 NodePort
类型的 Service 暴露了 MySQL 服务。同时,使用 ConfigMap 管理了 MySQL 的配置文件,并为其添加了一些优化参数。你可以根据实际需求进一步调整配置。
希望本文对你有所帮助!如果有任何问题,欢迎在评论区留言讨论。