做者:王悅
愛可生研發團隊成員,負責數據庫管理平臺相關項目的開發和故障排查,好奇 MySQL 技術原理及各種數據庫實現方案。
本文來源:轉載自公衆號-圖解 MySQL
*愛可生開源社區出品,原創內容未經受權不得隨意使用,轉載請聯繫小編並註明來源。
注:閱讀本文須要瞭解 pod,controller,service 等一些 kubernetes 的基本概念。
容器憑藉其良好的移植性,敏捷性和革命性的打包方式迅速成爲雲服務的新基礎設施。但 Docker 畢竟只是 「container runtime」,咱們須要一個編排框架做爲系統核心來串聯開發、測試、部署、運維等整個軟件生命週期。kubernetes 就提供這樣一個框架,提供大量容器的部署、編排、管理的能力。mysql
雖然 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 觀察集羣現有狀態,管理集羣行爲,以達到用戶指望的集羣狀態。
說完了問題和挑戰,咱們來講說收益。框架
結合kubernetes的cni網絡插件能夠快速實現限流,黑白名單...
敏捷部署,滾動更新,依據負載狀況的節點調度...
然而考慮到 MySQL 這類持久層軟件的特殊性,不能簡單的套用 kubernetes 的原生 API 功能,好比滾動更新須要考慮主從角色的前後順序,配套高可用軟件在 MySQL 更新階段的行爲,業務流量的切換等等。這些在傳統環境中已經解決的問題在 kubernetes 中仍然須要被從新規劃解決方案。
鑑於以上種種挑戰,在 kubernetes 上管理 MySQL 須要一套專爲 MySQL 設計的控制器(就咱們前面說到的 operator),目前開源社區中比較流行的有如下兩個控制器:
先簡單過一遍功能:
具體的安裝步驟就不在這裏詳述了,你們能夠參考
下面探索一下 operator 部署時的一些實現方式:
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,可以部署高可用 master-slave 結構的 MySQL,但依託於 Percona 版的 MySQL 提供的功能,並不支持原生的 MySQL 鏡像。
使用 operator 運維有狀態應用確實可以解決多數問題,但維護數據庫應用自己就是複雜困難的,須要適應不少場景,在 kubernetes 上徹底解決這些問題短時間內很是困難。
上述兩個 MySQL operator 目前的實現都相對基礎,直接在生產環境部署的穩定性也沒有保障,只能做爲調研測試的對象。