技術分享 | kubernetes 環境測試部署 MySQL 的隨想

​做者:王悅
愛可生研發團隊成員,負責數據庫管理平臺相關項目的開發和故障排查,好奇 MySQL 技術原理及各種數據庫實現方案。
本文來源:轉載自公衆號-圖解 MySQL
*愛可生開源社區出品,原創內容未經受權不得隨意使用,轉載請聯繫小編並註明來源。

注:閱讀本文須要瞭解 pod,controller,service 等一些 kubernetes 的基本概念。

什麼是 kubernetes?有了容器技術後爲何還須要 kubernetes?

容器憑藉其良好的移植性,敏捷性和革命性的打包方式迅速成爲雲服務的新基礎設施。但 Docker 畢竟只是 「container runtime」,咱們須要一個編排框架做爲系統核心來串聯開發、測試、部署、運維等整個軟件生命週期。kubernetes 就提供這樣一個框架,提供大量容器的部署、編排、管理的能力。mysql

若是將 MySQL 部署在 kubernetes 會有哪些挑戰?帶來了什麼收益?

雖然 kubernetes 社區一直在努力使得有狀態應用成爲一等公民,也推出了 statefulset 控制器支持 pod 的順序部署,穩定的域名訪問和存儲訪問。但鑑於 MySQL 部署運維的多樣性和複雜性,在 kubernetes 上部署 MySQL 仍然要面臨衆多挑戰。git

一、業務流量入口的配置方式

傳統虛擬機環境下,咱們經過虛 IP 的方式,讓業務應用都配置事先定義的一個虛 IP 爲連接數據庫的地址,而後由高可用服務保證虛 IP 始終能被路由到 master 數據庫。github

在 kubernetes 中,出現了一層網絡插件屏蔽了底層網絡拓撲,高可用服務管理虛 IP 的方式須要隨之適應調整,好比經過 service 結合標籤完成虛 IP 的漂移,但 service 自己是 kubernetes 提供的一項功能,其可靠性和性能都取決於 kubernetes 服務的穩定。sql

以性能來講,service 是 kube proxy 組件經過配置 iptables 實現的,當 iptables 規則較多時不可避免的會產生時延,須要咱們針對性的解決。數據庫

二、容器隔離帶來的監控視野問題

在 kubernetes 中,若是將 MySQL 製做爲 container 運行在一個 pod 中,container 會將 MySQL 進程和運行環境隔離在一個單獨的 namespace 中。監控組件在獲取 MySQL 的一些 metirc 時,可能不得不進入與 MySQL 同一個 namespace 中,在部署和設計監控組件時須要考慮到這些限制。api

三、存儲

在 kubernetes 中,支持配置各類不一樣的存儲。若是使用本地存儲 local persistent volume,則須要綁定 MySQL 在一個固定的節點,這就徹底浪費了 kubernetes 靈活調度的自然優點;而若是使用遠程共享存儲,確實是將 MySQL 進程與其存儲徹底解耦,使得 MySQL 進程能夠在任意節點調度,然而考慮到高 I/O 吞吐量的狀況,就不是那麼美好了。網絡

設計時須要考量遠程存儲是否可以知足 MySQL 的帶寬要求。架構

四、高可用/備份恢復

kubernetes 提供的 statefulset 控制器只能提供最基本的部署,刪除功能,沒法實現完善的 MySQL 集羣高可用/備份恢復操做。對於有狀態應用的部署,仍須要定製開發,因此多數公司提供了定製的 operator 來完成應用容器的管理。好比 etcd operator,MySQL operator,後文將爲你們詳述我測試使用 MySQL operator 的一些記錄。oracle

注:operator 是 CoreOs 推出的旨在簡化複雜有狀態應用管理的框架,咱們能夠經過 operator 自定義一個有狀態應用容器的控制器,operator 經過 kubernetes API 觀察集羣現有狀態,管理集羣行爲,以達到用戶指望的集羣狀態。

說完了問題和挑戰,咱們來講說收益。框架

把 MySQL 塞進 kubernetes 生態帶來了什麼?

  1. 豐富的網絡配置

    結合kubernetes的cni網絡插件能夠快速實現限流,黑白名單...

  2. 各種 kubernetes 調度、運維功能

    敏捷部署,滾動更新,依據負載狀況的節點調度...

  3. 與一樣部署在 kubernetes 生態的業務應用緊密配合

然而考慮到 MySQL 這類持久層軟件的特殊性,不能簡單的套用 kubernetes 的原生 API 功能,好比滾動更新須要考慮主從角色的前後順序,配套高可用軟件在 MySQL 更新階段的行爲,業務流量的切換等等。這些在傳統環境中已經解決的問題在 kubernetes 中仍然須要被從新規劃解決方案。

控制器介紹

鑑於以上種種挑戰,在 kubernetes 上管理 MySQL 須要一套專爲 MySQL 設計的控制器(就咱們前面說到的 operator),目前開源社區中比較流行的有如下兩個控制器:

Oracle MySQL operator

先簡單過一遍功能:

  1. 最低支持 MySQL 8.0.11 版本
  2. 只能支持部署MySQL Group Replication 架構,不支持 Master-Slave 部署
  3. operator 自動創建的 service 沒法區分讀寫節點,推薦應用使用 mysql router,由 mysql router 路由至下游實例
  4. 提供 mysqldump(不支持其餘備份工具)配置定時備份,備份文件上傳遠程存儲,目前僅實現了 AWS S3 接口
  5. 支持從遠程存儲中獲取備份執行回放還原
  6. operator 內置提供了一些基礎 metric 監控集羣狀態
具體的安裝步驟就不在這裏詳述了,你們能夠參考

https://github.com/oracle/MyS...

下面探索一下 operator 部署時的一些實現方式:

  1. operator 監聽用戶定義的配置 cr,調用 kubernetes api 建立 statefulset 來部署MySQL Group Replication 集羣
  2. 使用 kubernetes secret 存儲和管理 root 密碼
  3. statefulset 建立的 pod 中定義兩個 container,一個容納 mysqld 進程,一個容納以 sidecar 的模式負責運維功能的 mysql agent 進程
  4. mysqld 做爲容器的 1 號進程,由 kubernetes 負責守護
  5. mysql agent 進程負責 mysqld 的狀態監控,備份和回聽任務的執行,opertaor 的 metric 也是由其提供

FAQ:

Q: pod 重啓後可否保證明例的數據不丟失?

A:operator 在建立實例時會將 datadir 配置爲 mysqlvolume 掛載(如 pvc 或 emptydir),因此實例重啓後可以從新掛載恢復數據。注:限制是用戶不能自定義 data,binlog,redolog 目錄,若是不在默認的 /var/lib/mysql 目錄中,數據會隨 pod 重啓而消亡

Q:能夠爲 mysqld container 設置 cpu,mem 資源限制嗎?

A:能夠在建立集羣時配置限制,但該功能只在 master 版本上存在,目前 helm hub 中使用的是 0.3.0 tag 版本,該版本中無該功能

Q:業務和實例不在一個 kubernetes 集羣時該如何鏈接?

A:在實例所在集羣上先部署一個 mysql-router,而後經過暴露 mysql-router 給外部集羣來提供訪問。

暴露方式有多種可選,如 NodePort,LoadBalancer,Ingress 等

可見 Oracle MySQL operator 提供的功能很是基礎,並且其 github 倉庫已經一年多沒有維護了,官方好像不是很想推進 MySQL 上 kubernetes,畢竟傳統雲服務提供的 RDS 服務已經可以知足大部分用戶場景。

Percona MySQL operator

另外,Percona 也提供了一個 MySQL 的 operator,可以部署高可用 master-slave 結構的 MySQL,但依託於 Percona 版的 MySQL 提供的功能,並不支持原生的 MySQL 鏡像。

結語

使用 operator 運維有狀態應用確實可以解決多數問題,但維護數據庫應用自己就是複雜困難的,須要適應不少場景,在 kubernetes 上徹底解決這些問題短時間內很是困難。

上述兩個 MySQL operator 目前的實現都相對基礎,直接在生產環境部署的穩定性也沒有保障,只能做爲調研測試的對象。

相關文章
相關標籤/搜索