Cloud Native PostgreSQLのInteractive Demoを使ってみよう

EDBでは、エンタープライズ用途でもKubernetes上でPostgreSQLが利用できるよう開発が進められているCloud Native PostgreSQLのInteractive Demoについて紹介します。

このInteractive DemoはKubernetes Operator を利用してデータベースの構築から運用までをブラウ上から簡単に試す事ができます。

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を利用するためのサイトにアクセスすることができます。

INTERACTIVE DEMO
Installation, Configuration and Deployment Demo
https://www.enterprisedb.com/docs/kubernetes/cloud_native_postgresql/interactive_demo/

EDB Cloud Native PostgreSQL Documentation

このサイトでは、以下の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ご確認ください。
https://github.com/EnterpriseDB/kubectl-cnp

以下のコードを全行コピーして、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と協力しましてお客様のコンテナデータベースの導入支援を提供いたします。


INTERACTIVE DEMO
Installation, Configuration and Deployment Demo

EDB Postgres for Kubernetes v1 - Installation, Configuration and Deployment Demo
Walk through the process of installing, configuring and deploying the EDB Postgres for Kubernetes Operator via a browser...