Zalando를 사용하여 GKE에 PostgreSQL 배포


이 가이드에서는 Zalando Postgres 연산자를 사용하여 Postgres 클러스터를 Google Kubernetes Engine(GKE)에 배포하는 방법을 설명합니다.

PostgreSQL은 수십 년간의 활발한 개발이 이루어진 강력한 오픈소스 객체 관계형 데이터베이스 시스템으로, 안정성, 기능 견고성, 성능으로 탄탄한 평판을 쌓았습니다.

이 가이드는 PostgreSQL용 Cloud SQL을 사용하는 대신 PostgreSQL을 GKE에서 데이터베이스 애플리케이션으로 실행하는 데 관심이 있는 플랫폼 관리자, 클라우드 설계자, 운영 전문가를 대상으로 합니다.

목표

  • Postgres용 GKE 인프라 계획 및 배포
  • Zalando Postgres 연산자 배포 및 구성
  • 가용성, 보안, 관측 가능성, 성능을 보장하기 위해 연산자를 사용하여 Postgres 구성

이점

Zalando에서 제공하는 이점은 다음과 같습니다.

  • PostgreSQL 클러스터를 관리하고 구성하는 선언적 Kubernetes 기반 방식
  • Patroni에서 제공하는 고가용성
  • Cloud Storage 버킷을 사용한 백업 관리 지원
  • 빠른 부 버전 업데이트를 포함한 Postgres 클러스터 변경사항에 대한 순차적 업데이트
  • 커스텀 리소스를 사용하여 비밀번호 생성 및 순환을 사용하는 선언적 사용자 관리
  • TLS, 인증서 순환, 연결 풀 지원
  • 클러스터 클론 및 데이터 복제

배포 아키텍처

이 튜토리얼에서는 Zalando Postgres 연산자를 사용하여 가용성이 높은 Postgres 클러스터를 GKE에 배포하고 구성합니다. 클러스터에는 Patroni에서 관리하는 리더 복제본 1개와 대기(읽기 전용) 복제본 2개가 있습니다. Patroni는 Postgres에 고가용성 및 자동 장애 조치 기능을 제공하기 위해 Zalando에서 유지관리하는 오픈소스 솔루션입니다. 리더 장애가 발생하면 대기 복제본 하나가 자동으로 리더 역할로 승격됩니다.

또한 여러 가용성 영역에 분산된 Kubernetes 노드와 함께 Postgres를 위한 고가용성 리전 GKE 클러스터를 배포합니다. 이 설정은 내결함성, 확장성, 지리적 중복성을 보장하는 데 도움이 됩니다. 업타임 및 가용성을 위한 SLA를 제공하면서 순차적 업데이트 및 유지보수를 가능하게 해줍니다. 자세한 내용은 리전 클러스터를 참조하세요.

다음 다이어그램에서는 GKE 클러스터의 여러 노드 및 영역에서 실행되는 Postgres 클러스터를 보여줍니다.

다이어그램에서 Postgres StatefulSet는 서로 다른 3개 영역의 노드 3개에 배포되어 있습니다. postgresql 커스텀 리소스 사양에 필요한 포드 어피니티 및 안티-어피니티 규칙을 설정하여 GKE가 노드에 배포되는 방식을 제어할 수 있습니다. 한 영역에 장애가 발생하면 GKE가 권장 구성을 사용해서 클러스터에서 사용 가능한 다른 노드에 포드를 다시 예약합니다. 데이터를 유지하려면 SSD 디스크(premium-rwo StorageClass)를 사용합니다. 이는 대기 시간이 짧고 IOPS가 높기 때문에 로드가 많은 데이터베이스인 경우 권장됩니다.

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.

시작하기 전에

Cloud Shell에는 kubectl, gcloud CLI, Helm, Terraform 등 이 튜토리얼에 필요한 소프트웨어가 사전 설치되어 있습니다. Cloud Shell을 사용하지 않는 경우에는 gcloud CLI를 설치해야 합니다.

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud CLI를 설치합니다.
  3. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

    gcloud init
  4. Google Cloud 프로젝트를 만들거나 선택합니다.

    • Google Cloud 프로젝트를 만듭니다.

      gcloud projects create PROJECT_ID

      PROJECT_ID를 만들려는 Google Cloud 프로젝트의 이름으로 바꿉니다.

    • 만든 Google Cloud 프로젝트를 선택합니다.

      gcloud config set project PROJECT_ID

      PROJECT_ID를 Google Cloud 프로젝트 이름으로 바꿉니다.

  5. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  6. Compute Engine, IAM, GKE, Backup for GKE API를 사용 설정합니다.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com
  7. Google Cloud CLI를 설치합니다.
  8. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

    gcloud init
  9. Google Cloud 프로젝트를 만들거나 선택합니다.

    • Google Cloud 프로젝트를 만듭니다.

      gcloud projects create PROJECT_ID

      PROJECT_ID를 만들려는 Google Cloud 프로젝트의 이름으로 바꿉니다.

    • 만든 Google Cloud 프로젝트를 선택합니다.

      gcloud config set project PROJECT_ID

      PROJECT_ID를 Google Cloud 프로젝트 이름으로 바꿉니다.

  10. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  11. Compute Engine, IAM, GKE, Backup for GKE API를 사용 설정합니다.

    gcloud services enable compute.googleapis.com iam.googleapis.com container.googleapis.com gkebackup.googleapis.com
  12. Google 계정에 역할을 부여합니다. 다음 각 IAM 역할에 대해 다음 명령어를 한 번씩 실행합니다. roles/storage.objectViewer, roles/container.admin, roles/iam.serviceAccountAdmin, roles/compute.admin, roles/gkebackup.admin, roles/monitoring.viewer

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • PROJECT_ID를 프로젝트 ID로 바꿉니다.
    • EMAIL_ADDRESS를 이메일 주소로 바꿉니다.
    • ROLE을 각 개별 역할로 바꿉니다.

환경 설정하기

환경을 설정하려면 다음 단계를 수행합니다.

  1. 환경 변수를 설정합니다.

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

    PROJECT_ID를 Google Cloud 프로젝트 ID로 바꿉니다.

  2. GitHub 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. 작업 디렉터리로 변경합니다.

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

클러스터 인프라 만들기

이 섹션에서는 Terraform 스크립트를 실행하여 가용성이 높은 비공개 리전 GKE 클러스터를 만듭니다.

Standard 또는 Autopilot 클러스터를 사용하여 연산자를 설치할 수 있습니다.

Standard

다음 다이어그램에서는 서로 다른 영역 3개에 배포된 비공개 리전 Standard GKE 클러스터를 보여줍니다.

다음 인프라를 배포합니다.

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}

메시지가 표시되면 yes를 입력합니다. 이 명령어가 완료되고 클러스터에 준비 상태가 표시되는 데 몇 분 정도 걸릴 수 있습니다.

Terraform에서 다음 리소스를 만듭니다.

  • Kubernetes 노드의 VPC 네트워크 및 비공개 서브넷
  • NAT를 통해 인터넷에 액세스할 수 있는 라우터
  • us-central1 리전의 비공개 GKE 클러스터
  • 자동 확장이 사용 설정된 노드 풀(영역당 노드 1~2개, 최소 영역당 노드 1개)
  • 로깅 및 모니터링 권한이 있는 ServiceAccount
  • 재해 복구를 위한 Backup for GKE
  • 클러스터 모니터링을 위한 Google Cloud Managed Service for Prometheus

출력은 다음과 비슷합니다.

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

Autopilot

다음 다이어그램에서는 비공개 리전 Autopilot GKE 클러스터를 보여줍니다.

인프라를 배포합니다.

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}

메시지가 표시되면 yes를 입력합니다. 이 명령어가 완료되고 클러스터에 준비 상태가 표시되는 데 몇 분 정도 걸릴 수 있습니다.

Terraform에서 다음 리소스를 만듭니다.

  • Kubernetes 노드의 VPC 네트워크 및 비공개 서브넷
  • NAT를 통해 인터넷에 액세스할 수 있는 라우터
  • us-central1 리전의 비공개 GKE 클러스터
  • 로깅 및 모니터링 권한이 있는 ServiceAccount
  • 클러스터 모니터링을 위한 Google Cloud Managed Service for Prometheus

출력은 다음과 비슷합니다.

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

클러스터에 연결

클러스터와 통신하도록 kubectl을 구성합니다.

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

클러스터에 Zalando 연산자 배포

Helm 차트를 사용하여 Kubernetes 클러스터에 Zalando 연산자를 배포합니다.

  1. Zalando 연산자 Helm 차트 저장소를 추가합니다.

    helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
    
  2. Zalando 연산자 및 Postgres 클러스터의 네임스페이스를 만듭니다.

    kubectl create ns postgres
    kubectl create ns zalando
    
  3. Helm 명령줄 도구를 사용하여 Zalando 연산자를 배포합니다.

    helm install postgres-operator postgres-operator-charts/postgres-operator -n zalando \
        --set configKubernetes.enable_pod_antiaffinity=true \
        --set configKubernetes.pod_antiaffinity_preferred_during_scheduling=true \
        --set configKubernetes.pod_antiaffinity_topology_key="topology.kubernetes.io/zone" \
        --set configKubernetes.spilo_fsgroup="103"
    

    Postgres 클러스터를 나타내는 커스텀 리소스에서 직접 podAntiAffinity 설정을 구성할 수 없습니다. 대신 연산자 설정에서 모든 Postgres 클러스터에 대해 podAntiAffinity 설정을 전역적으로 설정합니다.

  4. Helm을 사용하여 Zalando 연산자의 배포 상태를 확인합니다.

    helm ls -n zalando
    

    출력은 다음과 비슷합니다.

    NAME                 NAMESPACE    REVISION    UPDATED                                STATUS      CHART                       APP VERSION
    postgres-operator    zalando     1           2023-10-13 16:04:13.945614 +0200 CEST    deployed    postgres-operator-1.10.1    1.10.1
    

Postgres 배포

Postgres 클러스터 인스턴스의 기본 구성에는 다음 구성요소가 포함됩니다.

  • Postgres 복제본 3개: 리더 1개와 대기 복제본 2개
  • CPU 요청 1개 및 CPU 한도 2개의 CPU 리소스 할당(4GB 메모리 요청 및 한도)
  • Kubernetes 노드 간 적절한 배포를 보장하고 해당 노드 풀 및 서로 다른 가용성 영역을 활용하는 각 워크로드에 구성된 톨러레이션(toleration), nodeAffinities, topologySpreadConstraints

이 구성은 프로덕션에 사용 가능한 Postgres 클러스터를 만드는 데 필요한 최소 설정을 나타냅니다.

다음 매니페스트에서는 Postgres 클러스터를 설명합니다.

apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: my-cluster
spec:
  dockerImage: ghcr.io/zalando/spilo-15:3.0-p1
  teamId: "my-team"
  numberOfInstances: 3
  users:
    mydatabaseowner:
    - superuser
    - createdb
    myuser: []
  databases:
    mydatabase: mydatabaseowner
  postgresql:
    version: "15"
    parameters:
      shared_buffers: "32MB"
      max_connections: "10"
      log_statement: "all"
      password_encryption: scram-sha-256
  volume:
    size: 5Gi
    storageClass: premium-rwo
  enableShmVolume: true
  podAnnotations:
    cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
  tolerations:
  - key: "app.stateful/component"
    operator: "Equal"
    value: "postgres-operator"
    effect: NoSchedule
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: "app.stateful/component"
          operator: In
          values:
          - "postgres-operator"
  resources:
    requests:
      cpu: "1"
      memory: 4Gi
    limits:
      cpu: "2"
      memory: 4Gi
  sidecars:
    - name: exporter
      image: quay.io/prometheuscommunity/postgres-exporter:v0.14.0
      args:
      - --collector.stat_statements
      ports:
      - name: exporter
        containerPort: 9187
        protocol: TCP
      resources:
        limits:
          cpu: 500m
          memory: 256M
        requests:
          cpu: 100m
          memory: 256M
      env:
      - name: "DATA_SOURCE_URI"
        value: "localhost/postgres?sslmode=require"
      - name: "DATA_SOURCE_USER"
        value: "$(POSTGRES_USER)"
      - name: "DATA_SOURCE_PASS"
        value: "$(POSTGRES_PASSWORD)"

이 매니페스트에는 다음과 같은 필드가 있습니다.

  • spec.teamId: 선택한 클러스터 객체의 프리픽스
  • spec.numberOfInstances: 클러스터의 총 인스턴스 수
  • spec.users: 권한이 있는 사용자 목록
  • spec.databases: dbname: ownername 형식의 데이터베이스 목록
  • spec.postgresql: postgres 매개변수
  • spec.volume: 영구 디스크 매개변수
  • spec.tolerations: 클러스터 포드를 pool-postgres 노드에 예약할 수 있는 톨러레이션(toleration) 포드 템플릿
  • spec.nodeAffinity: 클러스터 포드가 pool-postgres 노드에 예약되는 것을 GKE에 알려주는 nodeAffinity 포드 템플릿
  • spec.resources: 클러스터 포드의 요청 및 한도
  • spec.sidecars: postgres-exporter가 포함된 사이드카 컨테이너 목록

자세한 내용은 Postgres 문서의 클러스터 매니페스트 참조를 확인하세요.

기본 Postgres 클러스터 만들기

  1. 기본 구성을 사용하여 새 Postgres 클러스터를 만듭니다.

    kubectl apply -n postgres -f manifests/01-basic-cluster/my-cluster.yaml
    

    이 명령어는 다음을 사용하여 Zalando 연산자의 PostgreSQL 커스텀 리소스를 만듭니다.

    • CPU 및 메모리 요청과 한도
    • 프로비저닝된 포드 복제본을 GKE 노드 간에 배포하기 위한 taint 및 어피니티
    • 데이터베이스
    • 데이터베이스 소유자 권한이 있는 사용자 두 명
    • 권한이 없는 사용자
  2. GKE가 필요한 워크로드를 시작할 때까지 기다립니다.

    kubectl wait pods -l cluster-name=my-cluster  --for condition=Ready --timeout=300s -n postgres
    

    이 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다.

  3. GKE에서 Postgres 워크로드를 생성했는지 확인합니다.

    kubectl get pod,svc,statefulset,deploy,pdb,secret -n postgres
    

    출력은 다음과 비슷합니다.

    NAME                                    READY   STATUS  RESTARTS   AGE
    pod/my-cluster-0                        1/1     Running   0         6m41s
    pod/my-cluster-1                        1/1     Running   0         5m56s
    pod/my-cluster-2                        1/1     Running   0         5m16s
    pod/postgres-operator-db9667d4d-rgcs8   1/1     Running   0         12m
    
    NAME                        TYPE        CLUSTER-IP  EXTERNAL-IP   PORT(S)   AGE
    service/my-cluster          ClusterIP   10.52.12.109   <none>       5432/TCP   6m43s
    service/my-cluster-config   ClusterIP   None        <none>      <none>  5m55s
    service/my-cluster-repl     ClusterIP   10.52.6.152 <none>      5432/TCP   6m43s
    service/postgres-operator   ClusterIP   10.52.8.176 <none>      8080/TCP   12m
    
    NAME                        READY   AGE
    statefulset.apps/my-cluster   3/3   6m43s
    
    NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/postgres-operator   1/1     1           1           12m
    
    NAME                                                MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    poddisruptionbudget.policy/postgres-my-cluster-pdb   1              N/A             0                   6m44s
    
    NAME                                                            TYPE                DATA   AGE
    secret/my-user.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m45s
    secret/postgres.my-cluster.credentials.postgresql.acid.zalan.do   Opaque            2   6m44s
    secret/sh.helm.release.v1.postgres-operator.v1                  helm.sh/release.v1   1      12m
    secret/standby.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s
    secret/zalando.my-cluster.credentials.postgresql.acid.zalan.do  Opaque              2   6m44s
    

연산자는 다음 리소스를 만듭니다.

  • Postgres용 포드 복제본 세 개를 제어하는 Postgres StatefulSet
  • 사용 가능한 복제본 최소 1개를 보장하는 PodDisruptionBudgets
  • 리더 복제본만 대상으로 하는 my-cluster 서비스
  • my-cluster-repl 서비스, 수신되는 연결과 Postgres 복제본 간의 복제를 위한 Postgres 포트 노출
  • 실행 중인 Postgres 포드 복제본의 목록을 가져오기 위한 my-cluster-config 헤드리스 서비스
  • Postgres 노드 간 복제와 데이터베이스에 액세스하기 위한 사용자 인증 정보가 포함된 보안 비밀

Postgres 인증

Postgres 사용자를 만들고 데이터베이스 권한을 할당할 수 있습니다. 예를 들어 다음 매니페스트는 사용자와 역할을 할당하는 커스텀 리소스를 설명합니다.

apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: my-cluster
spec:
  ...
  users:
    mydatabaseowner:
    - superuser
    - createdb
    myuser: []
  databases:
    mydatabase: mydatabaseowner

이 매니페스트에서 각 항목은 다음을 수행합니다.

  • mydatabaseowner 사용자에게는 전체 관리자 권한(예: Postgres 구성 관리, 새 데이터베이스, 테이블, 사용자 만들기)을 허용하는 SUPERUSERCREATEDB 역할이 있습니다. 이 사용자를 클라이언트와 공유해서는 안 됩니다. 예를 들어 Cloud SQL에서는 고객이 SUPERUSER 역할이 있는 사용자에게 액세스하는 것을 허용하지 않습니다.
  • myuser 사용자에게 할당된 역할이 없습니다. 따라서 SUPERUSER를 사용하여 최소 권한으로 사용자를 만드는 권장사항을 따릅니다. mydatabaseowner에서 myuser에게 세분화된 권한을 부여합니다. 보안을 유지하려면 myuser 사용자 인증 정보를 클라이언트 애플리케이션에만 공유해야 합니다.

비밀번호 저장

scram-sha-256 비밀번호 저장에 권장되는 방법을 사용해야 합니다. 예를 들어 다음 매니페스트는 postgresql.parameters.password_encryption 필드를 사용하여 scram-sha-256 암호화를 지정하는 커스텀 리소스를 설명합니다.

apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: my-cluster
spec:
  ...
  postgresql:
    parameters:
      password_encryption: scram-sha-256

사용자 인증 정보 순환

Zalando를 사용하여 Kubernetes 보안 비밀에 저장된 사용자 인증 정보를 순환할 수 있습니다. 예를 들어 다음 매니페스트는 usersWithSecretRotation 필드를 사용하여 사용자 인증 정보 순환을 정의하는 커스텀 리소스를 설명합니다.

apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: my-cluster
spec:
  ...
  usersWithSecretRotation:
  - myuser
  - myanotheruser
  - ...

인증 예시: Postgres에 연결

이 섹션에서는 예시 Postgres 클라이언트를 배포하고 Kubernetes 보안 비밀의 비밀번호를 사용하여 데이터베이스에 연결하는 방법을 보여줍니다.

  1. 클라이언트 포드를 실행하여 Postgres 클러스터와 상호 작용합니다.

    kubectl apply -n postgres -f manifests/02-auth/client-pod.yaml
    

    myusermydatabaseowner 사용자의 사용자 인증 정보는 관련 보안 비밀에서 가져와 환경 변수로 포드에 마운트합니다.

  2. 준비되면 포드에 연결합니다.

    kubectl wait pod postgres-client --for=condition=Ready --timeout=300s -n postgres
    kubectl exec -it postgres-client -n postgres -- /bin/bash
    
  3. Postgres에 연결하고 myuser 사용자 인증 정보를 사용하여 새 테이블 만들기를 시도합니다.

    PGPASSWORD=$CLIENTPASSWORD psql \
      -h my-cluster \
      -U $CLIENTUSERNAME \
      -d mydatabase \
      -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);"
    

    다음과 유사한 오류가 표시되면서 명령어가 실패합니다.

    ERROR:  permission denied for schema public
    LINE 1: CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR...
    

    기본적으로 권한이 할당되지 않은 사용자는 Postgres에 로그인하고 데이터베이스를 나열할 수만 있기 때문에 명령어가 실패합니다.

  4. mydatabaseowner 사용자 인증 정보로 테이블을 만들고 테이블에 대한 모든 권한을 myuser에 부여합니다.

    PGPASSWORD=$OWNERPASSWORD psql \
      -h my-cluster \
      -U $OWNERUSERNAME \
      -d mydatabase \
      -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);GRANT ALL ON test TO myuser;GRANT ALL ON SEQUENCE test_id_seq TO myuser;"
    

    출력은 다음과 비슷합니다.

    CREATE TABLE
    GRANT
    GRANT
    
  5. myuser 사용자 인증 정보를 사용하여 테이블에 임의의 데이터를 삽입합니다.

    for i in {1..10}; do
      DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
      PGPASSWORD=$CLIENTPASSWORD psql \
      -h my-cluster \
      -U $CLIENTUSERNAME \
      -d mydatabase \
      -c "INSERT INTO test(randomdata) VALUES ('$DATA');"
    done
    

    출력은 다음과 비슷합니다.

    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    
  6. 삽입한 값을 가져옵니다.

    PGPASSWORD=$CLIENTPASSWORD psql \
      -h my-cluster \
      -U $CLIENTUSERNAME \
      -d mydatabase \
      -c "SELECT * FROM test;"
    

    출력은 다음과 비슷합니다.

    id |  randomdata
    ----+---------------
      1 | jup9HYsAjwtW4
      2 | 9rLAyBlcpLgNT
      3 | wcXSqxb5Yz75g
      4 | KoDRSrx3muD6T
      5 | b9atC7RPai7En
      6 | 20d7kC8E6Vt1V
      7 | GmgNxaWbkevGq
      8 | BkTwFWH6hWC7r
      9 | nkLXHclkaqkqy
     10 | HEebZ9Lp71Nm3
    (10 rows)
    
  7. 포드 셸을 종료합니다.

    exit
    

Prometheus가 Postgres 클러스터에 대해 측정항목을 수집하는 방법 이해

다음 다이어그램은 Prometheus 측정항목 수집의 작동 방식을 보여줍니다.

다이어그램에서 GKE 비공개 클러스터에는 다음이 포함됩니다.

  • / 경로 및 9187 포트로 측정항목을 수집하는 Postgres 포드
  • Postgres 포드의 측정항목을 처리하는 Prometheus 기반 수집기
  • Cloud Monitoring으로 측정항목을 전송하는 PodMonitoring 리소스

Google Cloud Managed Service for Prometheus는 Prometheus 형식의 측정항목 수집을 지원합니다. Cloud Monitoring은 Postgres 측정항목에 대해 통합 대시보드를 사용합니다.

Zalando는 postgres_exporter 구성요소사이드카 컨테이너로 사용하여 Prometheus 형식으로 클러스터 측정항목을 노출합니다.

  1. labelSelector로 측정항목을 스크래핑하도록 PodMonitoring 리소스를 만듭니다.

    kubectl apply -n postgres -f manifests/03-prometheus-metrics/pod-monitoring.yaml
    
  2. Google Cloud 콘솔에서 GKE 클러스터 대시보드 페이지로 이동합니다.

    GKE 클러스터 대시보드로 이동

    대시보드에 0이 아닌 측정항목 수집 비율이 표시됩니다.

  3. Google Cloud 콘솔에서 대시보드 페이지로 이동합니다.

    대시보드로 이동

  4. PostgreSQL Prometheus 개요 대시보드를 엽니다. 대시보드에 가져온 행의 수가 표시됩니다. 대시보드가 자동 프로비저닝되는 데 몇 분 정도 걸릴 수 있습니다.

  5. 클라이언트 포드에 연결합니다.

    kubectl exec -it postgres-client -n postgres -- /bin/bash
    
  6. 임의 데이터를 삽입합니다.

    for i in {1..100}; do
      DATA=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
      PGPASSWORD=$CLIENTPASSWORD psql \
      -h my-cluster \
      -U $CLIENTUSERNAME \
      -d mydatabase \
      -c "INSERT INTO test(randomdata) VALUES ('$DATA');"
    done
    
  7. 페이지를 새로고침합니다. 블록 그래프가 실제 데이터베이스 상태를 표시하도록 업데이트됩니다.

  8. 포드 셸을 종료합니다.

    exit
    

삭제

프로젝트 삭제

    Google Cloud 프로젝트를 삭제합니다.

    gcloud projects delete PROJECT_ID

개별 리소스 삭제

  1. 환경 변수를 설정합니다.

    export PROJECT_ID=${PROJECT_ID}
    export KUBERNETES_CLUSTER_PREFIX=postgres
    export REGION=us-central1
    
  2. terraform destroy 명령어를 실행합니다.

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

    FOLDERgke-autopilot 또는 gke-standard로 바꿉니다.

    메시지가 표시되면 yes를 입력합니다.

  3. 연결되지 않은 모든 디스크를 찾습니다.

    export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
    
  4. 디스크를 삭제합니다.

    for i in $disk_list; do
      disk_name=$(echo $i| cut -d'|' -f1)
      disk_zone=$(echo $i| cut -d'|' -f2|sed 's|.*/||')
      echo "Deleting $disk_name"
      gcloud compute disks delete $disk_name --zone $disk_zone --quiet
    done
    
  5. GitHub 저장소를 삭제합니다.

    rm -r ~/kubernetes-engine-samples/
    

다음 단계

  • Google Cloud에 대한 참조 아키텍처, 다이어그램, 권장사항 살펴보기 Cloud 아키텍처 센터 살펴보기