Cloud Native PostgreSQLのInteractive Demoについて

EDB Docs | Cloud Native PostgreSQL

Interactive Demoは、EDBドキュメントサイトのCloud Native PostgreSQL内に用意されています。

Cloud Native PostgreSQLのインストールから運用に必要な情報はこちらのドキュメントにすべて記載されていますので、合わせてご利用ください。

Installation, Configuration and Deployment Demo

EDB社が提供する Cloud Native PostgreSQLのドキュメンサイトより「Installation, Configuration, Deployment Demo」のメニューがあります。こちらのメニューにアクセスすると、以下の画面のようにInteractive Demoを利用するためのサイトにアクセスすることができます。

このサイトでは、以下のDemoを実際に使うことができます。

  1. Installing the Cloud Native PostgreSQL Operator
    (Cloud Native PostgreSQLオペレーターのインストール)
  2. Deploying a three-node PostgreSQL cluster
    (3ノードのPostgreSQLクラスタをデプロイ)
  3. Installing and using the kubectl-cnp plugin
    (kubectl-cnpのインストールと利用)
  4. Testing failover to verify the resilience of the cluster
    (フェイルオーバーのテストを実行し、クラスタの回復力を確認)

EDB Cloud Native PostgreSQL Interactive Demoの利用開始

Interactive Demoを開始するには「Interactive Demo Start Now」をクリックします。

Interactive Demoを開始すると画面下部にターミナルウィンドウが表示されます。

このInteractive Demoはブラウザ上で完結する仕組みになっているため、ドキュメントの内容に沿って進めていくことでKubernetes OperatorのインストールからPostgreSQLのデプロイ、そしてリカバリーのテストまで実施することができます。

ドキュメント内には以下のようにコマンドサンプルが用意されています。
以下は、一番最初の作業となる「minikubeを起動する」コマンドになりますが、このコマンドはそのまま入力頂いても構いませんが、Typoを防止するためにコマンド右上にある「Copy」をクリックしてTerminal内に貼り付けることをおすすめします。

画面下のTerminalにてminikubeの実行(minikube start)を行うと、以下のように表示されます。これはコマンドサンプルの下のOUTPUTの内容が出力されていきます。サンプルを見ていくだけでも作業の内容が把握できるようになっています。

上記は作業途中のスクリーンショットですが、サンプルにある「Done! kubectl is now configured to use “minikube”」まで表示され次の行に「$」が表示される状態、Terminalにコマンドが戻ってきたら次の作業に進めます。

minikubeの起動

Tarminalにて、minikubeコマンドminikube startをコピー&ペーストして起動を行います。

$ minikube start
* minikube v1.8.1 on Ubuntu 18.04
* Using the none driver based on user configuration
* Running on localhost (CPUs=2, Memory=2460MB, Disk=145651MB) ...
* OS release is Ubuntu 18.04.4 LTS
* Preparing Kubernetes v1.17.3 on Docker 19.03.6 ...
  - kubelet.resolv-conf=/run/systemd/resolve/resolv.conf
* Launching Kubernetes ... 
* Enabling addons: default-storageclass, storage-provisioner
* Configuring local host environment ...
* Waiting for cluster to come online ...
* Done! kubectl is now configured to use "minikube"

使用できるようになっています。起動状況を確認するためにkubectl get nodesにてステータスを取得します。

$ kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
minikube   Ready    master   7m32s   v1.17.3

STATUSがReadyとなっていることが確認できれば、minikubeは正常に起動しています。執筆時点では 1.17.3のバージョンを利用しております。

Cloud Native PostgreSQL(postgresql-operator)のインストール

minikubeクラスターが実行されたことを確認したら、次にCloud Native PostgreSQLのインストールを行います。

kubectlコマンドにてkubectl apply -f https://get.enterprisedb.io/cnp/postgresql-operator-1.7.1.yamlを実行します。コマンドが長くなりますのでコピー&ペーストを利用して実行することをお勧めします。

$ kubectl apply -f https://get.enterprisedb.io/cnp/postgresql-operator-1.7.1.yaml
namespace/postgresql-operator-system created
customresourcedefinition.apiextensions.k8s.io/backups.postgresql.k8s.enterprisedb.io created
customresourcedefinition.apiextensions.k8s.io/clusters.postgresql.k8s.enterprisedb.io created
customresourcedefinition.apiextensions.k8s.io/scheduledbackups.postgresql.k8s.enterprisedb.io created
mutatingwebhookconfiguration.admissionregistration.k8s.io/postgresql-operator-mutating-webhook-configuration created
serviceaccount/postgresql-operator-manager created
clusterrole.rbac.authorization.k8s.io/postgresql-operator-manager created
clusterrolebinding.rbac.authorization.k8s.io/postgresql-operator-manager-rolebinding created
service/postgresql-operator-webhook-service created
deployment.apps/postgresql-operator-controller-manager created
validatingwebhookconfiguration.admissionregistration.k8s.io/postgresql-operator-validating-webhook-configuration created

正常にインストールされたかをkubectl get deploy -n postgresql-operator-system postgresql-operator-controller-managerにて確認します。インストール実行直後に確認すると以下のように READYのステータスは0/1となります。

$ kubectl get deploy -n postgresql-operator-system postgresql-operator-controller-manager
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
postgresql-operator-controller-manager   0/1     1            0           4s

しばらく待ってから実行し、以下のようにREADYのステータスが1/1となっていることが確認できたら正常にCNP(postgresql-operator-controller-manager)のインストールが完了した事になります。

$ kubectl get deploy -n postgresql-operator-system postgresql-operator-controller-manager
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
postgresql-operator-controller-manager   1/1     1            1           12m

PostgreSQLクラスターのデプロイ

KubernetesのPostgreSQLクラスターをデプロイするには、クラスターを定義する構成ファイル(YAMLファイル)を適用する必要があります。

cluster-example.yamlサンプルファイルは、デフォルトのストレージクラスを使用してディスクスペースを割り当てるシンプルなクラスターを定義します。以下のコードはcat 〜 EOFまで全行をコピーして実行してください。

cat <<EOF > cluster-example.yaml
# Example of PostgreSQL cluster
apiVersion: postgresql.k8s.enterprisedb.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3

  # Example of rolling update strategy:
  # - unsupervised: automated update of the primary once all
  #                 replicas have been upgraded (default)
  # - supervised: requires manual supervision to perform
  #               the switchover of the primary
  primaryUpdateStrategy: unsupervised

  # Require 1Gi of space
  storage:
    size: 1Gi
EOF

実行した場合の表示はTerminal上では以下のようになります。

$ cat <<EOF > cluster-example.yaml
> # Example of PostgreSQL cluster
> apiVersion: postgresql.k8s.enterprisedb.io/v1
> kind: Cluster
> metadata:
>   name: cluster-example
> spec:
>   instances: 3
> 
>   # Example of rolling update strategy:
>   # - unsupervised: automated update of the primary once all
>   #                 replicas have been upgraded (default)
>   # - supervised: requires manual supervision to perform
>   #               the switchover of the primary
>   primaryUpdateStrategy: unsupervised
> 
>   # Require 1Gi of space
>   storage:
>     size: 1Gi
> EOF

3ノードのPostgreSQLクラスターを作成するには、次のコマンドを実行します。

$ kubectl apply -f cluster-example.yaml
cluster.postgresql.k8s.enterprisedb.io/cluster-example created

get podsコマンドを使用して、ポッドが作成されていることを確認できます。

初期化には少し時間がかかるため、クラスター構成を適用した直後に実行すると、ステータスがInit またはPodInitializingとして表示されます。

$ kubectl get pods
NAME                             READY   STATUS            RESTARTS   AGE
cluster-example-1-initdb-c7lh6   0/1     PodInitializing   0          2m21s

何度か実行し、以下のように3台のポッドがすべてRunning ステータスになれば起動が完了したことになります。

$ kubectl get pods
NAME                READY   STATUS    RESTARTS   AGE
cluster-example-1   1/1     Running   0          9m1s
cluster-example-2   1/1     Running   0          8m29s
cluster-example-3   1/1     Running   0          8m3s

クラスターのステータスをkubectl get cluster cluster-example -o yamlにて確認します。

$ kubectl get cluster cluster-example -o yaml
apiVersion: postgresql.k8s.enterprisedb.io/v1
kind: Cluster
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"postgresql.k8s.enterprisedb.io/v1","kind":"Cluster","metadata":{"annotations":{},"name":"cluster-example","namespace":"default"},"spec":{"instances":3,"primaryUpdateStrategy":"unsupervised","storage":{"size":"1Gi"}}}
  creationTimestamp: "2021-09-07T10:25:55Z"
  generation: 1
  name: cluster-example
  namespace: default
  resourceVersion: "6469"
  selfLink: /apis/postgresql.k8s.enterprisedb.io/v1/namespaces/default/clusters/cluster-example
  uid: e181246e-0704-4335-bfd6-1554add2394e
spec:
  affinity:
    podAntiAffinityType: preferred
    topologyKey: ""
  bootstrap:
    initdb:
      database: app
      owner: app
  imageName: quay.io/enterprisedb/postgresql:13.3
  instances: 3
  postgresql:
    parameters:
      log_destination: csvlog
      log_directory: /controller/log
      log_filename: postgres
      log_rotation_age: "0"
      log_rotation_size: "0"
      log_truncate_on_rotation: "false"
      logging_collector: "on"
      max_parallel_workers: "32"
      max_replication_slots: "32"
      max_worker_processes: "32"
      shared_preload_libraries: ""
      wal_keep_size: 512MB
  primaryUpdateStrategy: unsupervised
  resources: {}
  storage:
    size: 1Gi
status:
  certificates:
    clientCASecret: cluster-example-ca
    expirations:
      cluster-example-ca: 2021-12-06 10:20:55 +0000 UTC
      cluster-example-replication: 2021-12-06 10:20:55 +0000 UTC
      cluster-example-server: 2021-12-06 10:20:55 +0000 UTC
    replicationTLSSecret: cluster-example-replication
    serverAltDNSNames:
    - cluster-example-rw
    - cluster-example-rw.default
    - cluster-example-rw.default.svc
    - cluster-example-r
    - cluster-example-r.default
    - cluster-example-r.default.svc
    - cluster-example-ro
    - cluster-example-ro.default
    - cluster-example-ro.default.svc
    serverCASecret: cluster-example-ca
    serverTLSSecret: cluster-example-server
  configMapResourceVersion: {}
  currentPrimary: cluster-example-1
  healthyPVC:
  - cluster-example-3
  - cluster-example-1
  - cluster-example-2
  instances: 3
  instancesStatus:
    healthy:
    - cluster-example-1
    - cluster-example-3
    - cluster-example-2
  latestGeneratedNode: 3
  licenseStatus:
    isImplicit: true
    isTrial: true
    licenseExpiration: "2021-10-07T10:25:55Z"
    licenseStatus: Implicit trial license
    repositoryAccess: false
    valid: true
  phase: Cluster in healthy state
  pvcCount: 3
  readService: cluster-example-r
  readyInstances: 3
  secretsResourceVersion:
    applicationSecretVersion: "1947"
    clientCaSecretVersion: "1943"
    replicationSecretVersion: "1945"
    serverCaSecretVersion: "1943"
    serverSecretVersion: "1944"
    superuserSecretVersion: "1946"
  targetPrimary: cluster-example-1
  writeService: cluster-example-rw

デフォルトでは、OperatorはPostgreSQLの最新のメジャーバージョンの利用可能な最新のマイナーバージョンをインストールします。 特定のバージョンを指定したい時はクラスター定義のspecでimageName keyを設定します。

実稼働環境では、常に特定のバージョンのコンテナイメージを指す必要があります。latestや13のようなタグを使用しないでください。クラスター内の更新ポリシーとバージョンの一貫性で予測できない問題が発生する可能性があります。

kubectl-cnp pluginのインストール

Cloud Native PostgreSQLは、kubernetesでクラスターを管理するための kubectlのプラグイン「kubectl-cnp」と、それをインストールするためのスクリプトを提供します。

kubectl-cnpの情報は下記URLご確認ください。

以下のコードを全行コピーして、Terminal画面で実行します

curl -sSfL \
  https://github.com/EnterpriseDB/kubectl-cnp/raw/main/install.sh | \
  sudo sh -s -- -b /usr/local/bin

Terminal の実行結果は以下のようになります。

$ curl -sSfL \
>   https://github.com/EnterpriseDB/kubectl-cnp/raw/main/install.sh | \
>   sudo sh -s -- -b /usr/local/bin
EnterpriseDB/kubectl-cnp info checking GitHub for latest tag
EnterpriseDB/kubectl-cnp info found version: 1.7.1 for v1.7.1/linux/x86_64
EnterpriseDB/kubectl-cnp info installed /usr/local/bin/kubectl-cnp

cnpコマンドがkubectlで使用できるようになりました。kubectl cnp status cluster-example を実行してみましょう。

$ kubectl cnp status cluster-example
Cluster in healthy state   
Name:              cluster-example
Namespace:         default
PostgreSQL Image:  quay.io/enterprisedb/postgresql:13.3
Primary instance:  cluster-example-1
Instances:         3
Ready instances:   3

Instances status
Pod name           Current LSN  Received LSN  Replay LSN  System ID            Primary  Replicating  Replay paused  Pending restart  Status
--------           -----------  ------------  ----------  ---------            -------  -----------  -------------  ---------------  ------
cluster-example-1  0/9000000                              7005136372083945490  ✓        ✗            ✗              ✗                OK
cluster-example-2               0/9000000     0/9000000   7005136372083945490  ✗        ✓            ✗              ✗                OK
cluster-example-3               0/9000000     0/9000000   7005136372083945490  ✗        ✓            ✗              ✗                OK

Cloud Native PostgreSQLのFailoverテスト

ステータスが示すように2つのレプリカを実行しています。PostgreSQLのプライマリポッドに何らかの問題が発生した場合、クラスターはそのうちの1つにフェイルオーバーします。プライマリポッドを強制終了してフェイルオーバーが実行されるかをテストします。

kubectl delete pod –wait=false cluster-example-1 コマンドにて cluster-example-1 ポッドを削除します。これは問題発生シナリオとしてサーバーのハードシャットダウンをシミュレートしています。

$ kubectl delete pod --wait=false cluster-example-1
pod "cluster-example-1" deleted

kubectl cnp status cluster-exampleにてステータスを確認すると・・・

$ kubectl cnp status cluster-example
Failing over   Failing over to cluster-example-2
Name:              cluster-example
Namespace:         default
PostgreSQL Image:  quay.io/enterprisedb/postgresql:13.3
Primary instance:  cluster-example-2
Instances:         3
Ready instances:   2

Instances status
Pod name           Current LSN  Received LSN  Replay LSN  System ID            Primary  Replicating  Replay paused  Pending restart  Status
--------           -----------  ------------  ----------  ---------            -------  -----------  -------------  ---------------  ------
cluster-example-1  -            -             -           -                    -        -            -              -                pod not available
cluster-example-2  0/9000DD0                              7005136372083945490  ✓        ✗            ✗              ✗                OK
cluster-example-3               0/90000A0     0/90000A0   7005136372083945490  ✗        ✗            ✗              ✗                OK

cluster-example-1のステータスがpod not availableとなり、ダウンしたことが確認できます。

この状態から少し待ちステータスを確認すると・・・

Cluster in healthy state   
Name:              cluster-example
Namespace:         default
PostgreSQL Image:  quay.io/enterprisedb/postgresql:13.3
Primary instance:  cluster-example-2
Instances:         3
Ready instances:   3

Instances status
Pod name           Current LSN  Received LSN  Replay LSN  System ID            Primary  Replicating  Replay paused  Pending restart  Status
--------           -----------  ------------  ----------  ---------            -------  -----------  -------------  ---------------  ------
cluster-example-1               0/6004230     0/6004230   6984299688308645905  ✗        ✓            ✗              ✗                OK
cluster-example-2  0/6004230                              6984299688308645905  ✓        ✗            ✗              ✗                OK
cluster-example-3               0/6004230     0/6004230   6984299688308645905  ✗        ✓            ✗              ✗                OK

プライマリが切り替わり、2台のレプリカが稼働していることが確認できます。このように自動的に障害を検知してFailoverを行っていることが確認できました。

Interactive Demoはここまでになります。

いかがでしたでしょうか?
新しいものはまずは試してみるを気軽に実現できるInteractive Demoをぜひ皆様もご活用ください。もしこのデモについて詳しく知りたいという方がいましたらお気軽にサイオステクノロジーまでお問い合わせください。EDB Japanと協力しましてお客様のコンテナデータベースの導入支援を提供いたします。