Men-deploy database vektor PostgreSQL di GKE


Tutorial ini menunjukkan cara men-deploy cluster database vektor PostgreSQL di Google Kubernetes Engine (GKE).

PostgreSQL dilengkapi dengan berbagai modul dan ekstensi yang memperluas fungsi database. Dalam tutorial ini, Anda akan menginstal ekstensi pgvector pada cluster PostgreSQL yang ada yang di-deploy ke GKE. Dengan ekstensi Pgvector, Anda dapat menyimpan vektor dalam tabel database dengan menambahkan jenis vektor ke PostgreSQL. Pgvector juga menyediakan penelusuran kesamaan dengan menjalankan kueri SQL umum.

Kami menyederhanakan deployment ekstensi PGvector dengan men-deploy operator CloudnativePG terlebih dahulu, karena operator menyediakan versi ekstensi yang dipaketkan.

Tutorial ini ditujukan untuk administrator dan arsitek platform cloud, engineer ML, serta profesional MLOps (DevOps) yang tertarik untuk men-deploy cluster database PostgreSQL di GKE.

Tujuan

Dalam tutorial ini, Anda akan mempelajari cara:

  • Men-deploy infrastruktur GKE untuk PostgreSQL.
  • Instal ekstensi pgvector di cluster PostgreSQL yang di-deploy ke GKE.
  • Men-deploy dan mengonfigurasi operator PostgreSQL CloudNativePG dengan Helm.
  • Unggah {i>dataset<i} demo dan jalankan kueri penelusuran dengan Jupyter Notebook.

Biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.

Sebelum memulai

Dalam tutorial ini, Anda menggunakan Cloud Shell untuk menjalankan perintah. Cloud Shell adalah lingkungan shell untuk mengelola resource yang dihosting di Google Cloud. Library ini dilengkapi dengan alat command line Google Cloud CLI, kubectl, Helm, dan Terraform. Jika tidak menggunakan Cloud Shell, Anda harus menginstal Google Cloud CLI.

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Menginstal Google Cloud CLI.
  3. Untuk initialize gcloud CLI, jalankan perintah berikut:

    gcloud init
  4. Buat atau pilih project Google Cloud.

    • Membuat project Google Cloud:

      gcloud projects create PROJECT_ID

      Ganti PROJECT_ID dengan nama untuk project Google Cloud yang Anda buat.

    • Pilih project Google Cloud yang Anda buat:

      gcloud config set project PROJECT_ID

      Ganti PROJECT_ID dengan nama project Google Cloud Anda.

  5. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  6. Aktifkan API Cloud Resource Manager, Compute Engine, GKE, and IAM Service Account Credentials:

    gcloud services enable cloudresourcemanager.googleapis.com compute.googleapis.com container.googleapis.com iamcredentials.googleapis.com
  7. Menginstal Google Cloud CLI.
  8. Untuk initialize gcloud CLI, jalankan perintah berikut:

    gcloud init
  9. Buat atau pilih project Google Cloud.

    • Membuat project Google Cloud:

      gcloud projects create PROJECT_ID

      Ganti PROJECT_ID dengan nama untuk project Google Cloud yang Anda buat.

    • Pilih project Google Cloud yang Anda buat:

      gcloud config set project PROJECT_ID

      Ganti PROJECT_ID dengan nama project Google Cloud Anda.

  10. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  11. Aktifkan API Cloud Resource Manager, Compute Engine, GKE, and IAM Service Account Credentials:

    gcloud services enable cloudresourcemanager.googleapis.com compute.googleapis.com container.googleapis.com iamcredentials.googleapis.com
  12. Berikan peran ke Akun Google Anda. Jalankan perintah berikut satu kali untuk setiap peran IAM berikut: roles/compute.securityAdmin, roles/compute.viewer, roles/container.clusterAdmin, roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUser

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • Ganti PROJECT_ID dengan project ID Anda.
    • Ganti EMAIL_ADDRESS dengan alamat email Anda.
    • Ganti ROLE dengan setiap peran individual.

Menyiapkan lingkungan Anda

Untuk menyiapkan lingkungan Anda dengan Cloud Shell, ikuti langkah-langkah berikut:

  1. Tetapkan variabel lingkungan untuk project, region, dan awalan resource cluster Kubernetes Anda:

    export PROJECT_ID=PROJECT_ID
    export KUBERNETES_CLUSTER_PREFIX=postgres
    export REGION=us-central1
    
    • Ganti PROJECT_ID dengan project ID Google Cloud Anda.

    Tutorial ini menggunakan region us-central1.

  2. Clone repositori kode contoh dari GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. Buka direktori postgres-pgvector:

    cd kubernetes-engine-samples/databases/postgres-pgvector
    

Membuat infrastruktur cluster

Di bagian ini, Anda akan menjalankan skrip Terraform untuk membuat cluster GKE regional pribadi yang sangat tersedia untuk men-deploy database PostgreSQL Anda.

Anda dapat memilih untuk men-deploy PostgreSQL menggunakan cluster Standar atau Autopilot. Masing-masing memiliki keunggulan dan model penetapan harga yang berbeda.

Autopilot

Untuk men-deploy infrastruktur cluster Autopilot, jalankan perintah berikut di Cloud Shell:

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

GKE mengganti variabel berikut pada runtime:

  • GOOGLE_OAUTH_ACCESS_TOKEN menggunakan perintah gcloud auth print-access-token untuk mengambil token akses yang mengautentikasi interaksi dengan berbagai Google Cloud API
  • PROJECT_ID, REGION, dan KUBERNETES_CLUSTER_PREFIX adalah variabel lingkungan yang ditentukan di bagian Menyiapkan lingkungan Anda dan ditetapkan ke variabel baru yang relevan untuk cluster Autopilot yang Anda buat.

Saat diminta, ketik yes.

Terraform membuat resource berikut:

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

Outputnya mirip dengan hal berikut ini:

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

Standar

Untuk men-deploy infrastruktur cluster Standar, jalankan perintah berikut di Cloud Shell:

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

GKE mengganti variabel berikut pada runtime:

  • GOOGLE_OAUTH_ACCESS_TOKEN menggunakan perintah gcloud auth print-access-token untuk mengambil token akses yang mengautentikasi interaksi dengan berbagai Google Cloud API.
  • PROJECT_ID, REGION, dan KUBERNETES_CLUSTER_PREFIX adalah variabel lingkungan yang ditentukan di bagian Menyiapkan lingkungan Anda dan ditetapkan ke variabel baru yang relevan untuk cluster Standar yang Anda buat.

Saat diminta, ketik yes. Mungkin perlu waktu beberapa menit untuk menyelesaikan perintah ini dan cluster akan menampilkan status siap.

Terraform membuat resource berikut:

  • Jaringan VPC kustom dan subnet pribadi untuk node Kubernetes.
  • Cloud Router untuk mengakses internet melalui Penafsiran Alamat Jaringan (NAT).
  • Cluster GKE pribadi di region us-central1 dengan penskalaan otomatis yang diaktifkan (satu hingga dua node per zona).
  • ServiceAccount dengan izin logging dan pemantauan untuk cluster.
  • Konfigurasi Google Cloud Managed Service for Prometheus untuk pemantauan dan pemberitahuan cluster.

Outputnya mirip dengan hal berikut ini:

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

Hubungkan ke cluster

Konfigurasikan kubectl untuk mengambil kredensial dan berkomunikasi dengan cluster GKE baru:

gcloud container clusters get-credentials \
    ${KUBERNETES_CLUSTER_PREFIX}-cluster --region ${REGION} --project ${PROJECT_ID}

Men-deploy operator CloudNativePG

Men-deploy CloudNativePG ke cluster Kubernetes Anda menggunakan chart Helm:

  1. Periksa versi Helm:

    helm version
    

    Update versi jika lebih lama dari 3.13:

    curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
    
  2. Tambahkan repositori Helm Chart operator CloudNativePG:

    helm repo add cnpg https://cloudnative-pg.github.io/charts
    
  3. 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 database vektor PostgreSQL

Di bagian ini, Anda akan men-deploy database vektor PostgreSQL.

  1. Buat pg-ns namespace untuk database:

    kubectl create ns pg-ns
    
  2. Terapkan manifes untuk men-deploy cluster PostgreSQL. Manifes cluster mengaktifkan ekstensi pgvector.

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

    Manifes postgreSQL_cluster.yaml menjelaskan Deployment:

    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:
          postInitTemplateSQL:
            - CREATE EXTENSION IF NOT EXISTS vector;
          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
  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.

Unggah {i>dataset<i} demo dan jalankan kueri penelusuran dengan Jupyter Notebook

Di bagian ini, Anda akan mengupload vektor ke dalam tabel PostgreSQL dan menjalankan kueri penelusuran semantik menggunakan sintaksis SQL.

Pada contoh berikut, Anda menggunakan {i>dataset<i} dari file CSV yang berisi daftar buku dalam berbagai genre. Pgvector berfungsi sebagai mesin telusur, dan Pod yang Anda buat berfungsi sebagai klien yang melakukan kueri database PostgreSQL.

  1. Tunggu hingga Pod pemimpin PostgreSQL dibuat dan siap:

    while [[ $(kubectl get pod -l cnpg.io/cluster=gke-pg-cluster,role=primary -n pg-ns -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do
    sleep 5
    done
    
  2. Buat Configmap dengan books-dataset dan jalankan Pod Jupyter untuk berinteraksi dengan cluster PostgreSQL Anda:

    kubectl create -n pg-ns configmap books-dataset --from-file=manifests/02-notebook/dataset.csv
    kubectl create -n pg-ns configmap notebook --from-file=manifests/02-notebook/vector-database.ipynb
    kubectl apply -n pg-ns -f manifests/02-notebook/jupyter.yaml
    
    • Secret bernama gke-pg-cluster-superuser yang dibuat oleh operator CloudNativePG dipasang ke Pod klien sebagai variabel lingkungan bernama CLIENTUSERNAME dan CLIENTPASSWORD.
    • ConfigMap books-dataset berisi file csv dengan data buku untuk database PostgreSQL.
    • ConfigMap demo-app berisi kode Python untuk membuat tabel PostgreSQL dari books-dataset.

    Manifes jupyter.yaml menjelaskan Deployment notebook dan Layanannya:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels: &labels
        app: jupyter-notebook
      name: notebook
    spec:
      ports:
      - port: 8888
      selector: *labels
      type: LoadBalancer
      # type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: notebook
      labels: &labels
        app: jupyter-notebook
    spec:
      selector:
        matchLabels: *labels
      template:
        metadata: 
          labels: *labels
        spec:
          containers:
          - name: jupyter
            image: tensorflow/tensorflow:2.15.0-jupyter
            resources:
              requests:
                memory: "4500Mi"
                cpu: "1"
              limits:
                memory: "4500Mi"
                cpu: "1"
            ports:
            - containerPort: 8888
            env:
            - name: CLIENTPASSWORD
              valueFrom:
                secretKeyRef:
                  name: gke-pg-cluster-superuser
                  key: password
            - name: CLIENTUSERNAME
              valueFrom:
                secretKeyRef:
                  name: gke-pg-cluster-superuser
                  key: username
            volumeMounts:
            - name: books-dataset
              mountPath: /usr/local/dataset
            - name: notebook
              mountPath: /tf
          volumes:
          - name: books-dataset
            configMap:
              name: books-dataset
          - name: notebook
            configMap:
              name: notebook
  3. Tunggu GKE memulai Pod Jupyter:

    kubectl wait pods -l app=jupyter-notebook --for condition=Ready --timeout=300s -n pg-ns
    
  4. Dapatkan URL dengan token akses untuk terhubung ke Jupyter:

    export EXTERNAL_IP=$(kubectl -n pg-ns get svc notebook --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
    kubectl logs deploy/notebook -n pg-ns| grep '^ .*http://127'|sed "s|127.0.0.1|${EXTERNAL_IP}|"
    

    Outputnya mirip dengan hal berikut ini:

    http://34.123.21.1:8888/tree?token=a1d48d3531c48328695d6901004c94060aa0aa3554ff7463
    
  5. Buka URL ini dan klik file vector-database.ipynb.

  6. Klik Run > Run all cells. Jupyter mengeksekusi kode dan melakukan kueri penelusuran untuk teks drama about people and unhappy love.

    Kueri ini melakukan penelusuran semantik terhadap tabel documents di PostgreSQL, yang mengambil maksimum dua hasil dengan skor kecocokan tertinggi yang relevan dengan kueri Anda.

    Outputnya mirip dengan hal berikut ini:

    Title: Romeo and Juliet, Author: William Shakespeare, Paul Werstine (Editor),
    Barbara A. Mowat (Editor), Paavo Emil Cajander (Translator)
    In Romeo and Juliet, Shakespeare creates a violent world, in which two young
    people fall in love. It is not simply that their families disapprove; the Montagues
    and the Capulets are engaged in a blood feud.In this death-filled setting, the
    movement from love at first sight to the lovers' final union in death seems
    almost inevitable. And yet, this play set in an extraordinary world has become
    the quintessential story of young love. In part because of its exquisite language,
    it is easy to respond as if it were about all young lovers.
    ---------
    Title: A Midsummer Night's Dream, Author: William Shakespeare, Paul Werstine (Editor),
    Barbara A. Mowat (Editor), Catherine Belsey (Contributor)
    Shakespeare's intertwined love polygons begin to get complicated from the start--Demetrius
    and Lysander both want Hermia but she only has eyes for Lysander. Bad news is,
    Hermia's father wants Demetrius for a son-in-law. On the outside is Helena,
    whose unreturned love burns hot for Demetrius. Hermia and Lysander plan to flee
    from the city under cover of darkness but are pursued by an enraged Demetrius
    (who is himself pursued by an enraptured Helena). In the forest, unbeknownst
    to the mortals, Oberon and Titania (King and Queen of the faeries) are having
    a spat over a servant boy. The plot twists up when Oberon's head mischief-maker,
    Puck, runs loose with a flower which causes people to fall in love with the
    first thing they see upon waking. Throw in a group of labourers preparing a
    play for the Duke's wedding (one of whom is given a donkey's head and Titania
    for a lover by Puck) and the complications become fantastically funny.
    ---------
    

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus project

Cara termudah untuk menghindari penagihan adalah dengan menghapus project yang Anda buat untuk tutorial ini.

Menghapus project Google Cloud:

gcloud projects delete PROJECT_ID

Jika Anda menghapus project ini, berarti pembersihan telah selesai. Jika Anda tidak menghapus project, lanjutkan dengan menghapus resource individual.

Menghapus resource satu per satu

  1. Menetapkan variabel lingkungan.

    export PROJECT_ID=${PROJECT_ID}
    export KUBERNETES_CLUSTER_PREFIX=postgres
    export REGION=us-central1
    
  2. Jalankan perintah terraform destroy:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    terraform  -chdir=../postgresql-cloudnativepg/terraform/FOLDER destroy \
    -var project_id=${PROJECT_ID} \
    -var region=${REGION} \
    -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    Ganti FOLDER dengan gke-autopilot atau gke-standard, bergantung pada jenis cluster GKE yang Anda buat.

    Saat diminta, ketik yes.

Langkah selanjutnya