使用 PGO 简化 Amazon EKS 上的 PostgreSQL 部署 - AWS 规范指引

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 PGO 简化 Amazon EKS 上的 PostgreSQL 部署

Shalaka Dengale,Amazon Web Services

Summary

此模式会将来自 Crunchy Data 的 Postgres Operator(PGO)与 Amazon Elastic Kubernetes Service(Amazon EKS)集成在一起,以便简化云原生环境中的 PostgreSQL 部署。PGO 能够以自动化、可扩展的方式来管理 Kubernetes 中的 PostgreSQL 数据库。将 PGO 与 Amazon EKS 结合使用时,它将成为一个强大的平台,用于高效地部署、管理和扩展 PostgreSQL 数据库。

这一集成提供了下面这些主要优势:

  • 自动部署:简化 PostgreSQL 集群的部署和管理。

  • 自定义资源定义 (CRDs):使用 Kubernetes 原语进行 PostgreSQL 管理。

  • 高可用性:支持自动失效转移和同步复制。

  • 自动备份和恢复:简化备份和还原过程。

  • 水平扩展:为 PostgreSQL 集群启用动态扩展。

  • 版本升级:帮助进行滚动升级,并最大限度地减少停机时间。

  • 安全性:实施加密、访问控制和身份验证机制。

先决条件和限制

先决条件

产品版本

  • Kubernetes 版本 1.21 到 1.24 或更高版本(请参阅 PGO 文档)。

  • PostgreSQL 版本 10 或更高版本。此模式使用 PostgreSQL 版本 16。

限制

架构

目标技术堆栈

  • Amazon EKS

  • Amazon Virtual Private Cloud(Amazon VPC)

  • 亚马逊弹性计算云(亚马逊 EC2)

目标架构

使用具有三个可用区和两个副本的 PGO 的架构 PgBouncer,以及 PGO 操作员。

此模式将构建一个架构,其中包含一个具有三个节点的 Amazon EKS 集群。每个节点在后端的一组 EC2 实例上运行。此 PostgreSQL 设置遵循主副本架构,这对于需要执行大量读取操作的使用案例特别有效。此架构包括以下组件:

  • 主数据库容器(pg-primary)托管着主 PostgreSQL 实例,所有写入操作都将定向到此实例。

  • 辅助副本容器(pg-replica)托管着 PostgreSQL 实例,这些实例将从主数据库复制数据并处理读取操作。

  • PgBouncer是 PGO 中包含的 PostgreSQL 数据库的轻量级连接池器。它位于客户端与 PostgreSQL 服务器之间,并充当各个数据库连接的媒介。

  • 在此 Kubernetes 环境中,PGO 可以自动部署和管理 PostgreSQL 集群。

  • Patroni 是一款开源工具,负责管理和自动执行 PostgreSQL 的高可用性配置。它包含在 PGO 中。当在 Kubernetes 中将 Patroni 与 PGO 结合使用时,它将发挥至关重要的作用,确保 PostgreSQL 集群的弹性和容错能力。有关详情,请参阅 Patroni 文档

此工作流包含以下步骤:

  • 部署 PGO Operator。您需要将 PGO Operator 部署到 Amazon EKS 上运行的 Kubernetes 集群上。可以使用 Kubernetes 清单或 Helm 图表来完成此操作。此模式使用 Kubernetes 清单。

  • 定义 PostgreSQL 实例。当操作符运行时,您可以创建自定义资源 (CRs) 来指定 PostgreSQL 实例的所需状态。这包括存储、复制和高可用性设置等配置。

  • Operator 管理。您可以通过 Kubernetes API 对象与操作员进行交互,例如 CRs 创建、更新或删除 PostgreSQL 实例。

  • 监控和维护。您可以监控 Amazon EKS 上运行的 PostgreSQL 实例的运行状况和性能。Operator 通常会提供用于进行监控的指标和日志记录功能。您可以根据需要执行例行维护任务,例如升级和修补。有关详情,请参阅 Amazon EKS 文档中的监控集群性能和查看日志

  • 扩展和备份:您可以使用 Operator 提供的功能来扩展 PostgreSQL 实例以及管理备份。

此模式不包含监控、维护和备份操作。

自动化和扩展

  • 您可以使用自动 CloudFormation 创建基础架构。有关详情,请参阅 Amazon EKS 文档中的使用 CloudFormation创建 Amazon EKS 资源

  • 您可以使用 GitVersion 或 Jenkins 内部版本号来自动部署数据库实例。

工具

AWS 服务

其他工具

  • eksctl 是一款简单的命令行工具,用于在 Amazon EKS 上创建集群。

  • kubectl 是一个命令行实用程序,用于对 Kubernetes 集群运行命令。

  • PGO 会自动管理和扩展 Kubernetes 中的 PostgreSQL 数据库。

最佳实践

请遵循以下最佳实践,以便确保顺利、高效地进行部署:

  • 保护您的 EKS 集群。为您的 EKS 集群实施安全最佳实践,例如为服务账户 AWS Identity and Access Management (IRSA)、网络策略和 VPC 安全组使用 (IRSA) 角色。限制对 EKS 集群 API 服务器的访问,并使用 TLS 对节点与 API 服务器之间的通信进行加密。

  • 确保 Amazon EKS 上运行的 PGO 版本与 Kubernetes 版本兼容。有些 PGO 功能可能需要特定的 Kubernetes 版本,或者引入了兼容性限制。有关详情,请参阅 PGO 文档中的组件和兼容性

  • 为 PGO 部署规划资源分配,包括 CPU、内存和存储。考虑 PGO 以及它管理的 PostgreSQL 实例的资源需求。监控资源使用情况,并根据需要来扩展资源。

  • 专为高可用性而设计。设计您的 PGO 部署以便实现高可用性,从而最大限度地减少停机时间并确保可靠性。跨多个可用区部署 PGO 的多个副本,以便获得容错能力。

  • 为 PGO 管理的 PostgreSQL 数据库实施备份和还原程序。使用 PGO 提供的功能,或者使用与 Kubernetes 和 Amazon EKS 兼容的第三方备份解决方案。

  • 为 PGO 部署设置监控和日志记录,以便跟踪性能、运行状况和事件。使用 Prometheus 等工具来监控指标,并使用 Grafana 进行可视化。配置日志记录以便捕获 PGO 日志,从而进行问题排查和审核。

  • 正确配置网络,以便能够在 PGO、PostgreSQL 实例以及 Kubernetes 集群中的其他服务之间进行通信。使用 Amazon VPC 联网功能和 Kubernetes 联网插件(例如 Calico 或 Amazon VPC CNI)来实施网络策略和隔离流量。

  • 考虑性能、持久性和可扩展性等因素,为 PostgreSQL 数据库选择合适的存储选项。使用亚马逊 Elastic Block Store (Amazon EBS) 卷 AWS 或托管存储服务进行永久存储。有关详情,请参阅 Amazon EKS 文档中的使用 Amazon EBS 存储 Kubernetes 卷

  • 使用基础设施即代码 (IaC) 工具,例如 CloudFormation 在 Amazon EKS 上自动部署和配置 PGO。将基础设施组件(包括 EKS 集群、网络和 PGO 资源)定义为代码,以便实现一致性、可重复性和版本控制。

操作说明

Task说明所需技能

创建 IAM 角色。

  1. 在 AWS CLI中,使用如下命令创建一个 IAM 角色:

    aws iam create-role \ --role-name {YourRoleName} \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' && \ aws iam attach-role-policy \ --role-name {YourRoleName}\ --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy && \ aws iam attach-role-policy \ --role-name {YourRoleName}\ --policy-arn arn:aws:iam::aws:policy/AmazonEKSServicePolicy && \ aws iam attach-role-policy \ --role-name {YourRoleName}\ --policy-arn arn:aws:iam::aws:policy/CloudWatchFullAccess
  2. 在 AWS 管理控制台中,审核此角色:

    1. 打开 IAM 控制台

    2. 选择角色,然后搜索您创建的角色名称。

    3. 确认已经附加以下策略:

      AmazonEKSClusterPolicy

      AmazonEKSServicePolicy

      CloudWatchFullAccess

AWS 管理员
Task说明所需技能

创建一个 Amazon EKS 集群。

如果您已部署一个集群,请跳过此步骤。否则,请使用 eksctl Terraform 或在当前 AWS 账户 集群中部署 Amazon EKS 集群。 CloudFormation此模式使用 eksctl 来部署集群。

注意

此模式使用亚马逊 EC2 作为 Amazon EKS 的节点组。如果要使用 AWS Fargate,请参阅 eksctl 文档中的managedNodeGroups配置。

  1. 使用如下 eksctl 输入文件,生成此集群。

    sample-cluster.yaml:

    apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: postgresql region: us-east-1 version: "1.29" accessConfig: authenticationMode: API_AND_CONFIG_MAP availabilityZones: - us-east-1a - us-east-1b - us-east-1c nodeGroups: - name: ng-1 instanceType: m5.16xlarge desiredCapacity: 2 - name: ng-2 instanceType: m5.16xlarge desiredCapacity: 2 - name: ng-3 instanceType: m5.16xlarge desiredCapacity: 2 vpc: cidr: 192.168.0.0/16 clusterEndpoints: publicAccess: true nat: gateway: HighlyAvailable iamIdentityMappings: - arn: arn:aws:iam::<account-id>:role/<role-name> # update the IAM role ARN created in step 1 username: <user-name> # Enter the user name per your choice noDuplicateARNs: false
  2. 运行如下命令,创建此集群(为您的 sample-cluster.yaml 文件提供文件路径):

    eksctl create cluster -f sample-cluster.yaml
AWS 管理员、Terraform 或 eksctl 管理员、Kubernetes 管理员

验证此集群的状态。

运行如下命令,查看此集群中的节点的当前状态:

kubectl get nodes

如果遇到错误,请参阅 Amazon EKS 文档中的问题排查部分

AWS 管理员、Terraform 或 eksctl 管理员、Kubernetes 管理员
Task说明所需技能

启用 IAM OIDC 提供程序。

Amazon EBS Container Storage Interface(CSI)驱动程序的一个先决条件是,您的集群必须具有一个现有的 IAM OpenID Connect(OIDC)提供程序。

使用如下命令,启用 IAM OIDC 提供程序:

eksctl utils associate-iam-oidc-provider --region={region} --cluster={YourClusterNameHere} --approve

有关此步骤的详情,请参阅 Amazon EKS 文档

AWS 管理员

为 Amazon EBS CSI 驱动程序创建一个 IAM 角色。

使用如下 eksctl 命令,为 CSI 驱动程序创建 IAM 角色:

eksctl create iamserviceaccount \ --region {RegionName} \ --name ebs-csi-controller-sa \ --namespace kube-system \ --cluster {YourClusterNameHere} \ --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \ --approve \ --role-only \ --role-name AmazonEKS_EBS_CSI_DriverRole

如果使用加密的 Amazon EBS 驱动器,您必须进一步配置此策略。有关说明,请参阅 Amazon EBS SCI 驱动程序文档

AWS 管理员

添加 Amazon EBS CSI 驱动程序。

使用如下 eksctl 命令,添加 Amazon EBS CSI 驱动程序:

eksctl create addon \ --name aws-ebs-csi-driver \ --cluster <YourClusterName> service-account-role-arn arn:aws:iam::$(aws sts get-caller-identity \ --query Account \ --output text):role/AmazonEKS_EBS_CSI_DriverRole \ --force
AWS 管理员
Task说明所需技能

克隆 PGO 存储库。

克隆 PGO 的 GitHub 存储库:

git clone https://github.com/CrunchyData/postgres-operator-examples.git
AWS DevOps

提供用于创建服务账户的角色详细信息。

要授予 Amazon EKS 集群访问所需 AWS 资源的权限,请指定您之前在文件中创建的 OIDC 角色的亚马逊资源名称 (ARN)。service_account.yaml此文件位于存储库的命名空间文件夹中。

cd postgres-operator-examples
--- metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<accountId>:role/<role_name> # Update the OIDC role ARN created earlier
AWS 管理员、Kubernetes 管理员

创建此命名空间和 PGO 先决条件。

  1. 运行如下命令,创建此命名空间:

    kubectl apply -k kustomize/install/namespace

    这样将为 PGO 建立一个专用的命名空间。如果需要,您可以修改 namespace.yml 文件,并为此命名空间分配一个不同的名称。

  2. 运行如下命令,对此集群应用默认配置:

    kubectl apply --server-side -k kustomize/install/default

    kustomize/install/default 为 Kubernetes 基于角色的访问控制(RBAC)、自定义资源定义(CRD)和 Kubernetes Manager 文件提供了默认配置。

Kunernetes 管理员

确认已创建容器组(pod)。

确认已创建此命名空间和默认配置:

kubectl get pods -n postgres-operator
AWS 管理员、Kubernetes 管理员

验证 PVCs。

使用以下命令验证永久卷声明 (PVCs):

kubectl describe pvc -n postgres-operator
AWS 管理员、Kubernetes 管理员
Task说明所需技能

创建一个 Operator。

修改位于 /kustomize/postgres/postgres.yaml 的文件的内容,以便与以下内容相匹配:

spec: instances: - name: pg-1 replicas: 3 patroni: dynamicConfiguration: postgresql: pg_hba: - "host all all 0.0.0.0/0 trust" # this line enabled logical replication with programmatic access - "host all postgres 127.0.0.1/32 md5" synchronous_mode: true users: - name: replicator databases: - testdb options: "REPLICATION"

这些更新将执行以下操作:

  • 调整 PostgreSQL 配置设置,以方便访问 PostgreSQL 实例。

  • 包括面向复制用户、数据库用户和超级用户的配置,以便能够进行流式复制、数据库访问和集群管理。

AWS 管理员、数据库管理员、Kubernetes 管理员

部署此 Operator。

部署此 PGO Operator,以便能够简化 Kubernetes 环境中的 PostgreSQL 数据库的管理和操作:

kubectl apply -k kustomize/postgres
AWS 管理员、数据库管理员、Kubernetes 管理员

验证部署。

  1. 确认已经部署此 Operator:

    kubectl get pods -n postgres-operator --selector=postgres-operator.crunchydata.com/instance-set \ -L postgres-operator.crunchydata.com/role
  2. 确认已经创建与此 Operator 容器组(pod)相关联的服务资源:

    kubectl get svc -n postgres-operator

从命令输出中,记下主副本(primary_pod_name)和只读副本(read_pod_name)。您将在后续步骤中使用这些副本。

AWS 管理员、数据库管理员、Kubernetes 管理员
Task说明所需技能

向主副本写入数据。

使用以下命令,连接到 PostgreSQL 主副本,并向数据库写入数据:

kubectl exec -it <primary_pod_name> bash -n postgres-operator
psql
CREATE TABLE customers (firstname text, customer_id serial, date_created timestamp); \dt
AWS 管理员、Kubernetes 管理员

确认只读副本具有相同的数据。

连接到 PostgreSQL 只读副本,并检查流式复制功能是否正常运行:

kubectl exec -it {read_pod_name} bash -n postgres-operator
psql
\dt

只读副本应当具有您在上一步中在主副本中创建的表。

AWS 管理员、Kubernetes 管理员

问题排查

问题解决方案

容器组(pod)无法启动。

  • 使用如下命令,检查容器组(pod)状态:

    kubectl get pods -n your-namespace
  • 检查日志中是否存在任何错误:

    kubectl logs your-pod-name -n your-namespace
  • 检查容器组(pod)事件中是否存在与您的容器组(pod)相关联的任何异常事件:

    kubectl describe pod your-pod-name -n your-namespace

副本明显落后于主数据库。

  • 检查复制延迟:

    SELECT * FROM pg_stat_replication;
  • 确保副本具有足够的 CPU 和内存资源。检查资源限制:

    kubectl describe pod your-replica-pod -n your-namespace
  • 确认存储后端达到了最佳性能。磁盘速度慢 I/O 可能会导致复制延迟。

您无法了解 PostgreSQL 集群的性能和运行状况。

  • 启用 Amazon CloudWatch Logs 并确保将日志发送到亚马逊 CloudWatch 进行分析。有关详情,请参阅 Amazon EKS 文档

  • 请检查 pg_stat_activity

    SELECT * FROM pg_stat_activity;

复制功能无法正常工作。

  • postgresql.conf 中查看复制设置,以便检查主配置:

    wal_level = replica
    max_wal_senders = 10
    wal_keep_size = 64 # or wal_keep_segments in older versions
  • 确认 pg_hba.conf 中包含复制权限:

    host replication replica_user all md5
  • 检查副本配置。确保为副本正确设置了 recovery.conf 或等效设置(standby.signalprimary_conninfo)。

相关资源