雲原生 PostgreSQL – CrunchyData PGO 教程:創建、連接、刪除 Postgres 集群

  • 2022 年 2 月 25 日
  • 筆記

入門

作為安裝的一部分,請確保您已完成以下操作:

  1. 分叉 Postgres Operator 示例存儲庫並將其克隆到您的主機。
  2. PGO 安裝到 postgres-operator 命名空間。如果您位於 postgres-operator-examples 目錄中,則可以運行 kubectl apply -k kustomize/install 命令。
  3. 詳細安裝過程,請參閱:雲原生 PostgreSQL – CrunchyData PGO:5分鐘快速上手

在本教程中,我們將基於 kustomize/postgres 中提供的示例進行構建。

YAML 清單中引用嵌套對象時,我們將使用 . 格式類似於 kubectl explain。 例如,如果我們想引用這個 yaml 文件中最深的元素:

spec:
  hippos:
    appetite: huge

我們會說 spec.hippos.appetite

kubectl explain 是你的朋友。您可以使用 kubectl explain postgrescluster 來內省 postgrescluster.postgres-operator.crunchydata.com 自定義資源定義。您還可以查看 CRD reference

CRD

安裝好 PGO(Postgres Operator) 後,讓我們開始創建 Postgres 集群吧!

創建 Postgres 集群

創建 Postgres 集群非常簡單。使用 kustomize/postgres 目錄中的示例,我們所要做的就是運行:

kubectl apply -k kustomize/postgres

PGO 將在 postgres-operator 命名空間中創建一個名為 hippo 的簡單 Postgres 集群。 您可以使用 postgresclusters.postgres-operator.crunchydata.com 自定義資源上的 kubectl describe 跟蹤 Postgres 集群的狀態:

kubectl -n postgres-operator describe postgresclusters.postgres-operator.crunchydata.com hippo

您可以使用以下命令跟蹤 Postgres Pod 的狀態:

  --selector=postgres-operator.crunchydata.com/cluster=hippo,postgres-operator.crunchydata.com/instance

剛剛發生了什麼?

PGO 根據位於 kustomize/postgres 目錄中的 Kustomize 清單中提供的信息創建了一個 Postgres 集群。讓我們通過檢查 kustomize/postgres/postgres.yaml 文件更好地了解發生了什麼:

apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: hippo
spec:
  image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:centos8-13.5-0
  postgresVersion: 13
  instances:
    - name: instance1
      dataVolumeClaimSpec:
        accessModes:
        - "ReadWriteOnce"
        resources:
          requests:
            storage: 1Gi
  backups:
    pgbackrest:
      image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:centos8-2.36-0
      repos:
      - name: repo1
        volume:
          volumeClaimSpec:
            accessModes:
            - "ReadWriteOnce"
            resources:
              requests:
                storage: 1Gi

當我們之前運行 kubectl apply 命令時,我們所做的是在 Kubernetes 中創建一個 PostgresCluster 自定義資源。PGO 檢測到我們添加了一個新的 PostgresCluster 資源並開始創建在 Kubernetes 中運行 Postgres 所需的所有對象!

還發生了什麼?PGOmetadata.name 中讀取值,為 Postgres 集群提供名稱 hippo。此外,PGO 通過分別查看 spec.imagespec.backups.pgbackrest.image 中的值來知道哪些容器用於 PostgrespgBackRestspec.postgresVersion 中的值很重要,因為它將幫助 PGO 跟蹤您正在使用的 Postgres 的主要版本。

PGO 通過清單的 spec.instances 部分知道要創建多少個 Postgres 實例。 雖然名稱是可選的,但我們選擇將其命名為 instance1。 我們也可以在集群初始化期間創建多個副本和實例,但是當我們討論如何擴展和創建 HA Postgres 集群時,我們將介紹更多內容。

您的 PostgresCluster 自定義資源的一個非常重要的部分是 dataVolumeClaimSpec 部分。這描述了您的 Postgres 實例將使用的存儲。它以持久卷聲明為模型。如果您不提供 spec.instances.dataVolumeClaimSpec.storageClassName,則使用 Kubernetes 環境中的默認存儲類(storage class)

持久卷聲明

作為創建 Postgres 集群的一部分,我們還指定了有關備份存檔的信息。PGO 使用 pgBackRest,這是一種開源備份和恢復工具,旨在處理 TB 級備份。 作為初始化集群的一部分,我們可以指定我們希望備份和存檔(預寫日誌或 WAL)存儲的位置。我們將在本教程的災難恢復部分更深入地討論 PostgresCluster spec的這一部分,並了解我們如何將備份存儲在 Amazon S3Google GCSAzure Blob 存儲中。

連接到 Postgres 集群

創建 Postgres 集群是一回事;連接它是另一回事。讓我們來看看 PGO 是如何連接到 Postgres 集群的!

背後:Services, Secrets, 和 TLS

PGO 創建了一系列 Kubernetes 服務,以提供穩定的端點來連接您的 Postgres 數據庫。這些端點可以輕鬆地為您的應用程序提供一致的方式來保持與數據的連接。 要檢查哪些服務可用,您可以運行以下命令:

kubectl -n postgres-operator get svc --selector=postgres-operator.crunchydata.com/cluster=hippo

將產生類似於如下結果:

NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
hippo-ha          ClusterIP   10.103.73.92   <none>        5432/TCP   3h14m
hippo-ha-config   ClusterIP   None           <none>        <none>     3h14m
hippo-pods        ClusterIP   None           <none>        <none>     3h14m
hippo-primary     ClusterIP   None           <none>        5432/TCP   3h14m
hippo-replicas    ClusterIP   10.98.110.215  <none>        5432/TCP   3h14m

您無需擔心大多數這些服務,因為它們用於幫助管理 Postgres 集群的整體健康狀況。 為了連接到您的數據庫,感興趣的服務稱為 hippo-primary。 多虧了 PGO,您甚至不必擔心這一點,因為該信息是在 Secret 中捕獲的!

當您的 Postgres 集群初始化時,PGO 將引導您的應用程序可以訪問的數據庫和 Postgres 用戶。此信息存儲在以 <clusterName>-pguser-<userName> 模式命名的 Secret 中。對於我們的 hippo 集群,這個 Secret 稱為 hippo-pguser-hippo。 此 Secret 包含將應用程序連接到 Postgres 數據庫所需的信息:

  • user: 用戶帳戶的名稱。
  • password: 用戶帳戶的密碼。
  • dbname: 默認情況下用戶有權訪問的數據庫的名稱。
  • host: 數據庫主機的名稱。這引用了主 Postgres 實例的 Service
  • port: 數據庫正在偵聽的端口。
  • uri: 一個 PostgreSQL 連接 URI,它提供了登錄 Postgres 數據庫的所有信息。
  • jdbc-uri: 一個 PostgreSQL JDBC 連接 URI,它提供了通過 JDBC driver 登錄到 Postgres 數據庫的所有信息。

所有連接都通過 TLSPGO 提供自己的證書頒發機構 (CA) 以允許您將應用程序安全地連接到 Postgres 集群。這允許您使用 Postgresverify-full 「SSL mode」,它提供竊聽保護並防止 MITM 攻擊。 您還可以選擇帶上您自己的 CA,這將在本教程後面的「自定義集群」部分中進行描述。

verify-full 「SSL mode」

修改 Service Type

默認情況下,PGO 部署具有 ClusterIP Service type 的服務。 根據您想要公開數據庫的方式,您可能需要修改服務以使用不同的 Service type

Service type

您可以從以下屬性修改 PGO 管理的服務:

  • spec.service – 這管理用於連接到 Postgres 主服務器的 Service
  • spec.proxy.pgBouncer.service – 這管理用於連接到 PgBouncer 連接池的服務。

例如,要將 Postgres 主節點設置為使用 NodePort 服務,您可以在清單中添加以下內容:

spec:
  service:
    type: NodePort

對於我們的 hippo 集群,您將在。例如:

kubectl -n postgres-operator get svc --selector=postgres-operator.crunchydata.com/cluster=hippo

將產生類似於以下內容:

NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
hippo-ha          NodePort    10.96.17.210   <none>        5432:32751/TCP   2m37s
hippo-ha-config   ClusterIP   None           <none>        <none>           2m37s
hippo-pods        ClusterIP   None           <none>        <none>           2m37s
hippo-primary     ClusterIP   None           <none>        5432/TCP         2m37s
hippo-replicas    ClusterIP   10.96.151.53   <none>        5432/TCP         2m37s

(請注意,如果您在外部公開您的服務並依賴 TLS 驗證,您將需要使用 PGO自定義 TLS 功能)。

連接應用程序

對於本教程,我們將連接 Keycloak,一個開源身份管理應用程序。Keycloak 可以部署在 Kubernetes 上,並由 Postgres 數據庫提供支持。雖然我們在 Postgres Operator 示例存儲庫中提供了一個部署 KeycloakPostgresCluster 的示例,但下面的清單使用我們已經運行的 hippo 集群來部署它:

Keycloak

部署 KeycloakPostgresCluster 的示例

官方清單可能水土不服,請參閱:雲原生 PostgreSQL – CrunchyData PGO:5分鐘快速上手

kubectl apply --filename=- <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
  namespace: postgres-operator
  labels:
    app.kubernetes.io/name: keycloak
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: keycloak
  template:
    metadata:
      labels:
        app.kubernetes.io/name: keycloak
    spec:
      containers:
      - image: quay.io/keycloak/keycloak:latest
        name: keycloak
        env:
        - name: DB_VENDOR
          value: "postgres"
        - name: DB_ADDR
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: host } }
        - name: DB_PORT
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: port } }
        - name: DB_DATABASE
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: dbname } }
        - name: DB_USER
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: user } }
        - name: DB_PASSWORD
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: password } }
        - name: KEYCLOAK_USER
          value: "admin"
        - name: KEYCLOAK_PASSWORD
          value: "admin"
        - name: PROXY_ADDRESS_FORWARDING
          value: "true"
        ports:
        - name: http
          containerPort: 8080
        - name: https
          containerPort: 8443
        readinessProbe:
          httpGet:
            path: /auth/realms/master
            port: 8080
      restartPolicy: Always
EOF

注意清單的這一部分:

- name: DB_ADDR
  valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: host } }
- name: DB_PORT
  valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: port } }
- name: DB_DATABASE
  valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: dbname } }
- name: DB_USER
  valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: user } }
- name: DB_PASSWORD
  valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: password } }

上面的清單顯示了所有這些值是如何從 hippo-pguser-hippo Secret 派生的。 這意味着我們不需要知道任何連接憑據,也不需要不安全地傳遞它們 — 它們直接可供應用程序使用!

使用這種方法,您可以將應用程序直接綁定到連接到 PostgresGitOps 管道,而無需事先了解 PGO 將如何部署 Postgres:您的應用程序需要的所有信息都會傳播到 Secret

刪除 Postgres 集群

有時需要刪除您的集群。如果您一直遵循官方示例,您可以通過簡單地運行以下命令來刪除您的 Postgres 集群:

kubectl delete -k kustomize/postgres

PGO 將刪除與您的集群關聯的所有對象。

對於數據保留,這取決於您的 PVC 的保留策略。有關 Kubernetes 如何管理數據保留的更多信息,請參閱關於卷回收的 Kubernetes 文檔

PVC 的保留策略

公眾號:黑客下午茶