k8s搭建mysql 8.0主從同步
- 1. mysql master鏡像配置
- 2. mysql slave鏡像配置
- 3. 生成docker鏡像
- 4. k8s配置
- 5. 檢查測試
-
- (1)檢查結果
- (2)測試
- 6. 鏡像,配置檔案下載下傳
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鏡像
在8.0_slave檔案夾中執行指令生成slave鏡像
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 * form 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