Men-deploy PostgreSQL ke GKE menggunakan CloudNativePG

Panduan ini menunjukkan cara men-deploy cluster PostgreSQL di Google Kubernetes Engine (GKE) menggunakan operator CloudNativePG.

PostgreSQL adalah database relasional objek open source dengan pengembangan aktif selama beberapa dekade, sehingga memastikan performa klien yang stabil. Layanan ini menawarkan berbagai fitur, termasuk replikasi, pemulihan point-in-time, fitur keamanan, dan kemampuan untuk diperluas. PostgreSQL kompatibel dengan sistem operasi utama dan sepenuhnya mematuhi standar ACID (Atomisitas, Konsistensi, Isolasi, Daya Tahan).

Panduan ini ditujukan untuk administrator platform, arsitek cloud, dan tenaga profesional operasi yang tertarik untuk men-deploy cluster Postgres di GKE. Menjalankan Postgres di GKE, bukan menggunakan Cloud SQL, dapat memberikan fleksibilitas dan kontrol konfigurasi yang lebih besar kepada administrator database berpengalaman.

Manfaat

CloudNativePG adalah operator open source yang dikembangkan oleh EDB berdasarkan lisensi Apache 2. Fitur ini menghadirkan fitur berikut pada deployment PostgreSQL:

  • Cara deklaratif dan berbasis Kubernetes untuk mengelola serta mengonfigurasi cluster PostgreSQL
  • Pengelolaan cadangan menggunakan snapshot volume atau Cloud Storage
  • Koneksi TLS terenkripsi saat transit, kemampuan untuk menggunakan certificate authority Anda sendiri, dan integrasi dengan Certificate Manager untuk penerbitan dan rotasi sertifikat TLS otomatis
  • Update bertahap untuk rilis minor PostgreSQL
  • Penggunaan server API Kubernetes untuk mempertahankan status cluster PostgreSQL dan failover untuk ketersediaan tinggi tanpa memerlukan alat tambahan
  • Konfigurasi eksportir Prometheus bawaan melalui metrik yang ditentukan pengguna dan ditulis dalam SQL

Menyiapkan lingkungan Anda

Untuk menyiapkan lingkungan Anda, ikuti langkah-langkah berikut:

  1. Menetapkan variabel lingkungan:

    export PROJECT_ID=PROJECT_ID
    export KUBERNETES_CLUSTER_PREFIX=postgres
    export REGION=us-central1
    

    Ganti PROJECT_ID dengan Google Cloud project ID Anda.

  2. Buat clone repositori GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. Ubah ke direktori kerja:

    cd kubernetes-engine-samples/databases/postgresql-cloudnativepg
    

Membuat infrastruktur cluster

Di bagian ini, Anda akan menjalankan skrip Terraform untuk membuat cluster GKE regional pribadi yang sangat tersedia.

Anda dapat menginstal operator menggunakan cluster Standard atau Autopilot.

Standar

Diagram berikut menunjukkan cluster GKE Standard regional pribadi yang di-deploy ke tiga zona yang berbeda:

Untuk men-deploy infrastruktur ini, jalankan perintah berikut:

export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply \
-var project_id=${PROJECT_ID}   \
-var region=${REGION}  \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}

Saat diminta, ketik yes. Anda mungkin perlu menunggu beberapa menit agar perintah ini selesai dan cluster akan menampilkan status siap.

Terraform membuat resource berikut:

  • Jaringan VPC dan subnet pribadi untuk node Kubernetes
  • Router untuk mengakses internet melalui NAT
  • Cluster GKE pribadi di region us-central1
  • Node pool dengan penskalaan otomatis diaktifkan (satu hingga dua node per zona, minimum satu node per zona)

Outputnya mirip dengan hal berikut ini:

...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
...

Autopilot

Diagram berikut menunjukkan cluster GKE Autopilot regional pribadi:

Untuk men-deploy infrastruktur, jalankan perintah berikut:

export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}

Saat diminta, ketik yes. Anda mungkin perlu menunggu beberapa menit agar perintah ini selesai dan cluster akan menampilkan status siap.

Terraform membuat resource berikut:

  • Jaringan VPC dan subnet pribadi untuk node Kubernetes
  • Router untuk mengakses internet melalui NAT
  • Cluster GKE pribadi di region us-central1
  • ServiceAccount dengan izin logging dan pemantauan
  • Google Cloud Managed Service for Prometheus untuk pemantauan cluster

Outputnya mirip dengan hal berikut ini:

...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
...

Hubungkan ke cluster

Konfigurasi kubectl untuk berkomunikasi dengan cluster:

gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${REGION}

Men-deploy operator CloudNativePG

Deploy CloudNativePG ke cluster Kubernetes Anda menggunakan diagram Helm:

  1. Tambahkan repositori Helm Chart operator CloudNativePG:

    helm repo add cnpg https://cloudnative-pg.github.io/charts
    
  2. Deploy operator CloudNativePG menggunakan alat command line Helm:

    helm upgrade --install cnpg \
        --namespace cnpg-system \
        --create-namespace \
        cnpg/cloudnative-pg
    

    Outputnya mirip dengan hal berikut ini:

    Release "cnpg" does not exist. Installing it now.
    NAME: cnpg
    LAST DEPLOYED: Fri Oct 13 13:52:36 2023
    NAMESPACE: cnpg-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    ...
    

Men-deploy Postgres

Manifes berikut menjelaskan cluster PostgreSQL seperti yang ditentukan oleh resource kustom operator CloudNativePG:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: gke-pg-cluster
spec:
  description: "Standard GKE PostgreSQL cluster"
  imageName: ghcr.io/cloudnative-pg/postgresql:16.2
  enableSuperuserAccess: true
  instances: 3
  startDelay: 300
  primaryUpdateStrategy: unsupervised
  postgresql:
    pg_hba:
      - host all all 10.48.0.0/20 md5
  bootstrap:
    initdb:
      database: app
  storage:
    storageClass: premium-rwo
    size: 2Gi
  resources:
    requests:
      memory: "1Gi"
      cpu: "1000m"
    limits:
      memory: "1Gi"
      cpu: "1000m"
  affinity:
    enablePodAntiAffinity: true
    tolerations:
    - key: cnpg.io/cluster
      effect: NoSchedule
      value: gke-pg-cluster
      operator: Equal
    additionalPodAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app.component
              operator: In
              values:
              - "pg-cluster"
          topologyKey: topology.kubernetes.io/zone
  monitoring:
    enablePodMonitor: true

Manifes ini memiliki kolom berikut:

  • spec.instances: jumlah Pod cluster
  • spec.primaryUpdateStrategy: strategi update bertahap:
    • Unsupervised: mengupdate node cluster utama secara mandiri setelah node replika
    • Supervised: pengalihan manual diperlukan untuk node cluster utama
  • spec.postgresql: Penggantian parameter file postgres.conf, seperti aturan pg-hba, LDAP, dan persyaratan agar replika sinkronisasi terpenuhi.
  • spec.storage: setelan terkait penyimpanan, seperti class penyimpanan, ukuran volume, dan setelan log tulis-dahulu.
  • spec.bootstrap: parameter database awal yang dibuat di cluster, kredensial pengguna, dan opsi pemulihan database
  • spec.resources: permintaan dan batas untuk Pod cluster
  • spec.affinity: aturan afinitas dan anti-afinitas workload cluster

Membuat cluster Postgres dasar

  1. Buat namespace

    kubectl create ns pg-ns
    
  2. Buat cluster PostgreSQL menggunakan resource kustom:

    kubectl apply -n pg-ns -f manifests/01-basic-cluster/postgreSQL_cluster.yaml
    

    Pemrosesan perintah ini mungkin membutuhkan waktu beberapa menit.

  3. Periksa status cluster:

    kubectl get cluster -n pg-ns --watch
    

    Tunggu hingga output menampilkan status Cluster in healthy state sebelum Anda melanjutkan ke langkah berikutnya.

    NAME             AGE     INSTANCES   READY   STATUS                     PRIMARY
    gke-pg-cluster   2m53s   3           3       Cluster in healthy state   gke-pg-cluster-1
    

Periksa resource

Konfirmasi bahwa GKE membuat resource untuk cluster:

kubectl get cluster,pod,svc,pvc,pdb,secret,cm -n pg-ns

Outputnya mirip dengan hal berikut ini:

NAME                                        AGE   INSTANCES   READY   STATUS                     PRIMARY
cluster.postgresql.cnpg.io/gke-pg-cluster   32m   3           3       Cluster in healthy state   gke-pg-cluster-1

NAME                   READY   STATUS    RESTARTS   AGE
pod/gke-pg-cluster-1   1/1     Running   0          31m
pod/gke-pg-cluster-2   1/1     Running   0          30m
pod/gke-pg-cluster-3   1/1     Running   0          29m

NAME                        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/gke-pg-cluster-r    ClusterIP   10.52.11.24   <none>        5432/TCP   32m
service/gke-pg-cluster-ro   ClusterIP   10.52.9.233   <none>        5432/TCP   32m
service/gke-pg-cluster-rw   ClusterIP   10.52.1.135   <none>        5432/TCP   32m

NAME                                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/gke-pg-cluster-1   Bound    pvc-bbdd1cdd-bdd9-4e7c-8f8c-1a14a87e5329   2Gi        RWO            standard       32m
persistentvolumeclaim/gke-pg-cluster-2   Bound    pvc-e7a8b4df-6a3e-43ce-beb0-b54ec1d24011   2Gi        RWO            standard       31m
persistentvolumeclaim/gke-pg-cluster-3   Bound    pvc-dac7f931-6ac5-425f-ac61-0cfc55aae72f   2Gi        RWO            standard       30m

NAME                                                MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
poddisruptionbudget.policy/gke-pg-cluster           1               N/A               1                     32m
poddisruptionbudget.policy/gke-pg-cluster-primary   1               N/A               0                     32m

NAME                                TYPE                       DATA   AGE
secret/gke-pg-cluster-app           kubernetes.io/basic-auth   3      32m
secret/gke-pg-cluster-ca            Opaque                     2      32m
secret/gke-pg-cluster-replication   kubernetes.io/tls          2      32m
secret/gke-pg-cluster-server        kubernetes.io/tls          2      32m
secret/gke-pg-cluster-superuser     kubernetes.io/basic-auth   3      32m

NAME                                DATA   AGE
configmap/cnpg-default-monitoring   1      32m
configmap/kube-root-ca.crt          1      135m

Operator membuat resource berikut:

  • Resource kustom cluster yang merepresentasikan cluster PostgreSQL yang dikontrol oleh operator
  • Resource PersistentVolumeClaim dengan Volume Persisten yang sesuai
  • Secret dengan kredensial pengguna untuk mengakses database dan replikasi antar-node Postgres.
  • Tiga layanan endpoint database: <name>-rw, <name>-ro, dan <name>-r untuk terhubung ke cluster. Untuk mengetahui informasi selengkapnya, lihat Arsitektur PostgreSQL.

Melakukan autentikasi ke Postgres

Anda dapat terhubung ke database PostgreSQL dan memeriksa akses melalui berbagai endpoint layanan yang dibuat oleh operator. Untuk melakukannya, Anda menggunakan Pod tambahan dengan klien PostgreSQL dan kredensial pengguna aplikasi yang disinkronkan yang di-mount sebagai variabel lingkungan.

  1. Jalankan Pod klien untuk berinteraksi dengan cluster Postgres Anda:

    kubectl apply -n pg-ns -f manifests/02-auth/pg-client.yaml
    
  2. Jalankan perintah exec di Pod pg-client dan login ke Layanan gke-pg-cluster-rw:

    kubectl wait --for=condition=Ready -n pg-ns pod/pg-client --timeout=300s
    kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
    
  3. Login ke database menggunakan Layanan gke-pg-cluster-rw untuk membuat koneksi dengan hak istimewa Baca-Tulis:

    psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app
    

    Terminal dimulai dengan nama database Anda:

    app=>
    
  4. Buat tabel:

    CREATE TABLE travel_agency_clients (
    client VARCHAR ( 50 ) UNIQUE NOT NULL,
    address VARCHAR ( 50 ) UNIQUE NOT NULL,
    phone VARCHAR ( 50 ) UNIQUE NOT NULL);
    
  5. Sisipkan data ke dalam tabel:

    INSERT INTO travel_agency_clients(client, address, phone)
    VALUES ('Tom', 'Warsaw', '+55555')
    RETURNING *;
    
  6. Melihat data yang Anda buat:

    SELECT * FROM travel_agency_clients ;
    

    Outputnya mirip dengan hal berikut ini:

    client | address |  phone
    --------+---------+---------
    Tom    | Warsaw  | +55555
    (1 row)
    
  7. Keluar dari sesi database saat ini:

    exit
    
  8. Login ke database menggunakan Layanan gke-pg-cluster-ro untuk memverifikasi akses hanya baca. Layanan ini mengizinkan kueri data, tetapi membatasi operasi tulis:

    psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-ro.pg-ns/app
    
  9. Mencoba memasukkan data baru:

    INSERT INTO travel_agency_clients(client, address, phone)
    VALUES ('John', 'Paris', '+55555')
    RETURNING *;
    

    Outputnya mirip dengan hal berikut ini:

    ERROR:  cannot execute INSERT in a read-only transaction
    
  10. Mencoba membaca data:

    SELECT * FROM travel_agency_clients ;
    

    Outputnya mirip dengan hal berikut ini:

    client | address |  phone
    --------+---------+---------
    Tom    | Warsaw  | +55555
    (1 row)
    
  11. Keluar dari sesi database saat ini:

    exit
    
  12. Keluar dari shell Pod:

    exit
    

Memahami cara Prometheus mengumpulkan metrik untuk cluster Postgres Anda

Diagram berikut menunjukkan cara kerja pengumpulan metrik Prometheus:

Dalam diagram, cluster pribadi GKE berisi:

  • Pod Postgres yang mengumpulkan metrik di jalur / dan port 9187
  • Pengumpul berbasis Prometheus yang memproses metrik dari Pod Postgres
  • Resource PodMonitoring yang mengirim metrik ke Cloud Monitoring

Untuk mengaktifkan pengumpulan metrik dari Pod Anda, lakukan langkah-langkah berikut:

  1. Buat resource PodMonitoring:

    kubectl apply -f manifests/03-observability/pod-monitoring.yaml -n pg-ns
    
  2. Di konsol Google Cloud , buka halaman Metrics explorer:

    Buka Metrics Explorer

    Dasbor menampilkan rasio penyerapan metrik bukan nol.

  3. Di Pilih metrik, masukkan Target Prometheus.

  4. Di bagian Active Metric Categories, pilih Cnpg.

Membuat dasbor metrik

Untuk memvisualisasikan metrik yang diekspor, buat dasbor metrik.

  1. Deploy dasbor:

    gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file manifests/03-observability/gcp-pg.json
    
  2. Di konsol Google Cloud , buka halaman Dashboards.

    Buka Dashboards

  3. Pilih dasbor PostgresQL Prometheus Overview.

    Untuk meninjau cara dasbor memantau fungsi, Anda dapat menggunakan kembali tindakan dari bagian Autentikasi database, dan menerapkan permintaan baca dan tulis di database, lalu meninjau visualisasi metrik yang dikumpulkan di dasbor.

  4. Hubungkan ke Pod klien:

    kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
    
  5. Menyisipkan data acak:

    psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);INSERT INTO test (randomdata) VALUES (generate_series(1, 1000));"
    
  6. Muat ulang dasbor. Grafik diperbarui dengan metrik yang diwujudkan.

  7. Keluar dari shell Pod:

    exit