雲原生在京東丨如何在Kubernetes上部署有狀態的雲原生應用?(下)

image.png
點擊閱讀:《如何在Kubernetes上部署有狀態的雲原生應用(上)》html

下面咱們將以最早進的開源數據庫PostgreSQL爲例,介紹如何在 Kubernetes 上部署運維有狀態雲服務(如下全部的操做都是基於Kubernetes 1.14及以上版原本完成的)。node

Operator出來之前,即便有StatefulSet控制器,將PostgreSQL、MySQL等數據庫部署到Kubernetes也是很是複雜的。兩年前關於在Kubernetes上部署數據庫還有過一場討論,當時的廣泛建議是不要在Kubernetes部署數據庫。git

關於這場討論能夠經過該連接查看:github

https://www.reddit.com/r/devo...sql

經過StatefulSet在Kubernetes上部署高可用的MySQL服務請參考如下連接:數據庫

https://www.kubernetes.org.cn...centos

這個方法中yaml文件至關複雜,用戶能夠參與控制的地方很少。安全

開源的PostgreSQL Operator有CrunchyData/postgres-operator、zalando-incubator/postgres-operator,咱們以CrunchyData/postgres-operator爲例來說解如何經過Operator這個新生事物在Kubernetes上管理PostgreSQL數據庫,選擇它的緣由是功能至關完備而且集成了PostgreSQL周邊生態相關的應用。服務器

該Operator實現了在Kubernetes上自動化部署PostgreSQL集羣,簡化了PostgreSQL服務的部署,並經過Kubernetes平臺保持PostgreSQL集羣的運行狀態,其中包含的基本功能有:網絡

PostgreSQL集羣配置:輕鬆建立、擴展和刪除PostgreSQL集羣,同時徹底自定義Pod和PostgreSQL配置。

高可用性:基於分佈式共識的高可用解決方案,支持安全的自動故障轉移。使用Pod Anti-Affinity來加強彈性,失敗的主數據庫會自動恢復,從而縮短恢復時間。

災難恢復:利用開源pgBackRest程序實現備份和還原功能,幷包括對全備,增量和差別備份以及有效增量還原的支持。能夠設置要保留的備份時間,比較適合較大型的數據庫,也經過共享S3存儲及多Kubernetes部署實現了跨機房多區域異地災備。

TLS:經過爲PostgreSQL服務器啓用TLS來保護應用程序和數據服務器之間的通訊安全,包括強制全部鏈接使用TLS。

監控方式:使用開源pgMonitor庫跟蹤PostgreSQL集羣的運行情況。

PostgreSQL用戶管理:使用功能強大的命令給PostgreSQL集羣快速添加和刪除用戶。管理密碼過時策略或使用首選的PostgreSQL身份驗證方案。

升級管理:安全地將PostgreSQL更新應用到您的PostgreSQL集羣中,而對可用性的影響最小。

高級複製支持:用戶能夠在異步複製和同步複製之間進行選擇,以處理對丟失事務敏感的工做負載。

克隆:使用簡單的pgo clone命令從現有集羣中建立新集羣。

鏈接池:使用pgBouncer進行鏈接池。

節點親和力:將PostgreSQL集羣部署到您喜歡的Kubernetes節點。

備份策略定製:選擇備份的類型(全量,增量,差別備份)以及但願其在每一個PostgreSQL集羣上發生週期及時間點。

備份到S3:將您的備份存儲在任何支持S3協議的對象存儲系統中。PostgreSQL Operator能夠從這些備份中還原和建立新的集羣。

_多命名空間支持:_您能夠經過幾種不一樣的部署模型來控制PostgreSQL Operator如何利用Kubernetes命名空間:

  • 將PostgreSQL Operator和全部PostgreSQL集羣部署到同一名稱空間;
  • 將PostgreSQL Operator部署到一個名稱空間,並將全部PostgreSQL集羣部署到另外一名稱空間;
  • 將PostgreSQL Operator部署到一個名稱空間,並跨多個命名空間管理PostgreSQL集羣;
  • 使用pgo create namespace和pgo delete namespace命令動態添加和刪除由PostgreSQL Operator管理的名稱空間。

徹底可定製:

  • 爲主存儲,WAL存儲,副本存儲和備份存儲選擇不一樣的存儲類別;
  • 爲每一個PostgreSQL集羣部署選擇容器資源類;區別應用於主羣集和副本羣集的資源;
  • 使用您私有的鏡像存儲庫,包括支持imagePullSecrets存儲庫和私有存儲庫;
  • 自定義PostgreSQL配置等。

PostgreSQL Operator包含各類組件,這些組件已部署到您的Kubernetes集羣中,以下圖所示:

PostgreSQL Operator在指定的namespace中以Deployment對象運行,而且最多由四個容器的Pod組成,其中包括:

  • Operator:這是PostgreSQL Operator的核心。它包含一系列Kubernetes 控制器,這些控制器將監視事件關注在一系列本地Kubernetes資源(如Job,Pods)以及PostgreSQL Operator自定義的CRD上,如:Pgcluster,Pgtask等。
  • ApiServer: 提供了一套Restful API接口,方便用戶經過pgo命令行或直接經過HTTP請求與其交互,ApiServer還利用一系列RBAC規則來控制用戶對資源的訪問權限。
  • Scheduler:運行cron並容許用戶設置週期性任務(如備份)以Kubernetes Job的方式運行。
  • Event:可選組件,一個提供nsq消息隊列接口並輸出有關Operator內發生的生命週期事件的信息的容器(例如,建立集羣,進行備份,建立克隆失敗等),能夠由pgo watch命令接受消息。

下列流程是理解 Operator工做原理的關鍵:

使用Kubernetes的CustomResourceDefinition(CRD)定義若干和 PostgreSQL部署運維相關的資源對象。

  • pgclusters.crunchydata.com:存儲管理PostgreSQL集羣所需的信息。其中包括集羣名稱,要使用的存儲和資源類,要運行的PostgreSQL版本,有關如何維護高可用性集羣的信息等。
  • pgreplicas.crunchydata.com:存儲管理PostgreSQL集羣中的副本所需的信息。這包括諸如副本數,要使用的存儲和資源類,特殊的類似性規則等。
  • pgtasks.crunchydata.com:通用CRD,它接受針對集羣運行(例如,建立集羣,進行備份,執行克隆)所需的一種任務,並經過其工做流跟蹤該任務的狀態。
  • pgpolicies.crunchydata.com:存儲對能夠對PostgreSQL集羣執行的SQL文件的引用。過去它用於管理PostgreSQL集羣上的RLS策略。

在Kubernetes中部署一個Operator實例,該Operator會持續監聽針對這些資源對象的CRUD操做,並觀察對象狀態。

當用戶執行了某項操做,例如建立一個PostgreSQL集羣時,一個新的 pgcluster 資源對象會被建立。當Operator監聽到了pgcluster的建立事件後,會根據用戶配置建立符合需求的集羣。這裏建立了一個基於流複製協議的高可用PostgreSQL集羣,使用了Deployment、Service、ConfigMap、PVC等原生 Kubernetes資源對象。

當Operator觀察到PostgreSQL Cluster的當前狀態與指望狀態存在差異時,會執行相應的編排操做,保證狀態的一致性。

經過helm部署PostgreSQL Operator。

1[root@RDS pgo]# helm search repo 
2NAME                           CHART VERSION   APP VERSION     DESCRIPTION  
3jd_tpaas_repo/customconfig     1               4.3.2       Deploys a custom configuration for postgreSQL  
4jd_tpaas_repo/pgodeployer      1               4.3.2       Deploys a job for the installation of the postg...

<左右滑動以查看完整代碼>

安裝Operator。

5  [root@RDS pgo]#  helm --namespace pgo install pg-operator jd_tpaas_repo/pgo-deployer

<左右滑動以查看完整代碼>

部署完成之後查看Operator的狀態 。

6  [root@RDS ~]# kubectl -n pgo get all  
7  NAME                                      READY   STATUS    RESTARTS   AGE  
8  pod/crunchy-grafana-77b4b84b57-cgrnn      1/1     Running   0          4m12s  
9  pod/crunchy-prometheus-57788f56fb-lcqsp   1/1     Running   0          4m15s  
10  pod/postgres-operator-7f6d4646cc-zf2dg    4/4     Running   0          4m50s  
11    
12  NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE  
13  service/crunchy-grafana      ClusterIP   192.168.58.207    3000/TCP                     5m34s  
14  service/crunchy-prometheus   ClusterIP   192.168.62.99     9090/TCP                     5m37s  
15  service/postgres-operator    ClusterIP   192.168.60.155    8080/TCP,4171/TCP,4150/TCP   5m23s  
16    
17  NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE  
18  deployment.apps/crunchy-grafana      1/1     1            1           5m34s  
19  deployment.apps/crunchy-prometheus   1/1     1            1           5m37s  
20  deployment.apps/postgres-operator    1/1     1            1           5m22s  
21    
22  NAME                                            DESIRED   CURRENT   READY   AGE  
23  replicaset.apps/crunchy-grafana-77b4b84b57      1         1         1       4m12s  
24  replicaset.apps/crunchy-prometheus-57788f56fb   1         1         1       4m15s  
25  replicaset.apps/postgres-operator-7f6d4646cc    1         1         1       4m50s

<左右滑動以查看完整代碼>

咱們看到有一個PostgreSQL-Operator Deployment裏面包含了4個容器:ApiServer、Operator、Scheduler、 Event,除了Operator,還部署了crunchy-prometheus和crunchy-grafana兩個Deployment能夠幫助用戶進行集中式監控管理。

PostgreSQL Operator的主要目的是圍繞PostgreSQL集羣的結構建立和更新信息,並傳遞有關PostgreSQL集羣的整體狀態和運行情況的信息。目標也是爲用戶儘量簡化此過程。

例如,假設咱們要建立一個具備單個副本的高可用PostgreSQL集羣,它支持在本地存儲和S3中進行備份,並具備內置監控指標收集和集中的日誌收集。咱們能夠利用以下命令來完成:

pgo create cluster hacluster --replica-count=1 --metrics --pgbackrest-storage-type="local,s3"

<左右滑動以查看完整代碼>

經過pgo命令行建立集羣示例:

首先爲集羣建立一個namespace 。

1[root@RDS pgo]# pgo create namespace pgouser2 
2created namespace pgouser2

<左右滑動以查看完整代碼>

建立集羣,帶一個副本並開啓監控。

3  [root@RDS pgo]# pgo -n pgouser2 create cluster test-pgcluter-002 --replica-count 1 --metrics 
4  created cluster: test-pgcluter-002  
5  workflow id: cb75373a-518f-49e1-8b6a-55e274d2fc58  
6  database name: test-pgcluter-002  
7  users: 
8  username: testuser password: 7iFe|iS4aF(}:3*6FibWo?jZ

<左右滑動以查看完整代碼>

查看集羣信息。

9  [root@RDS pgo]#  pgo -n pgouser2 show cluster  test-pgcluter-002 
10  cluster : test-pgcluter-002 (crunchy-postgres-ha:centos7-12.3-4.3.2-0)  
11     pod : test-pgcluter-002-b7d8b4bd4-qk5cp (Running) on k8s-node-vm7sjf-yn5hsstwuf (2/2) (primary)  
12     pvc : test-pgcluter-002  
13     pod : test-pgcluter-002-jcfm-6bfff77fcf-vxpn6 (Running) on k8s-node-vmr4ej-yn5hsstwuf (2/2) (replica)  
14     pvc : test-pgcluter-002-jcfm  
15     resources : Memory: 128Mi  
16     storage : Primary=20Gi Replica=20Gi  
17     deployment : test-pgcluter-002  
18     deployment : test-pgcluter-002-backrest-shared-repo  
19     deployment : test-pgcluter-002-jcfm  
20     service : test-pgcluter-002 - ClusterIP (192.168.120.61)  
21     service : test-pgcluter-002-replica - ClusterIP (192.168.123.182)  
22     pgreplica : test-pgcluter-002-jcfm  
23     ...

<左右滑動以查看完整代碼>

查看集羣的服務狀態。

24  [root@RDS pgo]# pgo -n pgouser2 test  test-pgcluter-002  
 25  cluster : test-pgcluter-002  
 26     Services  
 27         primary (192.168.120.61:5432): UP  
 28         replica (192.168.123.182:5432): UP  
 29     Instances  
 30         primary (test-pgcluter-002-b7d8b4bd4-qk5cp): UP  
 31         replica (test-pgcluter-002-jcfm-6bfff77fcf-vxpn6): UP

<左右滑動以查看完整代碼>

不難看到集羣中包含兩個Deployment,對應的兩個Pod各綁定一個PVC,暴露出兩個Service:

Service-Primary:test-pgcluter-002 - ClusterIP (192.168.120.61) 負責用戶的讀寫請求;

Service-Replica: test-pgcluter-002-replica - ClusterIP (192.168.123.182)負責用戶的只讀請求。

集羣建立成功之後,Pod和Service的狀態都是Up,處於正常運行狀態。

PostgreSQL的一大優勢是它的可靠性:它很是穩定,一般能夠「正常工做」。可是,在部署PostgreSQL的環境中可能會發生某些事情,從而影響其正常運行時間,包括:

  • 數據庫存儲磁盤發生故障或發生其餘一些硬件故障;
  • 數據庫所在的網絡沒法訪問;
  • 主機操做系統變得不穩定並崩潰;
  • 密鑰數據庫文件已損壞;
  • 數據中心丟失。

可能還會因爲正常操做而致使停機事件,例如執行小版本升級,操做系統的安全修補,硬件升級或其餘維護。

爲此,在Crunchy PostgreSQL Operator 建立的集羣中每個PostgreSQL容器裏面都包含Patroni工具,由Patroni經過raft 分佈式共識的特性來處理PostgreSQL的高可用。

Patroni是一個用Python編寫的開源工具套件,用於管理PostgreSQL集羣的高可用性。Patroni沒有構建本身的一致性協議,而是巧妙地利用了分佈式配置存儲(DCS)提供的一致性模型。它支持的DCS解決方案包括:Zookeeper,etcd,Consul和Kubernetes。Crunchy PostgreSQL Operator中採用的是Kubernetes的ConfigMap做爲其DCS。

Patroni確保PostgreSQL HA集羣的端到端設置,包括流複製。它支持各類方式建立備用節點,而且能夠像模板同樣工做,能夠根據須要進行自定義。這個功能豐富的工具經過RestFul API和稱爲patronictl的命令行程序暴露其功能。它經過使用其運行情況檢查API處理負載均衡來支持與HAProxy集成。在Operator中是經過處理Kubernetes的Service來實現,Patroni還藉助回調來支持事件通知,這些回調是由某些操做觸發的腳本。經過提供暫停/恢復功能,它使用戶可以執行任何維護操做。

最初,須要安裝PostgreSQL和Patroni二進制文件。完成此操做後,您還須要設置HA DCS配置。須要在yaml配置文件中指定全部用於引導集羣的必要配置,而且Patroni將使用該文件進行初始化。在第一個節點上,Patroni初始化數據庫,從DCS獲取領導者鎖,並確保該節點做爲主節點運行。

下一步是添加備用節點,Patroni爲此提供了多個選項。默認狀況下,Patroni使用pg_basebackup建立備用節點,而且還支持WAL-E、pgBackRest、Barman等自定義方法來建立備用節點。Patroni使添加備用節點變得很是簡單,而且能夠處理全部引導任務和流複製的設置。集羣設置完成後,Patroni將主動監視集羣並確保其處於正常狀態。主節點每ttl秒更新一次領導者鎖(默認值:30秒)。當主節點沒法更新領導者鎖時,Patroni會觸發選舉,而且得到領導者鎖的節點將被選舉爲新的主節點。

在分佈式系統中,共識在肯定一致性方面起着重要做用,而Patroni使用DCS來達成共識。只有持有領導者鎖的節點才能成爲主節點,而且領導者鎖是經過DCS得到的。若是主節點未持有領導者鎖,那麼Patroni將當即將其降級以做爲備用節點運行。這樣,在任什麼時候間點,系統中都只能運行一個主服務器。

咱們經過下面一系列的圖片來演示Patroni在集羣的Failover發生後從新選主的過程:

圖 A 顯示了一個集羣暫時的穩定狀態,Pod A是當前的主節點,每隔一段時間就要刷新一次本身的心跳信息,保持本身領導者的地位,其對應的PostgreSQL在集羣中是Primary的角色。Pod B 和 Pod C一直在watch leader,集羣中有兩個Service,master service其後掛載的endpoint指向帶有label=master標籤的Pod,replica service其後掛載的endpoint指向帶有label=replica標籤的Pod;

圖B 示意某一時刻,Pod A發生了故障,沒有及時更新心跳,超過ttl=30s後,Kubernetes會通知 Pod B、Pod C主節點Pod A心跳缺失超時信息。

圖C示意Pod B和Pod C都會發起檢查集羣中其餘節點的狀態,均會發現主節點Pod A Failed,從而從新發起選舉主節點流程,Pod B和Pod C誰的wal_position更大誰將是下一輪主節點,若是同樣大就會發生競爭,先搶到領導者鎖的節點將成爲下一輪的主節點。如圖D所示意,Pod B成功搶到了領導者鎖。

圖E示意_搶到領導者鎖的Pod B對應的PostgreSQL會被提高爲Master,Pod C中的PostgreSQL會向Pod B的PostgreSQL同步數據。_Pod B會週期刷新本身的心跳,鞏固本身領導者的地位,Pod C會一直Watch Leader。到此,集羣又進入下一輪穩定狀態。

圖F示意由於Operator要保證集羣的replica的個數,會拉起一個新的Pod D,做爲replica加入到集羣中,從Pod B的PostgreSQL同步數據,而且帶有replica的label,其endpoint會掛載到replica service下面。

實際操做示意:

刪除Primary的Pod 。

1  [root@RDS pgo]# kubectl -n pgouser2 delete pod test-pgcluter-002-b7d8b4bd4-qk5cp 
2  pod "test-pgcluter-002-b7d8b4bd4-qk5cp」 deleted  
3  稍等片刻......

<左右滑動以查看完整代碼>

查看集羣的狀態

4  [root@RDS pgo]# pgo -n pgouser2 show cluster  test-pgcluter-002 
5  cluster : test-pgcluter-002 (crunchy-postgres-ha:centos7-12.3-4.3.2-0)  
6     pod : test-pgcluter-002-b7d8b4bd4-97qqp (Running) on k8s-node-vm7sjf-yn5hsstwuf (2/2) (replica)  
7     pvc : test-pgcluter-002  
8     pod : test-pgcluter-002-jcfm-6bfff77fcf-vxpn6 (Running) on k8s-node-vmr4ej-yn5hsstwuf (2/2) (primary)  
9     pvc : test-pgcluter-002-jcfm  
10    resources : Memory: 128Mi  
11    storage : Primary=20Gi Replica=20Gi  
12    deployment : test-pgcluter-002  
13    deployment : test-pgcluter-002-backrest-shared-repo  
14    deployment : test-pgcluter-002-jcfm  
15    service : test-pgcluter-002 - ClusterIP (192.168.120.61)
16    service : test-pgcluter-002-replica - ClusterIP (192.168.123.182)  
17    pgreplica : test-pgcluter-002-jcfm  
18    ...  
19
20    [root@RDS pgo]# pgo -n pgouser2 test  test-pgcluter-002 
21    cluster : test-pgcluter-002 
22    Services  
23        primary (192.168.120.61:5432): UP  
24        replica (192.168.123.182:5432): UP  
25    Instances  
26       replica (test-pgcluter-002-b7d8b4bd4-97qqp): UP  
27       primary (test-pgcluter-002-jcfm-6bfff77fcf-vxpn6): UP

<左右滑動以查看完整代碼>

能夠看到原來的Replica Pod:test-pgcluter-002-jcfm-6bfff77fcf-vxpn6 變成了Primary,Operator又新建了一個Pod:test-pgcluter-002-b7d8b4bd4-97qqp 做爲replica 運行,其掛載的仍是原來Primary的PVC:test-pgcluter-002,Services相對於集羣建立的時候沒有發生變化,仍是primary (192.168.120.61:5432) 和 replica (192.168.123.182:5432),鏈接的用戶除了有秒級別的閃斷基本沒有感知。

經過pgo scale來進行水平擴容,如下命令對集羣test-pgcluter-002水平擴容增長一個replica節點。

1  [root@RDS pgo]# pgo -n pgouser2 scale test-pgcluter-002 --replica-count=1 
2  WARNING: Are you sure? (yes/no): yes  
3  created Pgreplica test-pgcluter-002-tbrl

<左右滑動以查看完整代碼>

查看擴容之後的集羣狀態:

4  [root@RDS pgo]#  pgo -n pgouser2 show cluster  test-pgcluter-002 
5  cluster : test-pgcluter-002 (crunchy-postgres-ha:centos7-12.3-4.3.2-0)  
6    pod : test-pgcluter-002-b7d8b4bd4-97qqp (Running) on k8s-node-vm7sjf-yn5hsstwuf (2/2) (replica)  
7    pvc : test-pgcluter-002  
8    pod : test-pgcluter-002-jcfm-6bfff77fcf-vxpn6 (Running) on k8s-node-vmr4ej-yn5hsstwuf (2/2) (primary)  
9    pvc : test-pgcluter-002-jcfm  
10    pod : test-pgcluter-002-tbrl-7d69bc5fb9-8xmx2 (Running) on k8s-node-vmwnpv-yn5hsstwuf (2/2) (replica)  
11    pvc : test-pgcluter-002-tbrl  
12    resources : Memory: 128Mi  
13    storage : Primary=20Gi Replica=20Gi  
14    deployment : test-pgcluter-002  
15    deployment : test-pgcluter-002-backrest-shared-repo  
16    deployment : test-pgcluter-002-jcfm  
17    deployment : test-pgcluter-002-tbrl  
18    service : test-pgcluter-002 - ClusterIP (192.168.120.61)  
19    service : test-pgcluter-002-replica - ClusterIP (192.168.123.182)

<左右滑動以查看完整代碼>

經過增長一個名爲test-pgcluter-002-tbr的Deployment,增長了一個replica。新建的pod爲test-pgcluter-002-tbrl-7d69bc5fb9-8xmx2,綁定的pvc:test-pgcluter-002-tbrl,暴露的服務仍是原來的兩個Service:primary (192.168.120.61:5432)、replica (192.168.123.182:5432) 。Service replica 後面對應着兩個replica節點的Pod暴露的endpoint,對用戶數據面沒有影響。

如下命令查看能夠縮容的replica節點:

1  [root@RDS pgo]# pgo -n pgouser2 scaledown test-pgcluter-002 --query 
2  Cluster: test-pgcluter-002  
3  REPLICA                 STATUS        NODE          REPLICATION LAG         PENDING RESTART  
4  test-pgcluter-002        running       k8s-node-vm7sjf-yn5hsstwuf               0 MB                   false  
5  test-pgcluter-002-tbrl    running       k8s-node-vmwnpv-yn5hsstwuf               0 MB                   false

<左右滑動以查看完整代碼>

經過pgo scaledown命令進行縮容:

6  [root@RDS pgo]# pgo -n pgouser2 scaledown test-pgcluter-002 --target test-pgcluter-002 
7  WARNING: Are you sure? (yes/no): yes  
8  deleted replica test-pgcluter-002

<左右滑動以查看完整代碼>

查看集羣的詳情:

9  [root@RDS pgo]# pgo -n pgouser2 show cluster test-pgcluter-002 
10  cluster : test-pgcluter-002 (crunchy-postgres-ha:centos7-12.3-4.3.2-0)  
11    pod : test-pgcluter-002-jcfm-6bfff77fcf-vxpn6 (Running) on k8s-node-vmr4ej-yn5hsstwuf (2/2) (primary)  
12    pvc : test-pgcluter-002-jcfm  
13    pod : test-pgcluter-002-tbrl-7d69bc5fb9-8xmx2 (Running) on k8s-node-vmwnpv-yn5hsstwuf (2/2) (replica)  
14    pvc : test-pgcluter-002-tbrl  
15    resources : Memory: 128Mi  
16    storage : Primary=20Gi Replica=20Gi  
17    deployment : test-pgcluter-002-backrest-shared-repo  
18    deployment : test-pgcluter-002-jcfm  
19    deployment : test-pgcluter-002-tbrl  
20    service : test-pgcluter-002 - ClusterIP (192.168.120.61)  
21    service : test-pgcluter-002-replica - ClusterIP (192.168.123.182)  
22  …

<左右滑動以查看完整代碼>

咱們不難發現,Pod:test-pgcluter-002 和其關聯的 PVC:test-pgcluter-002 已經被回收,兩個Service仍是保持在原來的狀態primary (192.168.120.61:5432)、replica (192.168.123.182:5432),對用戶數據面沒有影響。

經過pgo update cluster命令來修改集羣的cpu和memory資源。

1  [root@RDS pgo]# pgo -n pgouser2 update cluster test-pgcluter-002 --memory 256Mi --cpu 1 
2  Updating CPU resources can cause downtime.  
3  Updating memory resources can cause downtime.  
4  WARNING: Are you sure? (yes/no): yes  
5  updated pgcluster test-pgcluter-002  
6  
7  [root@RDS pgo]# pgo -n pgouser2 show cluster test-pgcluter-002 
8  
9  cluster : test-pgcluter-002 (crunchy-postgres-ha:centos7-12.3-4.3.2-0)  
10    pod : test-pgcluter-002-jcfm-54ff784874-jfwgk (Running) on k8s-node-vmr4ej-yn5hsstwuf (2/2) (replica)  
11    pvc : test-pgcluter-002-jcfm  
12    pod : test-pgcluter-002-tbrl-8695b6d956-j9pdv (Running) on k8s-node-vmwnpv-yn5hsstwuf (2/2) (primary)  
13    pvc : test-pgcluter-002-tbrl  
14    resources : CPU: 1 Memory: 256Mi

<左右滑動以查看完整代碼>

用戶在用pgo create cluster建立集羣的時候能夠經過參數--cpu ,--memory和--pvc-size來指定集羣所用的cpu,內存和存儲的大小,集羣建立完成之後,還能夠經過pgo update cluster命令來修改 cpu和memory資源配置,pvc大小的變動須要csi支持,如京東的chubaofs等。

出於安全的考慮,週期性的備份對於生產級別的數據庫服務來講是很是重要的,Crunchy PostgreSQL Operator提供了全量備份,差別備份,增量備份,週期性的備份和週期性的WAL文件歸檔。

備份策略定製:選擇備份的類型(全量,增量,差別備份)以及但願其在每一個PostgreSQL集羣上執行的頻率及時間點。

備份到S3:將您的備份存儲在任何支持S3協議的對象存儲系統中,Operator能夠從這些備份還原和建立新集羣。

示例:

建立用s3備份的cluster

1  pgo create cluster test-pgcluter-004 -n pgouser2 --pgbackrest-storage-type s3 --pgbackrest-s3-region cn-north-1 --pgbackrest-s3-endpoint s3.cn-north-1.jdcloud-oss.com --pgbackrest-s3-key 7FD8AC9D8XX --pgbackrest-s3-key-secret BE059515AXYX --pgbackrest-s3-bucket caas-test --replica-count 1 --metrics 
2  created cluster: test-pgcluter-004  
3  workflow id: 7c1ae19b-937d-441f-80ff-ff50ac8943b0  
4  database name: test-pgcluter-004  
5  users:  
6  username: testuser password: (Ev{k)VoEWStc8mWryL3r10

<左右滑動以查看完整代碼>

建立備份

7  [root@RDS pgo]# pgo -n pgouser2 backup test-pgcluter-004 --pgbackrest-storage-type s3 
8  created Pgtask backrest-backup-test-pgcluter-004

<左右滑動以查看完整代碼>

查看備份

9  [root@RDS pgo]# pgo -n pgouser2 show backup test-pgcluter-004 
10  cluster: test-pgcluter-004  
11  storage type: s3  
12  stanza: db  
13     status: ok  
14     cipher: none  
15     db (current)  
16         wal archive min/max (12-1)  
17         full backup: 20200710-022111F  
18             timestamp start/stop: 2020-07-10 10:21:11 +0800 CST / 2020-07-10 10:22:11 +0800 CST  
19             wal start/stop: 000000010000000000000002 / 000000010000000000000003  
20             database size: 31.1MiB, backup size: 31.1MiB  
21             repository size: 3.7MiB, repository backup size: 3.7MiB  
22             backup reference list:

<左右滑動以查看完整代碼>

週期備份設置

23  pgo create schedule --schedule="* * * * *" --schedule-type=pgbackrest --pgbackrest-backup-type=full test-pgcluter-004

<左右滑動以查看完整代碼>

使用簡單的pgo clone命令從現有集羣中建立新集羣。

經過命令pgo clone從源集羣test-pgcluter-007克隆建立新的集羣test-pgcluter-008,並打開監控。

1  [root@RDS pgo]# pgo -n pgouser2 clone test-pgcluter-007 test-pgcluter-008 --pgbackrest-storage-source s3 --enable-metrics 
2  Created clone task for:  test-pgcluter-008  
3  workflow id is  232b0c7b-fb13-451e-a65f-194ee3fe2413  
4

<左右滑動以查看完整代碼>

克隆過程當中的任務順序

5  [root@RDS pgo]# pgo -n pgouser2 show workflow 232b0c7b-fb13-451e-a65f-194ee3fe2413  
6  parameter           value  
7  ---------           -----  
8  clone 1.1: create pvc2020-07-10T06:33:59Z  
9  clone 1.2: sync pgbackrest repo2020-07-10T06:33:59Z  
10  clone 2: restoring backup2020-07-10T06:34:23Z  
11  clone 3: cluster creating2020-07-10T06:35:16Z  
12  pg-cluster          test-pgcluter-008  
13  task submitted      2020-07-10T06:33:59Z  
14  workflowid          232b0c7b-fb13-451e-a65f-194ee3fe2413  
15

<左右滑動以查看完整代碼>

克隆完成之後查看新的集羣test-pgcluter-008信息

16  [root@RDS pgo]# pgo -n pgouser2 show cluster test-pgcluter-008 
17  cluster : test-pgcluter-008 (crunchy-postgres-ha:centos7-12.3-4.3.2-0)  
18     pod : pgo-backrest-repo-sync-test-pgcluter-008-beje-b99pp (Succeeded) on k8s-node-vmj91e-yn5hsstwuf (0/1) (unknown)  
19     pvc : test-pgcluter-008-pgbr-repo  
20     pod : test-pgcluter-008-59cbf78584-cld7j (Running) on k8s-node-vm7sjf-yn5hsstwuf (2/2) (primary)  
21     pvc : test-pgcluter-008  
22     resources : Memory: 128Mi  
23     ...

<左右滑動以查看完整代碼>

不難從 show workflow的輸出中看到克隆大致流程:_先爲新集羣建立一個pvc,而後經過pgbackrest將老集羣的備份信息同步到新PVC中,再恢復增量WAL文件,最後用剛纔的PVC建立集羣。_

一個完備的系統少不了監控和告警,由Crunchy PostgreSQL Operator建立的PostgreSQL集羣能夠選擇經過Prometheus Exporters提供性能指標。指標收集器(metric exporter)包含在數據庫集羣的每一個Pod裏面,爲數據庫容器提供實時監控指標收集。爲了存儲和查看這些數據,還有須要使用Grafana和Prometheus兩個組件,用戶能夠經過最新版本的helm chart部署Operator項目自帶的Grafana和Prometheus組件。

Prometheus收集到的監控指標顯示以下:

示例圖片是集羣中WAL文件積壓空間的相關監控信息,圖片中階梯降低的線展現了集羣裏面wal文件由12GB左右的積壓數據,降到0GB的過程,期間PostgreSQL的archive commoand經過pgbackrest在週期性的作WAL文件歸檔操做,示例中WAL文件積壓消化的有點慢,能夠調整pgbackrest的並行度加速。更美觀更多維度的監控信息能夠經過Grafana展現,以下一小節所示。

Grafana監控指標信息顯示:

容器生成的日誌對於系統相當重要,由於它們提供了有關係統運行情況的詳細記錄。PostgreSQL日誌很是詳細,而且有些信息只能從日誌中獲取(但不只限於):

  • 用戶的鏈接和斷開。
  • 檢查點統計。
  • PostgreSQL服務器錯誤。

跨多個主機聚合容器日誌可以讓管理員很方便的審覈、調試問題並防止違規行爲。

本文首先探討了一下在Kubernetes上部署有狀態的服務的幾種可行方案,而後以開源社區的Crunchy PostgreSQL Operator爲例部署了一個基本功能相對完備的PostgreSQL雲服務。咱們能夠看到Operator屏蔽了複雜應用的編排細節,大大下降了它們在Kubernetes中的使用門檻,並且能作到對應用很是複雜而又精細的管理和控制,可以幫助開發人員實現全部主流雲廠商相同雲產品的同等功能。同時,藉助於強大的Kubernetes,系統更健壯、擴展更靈活方便,若是您有其它複雜應用須要部署,也建議採用Operator方式來部署。

參考資料

1.CrunchyData/postgres-operator:

https://github.com/CrunchyDat...

2.zalando/postgres-operator:

https://github.com/zalando/po...

3.Patroni組件:

https://github.com/zalando/pa...

4.K8s應用管理之道 - 有狀態服務:

https://developer.aliyun.com/...

5.Managing High Availability in PostgreSQL — Part 3  Patroni:

https://scalegrid.io/blog/man...

6.https://thenewstack.io/differ...

7.Databases on Kubernetes:

https://www.reddit.com/r/devo...

8.https://www.slideshare.net/jk...

9.https://www.slideshare.net/Al...

10.https://github.com/operator-f...

11.https://www.kubernetes.org.cn...

相關文章
相關標籤/搜索