在本文中,你将在 AKS 上部署高度可用的 PostgreSQL 数据库。
- 如果尚未为此部署创建所需的基础结构,请按照创建基础结构以在 AKS 上部署高度可用的 PostgreSQL 数据库中的步骤进行设置,然后可返回到本文。
重要
AKS 文档和示例中都提到了开源软件。 AKS 服务级别协议、有限保修和 Azure 支持不涵盖你部署的软件。 将开源技术与 AKS 一起使用时,请查阅相应社区和项目维护者提供的支持选项来制定计划。
例如,Ray GitHub 存储库描述了多个在响应时间、用途和支持级别方面各不相同的平台。
Microsoft 将负责生成我们在 AKS 上部署的开源包。 该责任包括对生成、扫描、签名、验证和修补过程拥有完整的所有权,以及对容器映像中的二进制文件的控制。 如需了解详细信息,请参阅 AKS 漏洞管理和 AKS 支持范围。
使用
kubectl create secret
命令为启动应用用户生成一个机密,通过交互式登录来验证 PostgreSQL 部署。PG_DATABASE_APPUSER_SECRET=$(echo -n | openssl rand -base64 16) kubectl create secret generic db-user-pass \ --from-literal=username=app \ --from-literal=password="${PG_DATABASE_APPUSER_SECRET}" \ --namespace $PG_NAMESPACE \ --context $AKS_PRIMARY_CLUSTER_NAME
使用
kubectl get
命令验证是否已成功创建机密。kubectl get secret db-user-pass --namespace $PG_NAMESPACE --context $AKS_PRIMARY_CLUSTER_NAME
部署 ConfigMap,使用以下
kubectl apply
命令为 PostgreSQL 群集设置环境变量:cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -f - apiVersion: v1 kind: ConfigMap metadata: name: cnpg-controller-manager-config data: ENABLE_AZURE_PVC_UPDATES: 'true' EOF
Prometheus 使用 CNPG GitHub 示例存储库中存储的一组默认记录规则为 CNPG 实例创建 PodMonitor。 在生产环境中,将根据需要修改这些规则。
使用
helm repo add
命令添加 Prometheus 社区 Helm 存储库。helm repo add prometheus-community \ https://prometheus-community.github.io/helm-charts
升级 Prometheus 社区 Helm 存储库,并使用带有
helm upgrade
标志的--install
命令在主群集上安装它。helm upgrade --install \ --namespace $PG_NAMESPACE \ -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/docs/src/samples/monitoring/kube-stack-config.yaml \ prometheus-community \ prometheus-community/kube-prometheus-stack \ --kube-context=$AKS_PRIMARY_CLUSTER_NAME
在本部分,你将创建 PostgreSQL 备份的联合标识凭据,以允许 CNPG 使用 AKS 工作负载标识向存储帐户目标进行身份验证来进行备份。 CNPG 运算符会创建一个与 CNPG 群集部署清单中使用的群集同名的 Kubernetes 服务帐户。
使用
az aks show
命令获取群集 OIDC 颁发者 URL。export AKS_PRIMARY_CLUSTER_OIDC_ISSUER="$(az aks show \ --name $AKS_PRIMARY_CLUSTER_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --query "oidcIssuerProfile.issuerUrl" \ --output tsv)"
使用
az identity federated-credential create
命令创建联合标识凭据。az identity federated-credential create \ --name $AKS_PRIMARY_CLUSTER_FED_CREDENTIAL_NAME \ --identity-name $AKS_UAMI_CLUSTER_IDENTITY_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --issuer "${AKS_PRIMARY_CLUSTER_OIDC_ISSUER}" \ --subject system:serviceaccount:"${PG_NAMESPACE}":"${PG_PRIMARY_CLUSTER_NAME}" \ --audience api://AzureADTokenExchange
在本部分,你将使用 CNPG 群集自定义资源定义 (CRD) 部署高度可用的 PostgreSQL 群集。
下表概述了在群集 CRD 的 YAML 部署清单中设置的关键属性:
properties | 定义 |
---|---|
inheritedMetadata |
特定于 CNPG 运算符。 元数据由与群集相关的所有对象继承。 |
annotations: service.beta.kubernetes.io/azure-dns-label-name |
公开读写和只读 Postgres 群集终结点时要使用的 DNS 标签。 |
labels: azure.workload.identity/use: "true" |
指示 AKS 应将工作负载标识依赖项注入托管 PostgreSQL 群集实例的 Pod。 |
topologySpreadConstraints |
需要不同的区域和具有 "workload=postgres" 标签的不同节点。 |
resources |
配置服务质量 (QoS) 类 Guaranteed。 在生产环境中,这些值是最大限度使用基础节点 VM 的关键,根据所使用的 Azure VM SKU 而有所不同。 |
bootstrap |
特定于 CNPG 运算符。 使用空的应用数据库进行初始化。 |
storage / walStorage |
特定于 CNPG 运算符。 为数据和日志存储的 PersistentVolumeClaim (PVC) 定义存储模板。 还可以为表空间指定存储来进行分片,以增加 IOPs。 |
replicationSlots |
特定于 CNPG 运算符。 启用复制槽来实现高可用性。 |
postgresql |
特定于 CNPG 运算符。 映射 postgresql.conf 、pg_hba.conf 和 pg_ident.conf config 的设置。 |
serviceAccountTemplate |
包含生成服务帐户所需的模板,并将 AKS 联合标识凭据映射到 UAMI,从而能够从托管 PostgreSQL 实例的 Pod 进行 AKS 工作负载标识身份验证来访问外部 Azure 资源。 |
barmanObjectStore |
特定于 CNPG 运算符。 使用 AKS 工作负载标识配置 barman-cloud 工具套件,以便向 Azure Blob 存储对象存储进行身份验证。 |
PostgreSQL 性能在很大程度上取决于群集的基础资源。 下表提供了有关如何计算高性能的关键参数的一些建议:
properties | 建议的值 | 定义 |
---|---|---|
wal_compression |
lz4 | 使用指定方法压缩 WAL 文件中的整页写入 |
max_wal_size |
6GB | 设置触发检查点的 WAL 大小 |
checkpoint_timeout |
15 分钟 | 在自动 WAL 检查点之间设置最长时间 |
checkpoint_flush_after |
2MB(兆字节) | 在将以前执行的写入刷新到磁盘之前所要达到的页数 |
wal_writer_flush_after |
2MB(兆字节) | WAL 写入器写出的 WAL 数量,达到该数量将触发刷新 |
min_wal_size |
4GB | 设置要将 WAL 收缩到的最小大小 |
shared_buffers |
25% 的节点内存 | 设置服务器使用的共享内存缓冲区数 |
effective_cache_size |
75% 的节点内存 | 设置规划器关于数据缓存总大小的假设 |
work_mem |
1/256 的节点内存 | 设置要用于查询工作区的最大内存 |
maintenance_work_mem |
6.25% 的节点内存 | 设置用于维护操作的最大内存 |
autovacuum_vacuum_cost_limit |
2400 | autovacuum 在短暂睡眠之前可用的清空成本量 |
random_page_cost |
1.1 | 设置规划器对不按顺序提取磁盘页的成本估计值 |
effective_io_concurrency |
64 | 磁盘子系统可有效处理的同时请求数 |
maintenance_io_concurrency |
64 | 用于维护工作的“effective_io_concurrency”变体 |
使用
kubectl apply
命令通过群集 CRD 部署 PostgreSQL 群集。cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -v 9 -f - apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: $PG_PRIMARY_CLUSTER_NAME spec: inheritedMetadata: annotations: service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX labels: azure.workload.identity/use: "true" instances: 3 startDelay: 30 stopDelay: 30 minSyncReplicas: 1 maxSyncReplicas: 1 replicationSlots: highAvailability: enabled: true updateInterval: 30 topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: cnpg.io/cluster: $PG_PRIMARY_CLUSTER_NAME affinity: nodeSelector: workload: postgres resources: requests: memory: '8Gi' cpu: 2 limits: memory: '8Gi' cpu: 2 bootstrap: initdb: database: appdb owner: app secret: name: db-user-pass dataChecksums: true storage: size: 32Gi pvcTemplate: accessModes: - ReadWriteOnce resources: requests: storage: 32Gi storageClassName: $POSTGRES_STORAGE_CLASS walStorage: size: 32Gi pvcTemplate: accessModes: - ReadWriteOnce resources: requests: storage: 32Gi storageClassName: $POSTGRES_STORAGE_CLASS monitoring: enablePodMonitor: true postgresql: parameters: wal_compression: lz4 max_wal_size: 6GB checkpoint_timeout: 15min checkpoint_flush_after: 2MB wal_writer_flush_after: 2MB min_wal_size: 4GB shared_buffers: 4GB effective_cache_size: 12GB work_mem: 62MB maintenance_work_mem: 1GB autovacuum_vacuum_cost_limit: "2400" random_page_cost: "1.1" effective_io_concurrency: "64" maintenance_io_concurrency: "64" pg_hba: - host all all all scram-sha-256 serviceAccountTemplate: metadata: annotations: azure.workload.identity/client-id: "$AKS_UAMI_WORKLOAD_CLIENTID" labels: azure.workload.identity/use: "true" backup: barmanObjectStore: destinationPath: "https://${PG_PRIMARY_STORAGE_ACCOUNT_NAME}.blob.core.chinacloudapi.cn/backups" azureCredentials: inheritFromAzureAD: true retentionPolicy: '7d' EOF
使用
kubectl get
命令验证是否已成功创建主要 PostgreSQL 群集。 CNPG 群集 CRD 指定了三个实例,可以在启动并加入每个实例进行复制后查看正在运行的 Pod 来验证。 请耐心等待,因为所有三个实例需要一些时间才能联机并加入群集。kubectl get pods --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME
示例输出
NAME READY STATUS RESTARTS AGE pg-primary-cnpg-r8c7unrw-1 1/1 Running 0 4m25s pg-primary-cnpg-r8c7unrw-2 1/1 Running 0 3m33s pg-primary-cnpg-r8c7unrw-3 1/1 Running 0 2m49s
CNPG 运算符使用在 Prometheus 社区安装期间创建的记录规则自动为主实例创建 PodMonitor。
使用
kubectl get
命令验证 PodMonitor 是否正在运行。kubectl --namespace $PG_NAMESPACE \ --context $AKS_PRIMARY_CLUSTER_NAME \ get podmonitors.monitoring.coreos.com \ $PG_PRIMARY_CLUSTER_NAME \ --output yaml
示例输出
kind: PodMonitor metadata: annotations: cnpg.io/operatorVersion: 1.23.1 ...
如果使用适用于托管 Prometheus 的 Azure Monitor,需要使用自定义组名再添加一个 Pod 监视器。 托管 Prometheus 不会从 Prometheus 社区获取自定义资源定义 (CRD)。 除了组名外,CRD 是相同的。 这使得托管 Prometheus 的 Pod 监视器能够与使用社区 Pod 监视器的项并排存在。 如果没有使用托管 Prometheus,可跳过此操作。 创建新的 Pod 监视器:
cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -f -
apiVersion: azmonitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: cnpg-cluster-metrics-managed-prometheus
namespace: ${PG_NAMESPACE}
labels:
azure.workload.identity/use: "true"
cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME}
spec:
selector:
matchLabels:
azure.workload.identity/use: "true"
cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME}
podMetricsEndpoints:
- port: metrics
EOF
验证是否已创建 Pod 监视器(请注意组名的差异)。
kubectl --namespace $PG_NAMESPACE \
--context $AKS_PRIMARY_CLUSTER_NAME \
get podmonitors.azmonitoring.coreos.com \
-l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME \
-o yaml
部署 Postgres 群集和 Pod 监视器后,可以在 Azure Monitor 工作区中使用 Azure 门户查看指标。
或者,部署 Postgres 群集和 Pod 监视器后,可以在部署脚本创建的托管 Grafana 实例上创建指标仪表板,可视化导出到 Azure Monitor 工作区的指标。 可以通过 Azure 门户访问托管 Grafana。 导航到部署脚本创建的托管 Grafana 实例,然后单击“终结点”链接,如下所示:
单击“终结点”链接会打开新的浏览器窗口,可在这里创建关于托管 Grafana 实例的仪表板。 按照说明配置 Azure Monitor 数据源,然后就可添加可视化效果,创建 Postgres 群集指标仪表板。 设置数据源连接后,在主菜单中单击“数据源”选项,你应该会看到一组用于数据源连接的数据源选项,如下所示:
在“托管 Prometheus”选项上,单击生成仪表板的选项以打开仪表板编辑器。 编辑器窗口打开后,单击“添加可视化效果”选项,然后单击“托管 Prometheus”选项,浏览来自 Postgres 群集的指标。 选择要可视化的指标后,单击“运行查询”按钮来提取数据进行可视化,如下所示:
单击“保存”按钮,将面板添加到仪表板。 可以单击仪表板编辑器中的“添加”按钮来添加其他面板,并重复此过程来可视化其他指标。 添加指标可视化效果后,应会显示如下所示的内容:
单击“保存”图标以保存仪表板。
Microsoft 会维护本文。 本系列文章为以下参与者的原创作品:
- Ken Kilty | 首席 TPM
- Russell de Pina | 首席 TPM
- Adrian Joian | 高级客户工程师
- Jenny Hayes | 高级内容开发人员
- Carol Smith | 高级内容开发人员
- Erin Schaffer | 内容开发人员 2
- Adam Sharif | 客户工程师 2