如何在Kubernetes上部署MySQL數據庫
Kubernetes改變了開發的方式,數據庫是應用程序的重要組成部分。在本文中,我們將展示如何在Kubernetes中部署數據庫,以及可以使用哪些方法在Kubernetes中部署數據庫。
01數據庫
數據庫是一種用于在計算機系統上存儲和處理數據的系統。數據庫引擎可以在數據庫上創建,讀取,更新和刪除。數據庫由數據庫管理系統(DBMS)控制。
在大多數數據庫中,數據按行和列進行建模,稱為關系型,這種類型的數據庫在80年代占主導地位。在2000年代,非關系數據庫開始流行,被稱為No-SQL,它們使用不同的查詢語言,并且這些類型的數據庫可用于鍵值對。
02StatefulSet
在本文中,我們將在Kubernetes中部署數據庫,因此我們必須了解什么是StatefulSet。
StatefulSet是用于管理有狀態應用程序的工作負載。它管理一組Pod的實現和擴展,并保證這些Pod的順序和唯一性。
像Deployment一樣,StatefulSet也管理具有相同容器規范的一組Pod。由StatefulSets維護的Pod具有唯一的,持久的身份和穩定的主機名,而不用管它們位于哪個節點上。如果我們想要一個跨存儲的持久性,我們可以創建一個持久性卷并將StatefulSet用作解決方案的一部分。即使StatefulSet中的Pod容易發生故障,存儲卷與新Pod進行匹配也很容易。
StatefulSet對于需要以下一項或多項功能的應用程序很有價值:
- 穩定的唯一網絡標識符。
- 穩定,持久的存儲。
- 有序,順暢的部署和擴展。
- 有序的自動滾動更新。
在Kubernetes上部署數據庫時,我們需要使用StatefulSet,但是使用StatefulSet有一些局限性:
- 需要使用持久性存儲卷為Pod提供存儲。
- 刪除副本或按比例縮小副本將不會刪除附加到StatefulSet的存儲卷。存儲卷確保數據的安全性。
- StatefulSet當前需要Headless Service 來負責Pod的網絡標識。
- 與Deployment 不同,StatefulSet不保證刪除StatefulSet資源時刪除所有Pod,而Deployment在被刪除時會刪除與Deployment關聯的所有Pod。在刪除StatefulSet之前,你必須將pod副本數量縮小到0 。
03Kubernetes上的數據庫
我們可以將數據庫作為有狀態應用程序部署到Kubernetes。通常,當我們部署Pod時,它們具有自己的存儲空間,但是該存儲空間是短暫的-如果容器被殺死了,則其存儲空間將隨之消失。
因此,我們需要有一個Kubernetes資源對象來解決這種情況:當我們想要數據持久化時,我們就把Pod和持久化存儲卷聲明關聯。通過這種方式,如果我們的容器被殺死了,我們的數據仍將位于集群中,新的pod也能夠相應地訪問數據。
Pod -> PVC-> PV
- PV =持久性存儲
- PVC =持久性存儲聲明
04Operators將數據庫部署到Kubernetes
- 我們可以使用由Oracle開發的Kubernetes Operators來部署MySQL數據庫:
https://github.com/oracle/mysql-operator
- 使用Crunchydata開發的PostgreSQL Operators,、將PostgreSQL部署到Kubernetes:
https://github.com/CrunchyData/postgres
-operator
- 使用MongoDB開發的Operators,可將MongoDB Enterprise部署到Kubernetes集群:
https://github.com/mongodb/mongodb
-enterprise-kubernetes
05在Kubernetes上部署數據庫是否可行?
在當今世界上,越來越多的公司致力于容器技術。在進行深入研究之前,讓我們回顧一下用于運行數據庫的選項。
1.完全托管的數據庫
完全托管的數據庫是那些不用自己來管理的數據庫-這種管理可以由AWS Google,Azure或Digital Cloud等云提供商完成。托管數據庫包括Amazon Web Services,Aurora DynamoDB或Google Spanner等。
使用這些完全托管的數據庫的優勢是操作少,云提供商可以處理許多維護任務,例如備份,擴展補丁等。你只需創建數據庫即可構建應用程序,其他的由云提供商幫你處理。
2.在VM或本地自行部署
使用此選項,你可以將數據庫部署到任何虛擬機(EC2或Compute Engine),并且將擁有完全控制權。你將能夠部署任何版本的數據庫,并且可以設置自己的安全性和備份計劃。
另一方面,這意味著你將自行管理,修補,擴展或配置數據庫。這將增加基礎架構的成本,但具有靈活性的優勢。
3.在Kubernetes上運行
在Kubernetes中部署數據庫更接近full-ops選項,但是從Kubernetes提供的自動化方面來看,你將獲得一些好處–能夠保持數據庫應用程序的正常運行。
要注意,pod是短暫的,因此數據庫應用程序重新啟動或失敗的可能性更大。另外,你將負責更具體的數據庫管理任務,例如備份,擴展等。
選擇在Kubernetes上部署數據庫時要考慮的一些重要點是:
- 有一些自定義資源和 operators可用于在Kubernetes上管理數據庫。
- 具有緩存層和瞬時態存儲的數據庫更適合Kubernetes。
- 你必須了解數據庫中可用的復制模式。異步復制模式為數據丟失留有空間,因為事務可能會提交給主數據庫,而不會提交給從數據庫。
上面,我們用一個簡單的圖表來顯示在Kubernetes上部署數據庫時的決策。
首先,我們需要嘗試了解數據庫是否具有與Kubernetes友好的功能,例如MySQL或PostgreSQL,然后我們查找kubernetes operators將數據庫與其他功能打包在一起。
第二個問題是,考慮到在Kubernetes中部署數據庫需要多少工作量,這是可以接受的?我們是否有一個運維團隊,或者在托管數據庫上部署數據庫是否可行?
06在Kubernetes上部署有狀態應用程序
步驟1:部署MySQL服務
- apiVersion: v1
- kind: Service
- metadata:
- name: mysql
- spec:
- ports:
- - port: 3306
- selector:
- app: mysql
- clusterIP: None
首先,我們在端口3306上為MySQL數據庫部署服務,所有Pod均具有標簽鍵app: mysql。
接下來,創建以下資源:
- Kubectl create -f mysql_service.yaml
步驟2:部署MySQL Deployment
- apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
- kind: Deployment
- metadata:
- name: mysql
- spec:
- selector:
- matchLabels:
- app: mysql
- strategy:
- type: Recreate
- template:
- metadata:
- labels:
- app: mysql
- spec:
- containers:
- - image: mysql:5.6
- name: mysql
- env:
- # Use secret in real usage
- - name: MYSQL_ROOT_PASSWORD
- value: password
- ports:
- - containerPort: 3306
- name: mysql
- volumeMounts:
- - name: mysql-persistent-storage
- mountPath: /var/lib/mysql
- volumes:
- - name: mysql-persistent-storage
- persistentVolumeClaim:
- claimName: mysql-pv-claim
此Deployment在3306端口上創建帶有MySQL5.6鏡像和密碼(使用secret)的Pod。我們還將附加一個持久卷mysql-pv-claim,將在接下來的步驟中進行顯示。
創建資源:
- Kubectl create -f mysql_deployment.yaml
第3步:創建持久卷
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: mysql-pv-volume
- labels:
- type: local
- spec:
- storageClassName: manual
- capacity:
- storage: 20Gi
- accessModes:
- - ReadWriteOnce
- hostPath:
- path: "/mnt/data"
這將創建一個持久卷,我們將使用它來附加到容器,以確保Pod重啟時的數據安全。該持久卷具有ReadWriteOne訪問模式,擁有20GB的存儲空間,存放路徑是/ mnt/data,我們所有的數據都將保存在該路徑中。
創建以下資源:
- Kubectl create -f persistence_volume.yaml
第4步:創建持久卷聲明
- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: mysql-pv-claim
- spec:
- storageClassName: manual
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 20Gi
該聲明從上面創建的“持久卷”中聲明20GB,并具有與上面的“持久卷”相同的訪問模式。
創建以下資源:
- Kubectl create -f pvClaim.yaml
步驟5:測試MySQL數據庫
- kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword
此命令在運行MySQL的集群中創建一個新的Pod,并連接到MySQL服務器。如果連接成功,則說明你的MySQL數據庫已啟動并正在運行。
- Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
- If you don't see a command prompt, try pressing enter.
- mysql>
07總結
- 有狀態應用程序是存儲用戶會話狀態的應用程序,保存的數據稱為應用程序狀態。
- StatefulSet是一個Kubernetes資源對象,用于管理有狀態應用程序,并提供有關Pod順序和唯一性的保證。
- 通過刪除StatefulSet,不會刪除StatefulSet中的pod。相反如果刪除,你必須將有狀態應用程序副本數量縮小為0。
- Kubernetes上的數據庫部署有一個持久存儲卷,只要你的集群正在運行,該存儲卷就可以永久存儲數據。這意味著它可以抵御pod的破壞,并且創建的任何新pod將能夠再次使用該存儲卷。
- 完全托管的數據庫是由云提供商管理的數據庫。我們不必管理數據庫。這些數據庫需要額外的費用,但是如果你想專注于應用程序,它們是最佳選擇。
- 你可以通過VM部署數據庫。但你將必須處理所有數據庫操作,例如擴展,設置和修補。
- 最后,我們展示了如何在Kubernetes上部署數據庫。