1. mysql master镜像配置

  首先,我们需要从docker hub官网上获取dockerfile文件用于后续的修改。地址如下:
  https://github.com/docker-library/mysql.git
  然后将8.0文件夹复制一份,将另一份命名为8.0_slave。进入到8.0文件夹中,里面有个Dockerfile.debian文件,修改名字为Dockerfile

mv Dockerfile.debian Dockerfile

  config文件夹下面的my.cnf是mysql的配置文件。我们需要加上以下配置

[mysql]
default-character-set=utf8 #设置mysql客户端默认字符集

[client]
default-character-set=utf8 #设置mysql客户端连接服务端时默认使用的端口

[mysqld]
server-id = 1   
log-bin = master-bin
log_bin_index =  master-bin.index
max_connections=200 # 允许最大连接数
max_connect_errors=10 # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
character-set-server=utf8 # 服务端使用的字符集默认为UTF8
default_authentication_plugin=mysql_native_password  # 默认使用“mysql_native_password”插件认证
binlog_format=mixed
expire_logs_days        = 10         #binlog过期清理时间
max_binlog_size         = 100m       #binlog每个日志文件大小
binlog_cache_size       = 4m         #binlog缓存大小
max_binlog_cache_size   = 512m       #最大binlog缓存大小

其中server-id 是mysql master库的id,必须是唯一且与slave库不一致。log-bin开启binlog并指定了binlog文件的名字。
  由于我们位于东八区,所以需要设置一下时区。在刚才的Dockerfile文件 ENTRYPOINT 上面加入下列命令
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ENTRYPOINT ["docker-entrypoint.sh"]

  最后,我们需要修改一下 docker-entrypoint.sh。在docker_setup_db()函数的最后加上下列代码,用于创建一个slave用户并配置权限。

	if [ -n "$MYSQL_REPLICATION_USER" ] && [ -n "$MYSQL_REPLICATION_PASSWORD" ]; then
		mysql_note "Creating user $MYSQL_REPLICATION_USER"
		docker_process_sql --database=mysql <<<"CREATE USER '$MYSQL_REPLICATION_USER'@'%' IDENTIFIED WITH 'mysql_native_password' BY '$MYSQL_REPLICATION_PASSWORD';"
		docker_process_sql --database=mysql <<<"GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_REPLICATION_USER'@'%';"
		docker_process_sql --database=mysql <<<"FLUSH PRIVILEGES ;"
	fi

2. mysql slave镜像配置

  首先进入到8.0_slave文件夹。与master类似,里面有个Dockerfile.debian文件,修改名字为Dockerfile

mv Dockerfile.debian Dockerfile

  修改config文件夹下面的my.cnf。

[mysql]
default-character-set=utf8 # 设置mysql客户端默认字符集

[client]
default-character-set=utf8# 设置mysql客户端连接服务端时默认使用的端口

[mysqld]
server-id = 10
log-bin = log/slave10-bin
log_bin_index =  log/slave10-bin.index
relay-log = log/slave10-relay-bin 
relay-log-index = log/slave10-relay-bin.index
max_connections=200 # 允许最大连接数
max_connect_errors=10 # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
character-set-server=utf8 # 服务端使用的字符集默认为UTF8
default_authentication_plugin=mysql_native_password  # 默认使用“mysql_native_password”插件认证
binlog_format=mixed
expire_logs_days        = 10         #binlog过期清理时间
max_binlog_size         = 100m       #binlog每个日志文件大小
binlog_cache_size       = 4m         #binlog缓存大小
max_binlog_cache_size   = 512m       #最大binlog缓存大小	

其中server-id 是mysql slave库的id,必须是唯一且与刚才的master库不一致,我这里是设置为固定10,当有多个slave时,可以固定设置为10,11,12,每个slave的id必须不一致。
  修改时区。在刚才的Dockerfile文件 ENTRYPOINT 上面加入下列命令
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ENTRYPOINT ["docker-entrypoint.sh"]

  最后,我们需要修改一下 docker-entrypoint.sh。在docker_setup_db()函数的最后加上下列代码,用于设置master的地址,用于同步的账号密码,并开启slave模式。

	if [ -n "$MYSQL_MASTER_SERVICE_HOST" ] && [ -n "$MYSQL_REPLICATION_USER" ]; then
			mysql_note "Connecting master_host: $MYSQL_MASTER_SERVICE_HOST, which user: $MYSQL_REPLICATION_USER, password: $MYSQL_REPLICATION_PASSWORD"
			docker_process_sql --database=mysql <<<"STOP SLAVE;"
			docker_process_sql --database=mysql <<<"CHANGE MASTER TO master_host='$MYSQL_MASTER_SERVICE_HOST', master_user='$MYSQL_REPLICATION_USER', master_password='$MYSQL_REPLICATION_PASSWORD' ;"
			docker_process_sql --database=mysql <<<"START SLAVE;"
	fi

可以看到上面我们写的代码里面有个变量MYSQL_MASTER_SERVICE_HOST,这个环节变量是k8s自动生成的,所以master mysql的service必须命名为mysql-master。

3. 生成docker镜像

在8.0文件夹中执行指令生成master镜像

docker build -t mysql_master:v0.1 .

在8.0_slave文件夹中执行指令生成slave镜像

docker build -t mysql_slave:v0.1 .

4. k8s配置

在喜欢的文件夹中,创建mysql_master.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: database
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-master
  namespace: database
  labels:
    app: mysql-master
spec:
  ports:
    - port: 3306
      targetPort: 3306
  selector:
    app: mysql-master
---
apiVersion: apps/v1                 #apiserver的版本
kind: Deployment                                      #副本控制器deployment,管理pod和RS
metadata:
  namespace: database
  name: mysql-master                                            #deployment的名称,全局唯一
spec:
  replicas: 1                                                #Pod副本期待数量
  selector:
    matchLabels:                                         #定义RS的标签
      app: mysql-master                                             #符合目标的Pod拥有此标签
  strategy:                                                  #定义升级的策略
    type: RollingUpdate                               #滚动升级,逐步替换的策略
  template:                                                #根据此模板创建Pod的副本(实例)
    metadata:
      labels:
        app: mysql-master                                       #Pod副本的标签,对应RS的Selector
    spec:
      containers:                                          #Pod里容器的定义部分
      - name: mysql                                     #容器的名称
        image: mysql_master:v0.1                         #容器对应的docker镜像
        ports:
        - containerPort: 3306                         #容器暴露的端口号
        env:                                                   #写入到容器内的环境容量
        - name: MYSQL_ROOT_PASSWORD   #定义了一个mysql的root密码的变量
          value: "123456"
        - name: MYSQL_REPLICATION_USER   #定义了一个mysql的root密码的变量
          value: "rep1ication"
        - name: MYSQL_REPLICATION_PASSWORD   #定义了一个mysql的root密码的变量
          value: "123456"

创建mysql_slave.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql-slave
  namespace: database
  labels:
    app: mysql-slave
spec:
  ports:
    - port: 3306
      targetPort: 3306
  selector:
    app: mysql-slave
---
apiVersion: apps/v1                 #apiserver的版本
kind: Deployment                                      #副本控制器deployment,管理pod和RS
metadata:
  namespace: database
  name: mysql-slave                                            #deployment的名称,全局唯一
spec:
  replicas: 1                                                #Pod副本期待数量
  selector:
    matchLabels:                                         #定义RS的标签
      app: mysql-slave                                             #符合目标的Pod拥有此标签
  strategy:                                                  #定义升级的策略
    type: RollingUpdate                               #滚动升级,逐步替换的策略
  template:                                                #根据此模板创建Pod的副本(实例)
    metadata:
      labels:
        app: mysql-slave                                       #Pod副本的标签,对应RS的Selector
    spec:
      containers:                                          #Pod里容器的定义部分
      - name: mysql                                     #容器的名称
        image: mysql_slave:v0.1                           #容器对应的docker镜像
        ports:
        - containerPort: 3306                         #容器暴露的端口号
        env:                                                   #写入到容器内的环境容量
        - name: MYSQL_ROOT_PASSWORD   #定义了一个mysql的root密码的变量
          value: "123456"
        - name: MYSQL_REPLICATION_USER   #定义了一个mysql的root密码的变量
          value: "rep1ication"
        - name: MYSQL_REPLICATION_PASSWORD   #定义了一个mysql的root密码的变量
          value: "123456"

最后执行,查看k8s里面pod的情况是否正常,需要注意,为了方便,本人没有为pod设置持久化存储,正常的环境都是需要设置持久化存储的。设置外部存储容器的/var/lib/mysql即可实现持久化。

kubectl apply -f mysql_master.yaml 
kubectl apply -f mysql_salve.yaml 

5. 检查测试

(1)检查结果

进入slave对应的pod,进入mysql

mysql -uroot -p
show slave status\G;

如果 Slave_IO_Running,Slave_SQL_Running状态都是yes,说明主从mysql配置完成。
如果不成功,则需要使用kubectl describe命令来查看slave pod的日志,一般最有可能就是master mysql设置slave账号出现问题。在mysql里面使用命令

select user,host from mysql.user; //结果应该有账号rep1ication
show grants for 'rep1ication'@'%'; 
//结果为GRANT USAGE SLAVE ON *.* TO 'rep1ication'@'%' 则为错误
//结果为GRANT REPLICATION SLAVE ON *.* TO 'rep1ication'@'%'则为正确

(2)测试

进入master对应的pod,进入mysql

kubectl exec -it mysql-master-pe18a /bin/bash
mysql -uroot -p
create database test; use test; create table test_tb(id int(3),name char(10)); 
insert into test_tb values(001,'ok');
insert into test_tb values(002,'ok');

然后在slave的pod里面,查看是否有数据

mysql -uroot -p
use test;
select * from test_tb;

6. 镜像,配置文件下载

镜像地址:一共两个,一个是master,一个是slave
https://registry.hub.docker.com/r/evilskyman/mysql_master
https://registry.hub.docker.com/r/evilskyman/mysql_slave
Dockerfile和yaml文件
https://gitee.com/evilskyman/mysql-test

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐