Kubernetes安装Mysql集群

Kubernetes安装Mysql集群

默认已配置好kubernetes与storageClass(本文使用directpv-min-io)
文章部署未使用helm和operator,慎用
kubernetes1.25 mysql5.7

1、namsSpace

apiVersion: v1
kind: Namespace
metadata:
  name: mysql
  labels:
    app: mysql

2、configMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  namespace: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    # Master配置
    [mysqld]
    datadir=/var/lib/mysql
    pid-file=/var/run/mysqld/mysqld.pid
    socket=/var/run/mysql/mysql.sock
    log-error=/var/log/mysql/error.log
    log-bin=mysqllog
    skip-name-resolve
    lower-case-table-names=1
    log_bin_trust_function_creators=1
  slave.cnf: |
    # Slave配置
    [mysqld]
    datadir=/var/lib/mysql
    pid-file=/var/run/mysqld/mysqld.pid
    socket=/var/run/mysql/mysql.sock
    log-error=/var/log/mysql/error.log
    skip-name-resolve
    log-bin=mysql-bin
    lower-case-table-names=1
    log_bin_trust_function_creators=1

3、secret

apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: mysql
  labels:
    app: mysql
type: Opaque
data:
  # 需使用base64编码
  password: MTIzNDU2 # 123456
  # 主从用的账号
  replicationUser: Y29weQ== # copy
  replicationPassword: MTIzNDU2 # 123456

4、service

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: mysql
  labels:
    app: mysql
spec:
  selector:
    # 匹配带有app: mysql标签的pod
    app: mysql
  clusterIP: None
  ports:
    - name: mysql
      port: 3306
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: mysql-master-node
  name: mysql-master-node
  namespace: mysql
spec:
  type: NodePort
  ports:
    - name: mysql
      port: 3306
      # 可使用此端口在外部访问
      nodePort: 30000
  selector:
    # 匹配带有mysql-role=master标签的pod
    mysql-role: master

5、statefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: mysql
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  # 需与service name保持一致
  serviceName: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      volumes:
        # 将configMap中的数据挂载到容器
        - name: configmap
          configMap:
            name: mysql
      # 初始化容器,为mysql准备配置文件
      initContainers:
        - name: init-mysql
          image: mysql:5.7
          # 需要将mysql数据和配置文件挂载出去,因为initContainers与containers数据不互通
          volumeMounts:
            - name: configmap
              mountPath: /app
            - name: conf
              mountPath: /etc/mysql/conf.d
            - name: data
              mountPath: /var/lib/mysql
          # mysql用户配置
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            - name: MYSQL_REPLICATION_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: replicationUser
            - name: MYSQL_REPLICATION_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: replicationPassword
          # 启动命令为sh脚本文件
          command:
            - /bin/bash
            - -c
            - |
              set -ex
              # 获取mysql-0后面的0,如果pod名称不是mysql-x,需要修改此处获取方法
              ordinal=`hostname | awk -F"-" '{print $2}'`
              # 为mysql准备server-id
              echo [mysqld] > /etc/mysql/conf.d/server-id.cnf
              # server-id不能是0,所以添加偏移
              echo server-id=$((100 + $ordinal)) >> /etc/mysql/conf.d/server-id.cnf
              # 如果是主节点,则用master.cnf,否则使用slave.cnf
              if [[ ${ordinal} -eq 0 ]]; then
                cp /app/master.cnf /etc/mysql/conf.d
              else
                cp /app/slave.cnf /etc/mysql/conf.d
              fi
      containers:
        - name: mysql
          image: mysql:5.7
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3306
              protocol: TCP
          # mysql用户配置
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            - name: MYSQL_REPLICATION_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: replicationUser
            - name: MYSQL_REPLICATION_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: replicationPassword
          # 需要将mysql数据和配置文件挂载出去,这里用来获取initContainers初始化好的配置文件
          volumeMounts:
            - name: configmap
              mountPath: /app
            - name: conf
              mountPath: /etc/mysql/conf.d
            - name: data
              mountPath: /var/lib/mysql
          lifecycle:
            postStart:
              exec:
                command:
                  - bash
                  - -c
                  - |
                    set -ex
                    cd /var/lib/mysql
                    # 判断是否已经初始化
                    if [ ! -f mysqlInitOk ]; then
                        # 一直尝试执行mysql命令,直到成功
                    	until mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "use mysql;SELECT 1;"; do sleep 1; done
                    	echo "Initialize ready"
                        # 判断是否为主节点
                    	pod_seq=$(hostname | awk -F"-" '{print $2}')
                        # 如果是主节点
                    	if [ $pod_seq -eq 0 ]; then
                            # 创建主从用户
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "create user '${MYSQL_REPLICATION_USER}'@'%' identified by '${MYSQL_REPLICATION_PASSWORD}';"
                    		# 为用户添加权限
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "grant replication slave on *.* to '${MYSQL_REPLICATION_USER}'@'%' with grant option;"
                    		# 刷新配置
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "flush privileges;"
                    		# 重启
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "reset master;"
                    	# 如果是从节点
                    	else
                            # 连接主节点,mysql-0.mysql.mysql表示{pod-name}.{service-name}.{namespace}
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e \
                    		"change master to master_host='mysql-0.mysql.mysql',master_port=3306, \
                                            master_user='${MYSQL_REPLICATION_USER}',master_password='${MYSQL_REPLICATION_PASSWORD}', \
                                            master_log_file='mysql-bin.000001',master_log_pos=156;"
                            # 重置slave
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "reset slave;"
                            # 重启
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "start slave;"
                            # 设置从节点只读
                    		mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "set global super_read_only=on;"
                    	fi
                        # 标识已初始化
                    	touch mysqlInitOk
                    fi
  # 卷申请模版
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: directpv-min-io
        resources:
          requests:
            storage: 5Gi
    - metadata:
        name: conf
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: directpv-min-io
        resources:
          requests:
            storage: 50Mi
# 为主节点打标记
kubectl label -n mysql pod mysql-0 mysql-role=master

6、测试

# 查看initContainers日志
kubectl logs -n mysql mysql-0 -c init-mysql
# 进入指定容器(主节点无法查看从节点连接情况)
kubectl exec -it -n mysql mysql-0 -c mysql -- /bin/bash
# 查看从节点连接情况
mysql -uroot -p123456
show slave status\G;
# 可以自己尝试在主节点创建数据库、表,查看从节点是否同步创建
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

眼眸流转

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值