利用Kubernetes搭建mysql主從復(fù)制集群

之前相關(guān)的文章請參考:
Docker集群管理方案Kubernetes之部署
Docker集群管理方案Kubernetes之組件

通過本文的實踐,我們可以了解一下k8s能帶給我們什么。另外,實際生產(chǎn)環(huán)境中mysql的主從復(fù)制考慮的事情會更多。

mysql主從復(fù)制

mysql的主從復(fù)制可以通過如下方式實現(xiàn)。

  1. master
    在master主機上修改配置文件,比如通常是修改my.cnf。
    [mysqld] server-id=1 log-bin
    在mysql上創(chuàng)建同步賬號并授權(quán)。
    如下,創(chuàng)建用戶名為repl,密碼為1234567:
    create user 'repl'@'%' identified by '1234567';
    如下,給repl用戶授權(quán)允許同步:
    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為主機標(biāo)識,不能重復(fù)。

利用Docker實現(xiàn)主從復(fù)制

本節(jié)介紹利用Docker官網(wǎng)鏡像文件實現(xiàn)上述的各項配置,這是為了接下來k8s的使用。利用Docker實現(xiàn)mysql的方式有很多種,可以參考其他文章。

mysql官網(wǎng)Docker鏡像文件地址:https://hub.docker.com/_/mysql/
這里用的是8.0 Dockerfile,包括兩個文件Dockerfile, docker-entrypoint.sh。

  1. 準(zhǔn)備master的鏡像
    將Dockerfile, docker-entrypoint.sh復(fù)制一份作為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[@]}"
    可以看到上面添加了兩個環(huán)境變量MYSQL_REPLICATION_USER和MYSQL_REPLICATION_PASSWORD,用作主從復(fù)制的賬號和密碼。
    通過下面的截圖可以看到上面添加內(nèi)容所在的位置。

    Dockerfile.png

    docker-entrypoint.sh.png

  2. 準(zhǔn)備slave的鏡像
    將Dockerfile, docker-entrypoint.sh復(fù)制一份作為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用的是隨機數(shù)。
    在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[@]}"
    通過下面的截圖可以看到上面添加內(nèi)容所在的位置。

    Dockerfile.png

    docker-entrypoint.sh.png

    重要的來了,上面slave的配置中,master_host一項用的是$MYSQL_MASTER_SERVICE_HOST,這個環(huán)境變量(enviromnent variable)是由k8s生成的。
    k8s的service創(chuàng)建后,會自動分配一個cluster ip,這個cluster ip是動態(tài)的,我們沒法直接使用或硬編碼,k8s為了service對容器的可見,生成了一組環(huán)境變量,這些環(huán)境變量用于記錄service name到cluster ip地址的映射關(guān)系,這樣容器中就可以使用這些變量來使用service。(類似的,Docker中提供了links。)

舉例:如果service的名稱為foo,則生成的環(huán)境變量如下:
FOO_SERVICE_HOST
FOO_SERVICE_PORT
更多介紹請參考k8s官方資料:http://kubernetes.io/docs/user-guide/container-environment/

  1. 構(gòu)建鏡像并上傳至docker hub
    分別構(gòu)建用于mysql master和mysql slave的Docker鏡像,并上傳至docker hub,地址為https://hub.docker.com/ (這是因為當(dāng)我們用k8s去做mysql集群部署的時候,k8s默認(rèn)會去docker hub下載鏡像。通常在生產(chǎn)環(huán)境中服務(wù)器是不運行連接internet的,因此通常會搭建自己的docker hub服務(wù)器。)。

構(gòu)建master鏡像

切換到master Dockerfile所在的目錄,執(zhí)行命令:
docker build -t paulliu/mysql-master:0.1 .

構(gòu)建slave鏡像

切換到slave Dockerfile所在的目錄,執(zhí)行命令:
docker build -t paulliu/mysql-slave:0.1 .

鏡像推送

然后將構(gòu)建好的鏡像文件推送到docker hub,首先使用下面的命令登陸,如果沒有注冊,需要先到官網(wǎng)注冊一下。
docker login
接著執(zhí)行推送命令:
docke push paulliu/mysql-master:0.1
docke push paulliu/mysql-slave:0.1

如果感覺上面的一堆配置太麻煩,可以直接使用我構(gòu)建好的鏡像,地址為:
https://hub.docker.com/u/paulliu/

k8s部署

終于進入到正題,接下來開始利用k8s構(gòu)建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需要的環(huán)境變量。
    service:
    mysql-master-service.yaml.png

    切換到y(tǒng)aml文件所在目錄,執(zhí)行命令以部署mysql master服務(wù):
    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

    切換到y(tǒng)aml文件所在目錄,執(zhí)行命令以部署mysql slave服務(wù):
    kubectl create -f mysql-slave-rc.yaml
    kubectl create -f mysql-slave-service.yaml

  3. 查看運行狀態(tài)
    執(zhí)行命令,查看k8s各資源的運行情況:
    kubectl get pods,service,rc
    我的環(huán)境的運行截圖,各資源運行正常。

    k8s.png

  4. 測試mysql的主從復(fù)制
    到目前為止,mysql的一主一從均運行在k8s的pod中。由于上面service創(chuàng)建并沒有使用type: NodePort方式,所以service只能在kubernetes的pods中引用,外界是無法使用的。

mysql master上的操作

通過如下命令連接到pods中的容器,其中mysql-master-pe18a為pod名稱。
kubectl exec -it mysql-master-pe18a /bin/bash
接著連接本地mysql master服務(wù)器:
mysql -uroot -p
至此進入到mysql命令模式。
執(zhí)行命令show master status;查看狀態(tài)。
執(zhí)行下面的命令創(chuàng)建數(shù)據(jù)庫以及表,以測試數(shù)據(jù)同步:
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的命令行,執(zhí)行以下命令:
show slave status\G;
通過該命令可以查看主從同步的情況,通常利用該命令來檢查主從配置是否有問題。

mysql-slave-running.png

執(zhí)行以下命令,可以看到剛才在master上創(chuàng)建的庫表已經(jīng)同步過來了:
show databases; use paul_test_sync_db; select * from test_tb;

  1. 集群伸縮
    上面僅僅是一主一從,那接下來看看如何利用k8s對從服務(wù)器進行擴展。
    此處將原先的1臺從服務(wù)器擴展為3臺,執(zhí)行命令:
    kubectl scale rc mysql-slave --replicas=3
    上面命令的意思是將名稱為mysql-slave的rc控制的pod副本數(shù)量變更為3。
    執(zhí)行kubectl get pods命令可以看到擴展后的結(jié)果。

總結(jié)

本文假設(shè)你已經(jīng)對kubernetes有一定了解,因此并沒有對一些命令、文件進行解釋。
本文搭建的mysql一主多從集群環(huán)境,并沒有考慮外部卷的掛載,因此當(dāng)集群服務(wù)重啟后,在mysql中創(chuàng)建的數(shù)據(jù)庫、添加的數(shù)據(jù)會全部丟失。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容