本文将详细介绍如何在 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 的配置文件,并为其添加了一些优化参数。你可以根据实际需求进一步调整配置。
希望本文对你有所帮助!如果有任何问题,欢迎在评论区留言讨论。