kubernetes部署 MySQL MGR StatefulSet 和 MySQL Router

MySQL MBR StatefuSet

kind: StatefulSet
apiVersion: apps/v1
metadata:
  name: mysql
  namespace: middleware
  labels:
    app: mysql
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: mysql
    spec:
      volumes:
        - name: host-time
          hostPath:
            path: /etc/localtime
            type: ''
        - name: volume-confmap
          configMap:
            name: mysql-innodb-config
            defaultMode: 420
        - name: mysqlconf
          emptyDir: {}
      initContainers:
        - name: init-config
          image: 'busybox:1.35'
          command:
            - sh
          args:
            - '-c'
            - >-
              cp /config-map/my.cnf /mnt/my.cnf;

              ordinal=$(echo $HOSTNAME |grep  '[0-9]' -o)

              echo -e "\nserver-id=$((100 + $ordinal))" >> /mnt/my.cnf

              echo -e
              "\nreport_host=${HOSTNAME}.${MY_POD_SVC}.${MY_POD_NAMESPACE}" >>
              /mnt/my.cnf
          env:
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            - name: MY_POD_SVC
              value: mysql-svc
          resources: {}
          volumeMounts:
            - name: volume-confmap
              readOnly: true
              mountPath: /config-map
            - name: mysqlconf
              mountPath: /mnt
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      containers:
        - name: mysql
          image: 'mysql/mysql-server:8.0.28'
          ports:
            - name: tcp-3306
              containerPort: 3306
              protocol: TCP
            - name: tcp-33060
              containerPort: 33060
              protocol: TCP
            - name: tcp-33061
              containerPort: 33061
              protocol: TCP
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: QFedu123_
            - name: MYSQL_ROOT_HOST
              value: 127.0.0.1
          resources: {}
          volumeMounts:
            - name: host-time
              mountPath: /etc/localtime
            - name: mysql-data
              mountPath: /var/lib/mysql
              subPath: mysql
            - name: mysqlconf
              readOnly: true
              mountPath: /etc/my.cnf
              subPath: my.cnf
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
        - name: set-cluster
          image: 'mysql/mysql-server:8.0.28'
          command:
            - bash
          args:
            - '-c'
            - >-

              # 首先判断 mysql是否已经是可用状态

              until mysql -uroot -pQFedu123_ -h 127.0.0.1 -e 'SELECT 1'

              do
                  sleep 2
              done


              echo '判断是否存在 cfAdmin 用户'

              name=$(mysql -uroot -pQFedu123_ -h 127.0.0.1 -NB -e "select user
              from mysql.user where user='cfAdmin';")

              if [ $name ];then
                  echo '集群配置管理员 cfAdmin 用户存在,集群已经创建过'
                  sh
              else
                  echo '集群配置管理员 cfAdmin 不存在, 创建此用户'
                  mysqlsh --uri root:QFedu123_@localhost -- dba configure-instance --clusterAdmin=cfAdmin --clusterAdminPassword=cfAdmin_F127
                  if [ $? -eq 0 ];then
                      echo '集群配置管理员 cfAdmin 已创建完成,接下来准备创建集群'
                  else
                      echo '集群配置管理员 cfAdmin 创建失败,容器退出'
                      exit 1
                  fi
              fi

              echo "主机名:$HOSTNAME"

              pod_prefix=$(echo $HOSTNAME |awk -F '-[0123456789]' '{print $1}')

              echo "判断当前 Pod 是否是 ${pod_prefix}-0"

              if [ ${HOSTNAME} == ${pod_prefix}-0 ];then
                  echo "本 Pod 是 ${pod_prefix}-0,接着判断是否创建过集群"
                  mysqlsh --uri cfAdmin:cfAdmin_F127@localhost:3306 -- cluster status
                  if [ $? -ne 0 ];then
                      echo '没有创建过集群,开始创建集群,并初始化为主节点'
                      mysqlsh --uri cfAdmin:cfAdmin_F127@localhost:3306 -- dba create-cluster InnoDB_Cluster8 --multiPrimary=false --memberWeight=100 --ipAllowlist="10.244.0.0/16"
                  fi
                  echo '获取当前集群状态'
                  mysqlsh --uri cfAdmin:cfAdmin_F127@localhost:3306 -- cluster status
                  sh
              else
                  echo "本 Pod 不是 ${pod_prefix}-0,将其添加到集群"
                  pod_id=$(echo $HOSTNAME |awk -F- '{print $NF}')
                  echo "开始查找集群内可通信的节点"
                  for i in $(seq 0 $((pod_id - 1)))
                  do
                      befor_pod=${pod_prefix}-$((pod_id - 1)).${MY_POD_SVC}
                      mysql -ucfAdmin -pcfAdmin_F127 -h${befor_pod} -NB -e "select 1"
                      if [ $? -eq 0 ];then
                          echo "已找到集群内可通信的节点: ${befor_pod}"
                          break
                      fi
                  done
                  echo "从 ${befor_pod} 获取集群中主节点信息"
                  node_primary=''
                  while [[ -z $node_primary ]]; do
                      node_primary=$(mysqlsh --uri cfAdmin:cfAdmin_F127@${befor_pod}:3306 -- cluster status|awk '/SourceMember/ {print $NF}'|tr -d '"')
                      sleep 2
                  done
                  echo "当前主节点是 ${node_primary} 开始将 ${HOSTNAME} 添加到集群"
                  mysqlsh --uri cfAdmin:cfAdmin_F127@${node_primary} -- cluster add-instance ${HOSTNAME}.${MY_POD_SVC}.${MY_POD_NAMESPACE}:3306 --ipAllowlist=10.244.0.0/16 --memberWeight=60 --recoveryMethod=incremental

                  echo "判断是否创建过集群管理员账户"
                  name=$(mysqlsh --uri cfAdmin:cfAdmin_F127@${node_primary} --sql -e "select user from mysql.user where user='icAdmin';" |awk 'NR==2 {print $1}')
                  if [ -z "${name}" ];then
                      echo "集群管理员账户不存在:${name},开始创建管理员账户"
                      mysqlsh --uri cfAdmin:cfAdmin_F127@${node_primary} -- cluster setup-admin-account icAdmin@10.%  --password='icAdmin_F127'
                  else
                      echo "集群管理员账户已存在:${name}"
                  fi
                  echo '获取当前集群状态'
                  mysqlsh --uri icAdmin:icAdmin_F127@${node_primary} -- cluster status
                  sh
              fi
          env:
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            - name: MY_POD_SVC
              value: mysql-svc
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
          stdin: true
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: default
      serviceAccount: default
      securityContext: {}
      schedulerName: default-scheduler
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: mysql-data
        namespace: middleware
        creationTimestamp: null
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 30Gi
        storageClassName: nfs-storage
        volumeMode: Filesystem
  serviceName: mysql-svc
  podManagementPolicy: OrderedReady
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0
  revisionHistoryLimit: 10
---
kind: Service
apiVersion: v1
metadata:
  name: mysql-svc
  namespace: middleware
  labels:
    app: mysql
spec:
  ports:
    - name: tcp-3306
      protocol: TCP
      port: 3306
      targetPort: 3306
    - name: tcp-33060
      protocol: TCP
      port: 33060
      targetPort: 33060
    - name: tcp-33061
      protocol: TCP
      port: 33061
      targetPort: 33061
  selector:
    app: mysql
  clusterIP: None
  clusterIPs:
    - None
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  internalTrafficPolicy: Cluster

  #####备注:这个只是模板需要改的信息较多 1、pod的名称 2、service的 这两项都可统一替换 3、配置文件需要提前创建configmap

my.cnf

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

[mysqld]
user=mysql

character_set_server=utf8mb4
collation-server = utf8mb4_unicode_ci

default-time_zone = '+8:00'
lower_case_table_names = 1

# 开启事务功能
event_scheduler=ON

# 最大连接数
max_connections=2000

# 允许最大数据包大小
max_allowed_packet = 500M

disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
# 优化iO
sync_binlog=1000

innodb_lru_scan_depth=100  # from 1024 to conserve 90% CPU cycles used for function
innodb_io_capacity=1900  # from 200 to allow more IOPSecond to your storage device
innodb_flush_neighbors=2  # from 0 to expedite writing to current extent
#innodb_max_dirty_pages_pct_lwm=1  # from 10 percent to expedite writes
#innodb_max_dirty_pages_pct=1  # from 90 percent to reduce innodb_buffer_pool_pages_dirty count
innodb_change_buffer_max_size=50  # from 25 percent to expedite your high volume activity

transaction_isolation=REPEATABLE-READ
innodb_max_dirty_pages_pct=50
innodb_adaptive_flushing=ON
innodb_flush_method=O_DIRECT

lower_case_table_names=1
innodb_fast_shutdown=0
innodb_force_recovery=0
innodb_buffer_pool_dump_at_shutdown=1
innodb_buffer_pool_load_at_startup=1

innodb_flush_log_at_trx_commit=1
innodb_log_file_size=1G
innodb_log_files_in_group=3
innodb_log_group_home_dir=./

read_buffer_size=8M
optimizer_switch="index_condition_pushdown=on,mrr=on,mrr_cost_based=on,batched_key_access=off,block_nested_loop=on"
read_rnd_buffer_size=8M
innodb_old_blocks_pct=35
innodb_buffer_pool_size=1G
innodb_buffer_pool_instances=64
innodb_log_buffer_size=32M

bulk_insert_buffer_size=128M
innodb_change_buffer_max_size=50
innodb_doublewrite=on
innodb_adaptive_hash_index=on
innodb_file_per_table=1
innodb_data_file_path=ibdata1:1024M:autoextend
innodb_page_size=16k
innodb_lock_wait_timeout=35
innodb_rollback_on_timeout=on
innodb_sync_spin_loops=100
innodb_spin_wait_delay=30
innodb_lru_scan_depth=4000

innodb_thread_concurrency=0
innodb_write_io_threads=2
innodb_read_io_threads=2
innodb_purge_threads=2
innodb_io_capacity=800
innodb_io_capacity_max=1600

log_bin=bin-log
binlog_format=ROW
binlog_checksum=NONE

# 针对单次操作语句过多造成主从复制延迟
max_binlog_cache_size = 1024M

#执行导入与导出文件的安全目录
#secure_file_priv='/apps/mysql/outdata'


allow-suspicious-udfs=FALSE
local_infile=FALSE
skip-grant-tables=FALSE

##标记relay log 允许的最大值,如果该值为0,则默认值为max_binlog_size(1G);如果不为0,则max_relay_log_size则为最大的relay_log文件大小;
max_relay_log_size=0
##relay-log日志记录的是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,
relay_log=mysql-relay-bin
##binlog传到备机被写道relaylog里,备机的slave sql线程从relaylog里读取然后应用到本地。
relay_log_index=mysql-relay-bin.index

#慢查询sql日志设置
# 开启慢查询sql日志
#slow_query_log=1
# (自行修改)
#slow_query_log_file=slow_query_log.log

# 未使用索引的语句也记录
#log_queries_not_using_indexes=ON


#将所有到达MySQL Server的SQL语句记录下来,默认关闭
#general_log=ON
#general_log路径  # (自行修改)
#general_log_file=/apps/mysql/syslog/general_log.log


allow-suspicious-udfs=OFF
local_infile=OFF
# 禁止以--skip-grant-tables选项启动数据库
skip-grant-tables=OFF
# 不要对表使用软连接

relay_log_recovery=ON

local_infile=0

# 以--safe-user-create模式启动数据库
safe-user-create

# 加密方式
block_encryption_mode = 'aes-128-ecb'

# 配置密码策略(复杂度)
#plugin_load_add='validate_password.so'
#validate-password=FORCE_PLUS_PERMANENT
#validate_password_length=14
#validate_password_mixed_case_count=1
#validate_password_number_count=1
#validate_password_policy=MEDIUM
#validate_password_special_char_count=1
## 密码过期的策略 90天
#default_password_lifetime=90

# 使用SHA256哈希算法加密密码
#old_passwords=2
#default-authentication-plugin=sha256_password


#只有授权用户才能执行show databases命令
#skip_show_database=1

#MySQL连接闲置超过一定时间后(单位:秒)将会被强行关闭
#MySQL默认的wait_timeout值为8个小时, interactive_timeout参数需要同时配置才能生效
interactive_timeout=7200
wait_timeout=7200
# 60秒内没有收到 master的任何数据 slave认为连接断开,会进行重连
replica_net_timeout = 60

# 配置防暴力破解
#plugin_load_add='connection_control.so'
# 用来控制登录失败的次数及延迟响应时间
#connection-control=FORCE_PLUS_PERMANENT
# 将登录失败的操作记录至IS库中
#connection-control-failed-login-attempts=FORCE_PLUS_PERMANENT
# 设定允许失败的次数
#connection-control-failed-connections-threshold=3
# 设定最小延迟登录时间为1000 毫秒
#connection-control-min-connection-delay=1000
# 最大延迟登录时间  单位:毫秒
#connection-control-max-connection-delay=2147483647


# 为mysql配置加密通信

#ssl_ca="/etc/cert/cacert.pem"
#ssl_cert="/etc/cert/server.crt"
#ssl_key="/etc/cert/server.key"


# 选择安全性强的加密算法套件
#ssl-cipher=DHE-RSA-AES256-SHA

# 强制要求客户端使用加密连接
#require_secure_transport=ON

# 加密协议版本
#tls_version=TLSv1.2

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# GROUP_CONCAT函数 拼接最大长度 datav 大屏使用
group_concat_max_len = 102400

# 优化
table_open_cache = 2048


# 集群设置
log-bin=/var/lib/mysql/bin-log

# 二进制日志保留时间 10 天
binlog_expire_logs_seconds = 864000
binlog_format = ROW
binlog_transaction_dependency_tracking = WRITESET
enforce_gtid_consistency = ON
gtid_mode = ON
# 默认情况下,要接受 CREATE FUNCTION 语句,必须至少显式指定 DETERMINISTIC, NO SQL,
# 或者 READS SQL # DATA 中的一个。否则在复制时会发生如下错误:
# ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL,
# or READS SQL DATA in its declaration and binary logging is enabled
# (you *might* want to use the less safe log_bin_trust_function_creators variable)
# 正确示例:
# CREATE FUNCTION f1(i INT)
# RETURNS INT
# DETERMINISTIC
# READS SQL DATA
# BEGIN
#   RETURN i;
#   END;
# 可以设置如下值避免此检查
log_bin_trust_function_creators = 1

# mysql8
replica_parallel_type = LOGICAL_CLOCK
replica_parallel_workers = 4
replica_preserve_commit_order = ON
report_port = 3306

auto_increment_increment = 1
auto_increment_offset = 2
binlog_checksum = NONE

# 从服务器将从主服务器接收到的更新也写入自己的二进制日志中,默认是不会
log_slave_updates = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE

############################
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

MySQL Router

kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysqlrouter
  namespace: middleware
  labels:
    app: mysqlrouter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysqlrouter
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: mysqlrouter
    spec:
      volumes:
        - name: host-time
          hostPath:
            path: /etc/localtime
            type: ''
      containers:
        - name: mysqlrouter
          image: 'mysql/mysql-router:8.0.28'
          ports:
            - name: tcp-6446
              containerPort: 6446
              protocol: TCP
            - name: tcp-6447
              containerPort: 6447
              protocol: TCP
            - name: tcp-6448
              containerPort: 6448
              protocol: TCP
            - name: tcp-6449
              containerPort: 6449
              protocol: TCP
            - name: tcp-8443
              containerPort: 8443
              protocol: TCP
          env:
            - name: MYSQL_HOST
              value: mysql-0.mysql-svc.middleware
            - name: MYSQL_PORT
              value: '3306'
            - name: MYSQL_USER
              value: icAdmin
            - name: MYSQL_PASSWORD
              value: icAdmin_F127
            - name: MYSQL_ROUTER_BOOTSTRAP_EXTRA_OPTIONS
              value: >-
                --client-ssl-mode=PASSTHROUGH
                --conf-set-option=DEFAULT.max_total_connections=5000
                --conf-set-option=routing:InnoDB_Cluster8_ro.routing_strategy=round-robin
          resources: {}
          volumeMounts:
            - name: host-time
              readOnly: true
              mountPath: /etc/localtime
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: mysqlrouter
                topologyKey: kubernetes.io/hostname
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: Service
apiVersion: v1
metadata:
  name: mysqlrouter
  namespace: middleware
  labels:
    app: mysqlrouter
spec:
  ports:
    - name: tcp-6446
      protocol: TCP
      port: 6446
      targetPort: 6446
    - name: tcp-6447
      protocol: TCP
      port: 6447
      targetPort: 6447
  selector:
    app: mysqlrouter
  type: NodePort

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

shark_西瓜甜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值