美文网首页KubernetesIT技术文章收藏高性能MySQL
利用Kubernetes搭建mysql主从复制集群

利用Kubernetes搭建mysql主从复制集群

作者: paulliu | 来源:发表于2016-10-17 14:40 被阅读7747次

    之前相关的文章请参考:
    Docker集群管理方案Kubernetes之部署
    Docker集群管理方案Kubernetes之组件

    通过本文的实践,我们可以了解一下k8s能带给我们什么。另外,实际生产环境中mysql的主从复制考虑的事情会更多。

    mysql主从复制

    mysql的主从复制可以通过如下方式实现。

    1. master
      在master主机上修改配置文件,比如通常是修改my.cnf。
      [mysqld] server-id=1 log-bin
      在mysql上创建同步账号并授权。
      如下,创建用户名为repl,密码为1234567:
      create user 'repl'@'%' identified by '1234567';
      如下,给repl用户授权允许同步:
      grant replication slave on *.* to 'repl'@'%' identified by '1234567';

    2. slave
      同样,在slave主机上修改配置文件。
      [mysqld] server-id=2 log-bin
      接着配置如下,其中x.x.x.x为master主机ip地址。
      change master to master_host='x.x.x.x',master_user='repl',master_password='1234567';

    注意server-id为主机标识,不能重复。

    利用Docker实现主从复制

    本节介绍利用Docker官网镜像文件实现上述的各项配置,这是为了接下来k8s的使用。利用Docker实现mysql的方式有很多种,可以参考其他文章。

    mysql官网Docker镜像文件地址:https://hub.docker.com/_/mysql/
    这里用的是8.0 Dockerfile,包括两个文件Dockerfile, docker-entrypoint.sh。

    1. 准备master的镜像
      将Dockerfile, docker-entrypoint.sh复制一份作为master的镜像。
      在Dockerfile中添加如下:
      RUN sed -i '/\[mysqld\]/a server-id=1\nlog-bin' /etc/mysql/mysql.conf.d/mysqld.cnf
      在docker-entrypoint.sh中添加如下:
      echo "CREATE USER '$MYSQL_REPLICATION_USER'@'%' IDENTIFIED BY '$MYSQL_REPLICATION_PASSWORD' ;" | "${mysql[@]}" echo "GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_REPLICATION_USER'@'%' IDENTIFIED BY '$MYSQL_REPLICATION_PASSWORD' ;" | "${mysql[@]}" echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
      可以看到上面添加了两个环境变量MYSQL_REPLICATION_USER和MYSQL_REPLICATION_PASSWORD,用作主从复制的账号和密码。
      通过下面的截图可以看到上面添加内容所在的位置。

      Dockerfile.png
      docker-entrypoint.sh.png
    2. 准备slave的镜像
      将Dockerfile, docker-entrypoint.sh复制一份作为slave的镜像。
      在Dockerfile中添加如下:
      RUN RAND="$(date +%s | rev | cut -c 1-2)$(echo ${RANDOM})" && sed -i '/\[mysqld\]/a server-id='$RAND'\nlog-bin' /etc/mysql/mysql.conf.d/mysqld.cnf
      这里server-id用的是随机数。
      在docker-entrypoint.sh中添加如下:
      echo "STOP SLAVE;" | "${mysql[@]}" echo "CHANGE MASTER TO master_host='$MYSQL_MASTER_SERVICE_HOST', master_user='$MYSQL_REPLICATION_USER', master_password='$MYSQL_REPLICATION_PASSWORD' ;" | "${mysql[@]}" echo "START SLAVE;" | "${mysql[@]}"
      通过下面的截图可以看到上面添加内容所在的位置。

      Dockerfile.png
      docker-entrypoint.sh.png
      重要的来了,上面slave的配置中,master_host一项用的是$MYSQL_MASTER_SERVICE_HOST,这个环境变量(enviromnent variable)是由k8s生成的。
      k8s的service创建后,会自动分配一个cluster ip,这个cluster ip是动态的,我们没法直接使用或硬编码,k8s为了service对容器的可见,生成了一组环境变量,这些环境变量用于记录service name到cluster ip地址的映射关系,这样容器中就可以使用这些变量来使用service。(类似的,Docker中提供了links。)

    举例:如果service的名称为foo,则生成的环境变量如下:
    FOO_SERVICE_HOST
    FOO_SERVICE_PORT
    更多介绍请参考k8s官方资料:http://kubernetes.io/docs/user-guide/container-environment/

    1. 构建镜像并上传至docker hub
      分别构建用于mysql master和mysql slave的Docker镜像,并上传至docker hub,地址为https://hub.docker.com/ (这是因为当我们用k8s去做mysql集群部署的时候,k8s默认会去docker hub下载镜像。通常在生产环境中服务器是不运行连接internet的,因此通常会搭建自己的docker hub服务器。)。

    构建master镜像

    切换到master Dockerfile所在的目录,执行命令:
    docker build -t paulliu/mysql-master:0.1 .

    构建slave镜像

    切换到slave Dockerfile所在的目录,执行命令:
    docker build -t paulliu/mysql-slave:0.1 .

    镜像推送

    然后将构建好的镜像文件推送到docker hub,首先使用下面的命令登陆,如果没有注册,需要先到官网注册一下。
    docker login
    接着执行推送命令:
    docke push paulliu/mysql-master:0.1
    docke push paulliu/mysql-slave:0.1

    如果感觉上面的一堆配置太麻烦,可以直接使用我构建好的镜像,地址为:
    https://hub.docker.com/u/paulliu/

    k8s部署

    终于进入到正题,接下来开始利用k8s构建mysql集群。
    首先声明,由于yaml格式的问题,没法直接贴源代码,只能贴截图,见谅。

    1. mysql master的部署
      replication controller和service的yaml文件如下,文件名分别为mysql-master-rc.yaml和mysql-master-service.yaml。
      replication controller:

      mysql-master-rc.yaml.png
      可以看到在env中添加了mysql需要的环境变量。
      service:
      mysql-master-service.yaml.png
      切换到yaml文件所在目录,执行命令以部署mysql master服务:
      kubectl create -f mysql-master-rc.yaml
      kubectl create -f mysql-master-service.yaml
    2. mysql slave的部署
      replication controller和service的yaml文件如下,文件名分别为mysql-slave-rc.yaml和mysql-slave-service.yaml。
      replication controller:

      mysql-slave-rc.yaml.png
      service:
      mysql-slave-service.yaml.png
      切换到yaml文件所在目录,执行命令以部署mysql slave服务:
      kubectl create -f mysql-slave-rc.yaml
      kubectl create -f mysql-slave-service.yaml
    3. 查看运行状态
      执行命令,查看k8s各资源的运行情况:
      kubectl get pods,service,rc
      我的环境的运行截图,各资源运行正常。

      k8s.png
    4. 测试mysql的主从复制
      到目前为止,mysql的一主一从均运行在k8s的pod中。由于上面service创建并没有使用type: NodePort方式,所以service只能在kubernetes的pods中引用,外界是无法使用的。

    mysql master上的操作

    通过如下命令连接到pods中的容器,其中mysql-master-pe18a为pod名称。
    kubectl exec -it mysql-master-pe18a /bin/bash
    接着连接本地mysql master服务器:
    mysql -uroot -p
    至此进入到mysql命令模式。
    执行命令show master status;查看状态。
    执行下面的命令创建数据库以及表,以测试数据同步:
    create database paul_test_sync_db; use paul_test_sync_db; create table test_tb(id int(3),name char(10)); insert into test_tb values(001,'ok');

    mysql slave上的操作

    按照上面相同的方式进入到mysql slave的命令行,执行以下命令:
    show slave status\G;
    通过该命令可以查看主从同步的情况,通常利用该命令来检查主从配置是否有问题。

    mysql-slave-running.png
    执行以下命令,可以看到刚才在master上创建的库表已经同步过来了:
    show databases; use paul_test_sync_db; select * from test_tb;
    1. 集群伸缩
      上面仅仅是一主一从,那接下来看看如何利用k8s对从服务器进行扩展。
      此处将原先的1台从服务器扩展为3台,执行命令:
      kubectl scale rc mysql-slave --replicas=3
      上面命令的意思是将名称为mysql-slave的rc控制的pod副本数量变更为3。
      执行kubectl get pods命令可以看到扩展后的结果。

    总结

    本文假设你已经对kubernetes有一定了解,因此并没有对一些命令、文件进行解释。
    本文搭建的mysql一主多从集群环境,并没有考虑外部卷的挂载,因此当集群服务重启后,在mysql中创建的数据库、添加的数据会全部丢失。

    相关文章

      网友评论

      • 52da04e00066:mysqld.cnf文件在最新的mysql8里面已经没有了。还有就是echo "GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_REPLICATION_USER'@'%' IDENTIFIED BY '$MYSQL_REPLICATION_PASSWORD' ;" | "${mysql[@]}"好像是写错了:innocent:
      • 9148a0a74a48:为什么slave中的镜像制作时 grant to的时候没有master_log_file='',和master_log_pos=;呢?但是我试了一下确实是可以的,方便的话请回复下。
      • 武斌OUC:mysql官网Docker镜像文件地址 加了个句号,直接点击链接不过去~
      • 巴图鲁:膜拜

      本文标题:利用Kubernetes搭建mysql主从复制集群

      本文链接:https://www.haomeiwen.com/subject/dqwayttx.html