使用 PGO 简化 Amazon EKS 上的 PostgreSQL 部署 - AWS Prescriptive Guidance

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

Shalaka Dengale,Amazon Web Services

摘要

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

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

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

  • 自定义资源定义(CRD):使用 Kubernetes 基元来管理 PostgreSQL。

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

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

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

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

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

先决条件和限制

先决条件

产品版本

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

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

限制

架构

目标技术堆栈

  • Amazon EKS

  • Amazon Virtual Private Cloud(Amazon VPC)

  • Amazon Elastic Compute Cloud(Amazon EC2)

目标架构

此架构用于使用具有三个可用区和两个副本、PgBouncer 和 PGO Operator 的 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 实例。当 Operator 运行时,您可以创建自定义资源(CR),以便为 PostgreSQL 实例指定所需的状态。这包括存储、复制和高可用性设置等配置。

  • Operator 管理。您可以通过 Kubernetes API 对象(例如 CR)与 Operator 进行交互,以便创建、更新或删除 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(IAM)角色(IRSA)、网络策略和 VPC 安全组。限制对 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 数据库选择合适的存储选项。使用 Amazon Elastic Block Store(Amazon EBS)卷,或者 AWS 托管式存储服务来进行持久存储。有关详情,请参阅 Amazon EKS 文档中的使用 Amazon EBS 存储 Kubernetes 卷

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

操作说明

任务说明所需技能

创建一个 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 管理员
任务说明所需技能

创建一个 Amazon EKS 集群。

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

注意

此模式将 Amazon 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 管理员
任务说明所需技能

启用 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 管理员
任务说明所需技能

克隆 PGO 存储库。

为 PGO 克隆 GitHub 存储库:

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

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

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

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 管理员

验证 PVC。

使用如下命令,验证持久卷声明(PVC):

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

创建一个 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 管理员
任务说明所需技能

向主副本写入数据。

使用以下命令,连接到 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,并确保正在将日志发送到 Amazon 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)。

相关资源