之前相关的文章请参考:
Docker集群管理方案Kubernetes之部署
Docker集群管理方案Kubernetes之组件
通过本文的实践,我们可以了解一下k8s能带给我们什么。另外,实际生产环境中mysql的主从复制考虑的事情会更多。
mysql主从复制
mysql的主从复制可以通过如下方式实现。
-
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';
-
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。
-
准备master的镜像
Dockerfile.png
将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,用作主从复制的账号和密码。
通过下面的截图可以看到上面添加内容所在的位置。
docker-entrypoint.sh.png -
准备slave的镜像
Dockerfile.png
将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[@]}"
通过下面的截图可以看到上面添加内容所在的位置。
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/
- 构建镜像并上传至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格式的问题,没法直接贴源代码,只能贴截图,见谅。
-
mysql master的部署
mysql-master-rc.yaml.png
replication controller和service的yaml文件如下,文件名分别为mysql-master-rc.yaml和mysql-master-service.yaml。
replication controller:
可以看到在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
-
mysql slave的部署
mysql-slave-rc.yaml.png
replication controller和service的yaml文件如下,文件名分别为mysql-slave-rc.yaml和mysql-slave-service.yaml。
replication controller:
service:
mysql-slave-service.yaml.png
切换到yaml文件所在目录,执行命令以部署mysql slave服务:
kubectl create -f mysql-slave-rc.yaml
kubectl create -f mysql-slave-service.yaml
-
查看运行状态
k8s.png
执行命令,查看k8s各资源的运行情况:
kubectl get pods,service,rc
我的环境的运行截图,各资源运行正常。
-
测试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;
通过该命令可以查看主从同步的情况,通常利用该命令来检查主从配置是否有问题。
执行以下命令,可以看到刚才在master上创建的库表已经同步过来了:
show databases; use paul_test_sync_db; select * from test_tb;
- 集群伸缩
上面仅仅是一主一从,那接下来看看如何利用k8s对从服务器进行扩展。
此处将原先的1台从服务器扩展为3台,执行命令:
kubectl scale rc mysql-slave --replicas=3
上面命令的意思是将名称为mysql-slave的rc控制的pod副本数量变更为3。
执行kubectl get pods
命令可以看到扩展后的结果。
总结
本文假设你已经对kubernetes有一定了解,因此并没有对一些命令、文件进行解释。
本文搭建的mysql一主多从集群环境,并没有考虑外部卷的挂载,因此当集群服务重启后,在mysql中创建的数据库、添加的数据会全部丢失。
网友评论