ITPub博客

首页 > 数据库 > SQL Server > 云原生在京东丨如何在Kubernetes上部署有状态的云原生应用?(下)

云原生在京东丨如何在Kubernetes上部署有状态的云原生应用?(下)

原创 SQL Server 作者:京东云技术新知 时间:2020-09-17 16:15:03 0 删除 编辑

点击阅读: 《如何在Kubernetes上部署有状态的云原生应用(上)》


下面我们将以最先进的开源数据库PostgreSQL为例,介绍如何在 Kubernetes 上部署运维有状态云服务(以下所有的操作都是基于Kubernetes 1.14及以上版本来完成的)。

 

Operator出来以前,即使有StatefulSet控制器,将PostgreSQL、MySQL等数据库部署到Kubernetes也是非常复杂的。两年前关于在Kubernetes上部署数据库还有过一场讨论,当时的普遍建议是不要在Kubernetes部署数据库。

 

关于这场讨论可以通过该链接查看:

https://www.reddit.com/r/devops/comments/8m1bp3/databases_on_kubernetes

 

通过StatefulSet在Kubernetes上部署高可用的MySQL服务请参考以下链接:

https://www.kubernetes.org.cn/3985.html


这个方法中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  id7c1ae19b -937d -441f -80ff-ff50ac8943b0  
4   database  nametest-pgcluter -004  
5   users:  
6  username: testuser  password: (Ev{k)VoEWStc8mW\ryL3r10  

<左右滑动以查看完整代码>


创建备份 

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  backup20200710-022111F  
18              timestamp  start/ stop2020-07-10  10: 21: 11 + 0800 CST /  2020-07-10  10: 22: 11 + 0800 CST  
19             wal  start/ stop000000010000000000000002 /  000000010000000000000003  
20              database  size31.1MiB,  backup  size31.1MiB  
21             repository  size3.7MiB, repository  backup  size3.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 232
b0c7b-fb13-451e-a65f-194ee3fe2413  

6   parameter            value  
7   ---------            -----  
8   clone 1 .1create  pvc2020-07-10T06:33:59Z  
9   clone 1 .2sync  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          232 b0c7b-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/CrunchyData/postgres-operator

2.zalando/postgres-operator:

https://github.com/zalando/postgres-operator

3.Patroni组件:

https://github.com/zalando/patroni

4.K8s应用管理之道 - 有状态服务:

https://developer.aliyun.com/article/689685spm=a2c6h.13262185.0.0.40eb6ca1qCAqyQ

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

https://scalegrid.io/blog/managing-high-availability-in-postgresql-part-3/

6.https://thenewstack.io/different-approaches-for-building-stateful-kubernetes-applications/

7.Databases on Kubernetes:

https://www.reddit.com/r/devops/comments/8m1bp3/databases_on_kubernetes 

8.https://www.slideshare.net/jkatz05/operating-postgresql-at-scale-with-kubernetes-137132067?from_action=save

9.https://www.slideshare.net/AlexanderKukushkin1/patroni-kubernetesnative-postgresql-companion

10.https://github.com/operator-framework/awesome-operators  

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



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69912185/viewspace-2721994/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-03-06

  • 博文量
    344
  • 访问量
    183242