APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

導入方法: OpenShift 4.14クラスタ環境でVMware SQL with Postgres for Kubernetesを導入する

概要

OpenShift 4.14クラスタ環境に、VMware SQL with Postgres for Kubernetesを導入します。

参考資料

docs.vmware.com

前提

  • コンテナイメージの取得方法
    • インターネット上のリポジトリに直接アクセスするようにはしない。
    • OCP 内部イメージレジストリにイメージを push した上で、OCP 内部イメージレジストリからコンテナをデプロイする方法とする。
  • cert-manager
    • インストール対象
      • OSS の cert-maneger ではなく cert-manager Operator for Red Hat OpenShift をインストールする。
    • インストール方法
      • OperatorHubからcert-manager Operator for Red Hat OpenShiftをインストールする。
  • VMware Tanzu Network のアカウント。VMware Postgres Operator ディストリビューションを VMware Tanzu Network からダウンロードする際に必要となる。
    • ユーザー名:<任意>
    • パスワード:<任意>

手順

Helm のインストール

  • [ ] Helm をインストールする。

OpenShift Bastion ノードに helm をインストールする。

Helm | Installing Helm

  1. 希望のバージョンをダウンロードする。

     curl -OL https://get.helm.sh/helm-v3.14.3-linux-amd64.tar.gz
    
  2. 解凍する。

     tar -zxvf helm-v3.14.3-linux-amd64.tar.gz
    
  3. 解凍したディレクトリで helm バイナリを見つけて、目的の場所に移動する。

     mv linux-amd64/helm /usr/local/bin/helm
    

cert-manager Operator for Red Hat OpenShift のインストール

  • [ ] cert-manager Operator for Red Hat OpenShift をインストールする。

access.redhat.com

設定値は以下の通り。

  • 更新チャネル
    • stable-v1
  • オペレーターの Installed Namespace
    • Operator 推奨の namespace: cert-manager-operator
  • Update approval strategy
    • Manual

「手動による承認が必要です」と表示されたら、「承認」をクリックする。

Postgres Operator のインストール

サーバーホストがインターネットにアクセスできない場合、またはプライベートレジストリからインストールする場合は、ダウンロード可能なアーカイブ ファイルによる VMware Postgres Operator のセットアップを使用する。

  • [ ] registry.tanzu.vmware.com から VMware SQL with Postgres for Kubernetes の配布ファイルをダウンロードして、ローカルに展開する。
  • [ ] Helm チャート内で使われるイメージ を podman load する。
    • [ ] Postgres インスタンス イメージ
    • [ ] Postgres オペレーター イメージ
  • [ ] Postgres Operator 用のプロジェクト(postgres-operator)を作成する。
  • [ ] イメージにタグをつける。
    • [ ] Postgres インスタンス イメージ
    • [ ] Postgres オペレーター イメージ
  • [ ] イメージを OCP 内部イメージレジストリに push する。
    • [ ] Postgres インスタンス イメージ
    • [ ] Postgres オペレーター イメージ
  • [ ] postgres-operator プロジェクト の default SA が使っている Image pull secrets (※1)を調べる。
  • [ ] operator/operator-values-overrides.yaml を作成する。
    • [ ] operatorImage: を、OCP 内部イメージレジストリの URL のものに設定する。
    • [ ] postgresImage: を、OCP 内部イメージレジストリの URL のものに設定する。
    • [ ] dockerRegistrySecretName: を※1に設定する。
    • [ ] enableSecurityContext: を false に設定する。
  • [ ] helm install を実行し、Postgres Operator をインストールする。
  • [ ] 必要に応じて、Postgres Operator の nodeSelecor を設定する。

ダウンロードしたアーカイブ ファイルによるセットアップ

インストール先(エアギャップ・ネットワークなど)が VMware Tanzu Network にアクセスできない場合、または Operator とインスタンス・イメージをプライベート Docker レジストリにロードしたい場合は、この方法を選択する。

Installing a VMware Postgres Operator

  1. VMware Postgres Operator ディストリビューションを VMware Tanzu Network からダウンロードする。

    以下にアクセスする。

    Download VMware SQL with Postgres for Kubernetes — VMware Tanzu Network

    VMware Tanzu Network のアカウントでサインインする。

    • ユーザー名:<任意>
    • パスワード:<任意>

    サインインすると、以下のように表示される。「Click here to sign the EULA.」をクリックした後、「AGREE」をクリックする。

     Warning: Before you can download any components of this release you will need to sign an end user license agreement (EULA). After signing the EULA you will be able to download the components of this release until a new major version of this product is released (for generally available products), until any new release of this product is released (for alpha or beta products) or when the EULA itself changes. Click here to sign the EULA.
    

    Postgres for VMware SQL v2.3.0 のアイコンをクリックし、ダウンロードする。

    ダウンロードしたファイルを以下に配置する。

     [root@ocp-bastion tanzusql]# pwd
     /root/work/tanzusql
    

    Postgres for VMware SQL v2.3.0 の「i」アイコンをクリックし、ダウンロード元の SHA256 ハッシュ値を確認する。 sha256sum を実行し、ダウンロード元の SHA256 ハッシュ値と、配置済み SHA256 ハッシュ値が一致することを確認する。

     [root@ocp-bastion tanzusql]# sha256sum postgres-for-kubernetes-v2.3.0.tar.gz
     73a881b6925df131b5b5bc20b7072fcb965aacbb833b9a716031f7ca0a3237a8  postgres-for-kubernetes-v2.3.0.tar.gz
    
  2. ダウンロードしたソフトウェアを解凍する。

     cd /root/work/tanzusql
     tar xzf postgres-for-kubernetes-v2.3.0.tar.gz
    

    ディストリビューションは、postgres-for-kubernetes-v という名前の新しいディレクトリに解凍される (例: postgres-for-kubernetes-v2.3.0)。

  3. 新しい postgres-for-kubernetes-vディレクトリに変更する。

     cd ./postgres-for-kubernetes-v2.3.0
    
  4. Postgres インスタンス イメージをロードする。

     podman load -i ./images/postgres-instance
    
     cc967c529ced: Loading layer [==================================================>]  65.57MB/65.57MB
     2c6ac8e5063e: Loading layer [==================================================>]  991.2kB/991.2kB
     6c01b5a53aac: Loading layer [==================================================>]  15.87kB/15.87kB
     e0b3afb09dc3: Loading layer [==================================================>]  3.072kB/3.072kB
     faee4b69eae8: Loading layer [==================================================>]  29.74MB/29.74MB
     6bc08b5f8a06: Loading layer [==================================================>]  4.096kB/4.096kB
     3bfb028071fa: Loading layer [==================================================>]  331.4MB/331.4MB
     6ef1a056590e: Loading layer [==================================================>]  57.86kB/57.86kB
     Loaded image: postgres-instance:v2.3.0
    
  5. Postgres オペレーター イメージをロードする。

     podman load -i ./images/postgres-operator
    
     0d1435bd79e4: Loading layer [==================================================>]  3.062MB/3.062MB
     b50265a0f809: Loading layer [==================================================>]  40.87MB/40.87MB
     Loaded image: postgres-operator:v2.3.0
    
  6. 2 つの Docker イメージが利用可能になったことを確認する。

     podman images "postgres-*"
    
     REPOSITORY                   TAG         IMAGE ID      CREATED       SIZE
     localhost/postgres-operator  v2.3.0      86b4a40467a6  2 months ago  727 MB
     localhost/postgres-instance  v2.3.0      b71c37463e00  2 months ago  3.51 GB
    
  7. VMware Postgres Operator Docker イメージを選択したコンテナ レジストリにプッシュする。各イメージのプロジェクトとイメージ リポジトリ名を設定し、イメージにタグを付けて、Docker コマンド podman push を使用してプッシュする。

    次の例では、プロジェクト名(postgres-operator)を使用して、イメージにタグを付けて OCP 内部イメージレジストリ にプッシュする。

     oc new-project postgres-operator
     oc get project postgres-operator
     oc project postgres-operator
    
     PROJECT="postgres-operator"
     REGISTRY="default-route-openshift-image-registry.apps.test-ocp.example.com/${PROJECT}"
    
     oc login -u ocp-admin-user
     podman login -u ocp-admin-user -p $(oc whoami -t) default-route-openshift-image-registry.apps.test-ocp.example.com
    
     INSTANCE_IMAGE_NAME="${REGISTRY}/postgres-instance:$(cat ./images/postgres-instance-tag)"
     podman tag $(cat ./images/postgres-instance-id) ${INSTANCE_IMAGE_NAME}
     podman push ${INSTANCE_IMAGE_NAME}
    
     OPERATOR_IMAGE_NAME="${REGISTRY}/postgres-operator:$(cat ./images/postgres-operator-tag)"
     podman tag $(cat ./images/postgres-operator-id) ${OPERATOR_IMAGE_NAME}
     podman push ${OPERATOR_IMAGE_NAME}
    
     oc get is -n postgres-operator
    
  8. Operator のインストールは、「Postgres Operator のデプロイ」の手順に従う。

Postgres Operator のデプロイ

  • 「Image pull secrets:」を確認する。(この値を後ほど、operator/operator-values-overrides.yaml の dockerRegistrySecretName に設定する。)

      [root@ocp-bastion postgres-for-kubernetes-v2.3.0]# oc describe sa default -n postgres-operator
      Name:                default
      Namespace:           postgres-operator
      Labels:              <none>
      Annotations:         <none>
      Image pull secrets:  default-dockercfg-pf9n5
      Mountable secrets:   default-dockercfg-pf9n5
      Tokens:              default-token-stc5z
      Events:              <none>
    
  • [ ] operator/operator-values-overrides.yaml を作成する。

    • [ ] operatorImage: を、OCP 内部イメージレジストリの URL のものに設定する。
    • [ ] postgresImage: を、OCP 内部イメージレジストリの URL のものに設定する。
    • [ ] dockerRegistrySecretName: を※1に設定する。
    • [ ] enableSecurityContext: を false に設定する。

operator/operator-values-overrides.yaml

---
# specify the url for the docker image for the operator, e.g. gcr.io/<my_project>/postgres-operator
operatorImage: image-registry.openshift-image-registry.svc:5000/postgres-operator/postgres-operator:v2.3.0

# specify the docker image for postgres instance, e.g. gcr.io/<my_project>/postgres-instance
postgresImage: image-registry.openshift-image-registry.svc:5000/postgres-operator/postgres-instance:v2.3.0

# specify the name of the docker-registry secret to allow the cluster to authenticate with the container registry for pulling images
dockerRegistrySecretName: default-dockercfg-pf9n5

# override the default self-signed cert-manager cluster issuer
certManagerClusterIssuerName: postgres-operator-ca-certificate-cluster-issuer

# override the namespace of the cert-manager installation namespace
certManagerNamespace: cert-manager

# set the resources for the postgres operator deployment
resources:
  limits:
    cpu: 1000m
    memory: 1Gi
  requests:
    cpu: 1000m
    memory: 1Gi

# enabled security context for the postgres-operator deployment and the managed instances, typically disabled on OpenShift clusters
enableSecurityContext: false

クラスタにインスタンス CRD が以前にインストールされていないことを確認する。

oc get crd postgres.sql.tanzu.vmware.com

これが新しい Operator インストールの場合、結果は次のようになる。

Error from server (NotFound): customresourcedefinitions.apiextensions.k8s.io "postgres.sql.tanzu.vmware.com" not found

Postgres Operator をデプロイする。

helm install postgres-operator /root/work/tanzusql/postgres-for-kubernetes-v2.3.0/operator/ \
    --values=/root/work/tanzusql/postgres-for-kubernetes-v2.3.0/operator/operator-values-overrides.yaml \
    --namespace=postgres-operator \
    --wait

Postgres Operator の nodeSelecor 設定

必要に応じて、Postgres Operator の nodeSelecor を設定する。

oc patch deployments postgres-operator -n postgres-operator -p '{"spec": {"template": {"spec": {"nodeSelector": {"node-role.kubernetes.io/infra": ""}}}}}'

Postgres インスタンスのデプロイ

  • [ ] Postgres インスタンス用のプロジェクト(test-postgres1)を作成する。
  • [ ] Postgres インスタンス用のプロジェクトの default サービスアカウントを、postgres-operator プロジェクト の system:image-puller ロールにバインドする。
  • [ ] test-postgres1 プロジェクト の default SA が使っている Image pull secrets (※2)を調べる。
  • [ ] example/postgres.yaml を作成する。
    • [ ] spec.imagePullSecret.name を※2に設定する。
    • [ ] spec.spec.monitorStorageClassName: thin-csi に設定する。
    • [ ] spec.highAvailability: ブロックのコメントアウトを外す。
    • [ ] spec.backupLocation: ブロックをコメントアウトする。
    • [ ] spec.monitorStorageClassName: 指定したい場合はコメントアウトを外す。無指定の場合は、デフォルトの StorageClass が使われる。
    • [ ] 必要に応じてnodeAffinityの設定を追加する。
  • [ ] Postgres インスタンスをデプロイする。

Project を作成する

  • Postgres インスタンス用のプロジェクト(test-postgres1)を作成する。

      oc new-project test-postgres1
      oc get project test-postgres1
      oc project test-postgres1
    

Pod が複数のプロジェクト間でイメージを参照できるようにする設定

  • Postgres インスタンス用のプロジェクトの default サービスアカウントを、postgres-operator プロジェクト の system:image-puller ロールにバインドする。

5.4. イメージプルシークレットの使用 OpenShift Container Platform 4.14 | Red Hat Customer Portal

test-postgres1 の Pod が postgres-operator のイメージを参照できるようにするには、test-postgres1 のサービスアカウントを postgres-operator の system:image-puller ロールにバインドする。

oc policy add-role-to-user \
  system:image-puller system:serviceaccount:test-postgres1:default \
  --namespace=postgres-operator

もし、上記で追加したロールを削除したくなった場合は、以下のコマンドで削除できる。

oc adm policy remove-role-from-user system:image-puller system:serviceaccount:test-postgres1:default -n postgres-operator

このロールを追加すると、デフォルトのサービスアカウントを参照する test-postgres1 の Pod は postgres-operator からイメージをプルできるようになる。

  • test-postgres1 プロジェクト の default SA が使っている Image pull secrets (※2)を調べる。

「Image pull secrets:」を確認する。(この値を後ほど、example/postgres.yaml の spec.imagePullSecret.name に設定する。)

[root@ocp-bastion postgres-for-kubernetes-v2.3.0]# oc describe sa default -n test-postgres1
Name:                default
Namespace:           test-postgres1
Labels:              <none>
Annotations:         <none>
Image pull secrets:  default-dockercfg-4j7wg
Mountable secrets:   default-dockercfg-4j7wg
Tokens:              default-token-8dnr2
Events:              <none>

Postgres インスタンスの構成

利用可能な CRD については以下に記載がある。 Postgres CRD API Reference

今回は、以下の項目を設定する。

  • [ ] example/postgres.yaml を作成する。
    • [ ] spec.imagePullSecret.name を※2に設定する。
    • [ ] spec.spec.monitorStorageClassName: thin-csi に設定する。
    • [ ] spec.highAvailability: ブロックのコメントアウトを外す。
    • [ ] spec.backupLocation: ブロックをコメントアウトする。
    • [ ] spec.monitorStorageClassName: 指定したい場合はコメントアウトを外す。無指定の場合は、デフォルトの StorageClass が使われる。
    • [ ] 必要に応じてnodeAffinityの設定を追加する。

/root/work/tanzusql/example/postgres.yaml

---
apiVersion: sql.tanzu.vmware.com/v1
kind: Postgres
metadata:
  name: postgres-sample
  namespace: test-postgres1
spec:
  #
  # Global features
  #
  pgConfig:
    dbname: postgres-sample
    username: pgadmin
    appUser: pgappuser
    readOnlyUser: pgrouser
    readWriteUser: pgrwuser
  #  customConfig:
  #    postgresql:
  #      name:
  #    pghba:
  #      name:
  postgresVersion:
    name: postgres-15 # View available versions with `kubectl get postgresversion`
  serviceType: ClusterIP
  serviceAnnotations:
    test: test
  readOnlyServiceType: ClusterIP
  #  readOnlyServiceAnnotations:
  seccompProfile:
    type: RuntimeDefault
  imagePullSecret:
    name: default-dockercfg-4j7wg
  persistentVolumeClaimPolicy: delete
  highAvailability:
    enabled: true
    readReplicas: 1
#  logLevel: Debug
#  backupLocation:
#    name: backuplocation-sample
#  certificateSecretName:
#  deploymentOptions:
#    continuousRestoreTarget: true
#    sourceStanzaName: <sample-stanza-from-prod-instance>

  #
  # Data Pod features
  #
  storageClassName: thin-csi
  storageSize: 400M
  sharedMemorySize: 64Mi
  dataPodConfig:
#    tolerations:
#      - key:
#        operator:
#        value:
#        effect:
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                  - key: type
                    operator: In
                    values:
                      - data
                      - monitor
                  - key: postgres-instance
                    operator: In
                    values:
                      - postgres-sample
              topologyKey: kubernetes.io/hostname
            weight: 100

  #
  # Monitor Pod features
  #
  monitorStorageClassName: thin-csi
  monitorStorageSize: 300M
  monitorPodConfig:
#    tolerations:
#      - key:
#        operator:
#        value:
#        effect:
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                  - key: type
                    operator: In
                    values:
                      - data
                      - monitor
                  - key: postgres-instance
                    operator: In
                    values:
                      - postgres-sample
              topologyKey: kubernetes.io/hostname
            weight: 100

  #
  # Resources
  #
  resources:
    data:
      limits:
        cpu: 800m
        memory: 800Mi
      requests:
        cpu: 800m
        memory: 800Mi
    monitor:
      limits:
        cpu: 800m
        memory: 800Mi
      requests:
        cpu: 800m
        memory: 800Mi
    metrics:
      limits:
        cpu: 100m
        memory: 100Mi
      requests:
        cpu: 100m
        memory: 100Mi

Postgres インスタンスをデプロイする。

cd /root/work/tanzusql/
oc apply -f example/postgres.yaml

Pod が Running になっていることを確認する。

[root@ocp-bastion tanzusql]# oc get pods -n test-postgres1 -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP             NODE             NOMINATED NODE   READINESS GATES
postgres-sample-0           5/5     Running   0          107s    10.0.173.160   ocp-worker-001   <none>           <none>
postgres-sample-1           5/5     Running   0          107s    10.0.180.32    ocp-worker-003   <none>           <none>
postgres-sample-monitor-0   4/4     Running   0          2m39s   10.0.180.163   ocp-worker-002   <none>           <none>

postgres へのアクセス

参考

docs.vmware.com

HA 構成の確認

Configuring High Availability in VMware SQL with Postgres for Kubernetes

どの Pod が Primary であるか、確認する。

[root@ocp-bastion tanzusql]# oc exec pod/postgres-sample-1 -n test-postgres1 -- pg_autoctl show state
Defaulted container "pg-container" out of: pg-container, instance-logging, reconfigure-instance, postgres-metrics-exporter, postgres-sidecar
  Name |  Node |                                                                     Host:Port |       TLI: LSN |   Connection |      Reported State |      Assigned State
-------+-------+-------------------------------------------------------------------------------+----------------+--------------+---------------------+--------------------
node_1 |     1 | postgres-sample-1.postgres-sample-agent.test-postgres1.svc.cluster.local:5432 |   1: 0/3525EF8 |   read-write |             primary |             primary
node_2 |     2 | postgres-sample-0.postgres-sample-agent.test-postgres1.svc.cluster.local:5432 |   1: 0/3525EF8 |    read-only |           secondary |           secondary

この例では、postgres-sample-1 が Primary で、read-write である。そのため、次のレコードの追加を行うステップでは postgres-sample-1 に接続する。

postgres インスタンス pod へのアクセス

コンテナにログインする。以下はコンテナにログインし、レコードを追加するサンプルである。

[root@e10isesak-tpoc903100 tanzusql]# oc exec -it postgres-sample-1 -n test-postgres1 -- psql
CREATE TABLE users (name TEXT, age INTEGER);
INSERT INTO users (name, age) VALUES ('John', 25);
INSERT INTO users (name, age) VALUES ('hoge', 88);
SELECT * from users;
exit