找回密码
 立即注册
首页 业界区 业界 【Kubernetes】部署数据库MySQL应用

【Kubernetes】部署数据库MySQL应用

哈梨尔 前天 13:50
Kubernetes部署MySQL

在部署MySQL前,先解释一下Deployment和StatefulSet差异
Deployment vs StatefulSet

Deployment
Deployment 主要用于部署无状态应用(Stateless Application)。它管理 Pod 的副本集,并支持滚动更新、回滚等功能。
特点:

  • 无状态:Deployment 管理的 Pod 是完全相同的、可替代的。任何一个 Pod 都可以被另一个 Pod 替换,不会影响应用的整体功能。

  • 随机命名和身份:Pod 的名称是随机的(例如:my-app-5d89b4f6d-xxxxx),没有固定的顺序。

  • 共享存储:多个 Pod 可以共享同一个持久化存储(例如:同一个 PVC),但通常每个 Pod 不需要独立的存储。

  • 服务发现和负载均衡:通过 Service 访问时,流量会被随机分配到任意一个 Pod。

  • 扩缩容:可以轻松地增加或减少副本数,新 Pod 会替代旧 Pod,没有顺序要求。

  • 使用场景

    • Web 服务器(如 Nginx、Apache)

    • 无状态 API 服务

    • 任何不需要保存状态或状态存储在外部(如数据库、Redis)的应用

      
StatefulSet
StatefulSet 用于部署有状态应用(Stateful Application),每个 Pod 有唯一的、稳定的身份标识。
特点:

  • 有状态:每个 Pod 有独立的、稳定的网络标识和存储。

  • 有序部署和扩展

    • 当部署多个 Pod 时,它们会按顺序创建(从 0 到 N-1),并且会等待前一个 Pod 准备就绪后才会创建下一个。

    • 缩容时,顺序相反(从 N-1 到 0)。

      
  • 稳定的网络标识

    • 每个 Pod 都有一个稳定的主机名,格式为:-。

    • 例如:一个名为 web 的 StatefulSet 有三个副本,Pod 名称分别为 web-0、web-1、web-2。

    • 每个 Pod 拥有一个稳定的 DNS 名称:...svc.cluster.local。

      
  • 独立的存储

    • 每个 Pod 可以拥有独立的持久化存储(通过 VolumeClaimTemplate 为每个 Pod 创建独立的 PVC)。

    • 当 Pod 被重新调度时,会挂载相同的存储,从而保持状态。

      
  • 使用场景

    • 数据库(如 MySQL、PostgreSQL 集群)

    • 分布式系统(如 Zookeeper、Etcd、Kafka)

    • 任何需要持久化数据且每个实例有独立状态的应用

      
核心差异总结
  特性 Deployment StatefulSet     适用场景 无状态应用 有状态应用   Pod身份 可互换、匿名 唯一、有序、稳定   网络标识 随机名称,不稳定 固定名称,有序(web-0,   存储 共享存储,Pod间无区别 独立存储,每个Pod专用   部署策略 滚动更新,可并行 顺序部署/删除(0→1→2)   服务发现 通过Service负载均衡 通过Headless  部署MySQL

1. 创建命名空间

mysql-namespace.yaml
  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4.   name: mysql
复制代码
2. 创建本地存储PV和StorageClass

mysql-storage.yaml
  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4.   name: local-storage
  5. provisioner: kubernetes.io/no-provisioner
  6. volumeBindingMode: WaitForFirstConsumer
  7. ---
  8. apiVersion: v1
  9. kind: PersistentVolume
  10. metadata:
  11.   name: mysql-local-pv
  12.   labels:
  13.     type: local
  14. spec:
  15.   capacity:
  16.     storage: 10Gi
  17.   accessModes:
  18.     - ReadWriteOnce
  19.   persistentVolumeReclaimPolicy: Retain
  20.   storageClassName: local-storage
  21.   local:
  22.     path: /data/mysql  # 节点上的本地目录
  23.   nodeAffinity:
  24.     required:
  25.       nodeSelectorTerms:
  26.       - matchExpressions:
  27.         - key: kubernetes.io/hostname
  28.           operator: In
  29.           values:
  30.           - colima  # 替换为实际节点名称
复制代码
3. 创建MySQL配置ConfigMap

mysql-configmap.yaml
  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4.   name: mysql-config
  5.   namespace: mysql
  6. data:
  7.   custom.cnf: |
  8.     [mysqld]
  9.     default_authentication_plugin=mysql_native_password
  10.     skip-name-resolve
  11.     explicit_defaults_for_timestamp
  12.     max_connections=1000
  13.     innodb_buffer_pool_size=256M
  14.     innodb_log_file_size=128M
  15.     character-set-server=utf8mb4
  16.     collation-server=utf8mb4_unicode_ci
复制代码
4. 创建MySQL密码Secret

mysql-secret.yaml
  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4.   name: mysql-secret
  5.   namespace: mysql
  6. type: Opaque
  7. data:
  8.   root-password: cm9vdDEyMyE=  # echo -n 'root123!' | base64
  9.   user-password: YXBwdXNlcjEyMyE=  # echo -n 'appuser123!' | base64
复制代码
5. 创建MySQL StatefulSet

mysql-statefulset.yaml
  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4.   name: mysql
  5.   namespace: mysql
  6. spec:
  7.   serviceName: mysql
  8.   replicas: 1
  9.   selector:
  10.     matchLabels:
  11.       app: mysql
  12.   template:
  13.     metadata:
  14.       labels:
  15.         app: mysql
  16.     spec:
  17.       containers:
  18.       - name: mysql
  19.         image: mysql:8.0
  20.         env:
  21.         - name: MYSQL_ROOT_PASSWORD
  22.           valueFrom:
  23.             secretKeyRef:
  24.               name: mysql-secret
  25.               key: root-password
  26.         - name: MYSQL_DATABASE
  27.           value: "myapp"
  28.         - name: MYSQL_USER
  29.           value: "appuser"
  30.         - name: MYSQL_PASSWORD
  31.           valueFrom:
  32.             secretKeyRef:
  33.               name: mysql-secret
  34.               key: user-password
  35.         ports:
  36.         - containerPort: 3306
  37.           name: mysql
  38.         volumeMounts:
  39.         - name: mysql-data
  40.           mountPath: /var/lib/mysql
  41.         - name: mysql-config
  42.           mountPath: /etc/mysql/conf.d
  43.         resources:
  44.           requests:
  45.             memory: "512Mi"
  46.             cpu: "250m"
  47.           limits:
  48.             memory: "1Gi"
  49.             cpu: "500m"
  50.         livenessProbe:
  51.           exec:
  52.             command:
  53.             - sh
  54.             - -c
  55.             - "mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}"
  56.           initialDelaySeconds: 30
  57.           periodSeconds: 10
  58.           timeoutSeconds: 5
  59.         readinessProbe:
  60.           exec:
  61.             command:
  62.             - sh
  63.             - -c
  64.             - "mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}"
  65.           initialDelaySeconds: 5
  66.           periodSeconds: 5
  67.           timeoutSeconds: 1
  68.       volumes:
  69.       - name: mysql-config
  70.         configMap:
  71.           name: mysql-config
  72.   volumeClaimTemplates:
  73.   - metadata:
  74.       name: mysql-data
  75.     spec:
  76.       accessModes: [ "ReadWriteOnce" ]
  77.       storageClassName: "local-storage"
  78.       resources:
  79.         requests:
  80.           storage: 10Gi
复制代码
6. 创建MySQL Service

mysql-service
  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4.   name: mysql
  5.   namespace: mysql
  6.   labels:
  7.     app: mysql
  8. spec:
  9.   ports:
  10.   - port: 3306
  11.     targetPort: 3306
  12.     name: mysql
  13.   selector:
  14.     app: mysql
  15.   type: ClusterIP
  16. ---
  17. # 可选:创建NodePort Service用于外部访问
  18. apiVersion: v1
  19. kind: Service
  20. metadata:
  21.   name: mysql-external
  22.   namespace: mysql
  23. spec:
  24.   type: NodePort
  25.   ports:
  26.   - port: 3306
  27.     targetPort: 3306
  28.     nodePort: 30306
  29.   selector:
  30.     app: mysql
复制代码
7. 部署脚本

  1. kubsuclr apply -f mysql-namespace.yaml
  2. kubectl apply -f mysql-storage.yaml
  3. kubectl apply -f mysql-configmap.yaml
  4. kubectl apply -f mysql-secret.yaml
  5. kubectl apply -f mysql-statefulset.yaml
  6. kubectl apply -f mysql-service.yaml
复制代码
8. 测试验证

1. 查看部署情况

  1. # 查看Pod状态
  2. kubectl get pods -n mysql -w
  3. # 检查PV/PVC状态...
  4. kubectl get pv,pvc -n mysql
  5. # 检查Service...
  6. kubectl get svc -n mysql
  7. # 进入mysql
  8. kubectl exec -it -n mysql mysql-0 -- mysql -u root -p
复制代码

2. 验证插入数据重启后数据不丢失


  • 创建表并保存数据
  1. CREATE TABLE IF NOT EXISTS `users` (
  2. `id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  3. `username` VARCHAR(50) NOT NULL COMMENT '用户名',
  4. `password` CHAR(60) NOT NULL COMMENT 'Bcrypt加密密码',  -- 固定60字符长度
  5. `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  6. `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  7. PRIMARY KEY (`id`))
  8. ENGINE=InnoDB
  9. DEFAULT CHARSET=utf8mb4
  10. COLLATE=utf8mb4_unicode_ci
  11. COMMENT='用户信息表';
  12. insert into users(username,`password`, created_at, updated_at) values('wilson', '123456', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP())
  13. select * from users;
复制代码

  • 重启k8s服务
  1. # 删除mysql pod
  2. kubectl delete -f mysql-statefulset.yaml
  3. # 重新部署mysql statefulset
  4. kubectl apply -f mysql-statefulset.yaml
复制代码


  • 验证数据
  1. # 重新进入
  2. kubectl exec -it -n mysql mysql-0 -- mysql -u root -p
  3. use myapp;
  4. select * from users;
复制代码

重要说明


  • 节点选择:需要根据实际环境修改PV中的节点名称

  • 目录权限:确保节点上的本地目录有正确的读写权限

  • 数据持久性:本地存储的数据不会在Pod重新调度时自动迁移

  • 备份策略:重要数据务必建立定期备份机制

  • 资源限制:根据实际需求调整CPU和内存限制

这个配置提供了一个生产可用的单机MySQL部署方案,包含了健康检查、资源配置、数据持久化等关键功能。
引用

https://github.com/WilsonPan/java-developer
例子: https://github.com/WilsonPan/java-developer/k8s/mysql
部署Spring应用

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册