本文档介绍了在 Compute Engine 上使用 Red Hat OpenShift Container Platform 工作负载实现高可用性 (HA) 的最佳实践。本文档重点介绍了应用级策略,以帮助您确保在发生故障时,您的工作负载仍能保持高可用性。这些策略有助于您消除单点故障,并实现自动故障切换和恢复机制。
本文档适用于平台和应用架构师,并假定您具备一些部署 OpenShift 的经验。如需详细了解如何部署 OpenShift,请参阅 Red Hat 文档。
将部署分布在多个可用区
我们建议您在一个Google Cloud 区域内的多个可用区中部署 OpenShift。这种方法有助于确保,如果某个可用区发生服务中断,集群的控制平面节点可在部署分布的其他可用区中继续运行。如需在多个可用区中部署 OpenShift,请在 install-config.yaml
文件中指定来自同一区域的 Google Cloud 可用区列表。
如需对部署节点的位置进行精细控制,我们建议您定义虚拟机布置政策,以确保虚拟机分布在同一可用区中的不同故障域。将分散布置政策应用于集群节点有助于减少同时受到特定位置中断影响的节点数量。如需详细了解如何为现有集群创建分散政策,请参阅创建分散布置政策并将其应用于虚拟机。
同样,为了防止多个 Pod 被调度到同一节点上,我们建议您使用 Pod 反亲和性规则。这些规则可将应用副本分散到多个可用区。以下示例演示了如何实现 Pod 反亲和性规则:
apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: my-app-namespace spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: # Pod Anti-Affinity: Prefer to schedule new pods on nodes in different zones. affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: my-app topologyKey: topology.kubernetes.io/zone containers: - name: my-app-container image: quay.io/myorg/my-app:latest ports: - containerPort: 8080
对于无状态服务(例如,Web 前端或 REST API),我们建议您为每个服务或路由运行多个 Pod 副本。此方法可确保流量自动路由到可用可用区中的 Pod。
主动管理负载,以防止资源过度承诺
我们建议您主动管理应用的负载,以防止资源过度承诺。过度承诺可能会导致服务在负载下性能不佳。您可以通过设置资源请求限制来帮助防止过度承诺,如需查看更详细说明,请参阅管理 Pod 资源。此外,您还可以使用 Pod 横向自动扩缩器根据 CPU、内存或自定义指标来自动增加或减少副本。
我们还建议您使用以下负载均衡服务:
- OpenShift Ingress Operator。Ingress Operator 会部署基于 HAProxy 的 Ingress 控制器来处理通向 Pod 的路由。具体而言,我们建议您为 Ingress 控制器配置全球访问权限,以便使负载均衡器所在的 VPC 网络和区域中的任何区域内的客户端都能访问集群上运行的工作负载。此外,我们建议您实现 Ingress 控制器健康检查,以监控 Pod 的健康状况并重启失败的 Pod。
- Google Cloud 负载均衡。负载均衡会在Google Cloud 可用区之间分配流量。选择符合应用需求的负载均衡器。
定义 Pod 中断预算
我们建议您定义中断预算,以指定应用在发生中断(例如维护事件或更新)期间所需的 Pod 数量下限。以下示例展示了如何定义中断预算:
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb namespace: my-app-namespace spec: # Define how many pods need to remain available during a disruption. # At least one of "minAvailable" or "maxUnavailable" must be specified. minAvailable: 2 selector: matchLabels: app: my-app
如需了解详情,请参阅为应用指定中断预算。
使用支持高可用性和数据复制的存储
对于需要在容器外部进行永久性数据存储的有状态工作负载,我们建议遵循以下最佳实践。
磁盘最佳实践
如果您需要磁盘存储,请使用以下选项之一:
- 块存储:具有同步复制功能的 Compute Engine 区域级永久性磁盘
- 共享文件存储:启用了快照和备份的 Filestore
选择存储选项后,请在集群中安装其驱动程序:
CSI Persistent Disk Operator 提供了一个存储类别,您可以使用该存储类别来创建永久性卷声明 (PVC)。对于 Filestore,您必须创建 Filestore 存储类别。
数据库最佳实践
如果您需要数据库,请使用以下选项之一:
- 全托管式数据库:我们建议您使用 Cloud SQL 或 AlloyDB for PostgreSQL 来代您管理数据库高可用性。如果您使用 Cloud SQL,可以使用 Cloud SQL Proxy Operator 简化应用与数据库之间的连接管理。
- 自行管理的数据库:我们建议您使用支持高可用性的数据库,并部署其 Operator 以启用高可用性。如需了解详情,请参阅与您的数据库 Operator 相关的文档,例如 Redis Enterprise for Kubernetes、MariaDB Operator 或 CloudNative PostgreSQL Operator。
安装数据库 Operator 后,请配置包含多个实例的集群。以下示例展示了具有以下属性的集群的配置:
- 创建了一个名为
my-postgres-cluster
的 PostgreSQL 集群,其中包含三个实例,以实现高可用性。 - 集群使用
regionalpd-balanced
存储类别为跨可用区提供持久性和复制存储服务。 - 以用户
myuser
的身份初始化名为mydatabase
的数据库,其凭证存储在名为my-database-secret
的 Kubernetes Secret 中。 - 超级用户访问权限已停用,以提高安全性。
- 为集群启用了 Monitoring。
apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: my-postgres-cluster namespace: postgres-namespace spec: instances: 3 storage: size: 10Gi storageClass: regionalpd-balanced bootstrap: initdb: database: mydatabase owner: myuser secret: name: my-database-secret enableSuperuserAccess: false monitoring: enabled: true --- apiVersion: 1 kind: Secret metadata: name: my-database-secret namespace: postgres-namespace type: Opaque data: username: bXl1c2Vy # Base64-encoded value of "myuser" password: c2VjdXJlcGFzc3dvcmQ= # Base64-encoded value of "securepassword"
外部化应用状态
我们建议您将会话状态或缓存移至配置为在高可用性模式下运行的共享内存中存储区(例如 Redis)或永久性数据存储区(例如 Postgres、MySQL)。
最佳做法摘要
总而言之,请实施以下最佳实践,以便通过 OpenShift 实现高可用性:
- 将部署分布在多个可用区
- 主动管理负载,以防止资源过度承诺
- 定义 Pod 中断预算
- 使用高可用性数据复制功能
- 外部化应用状态