更新於 2024/04/19閱讀時間約 13 分鐘

實現MySQL master-slave架構在K8S平台內的部署與功能驗證

上一篇說明了如何在Kubernetes上建立基本的MySQL standalone,並加入phpmyadmin(PMA)來進行圖形化的管理,本篇就再進階一步,實作MySQL replication架構(master-salve),並進行驗證是否成功。

raw-image

一般而言,在生產環境通常不會單純只用Standalone來運行這種類型的應用,至少會應用到本文所提到的MySQL replication或是MySQL cluster架構來確保資料的安全或高可用。

本文將分成以下部分進行說明:

  1. 什麼是MySQL replication?
  2. 實作MySQL replication(master-slave)
  3. 功能驗證
  4. 結論

1. 什麼是MySQL replication?

此處簡單說明什麼是MySQL replication,簡單來說就是將資料在多個節點上進行同步、備份以達成高可用的目的。

這種做法可以實現以下優點:

  1. 擴充性:在負載分散在多個slave上以提高效能。對於讀寫比要求較高的應用服務,replication可以透過增加slave節點來提供處理能力。並且因為寫入只能在master上提交,所以對於寫入要求高的效能提升較不明顯。
  2. 資料安全:slave可以中斷自已的replication程序,而不會影響到master。所以可以在slave上再達行備份任務。如果同樣的動作要在master上執行,則必須要將master狀態改為readonly,會影響服務。
  3. 分析:資料在master上寫入,但資料可以在slave上進行分析,所以不會影響服務的運作。通常利用mysql做資料分析的任務時,都是將slave做為資料接入端。
  4. 備援:可以將slave節點放在讀取需求較近的位置,可以讓資料取用的效率增加,不用一直往遠端的master節點去請求,對於災難備援有很大的好處。


※ 常用的架構有以下三種,簡單說明給大家有個基本了解:

1. Master-slave : 實務上大多數都是運行這種架構,主要是針對解決讀取壓力高的一種成本最底的解決方式。因為通常master與slave之間的延遲都不會太高,同時也可以透過增加slave的做法來拉高讀取需求的處理效率。

2. Master-master:為了減少master節點維護所造成的服務中斷時間,可以直接建立雙master架構來解決這個問題,實務上就是二個MySQL server互相將對方當做自已的master,自身為slave角色。

3. Master-salve-slave: 這種架構一般用在讀取的壓力特別大的情況,透過多層級的複製來減少master因為同時要處理請求又要複製資料到slave的壓力,等於由slave來負責將資料複製給下一層的slave。


2. 實作MySQL replication(master-slave)

#-----------------------------------------
# S2-1. 加入helm source下載mysql部署清單
#-----------------------------------------
[master]# helm repo add bitnami https://charts.bitnami.com/bitnami
[master]# helm search repo bitnami/mysql -l
[master]# helm3 pull bitnami/mysql --version 9.3.4 --untar
[master]# ls mysql
#-----------------------------------------
# S2-2. 修改value.yaml
#-----------------------------------------
[master]# vim values.ysml
...
#修改部署模式
architecture: replication

#DB相關帳號(root,user,replicastion user)、密碼(留空自動生成)DB
auth:
rootPassword: ""
createDatabase: true
database: "testapp"
username: "app"
password: ""
replicationUser: replicator
replicationPassword: ""

#修改mysql primary服務參數
primary:
persistence:
enabled: true
storageClass: "managed-nfs-storage"
accessModes:
- ReadWriteOnce
size: 8Gi
service:
type: NodePort
ports:
mysql: 3306
nodePorts:
mysql: "31006"

secondary:
persistence:
enabled: true
storageClass: "managed-nfs-storage"
accessModes:
- ReadWriteOnce
size: 8Gi
service:
type: NodePort
ports:
mysql: 3306
nodePorts:
mysql: "31005"
metrics:
enabled: true
#-----------------------------------------
# S2-3. 上傳鏡像到Harbor (optional)
#-----------------------------------------
[master]# docker pull bitnami/mysql:8.0.36-debian-12-r8
[master]# docker tag bitnami/mysql:8.0.36-debian-12-r8 harbor1.test.example.poc/mysql/mysql:8.0.36-debian-12-r8
[master]# docker push harbor1.test.example.poc/mysql/mysql:8.0.36-debian-12-r8

[master]# docker pull bitnami/mysqld-exporter:0.15.1-debian-12-r8
[master]# docker tag bitnami/mysqld-exporter:0.15.1-debian-12-r8 harbor1.test.example.poc/mysql/mysqld-exporter:0.15.1-debian-12-r8
[master]# docker push harbor1.test.example.poc/mysql/mysqld-exporter:0.15.1-debian-12-r8
#-----------------------------------------
# S2-4. 安裝
#-----------------------------------------
[master]# helm install mysql ./mysql --namespace mysql-replication --create-namespace
[master]# helm list -n mysql-replication
[master]# kubectl get sts,pod -n mysql-replication -l app.kubernetes.io/name=mysq

3.功能驗證

#-----------------------------------------
# S3-1. 取得自動生成的MySQL root, app, replication password
#-----------------------------------------
[master]# echo -n "MYSQL_ROOT_PASSWORD=";kubectl get secret --namespace mysql-replication mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d;echo
MYSQL_ROOT_PASSWORD=FLSDMzpjO3

[master]# echo -n "MYSQL_PASSWORD=";kubectl get secret --namespace mysql-replication mysql -o jsonpath="{.data.mysql-password}" | base64 -d;echo
MYSQL_PASSWORD=gAV87AooJk

[master]# echo -n "MYSQL_REPLICATION_PASSWORD=";kubectl get secret --namespace mysql-replication mysql -o jsonpath="{.data.mysql-replication-password}" | base64 -d;echo
MYSQL_REPLICATION_PASSWORD=U2pYaNkDO2
#-----------------------------------------
# S3-2. 使用phpmyadmin連接到主服務進行讀寫,驗證Slave節點是否正確可讀
# 從Master節點寫入資料 (直接在phpmyadmin執行SQL指令)
#-----------------------------------------
CREATE TABLE replication (
id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
INDEX name_in (name)
);

INSERT INTO testapp.replication(name) VALUES('Albert')

CREATE DATABASE testdev;
CREATE USER 'testdev'@'%' IDENTIFIED BY 'testdev.Albert.top';
GRANT ALL ON dev.* TO 'testdev'@"%";
FLUSH PRIVILEGES;
#-----------------------------------------
# S3-3. 從節點查詢插入的資料 (直接在phpmyadmin執行SQL指令)
#-----------------------------------------
[master]# kubectl run mysql-client --rm --tty -i --restart='Never' --image harbor1.test.example.poc/mysql/mysql:8.0.36-debian-12-r8 --namespace mysql-replication --env MYSQL_ROOT_PASSWORD=FLSDMzpjO3 --command -- bash
(連線到secondary service(read))

1001@mysql-client:/$ mysql -h mysql-secondary -u app -p
mysql> status
mysql> select * from testapp.replication

4.結論

本篇說明了什麼是MySQL replication,並且在kubernetes平台上實作了master-slave機制,這種做法可以同時利用到這種主從式架構的好處,同時又多一層kubernetes平台原生的機制加值,相信在未來愈來愈多的應用移轉至容器平台,這種架構也可以提供給大家一個部署時的參考。

本次分享就到這邊,我們下期再見~~~

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.