当前位置:首页 > 随笔 > 正文内容

在Kubernetes上部署MySQL 5.7及phpMyAdmin管理界面

访客 随笔 2026年10月23日 1

本文将详细介绍如何在Kubernetes (K8s) 集群中部署MySQL 5.7数据库服务,包括其配置、持久化存储、服务暴露、数据备份机制,以及一个方便的Web管理工具phpMyAdmin。

MySQL服务部署

1. 数据库配置(ConfigMap)

为了更好地管理MySQL的配置,我们将其核心参数定义在一个Kubernetes ConfigMap资源中。这允许我们将配置与Pod分离,便于更新和维护。

---
apiVersion: v1
data:
  mysqld.cnf: |-
    [mysqld]
    pid-file        = /var/run/mysqld/mysqld.pid
    socket          = /var/run/mysqld/mysqld.sock
    datadir         = /var/lib/mysql
    bind-address   = 0.0.0.0
    server_id = 1918
    default-time-zone='+08:00'

    # 禁用符号链接以增强安全性
    symbolic-links=0
    max_connections=1024
    default_storage_engine=innodb
    skip_external_locking
    lower_case_table_names=1
    skip_host_cache
    skip_name_resolve
    character_set_server=utf8mb4
    max_allowed_packet = 12M
    sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

    # ---------- 日志配置 ---------- #
    log_bin = mysql-bin
    binlog_format = ROW
    max_binlog_size = 100m
    binlog_cache_size = 4m
    max_binlog_cache_size = 512m
    expire_logs_days = 7
    log-error      = /var/lib/mysql/error.log
    slow-query-log = on
    slow_query_log_file = /var/lib/mysql/slow.log
    long_query_time = 1

    [client]
    default-character-set=utf8mb4
kind: ConfigMap
metadata:
  name: mysql-server-config
  namespace: bigdata
  labels:
    app.kubernetes.io/component: mysql-server

2. 数据库服务(Service)

Service用于为MySQL Pod提供稳定的网络访问入口。这里我们创建一个ClusterIP类型的Service,使其可在集群内部通过服务名称访问。

---
apiVersion: v1
kind: Service
metadata:
  name: mysql-database-service
  namespace: bigdata
  labels:
    app.kubernetes.io/component: mysql-server
spec:
  ports:
  - name: mysql-port
    port: 3306
    protocol: TCP
    targetPort: 3306
  selector:
    app.kubernetes.io/component: mysql-server

3. 数据库实例部署(Deployment)

Deployment负责管理MySQL Pod的创建和生命周期。为了实现数据持久化,本示例采用hostPath方式,将数据存储在宿主机节点上。这要求我们通过节点亲和性(Node Affinity)将MySQL Pod绑定到特定的、已打标签的节点。

在部署前,请确保您的目标节点已打上如kubectl label node <nodename> mysql-data-node=true的标签。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-database-instance
  namespace: bigdata
  labels:
    app.kubernetes.io/component: mysql-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/component: mysql-server
  template:
    metadata:
      labels:
        app.kubernetes.io/component: mysql-server
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: mysql-data-node
                operator: Exists # 确保Pod调度到带有'mysql-data-node'标签的节点上
      containers:
      - name: mysql-container
        env:
          - name: APP_NAME
            value: mysql
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: MYSQL_ROOT_USER
            value: root
          - name: MYSQL_ROOT_PASSWORD # 使用base64编码的root密码,这里是"password123"
            value: cGFzc3dvcmQxMjM=
          - name: TZ
            value: Asia/Shanghai
          - name: LANG
            value: en_US.UTF-8
        image: mysql:5.7.31
        imagePullPolicy: IfNotPresent
        livenessProbe: # 活性探针,检查MySQL服务是否正常运行
          exec:
            command:
            - /bin/bash
            - -c
            - mysql -u${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} -e 'SELECT 1'
          initialDelaySeconds: 30
          periodSeconds: 30
          timeoutSeconds: 10
        ports:
        - containerPort: 3306
          name: mysql-data-port
          protocol: TCP
        readinessProbe: # 就绪探针,检查MySQL服务是否准备好接收流量
          exec:
            command:
            - /bin/bash
            - -c
            - mysql -u${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD} -e 'SELECT 1'
          initialDelaySeconds: 30
          periodSeconds: 30
          timeoutSeconds: 10
        volumeMounts:
        - mountPath: /var/lib/mysql # 数据目录
          name: mysql-data-volume
        - mountPath: /etc/mysql/conf.d/ # 配置目录
          name: mysql-configuration
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      securityContext: {}
      terminationGracePeriodSeconds: 10
      volumes:
      - name: mysql-data-volume
        hostPath:
          path: /data/k8s_data/mysql # 宿主机路径,确保存在并有相应权限
          type: DirectoryOrCreate
      - name: mysql-configuration
        configMap:
          name: mysql-server-config # 引用前面定义的ConfigMap

4. 数据库备份(CronJob)

为了保障数据安全,我们配置一个CronJob来定期执行数据库备份。同样,为了确保备份数据存储在预期的宿主机上,这里也使用了节点亲和性。

在部署前,请为备份节点打上如kubectl label node <nodename> mysql-backup-node=true的标签。

注意:CronJob的schedule时间是基于Kubernetes集群的controller-manager时区。如果您的集群是kubeadm部署的,需要留意容器内时间和本地时区可能存在的差异(如八小时)。

---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: mysql-daily-backup-job
  namespace: bigdata
spec:
  schedule: "0 1 * * *" # 每天凌晨1点执行备份
  successfulJobsHistoryLimit: 3 # 保留最近3个成功的Job
  failedJobsHistoryLimit: 3     # 保留最近3个失败的Job
  jobTemplate:
    spec:
      template:
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: mysql-backup-node # 确保备份Job调度到带有此标签的节点
                    operator: Exists
          containers:
          - name: mysql-backup-container
            imagePullPolicy: IfNotPresent
            image: mysql:5.7.31
            env:
              - name: MYSQL_ROOT_USER
                value: root
              - name: MYSQL_ROOT_PASSWORD
                value: cGFzc3dvcmQxMjM= # 与MySQL实例相同的root密码
              - name: MYSQL_HOST
                value: mysql-database-service.bigdata.svc.cluster.local # MySQL服务地址
              - name: TZ
                value: Asia/Shanghai
              - name: LANG
                value: en_US.UTF-8
            command:
            - /bin/sh
            - -c
            - |
              set -ex
              mysqldump --host=${MYSQL_HOST} --user=${MYSQL_ROOT_USER} \
                        --password=${MYSQL_ROOT_PASSWORD} \
                        --routines --all-databases --single-transaction \
                        > /mysql-backup-dir/mysql-$(date +"%Y%m%dT%H_%M_%S").sql && \
              find /mysql-backup-dir/ -type f -mtime +3 -exec rm -rf {} \; # 备份后删除3天前的旧文件
            volumeMounts:
            - name: backup-storage-volume
              mountPath: /mysql-backup-dir
          restartPolicy: OnFailure
          volumes:
          - name: backup-storage-volume
            hostPath:
              path: /mnt/k8s_backup/mysql # 宿主机备份存储路径
              type: DirectoryOrCreate

phpMyAdmin图形化管理工具部署

phpMyAdmin是一个广泛使用的Web界面,用于管理MySQL数据库。它提供了一个直观的方式来执行数据库操作。

1. phpMyAdmin服务暴露(Service)

您可以选择通过ClusterIP在集群内部访问phpMyAdmin,或通过NodePort将服务暴露到集群外部。

  • 如果集群中已部署Ingress控制器,推荐使用ClusterIP模式,并通过Ingress规则暴露服务。
  • 如果没有Ingress,NodePort是一种简单直接的外部访问方式。请确保选择的NodePort端口(如30003)在集群节点上未被占用,且在有效端口范围(通常是30000-32767)。
---
apiVersion: v1
kind: Service
metadata:
  namespace: bigdata
  name: phpmyadmin-internal-svc # ClusterIP服务
  labels:
    app.kubernetes.io/component: phpmyadmin
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http-access
  selector:
    app.kubernetes.io/component: phpmyadmin
---
apiVersion: v1
kind: Service
metadata:
  namespace: bigdata
  name: phpmyadmin-external-svc # NodePort服务
  labels:
    app.kubernetes.io/component: phpmyadmin
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http-nodeport
    nodePort: 30003 # 自定义外部访问端口
  selector:
    app.kubernetes.io/component: phpmyadmin

2. phpMyAdmin管理界面部署(Deployment)

此Deployment创建phpMyAdmin的Pod。需要配置环境变量PMA_HOST和PMA_PORT指向您的MySQL服务。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: phpmyadmin-web-instance
  namespace: bigdata
  labels:
    app.kubernetes.io/component: phpmyadmin
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/component: phpmyadmin
  template:
    metadata:
      labels:
        app.kubernetes.io/component: phpmyadmin
    spec:
      containers:
      - name: phpmyadmin-container
        image: phpmyadmin/phpmyadmin:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        env:
        - name: PMA_HOST
          value: mysql-database-service.bigdata.svc.cluster.local # MySQL服务名称及命名空间
        - name: PMA_PORT
          value: "3306"

当所有Pod成功启动并运行后,您可以通过任意一个集群节点的IP地址加上NodePort(例如http://<NodeIP>:30003)来访问phpMyAdmin界面。使用之前配置的MySQL root用户名和密码即可登录管理您的数据库。

相关文章

可以按小时收费的VPS

很多 VPS 提供商都支持 按小时计费(hourly billing),想短期试用 / 临时搭建节点、测试网络、短期项目等场景非常合适。下面是当前最主流且靠谱的按小时 VPS 选项,分别按不同需求场景整理: 1. Vultr(全球节点,包括日本) 按小时计费 可选机房:东京 / 大阪 / 洛杉矶 / 法兰克福 / 伦敦 … 支持 PayPal(部分情况),但更常用信用卡/PayPal+卡价格参考$...

在 iPhone 上下载国外App

地区/国家限制App Store 会根据 Apple ID 的国家或地区限制应用下载。如果你的 Apple ID 绑定的是中国大陆,就可能无法下载 OpenAI 官方的 ChatGPT 应用,因为它在大陆 App Store 不上架。解决办法:换成美国、加拿大、香港等地区的 Apple ID。或者在现有 Apple ID 上更改地区。注册一个国外 Apple ID(推荐)比如注册 美国区 Appl...

Selenium自动化测试入门指南

Selenium自动化测试入门指南

什么是自动化测试? 自动化测试是指利用软件工具自动执行测试用例,模拟用户操作,如打开网页、点击链接、输入文本等,并验证结果是否符合预期。 其主要优点包括: 大幅减少人工成本 测试速度快 可以在非工作时间运行 支持持续集成和交付 然而,它也存在一些局限性,例如开发成本较高、不适合快速变化的项目、依赖稳定的UI界面等。 自动化测试的应用条件 适合引入自动化测试的情况包括: 手动测试耗时且需要大量...

MariaDB Galera集群故障快速恢复指南

OpenStack控制节点采用三节点MariaDB Galera集群架构。当数据库集群因故障重启时,有时会出现Galera集群无法正常启动的问题。虽然有多种方法可以恢复数据库服务,但如何实现快速启动同时确保数据完整性呢? 通过分析日志发现,MariaDB Galera集群节点宕机时会在日志中输出以下信息: [Note] WSREP: 新集群视图:全局状态: 874d8e7e-5980-11e8-8...

Android 中 EventBus 的通信机制与实现原理深度解析

EventBus 核心设计思想 EventBus 是一个基于观察者模式的事件总线框架,广泛应用于 Android 平台以实现组件解耦。它通过中心化的消息分发机制,使不同层级、不同线程的对象能够以"发布-订阅"方式通信,避免了传统接口回调或广播带来的强依赖问题。 核心角色说明 事件(Event):任意 Java 对象,作为数据载体,如网络状态变更通知、用户登录信息等。 发布者(Publi...

二叉树基础操作实现(C语言)

二叉树基础操作实现(C语言)

二叉树遍历方法 以下为二叉树结构示例 前序访问实现: void traversePreOrder(TreeNode* node) { if (node == NULL) { printf("N "); return; } printf("%d ", node->value); trave...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。