在 Kubernetes 中基於 StatefulSet 部署 MySQL(上)

KubeSphere發表於2022-06-09

大家好,我是老 Z!

本文實現了 MySQL 資料庫在基於 KubeSphere 部署的 K8s 叢集上的安裝部署,部署方式採用了圖形化這種形式。下一篇文章將會涉及 GitOps 的基礎操作,部署過程涉及的所有 YAML 檔案都會使用 Git 進行版本管理,並存放在 Git 倉庫中,敬請期待!

本文部署的 MySQL 選擇了比較保守的 5.7 系列,其他版本可能會有不同。本文的操作僅適用於小規模資料量且對可靠性和效能要求不高的資料庫使用場景,例如開發測試環境、例如我生產環境的 Nacos 服務。生產環境或是重要的資料庫個人不建議將資料放到 K8s 上,優先採用雲服務商提供的 RDS,其次自己利用虛擬機器搭建 MySQL 主從或是 Galera Cluster,且一定做好備份方案。

資料庫的可靠性、可用性是運維的重中之重,不容忽視,切記!!!

本文知識點

  • 定級:入門級
  • 單節點 MySQL 在 K8s 上的安裝配置
  • KubeSphere 圖形化部署工作負載
  • GitOps 入門
  • Git 常用操作
  • 配置程式碼如何實現在 GitHub 和 Gitee 保持同步
  • MySQL 效能測試基礎
  • 運維思想、思路

演示伺服器配置

主機名作業系統IPCPU記憶體系統盤資料盤用途
zdeops-masterCentOS-7.9-x86_64192.168.9.92440200Ansible 運維控制節點
ks-k8s-master-0CentOS-7.9-x86_64192.168.9.9183240200KubeSphere/k8s-master/k8s-worker
ks-k8s-master-1CentOS-7.9-x86_64192.168.9.9283240200KubeSphere/k8s-master/k8s-worker
ks-k8s-master-2CentOS-7.9-x86_64192.168.9.9383240200KubeSphere/k8s-master/k8s-worker
glusterfs-node-0CentOS-7.9-x86_64192.168.9.954840200GlusterFS/Elasticsearch
glusterfs-node-1 192.168.9.964840200GlusterFS/Elasticsearch
glusterfs-node-2CentOS-7.9-x86_64192.168.9.974840200GlusterFS/Elasticsearch

MySQL 安裝之旅

尋找參考文件

我個人查詢參考文件習慣的的尋找路徑

  • 官方網站-精準定位

    • 官網有時沒有相關文件、或是文件不夠詳細
    • 英文文件、閱讀困難
  • 搜尋關鍵字-大海撈針

    • CSDN
    • 部落格園
    • 某個人部落格
    • 問答網站
    • 其他

開啟 MySQL 官方網站

選擇 MySQL5.7 版本的 Reference Manual。

Installing MySQL on Linux 章節中,搜尋一番,發現在Deploying MySQL on Linux with Docker小節下兩篇具有參考價值的文件,先去看看。

瀏覽完以後你會發現,只是學會了利用 Docker Image 安裝 MySQL 的基本方法,細節不上圖了。

雖然官方沒有提到如何在 K8s 上部署 MySQL,但是我已經有 Docker 和 K8s 的基礎知識了,先不去進行搜尋吃別人的了,自己嘗試在 K8s 上部署一個單節點的 MySQL。

嘗試部署單節點 MySQL

先梳理一下思路,部署一個 MySQL 我們需要準備哪些資源

  • 在 Docker Hub 獲取 MySQL 映象。
  • 檢視 MySQL 映象說明,確定安裝初始化引數。
  • MySQL 屬於有狀態服務,所以我們需要定義 StatefulSet 型別的資源。
  • 編寫 StatefulSet 型別的 MySQL 資源定義檔案-YAML。

檢視官方映象說明,確定初始化引數

如果之前有 Docker 部署 MySQL 的經驗,這一步就很簡單了,直接把引數配置搬過來就行。

開啟 https://hub.docker.com,搜尋 mysql。

搜尋結果中會有很多的 mysql,我重點關注了兩個映象。

本次實驗我使用了 Docker 官方維護的倉庫,進入 MySQL 倉庫頁面。

大概瀏覽一遍,確認了幾個必須要配置的地方(確定過程需要經驗和技術積累)。

  • 映象:mysql:5.7.38
  • root 密碼:MYSQL_ROOT_PASSWORD
  • 資料持久化儲存目錄:/var/lib/mysql

利用 KubeSphere 部署 MySQL(V1 版)

確定了初始化的引數,接下來就開始部署 MySQL。

按 K8s 常規套路編寫資源定義 YAML 檔案?NO!我現在是小白,手寫配置檔案太高階了,還不適合我。

我們這裡投機取巧一下,利用 KubeSphere 的圖形化操作一波,這樣可以保證部署的一次成功率 (還有一個隱藏的好處,先賣個關子)。

使用企業空間管理員許可權的賬戶,登入 KubeSphere 控制檯。

這一步沒有使用 admin 使用者,採用多租戶戶形式,模擬真實的生產環境

<,>

點選專案,點選 lstack 專案,進入專案的管理頁面 (如無特殊說明,後面的很多介面操作都是在該頁面完成)。

<,>

應用負載->工作負載->有狀態副本集,點選建立

彈出建立有狀態副本集頁面,基本資訊頁,名稱輸入 mysql

容器組設定頁。

  • 容器組副本數量:1
  • 點選新增容器,映象搜尋欄輸入 mysql:5.7.38
  • 容器名稱: lstack-mysql
  • CPU(Core)資源:預留 0.5,限制 2
  • 記憶體(Mi):預留 500i,限制 4000
  • 埠設定:協議 TCP,名稱 tcp-mysql,容器埠:3306,服務埠 3306
  • 環境變數

    • 引用配置字典或保密字典
    • 建立保密字典,鍵(MYSQL_ROOT_PASSWORD),值(P@88w0rd)
  • 同步主機時區:勾選上
  • 其他未說明的配置採用預設值

<,,,>

建立保密字典:在環境變數選項中,點選建立保密字典,按後續圖示操作。

<,,,>

點選建立,返回容器組設定頁面。

按以上資訊配置完成後,點選對號按鈕。

容器組設定完成後,點選下一步,進入儲存卷設定

儲存卷設定->儲存卷模板->新增儲存卷模板

  • 儲存卷名稱:data

    • 這個地方不要多寫,系統會自動新增 StatefulSet 的名稱作為名稱字尾,生成類似 data-mysql-0 命名形式的儲存卷
  • 儲存型別:glusterfs
  • 訪問模式:ReadWriteOnce
  • 儲存卷容量:5Gi
  • 掛載路徑:讀寫 /var/lib/mysql

按以上資訊配置完成後,點選對號按鈕。

儲存卷設定完成後,點選下一步,進入高階設定,保持預設值,點選建立按鈕。

建立成功後,自動返回工作負載頁面。第一次建立會去 DockerHub 下載映象,所以初始顯示狀態為更新中

映象下載完成並且容器配置正確時,狀態變成執行中

點選 mysql,進入有狀態副本集詳細頁面。

<,,>

監控,可以看到初始啟動時的資源使用情況,後續可以根據監控資料調整我們的資源的配置。

環境變數,可以看到我們新增加的 Secret 字典生效了,並且密碼是隱藏顯示的。

<,>

再來看看容器組的詳細資訊,在資源狀態頁面,點選容器組 mysql-0。

<,,,,,>

再來看看 StatefulSet 對應的服務 (Service),應用負載->服務

可以看到自動建立了一個 StatefulSet MySQL 對應的有狀態服務 (Headless),mysql-2v7f(mysql)

點選 mysql-2v7f(mysql),可以檢視服務詳情。

<,,>

最後驗證一下,我們的 MySQL 服務是否正常 (這裡只看服務本身,先不測試外部連線)。

應用負載->工作負載->有狀態副本集->mysql->容器組->mysql-0->終端。

<,>

至此,MySQL 在 K8s 的基本安裝就完成了,K8s 叢集內的其他應用可以通過 svc 的地址訪問 MySQL 服務 (svc 地址就是 mysql-2v7f.lstack),此時名字看著還是很不友好,我們先不用它。

MySQL 配置進階

上面完成了 MySQL 的基本安裝配置。但是,實際使用中我們通常還有如下需求,需要我們對 MySQL 進行配置。

開啟外部訪問

開啟外部訪問方便管理員操作 MySQL 資料庫,也可以滿足 K8s 叢集之外的服務訪問 MySQL 資料庫的需求。

在 KubeSphere 中開啟服務的外部訪問需要先設定專案閘道器。

用專案管理員使用者登入控制檯。

工作臺->專案-> 點選具體的專案->專案設定->閘道器設定,點選開啟閘道器

目前訪問模式有 NodePort 和 LoadBalancer,但是 LoadBalancer 只支援公有云提供商雲上的負載均衡器,所以我們只能選擇 NodePort,點選確定。

NodePort 模式裡會建立一個採用了 nginx-ingress 的 kubesphere-router 的容器組,細節我們會在以後的專文探討。

<,>

閘道器設定的細節不在本文深入討論,後續會有專文探討。現在,做到這一步就 OK 了。

接下來建立一個 MySQL 服務用於對外提供服務。

應用負載->-服務>建立-> 選擇自定義服務->指定工作負載

這裡有一個外部服務的選項,那個是基於 Ingress 使用域名訪問的,不是目前我們想要的方式。

指定工作負載建立服務-基本資訊

  • 名稱:mysql-external

指定工作負載建立服務-服務設定,點選指定工作負載,選擇有狀態副本集->mysql,點選確定

指定工作負載建立服務-服務設定配置。

  • 協議: TCP
  • 名稱: tcp-mysql-external
  • 容器埠: 3306
  • 服務埠: 3306

指定工作負載建立服務-高階設定

  • 外部訪問: 訪問模式選擇 NodePort

完成所有設定後,點選建立,建立成功會自動返回服務列表,在服務列表中可以看到我們新建立的服務 mysql-external 及自動分配的外部訪問埠號。

先用 telnet 命令測試一下,MySQL 服務的連通性,能看到下面的結果就說明 MySQL 已經可以在 K8s 叢集外部訪問了。

[root@ks-k8s-master-0 ~]# telnet 192.168.9.91 32529
Trying 192.168.9.91...
Connected to 192.168.9.91.
Escape character is '^]'.
EHost '10.233.117.0' is not allowed to connect to this MySQL serverConnection closed by foreign host.

# 細節!上面的EHost地址是192.168.9.91這個節點在K8s叢集內部分配的IP
[root@ks-k8s-master-0 ~]# ip add | grep 117 -B 2 -A 1
7: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 10.233.117.0/32 scope global tunl0
       valid_lft forever preferred_lft forever
[root@ks-k8s-master-0 ~]# ip add | grep 91
    inet 192.168.9.91/24 brd 192.168.9.255 scope global noprefixroute ens160
    link/ether c6:d3:91:95:f1:0f brd ff:ff:ff:ff:ff:ff

自定義 MySQL 配置檔案

預設安裝的 MySQL 使用的 my.cnf 配置檔案,適配的使用場景有限,所以自定義 mysql 配置檔案是必然要做的一項配置。

這裡我隨機找了一份配置檔案,僅僅是為了實現自定義配置的功能,請根據自己的使用場景使用合適的自定義配置檔案。

使用自定義配置前,我們先需要了解目前 mysql 容器的配置檔案結構。

使用 KubeSphere 提供的終端工具,進入 mysql 容器內部,執行下面的命令,分析執行結果 (終端登入方式參考前文截圖)。

# bash
root@mysql-0:/# ls /etc/mysql/ -l
total 8
drwxr-xr-x 2 root root   62 Apr 28 06:20 conf.d
lrwxrwxrwx 1 root root   24 Apr 28 06:20 my.cnf -> /etc/alternatives/my.cnf
-rw-r--r-- 1 root root  839 Aug  3  2016 my.cnf.fallback
-rw-r--r-- 1 root root 1200 Mar 22 01:44 mysql.cnf
drwxr-xr-x 2 root root   24 Apr 28 06:20 mysql.conf.d

root@mysql-0:/# ls /etc/mysql/conf.d/ -l
total 12
-rw-r--r-- 1 root root 43 Apr 28 06:20 docker.cnf
-rw-r--r-- 1 root root  8 Aug  3  2016 mysql.cnf
-rw-r--r-- 1 root root 55 Aug  3  2016 mysqldump.cnf

root@mysql-0:/# ls /etc/mysql/mysql.conf.d/ -l
total 4
-rw-r--r-- 1 root root 1589 Apr 28 06:20 mysqld.cnf

root@mysql-0:/# ls -l /etc/alternatives/my.cnf
lrwxrwxrwx 1 root root 20 Apr 28 06:20 /etc/alternatives/my.cnf -> /etc/mysql/mysql.cnf

root@mysql-0:/# cat /etc/mysql/mysql.cnf
# Copyright (c) 2016, 2021, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation.  The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

## 挑兩個配置檔案看看
root@mysql-0:~# cat /etc/mysql/conf.d/docker.cnf
[mysqld]
skip-host-cache
skip-name-resolve

root@mysql-0:~# cat /etc/mysql/mysql.conf.d/mysqld.cnf
# Copyright (c) 2014, 2021, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation.  The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# The MySQL  Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
#log-error      = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address   = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

分析上面的輸出我們得到以下結論。

  • 根配置檔案:/etc/mysql/mysql.cnf
  • 自定義的配置檔案可以存放在 /etc/mysql/conf.d//etc/mysql/mysql.conf.d/ 目錄下
  • 通過上面的結論,發現有兩種方式實現自定義配置檔案。

    • 直接替換 /etc/mysql/mysql.cnf

      適用於個性化配置較多較複雜的場景,比如 50+的配置項。
    • 將自定義的配置放在 /etc/mysql/conf.d//etc/mysql/mysql.conf.d/ 目錄下,根據官方配置使用情況,建議選擇 /etc/mysql/conf.d/

      適用於自定義配置較少的場景,比如只是為了開啟個別功能,或是個別預設引數不符合使用需求

本文采用第二種方式,採用一個獨立的 custom.cnf 檔案配置以下引數。

[mysqld]
#performance setttings
lock_wait_timeout = 3600
open_files_limit    = 65535
back_log = 1024
max_connections = 512
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
  

實現思路。

  • k8s 中我們可以通過配置 ConfigMap 的方式將檔案掛載給容器
  • 將自定義的 mysql 配置檔案,定義為一個 ConfigMap
  • 將 ConfigMap 掛載給 mysql 的容器

建立 ConfigMap 配置檔案,配置->配置字典,點選建立

建立配置字典-基本資訊

  • 名稱:mysql-cnf

建立配置字典-資料設定

  • 點選新增資料
  • 鍵: custom.cnf
  • 值: 貼上上面的配置引數

<,>

填寫完鍵值資訊後,點選對號確定,最後點選建立,建立完成後會返回配置字典頁面。

<,>

接下來將自定義配置檔案,掛載到 mysql 容器。

應用負載->工作負載->有狀態副本集-> 點選 mysql-> 進入詳細配置頁面->更多操作-點選編輯設定

編輯設定->儲存卷->掛載配置字典或保密字典

<,>

儲存卷

  • 選擇配置字典:mysql-cnf
  • 只讀
  • 掛載路徑:/etc/mysql/conf.d/custom.cnf
  • 指定子路徑:custom.cnf

    • 此處必須這麼寫,否則會覆蓋掉指定目錄下的所有已存在檔案
    • 底層就是 subPath
    • 具體操作看下圖圖示,注意細節
  • 選擇特定鍵:

    • 鍵:custom.cnf
    • 路徑:custom.cnf

<,,>

輸入完成後,點選對號

再次點選對號,點選確定,mysql 容器會自動開始重建。

<,>

重建成功後我們驗證一下配置檔案是否成功掛載。

先看一下容器組的配置,發現新增了一個儲存卷 volume-xxxx

終端-> 進入容器內部檢視。

檢視配置檔案掛載和檔案內容。

# bash
root@mysql-0:/# ls /etc/mysql/conf.d/
custom.cnf  docker.cnf  mysql.cnf  mysqldump.cnf

root@mysql-0:/# ls -l /etc/mysql/conf.d/
total 16
-rw-r--r-- 1 root root 463 May 11 11:07 custom.cnf
-rw-r--r-- 1 root root  43 Apr 28 06:20 docker.cnf
-rw-r--r-- 1 root root   8 Aug  3  2016 mysql.cnf
-rw-r--r-- 1 root root  55 Aug  3  2016 mysqldump.cnf

root@mysql-0:/# cat /etc/mysql/conf.d/custom.cnf
[mysqld]
#performance setttings
lock_wait_timeout = 3600
open_files_limit    = 65535
back_log = 1024
max_connections = 512
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M

檢視配置引數是否生效。

root@mysql-0:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.38 MySQL Community Server (GPL)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW GLOBAL VARIABLES LIKE 'max_connect%';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_connect_errors | 1000000 |
| max_connections    | 512     |
+--------------------+---------+
2 rows in set (0.02 sec)

mysql>

執行結果跟我們的配置一致,說明配置成功。

匯入資料庫資料

將資料庫檔案(SQL),掛載到容器的指定目錄下 /docker-entrypoint-initdb.d,容器建立時會自動匯入(非必要不推薦)。

用資料庫管理工具遠端管理資料庫(推薦)。

總結

本文詳細介紹了 KubeSphere 圖形化部署單節點 MySQL 上的安裝配置過程,如何利用 KubeSphere 的圖形化功能建立資源配置清單 YAML 檔案的思路和具體操作過程,以後再部署其他在官網找不到詳細配置指南的服務都可以借鑑這個方法。

下篇文章將會介紹 GitOps 的基本概念並演示如何用 GitOps 理念在原生 K8S 上部署 MySQL 服務。

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章