2020-11-02 使用K8s部署MySQL 双主集群

机器 角色
mysql-0 master\slave
mysql-1 slave\master

最近对线上集群做高可用升级,在对比了几个集群策略之后,综合现有资源、复杂度、可用度之后,选择了两个:

  • MySQL双主的互为备份的2节点集群
  • MySQL基于wsrep协议的Galera Cluster的mysql多主集群

初步处于复杂度考虑,选择了方案一。

方案一又有两个版本:

  • 利用keepalived做活跃监督
  • 利用k8s service做负载均衡,达到和活跃监督一样的效果

我们选择最简单的k8s service,先做测试。无论哪一种,首先都要实现双主的互为备份的2节点部署。

一、部署

选择 dockerhub上的MySQL:5.7.32作为基础镜像。依赖于镜像本身的启动命令,做修改,然后部署。

1.Dockerfile

以dockerhub上的mysql为基础镜像

From mysql:5.7.32
COPY my.cnf /etc/mysql/
COPY replication.sh /usr/local/bin/
COPY docker-entrypoint.sh /usr/local/bin/

ENV MYSQL_ROOT_PASSWORD=123456

RUN     chmod 755 /usr/local/bin/replication.sh && \
        chmod a+x /usr/local/bin/replication.sh && \
        chmod 755 /usr/local/bin/docker-entrypoint.sh && \
        chmod a+x /usr/local/bin/docker-entrypoint.sh && \
        chmod 755 /etc/mysql/my.cnf && \
        chmod a+x /etc/mysql/my.cnf && \
        chown -R mysql:mysql /usr/local/bin/replication.sh && \
        chown -R mysql:mysql /usr/sbin/mysqld && \
        chown -R mysql:mysql /etc/mysql/

ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306 33060
CMD ["mysqld"]

2.docker-entrypoint.sh

新增一个方法:mysql_replication

mysql_replication() {
    echo 'start to do the mysql replication'
    master_host=''
    if [[ $MY_POD_NAME = 'mysql-0' ]];then
        master_host='mysql-1.mysql.'${MY_POD_NAMESPACE}'.svc.cluster.local'
    else
        master_host='mysql-0.mysql.'${MY_POD_NAMESPACE}'.svc.cluster.local'
    fi
    echo 'add the master and slave roles, the master host is:' $master_host
    replication_user=${MYSQL_REPLICATION_USER:-replication}
    replication_password=${MYSQL_REPLICATION_PASSWORD:-replication_password}
    echo 'the replication user is: '$replication_user ', pass is: '$replication_password
    docker_process_sql --database=mysql <<-EOSQL
            CREATE USER '$replication_user'@'%' IDENTIFIED BY '$replication_password' ;
            GRANT REPLICATION SLAVE ON *.* TO '$replication_user'@'%' IDENTIFIED BY '$replication_password' ;
            FLUSH PRIVILEGES ;
        EOSQL
        
    echo 'created the replication user.'
    
    echo 'start to register to master: ' $master_host
    master_bin_fetch=`
    docker_process_sql --database=mysql <<-EOSQL
            show master status;
        EOSQL
    `
    echo 'fetch the master status.'
    title='File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set'
    title_length=${#title}
    master_bin_info=${master_bin_fetch: $title_length+1}
    echo 'master bin info is: '$master_bin_info
    bin_name='mysql-bin.000002'
    bin_length=${#bin_name}
    bin_file==${master_bin_info: 0 :$bin_length+1}
    position_number=${master_bin_info: $bin_length+1}
    echo 'the master bin file is: '$bin_file ', the position number is: '$position_number
   #从本地文件读取最新的BIN_FILE,不过现在没有用了,作废了
   bin_file=`ls /var/log/mysql | grep mysql-bin.0 | sort -n | tail -1`
    echo 'the master bin file is: '$bin_file ', the position number is set to 0'
   #不设置MASTER_BIN_FILE和MASTER_LOG_POSITION,去除了master pod的区别设置,依赖MySQL自己去发现
    docker_process_sql --database=mysql <<-EOSQL
            STOP SLAVE;
            RESET SLAVE; 
            CHANGE MASTER TO master_host='$master_host', master_user='$replication_user', master_password='$replication_password';
            CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('mysql.%');
            START SLAVE;
        EOSQL

3.my.cnf

这里有一个报错:

2020-11-02T07:35:58.108646Z 2 [ERROR] Slave SQL for channel '': Error 'Operation CREATE USER failed for 'replication'@'%'' on query. Default database: 'mysql'. Query: 'CREATE USER 'replication'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*1A629BF5797BF6AE523D06B26B94561098D18F4C'', Error_code: 1396
2020-11-02T07:35:58.108692Z 2 [Warning] Slave: Operation CREATE USER failed for 'replication'@'%' Error_code: 1396
2020-11-02T07:35:58.108701Z 2 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000002' position 3071516.

是因为主从复制还带有master、slave中的User表,我们新增了用户,在log bin中写有日志,两个MySQL已启动就去同步log bin,造成原有用户已存在,同步失败的错误。

解决这个错误,就要忽略User表的变化,修改my.cnf中的replicate-ignore-db
或者修改REPLICATE_WILD_IGNORE_TABLE
这个还需要调研

# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# The MySQL  Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

[mysqld]
#这里的ID只能是纯数子,多么痛的领悟
server-id=<%id%>
log-bin=/var/log/mysql/mysql-bin.log
replicate-ignore-db = mysql
log_bin_index       = /var/log/mysql/mysql-bin.log.index
relay_log           = /var/log/mysql/mysql-relay-bin
relay_log_index     = /var/log/mysql/mysql-relay-bin.index
#log-error=/usr/local/mysql/log/error.log
#log=/usr/local/mysql/log/mysql.log
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
#log-error      = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address   = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
sql_mode="IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

4.mysql.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  replicas: 2
  updateStrategy:
    type: RollingUpdate
  serviceName: "mysql"
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      nodeSelector:
        mysql: "true"
      securityContext:
        runAsUser: 0
      containers:
        - name: mysql
          image: test/mysql:mysql1
          env:
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
          imagePullPolicy: Never
          ports:
            - containerPort: 3306

---
kind: Service
apiVersion: v1
metadata:
  name: mysql
spec:
  ports:
    - port: 3306
      targetPort: 3306
  selector:
    app: mysql

二、测试

分别登陆到两个MySQL,使用

show slave status\G;

创建新的数据库

create database test;

观察新数据库有没有同步到另一个MySQL上面。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342