操作指南:通过Rancher在K8S上运行PostgreSQL数据库

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 通过Rancher Kubernetes Engine运行高可用 PostgreSQL

通过Rancher Kubernetes Engine运行高可用 PostgreSQL

这篇是我们关于在Kubernetes上运行PostgreSQL系列文章的其中一篇。下面是相关文章和链接。

Rancher Kubernetes Engine (RKE)是一个轻量级的Kubernetes 安装程序,支持在裸金属和虚拟机上安装Kubernetes。RKE解决了Kubernetes安装的复杂性问题。通过RKE安装是比较简单的,而跟下层的操作系统无关。

Portworx是一个云原生的存储和数据管理平台,来支撑Kubernetes上持久性的工作负载。通过Portworx,用户能够管理不同基础架构上的、不同容器调度器上的数据库。它为所有的有状态服务(Stateful Service)提供了一个单一的数据管理层。

本文列出了操作步骤:通过RancherKubernetes Engine (RKE),在AWS的Kubernetes集群上,部署和管理高可用PostgreSQL集群。

总结来说,在Amazon上运行高可用PostgreSQL,需要:

  1. 通过Rancher KubernetesEngine安装一个Kubernetes集群
  2. 安装云原生存储解决方案Portworx,作为Kubernetes的一个DaemonSet。
  3. 建立一个存储类来定义你的存储要求,比如,复制因子,快照策略和性能情况
  4. 使用Kubernetes部署PostgreSQL
  5. 通过killing或者cordoning集群中的节点,来测试故障恢复
  6. 可能的话,动态的调整PG Volume的大小,快照和备份Postgres到S3

如何通过RKE来创建一个Kubernetes集群

RKE是一个安装和配置Kubernetes的工具。可以支持的环境包括裸金属,虚拟机或者IaaS。在本文中,我们会在AWS EC2上创建一个3节点的Kubernetes集群。

更为详细的步骤,可以参考这篇tutorial from The New Stack. (https://thenewstack.io/run-stateful-containerized-workloads-with-rancher-kubernetes-engine-and-portworx/

做完这些操作,我们会创建一个1 master 和 3 worker 节点的集群。

在Kubernetes上安装Portworx

在RKE的Kubernetes 上安装Portworx,跟在Kubernetes集群上通过Kops安装没什么不同。Portworx有详细的文档,列出每步的操作 (https://docs.portworx.com/portworx-install-with-kubernetes/cloud/aws/),来完成在AWS环境的Kubernetes上运行Portworx集群。

The New Stacktutorial(https://thenewstack.io/run-stateful-containerized-workloads-with-rancher-kubernetes-engine-and-portworx/) 也包含了在Kubernetes部署Portworx DaemonSet的所有操作步骤。

Kubernetes集群运行起来,Portworx安装和配置完成,我们就开始部署一个高可用的PostgreSQL数据库。

创建一个Postgres 存储类

通过存储类对象,一个Admin可以定义集群中不同的Portworx卷的类。这些类在动态的卷的部署过程中会被用到。存储类本身定义了复制因子,IO情况(例如数据库或者CMS),以及优先级(比如SSD或者HDD)。这些参数影响着工作负载的可用性和输出,因此参数可以被根据每个卷分别设置。这很重要,因为对生产系统的数据库的要求,跟研发测试系统是完全不一样的。

在下面的例子里,我们部署的存储类,它的复制因子是3,IO情况设定成“db”,优先级设定成“high”。这意味着存储会被优化为适合低传输速率的数据库负载(Postgres),并且自动的部署在集群具备最高性能的存储里。

$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/px-repl3-sc.yaml

storageclass "px-repl3-sc" created

创建一个Postgres PVC

我们现在可以基于存储类创建一个PersistentVolume Claim (PVC)。动态部署的优势就在于,claims能够在不需要显性部署持久卷Persistent Volume (PV)的情况下被创建。

$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/px-postgres-pvc.yaml

persistentvolumeclaim "px-postgres-pvc" created

PostgreSQL的密码会被创建成Secret。运行下面的命令来用正确的格式创建Secret。

$ echo postgres123 > password.txt
$ tr -d '\n' .strippedpassword.txt && mv .strippedpassword.txt password.txt
$ kubectl create secret generic postgres-pass --from-file=password.txt
secret "postgres-pass" created

在Kubernetes上部署PostgreSQL

最后,让我们创建一个PostgreSQL实例,作为一个Kubernetes部署对象。为了简单起见,我们只部署一个单独的Postgres Pod。因为Portworx提供同步复制来达到高可用。因此一个单独的Postgres实例,是Postgres数据库的最佳部署方式。Portworx也支持多节点的Postgres部署方式,看你的需要。

$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/postgres-app.yaml

deployment "postgres" created

确保Postgres的Pods是在运行的状态。

$ kubectl get pods -l app=postgres -o wide --watch

等候直到Postgres pod变成运行状态。

我们可以通过使用与PostgresPod一起运行的pxctl工具,来检查Portworx卷。

$ VOL=`kubectl get pvc | grep px-postgres-pvc | awk '{print $3}'`
$ PX_POD=$(kubectl get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}')
$ kubectl exec -it $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume inspect ${VOL}

命令的输出信息,确认了支撑PostgreSQL数据库实例的卷已经被创建完成了。

PostgreSQL的错误恢复

让我们为数据库填充5百万行的样例数据。

我们首先找到运行PostgreSQL的Pod,来访问shell。

$ POD=`kubectl get pods -l app=postgres | grep Running | grep 1/1 | awk '{print $1}'`
$ kubectl exec -it $POD bash

现在我们进入了Pod,我们能够连接到Postgres并且创建数据库。

# psql
pgbench=# create database pxdemo;
pgbench=# \l
pgbench=# \q

默认状态下,Pgbench会创建4张表:(pgbench_branches,pgbench_tellers,pgbench_accounts,pgbench_history),在主pgbench_accounts表里会有10万行。这样我们创建了一个简单的16MB大小的数据库。

使用-s选项, 我们可以增加在每张表中的行的数量。在上面的命令中,我们在“scaling”上填写了50,这样pgbench就会创建一个50倍默认大小的数据库。

我们的pgbench_accounts现在有5百万行了。这样我们的数据库变成了800MB (50*16MB)

# pgbench -i -s 50 pxdemo;

等待直到pgbench完成表的创建。我们接着来确认一下

pgbench_accounts现在有500万行的填充。

# psql pxdemo
\dt
select count(*) from pgbench_accounts;
\q
exit



现在,我们来模拟PostgreSQL正在运行的节点的失效,

$ NODE=`kubectl get pods -l app=postgres -o wide | grep -v NAME | awk '{print $7}'`
$ kubectl cordon ${NODE}

node "ip-172-20-57-55.ap-southeast-1.compute.internal" cordoned

执行kubectl get nods, 确认了其中一个节点的排程已经失效了。

$ kubectl get nodes

我们继续删除这个PostgreSQLpod。

$ POD=`kubectl get pods -l app=postgres -o wide | grep -v NAME | awk '{print $1}'`
$ kubectl delete pod ${POD}

pod "postgres-556994cbd4-b6ghn" deleted

一旦删除完成。Portworx STorageORchestrator for Kubernetes (STORK)(https://portworx.com/stork-storage-orchestration-kubernetes/),会把pod重置来创建有数据复制集的节点。

一旦Pod被删除,它会被重置到有数据复制集的节点上。Portworx STorageORchestrator for Kubernetes (STORK) (https://portworx.com/stork-storage-orchestration-kubernetes/)- Portworx的客户存储排程器,允许在数据所在节点上放置多个pod,并且确保正确的节点能够被选择来用来排程Pod。

让我们运行下面的命令验证一下。我们会发现一个新的pod被创建了,并且被排程在了一个不同的节点上。

$ kubectl get pods -l app=postgres

在这里插入图片描述

让我们把之前的节点重新部署回来。

$ kubectl uncordon ${NODE}

node "ip-172-20-57-55.ap-southeast-1.compute.internal" uncordoned

最后,我们验证一下数据仍然是可用的。

我们来看下容器里的pod名称和exec。

$ POD=`kubectl get pods -l app=postgres | grep Running | grep 1/1 | awk '{print $1}'`
$ kubectl exec -it $POD bash

现在用psql来确保我们的数据还在。

# psql pxdemo
pxdemo=# \dt
pxdemo=# select count(*) from pgbench_accounts;
pxdemo=# \q
pxdemo=# exit

我们看到数据库表都还在,并且所有的内容都是正确的。

在Postgres进行存储管理

测试了端到端的数据库错误恢复后,我们在Kubernetes集群上来运行StorageOps。

完全无停机下,扩充卷

我们现在来演示一下,在空间将满的情况下,如何简单的、动态的为卷添加空间。

在容器内打开一个shell,

$ POD=`kubectl get pods -l app=postgres | grep Running | awk '{print $1}'`
$ kubectl exec -it $POD bash

让我们来用pgbench来运行一个baseline transaction benchmark,它将尝试增加卷容量到1Gib,并且没能成功。

$ pgbench -c 10 -j 2 -t 10000 pxdemo
$ exit


在运行上面命令的时候,可能会有多种错误产生。第一个错误提示Pod已经没有空间了。

PANIC: could not write to file "pg_xlog/xlogtemp.73": No space left on device

Kubernetes并不支持在PVC创建后进行修改。我们在Portworx上用pxctl CLI工具来进行操作。

我们来获取卷的名称,用pxctl工具来查看。

SSH到节点里,运行下面的命令

POD=`/opt/pwx/bin/pxctl volume list --label pvc=px-postgres-pvc | grep -v ID | awk '{print $1}'`

$ /opt/pwx/bin/pxctl v i $POD

注意到卷还有10%就要满了。让我们用下面的命令来扩充。

$ /opt/pwx/bin/pxctl volume update $POD --size=2

Update Volume: Volume update successful for volume 834897770479704521

为卷做快照,并且恢复数据库

Portworx支持为Kubernetes PVCs创建快照。让我们为之前创建的Postgres PVC来创建一个快照。

$ kubectl create -f https://github.com/fmrtl73/katacoda-scenarios-1/raw/master/px-k8s-postgres-all-in-one/assets/px-snap.yaml

volumesnapshot "px-postgres-snapshot" created

可以通过下面的命令来看所有的快照。

$ kubectl get volumesnapshot,volumesnapshotdata


有了快照,我们来删掉数据库。

$ POD=`kubectl get pods -l app=postgres | grep Running | grep 1/1 | awk '{print $1}'`
$ kubectl exec -it $POD bash
$ psql
drop database pxdemo;
\l
\q
exit

快照就跟卷是一样的,我们可以使用它来创建一个新的PostgreSQL实例。让我们恢复快照数据,来创建一个新的PostgreSQL实例。

$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/px-snap-pvc.yaml

persistentvolumeclaim "px-postgres-snap-clone" created

从新的PVC,我们创建一个PostgreSQL Pod,

$ kubectl create -f https://raw.githubusercontent.com/fmrtl73/katacoda-scenarios-1/master/px-k8s-postgres-all-in-one/assets/postgres-app-restore.yaml

deployment "postgres-snap" created

确认这个pod是在运行状态。

$ kubectl get pods -l app=postgres-snap


最后,让我们访问由benchmark工具创建的数据。

$ POD=`kubectl get pods -l app=postgres-snap | grep Running | grep 1/1 | awk '{print $1}'`
$ kubectl exec -it $POD bash
$ psql pxdemo
\dt
select count(*) from pgbench_accounts;
\q
exit

我们发现表和数据都是正常的。如果我们想要在另一个Amazon区域创建一个容灾备份,我们可以把快照推送到Amazon S3。Portworx快照支持所有的S3兼容存储对象,所以备份也可以是其他的云或者是本地部署的数据中心。

_
小结
Portworx可以通过RKE很容易的部署,用来运行Kubernetes上生产系统中有状态的工作负载。通过跟STORK的整合,DevOps和StorageOps团队能够无缝的在Kubernetes上运行数据库集群。他们也可以为云原生应用运行传统的操作,比如扩充卷,快照,备份,容灾恢复。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
20天前
|
JSON Kubernetes Shell
【Azure K8S | AKS】在不丢失文件/不影响POD运行的情况下增加PVC的大小
【Azure K8S | AKS】在不丢失文件/不影响POD运行的情况下增加PVC的大小
|
23天前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
108 2
|
18天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~
|
22天前
|
关系型数据库 MySQL 数据库
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
|
19天前
|
人工智能 小程序 关系型数据库
【MySQL】黑悟空都掌握的技能,数据库隔离级别全攻略
本文以热门游戏《黑神话:悟空》为契机,深入浅出地解析了数据库事务的四种隔离级别:读未提交、读已提交、可重复读和串行化。通过具体示例,展示了不同隔离级别下的事务行为差异及可能遇到的问题,如脏读、不可重复读和幻读等。此外,还介绍了在MySQL中设置隔离级别的方法,包括全局和会话级别的调整,并通过实操演示了各隔离级别下的具体效果。本文旨在帮助开发者更好地理解和运用事务隔离级别,以提升数据库应用的一致性和性能。
96 2
【MySQL】黑悟空都掌握的技能,数据库隔离级别全攻略
|
11天前
|
关系型数据库 分布式数据库 数据库
开源云原生数据库PolarDB PostgreSQL 15兼容版本正式发布
PolarDB进行了深度的内核优化,从而实现以更低的成本提供商业数据库的性能。
|
21天前
|
SQL 关系型数据库 MySQL
【MySQL 慢查询秘籍】慢SQL无处遁形!实战指南:一步步教你揪出数据库性能杀手!
【8月更文挑战第24天】本文以教程形式深入探讨了MySQL慢SQL查询的分析与优化方法。首先介绍了如何配置MySQL以记录执行时间过长的SQL语句。接着,利用内置工具`mysqlslowlog`及第三方工具`pt-query-digest`对慢查询日志进行了详细分析。通过一个具体示例展示了可能导致性能瓶颈的查询,并提出了相应的优化策略,包括添加索引、缩小查询范围、使用`EXPLAIN`分析执行计划等。掌握这些技巧对于提升MySQL数据库性能具有重要意义。
50 1
|
23天前
|
关系型数据库 MySQL Linux
在Linux中,如何配置数据库服务器(如MySQL或PostgreSQL)?
在Linux中,如何配置数据库服务器(如MySQL或PostgreSQL)?
|
1天前
|
存储 缓存 关系型数据库
MySQL 视图:数据库中的灵活利器
视图是数据库中的虚拟表,由一个或多个表的数据经筛选、聚合等操作生成。它不实际存储数据,而是动态从基础表中获取。视图可简化数据访问、增强安全性、提供数据独立性、实现可重用性并提高性能,是管理数据库数据的有效工具。
|
2天前
|
SQL 关系型数据库 MySQL
MySQL技术安装配置、数据库与表的设计、数据操作解析
MySQL,作为最流行的关系型数据库管理系统之一,在WEB应用领域中占据着举足轻重的地位。本文将从MySQL的基本概念、安装配置、数据库与表的设计、数据操作解析,并通过具体的代码示例展示如何在实际项目中应用MySQL。
7 0