2.4. Kubernetes(Helm チャート)

2.4.1. 必須要件

  • 動作に必要な環境

    • (ローカル環境に構築する場合のみ)kind v0.17.0

    • kubectl v1.26.x

    • Kubernetes v1.24.x 以上

  • 動作に必要なミドルウェア

    • PostgreSQL 15系

    • InfluxDB v1.8系

    • NATS v2.9系

    • S3 、または minio (S3互換のオブジェクトストレージ)

      注釈

      ミドルウェアはKubernetesクラスタから参照できるネットワークに配置してください。

    • デプロイ環境に応じたIngress Controller(AWS Load Balancer Controllerなど)

  • インストールの手順で使用するツール

  • 用意しておくファイル

    • サーバー証明書

  • 最小ハードウェア要件

    • 20GB以上の空きディスク容量

    • Kubernetesクラスタのノード構成は次のいずれかを満たすこと

      • AWS m5.large相当(vCPU2、メモリ8GiB)のインスタンス3台以上

注釈

deployment.zip 内の k8s ディレクトリに本章を基準とした、構築のためのサンプルファイルがあります。 必要に応じて参照してください。

2.4.2. 外部ミドルウェアの設定

intdashが使用するミドルウェアについては、既にKubernetesクラスタから参照できるネットワークにインストールされている前提として進めます。 ミドルウェアのインストール方法は各種公式Webサイトを参照してください。

2.4.2.1. PostgreSQL

  1. psql コマンドで対話型シェルを起動します。

sudo -u postgres psql -d template1
  1. データベースとユーザーを作成します。パスワードは同一ものを設定します。

CREATE ROLE "intdash-api-broker" WITH LOGIN;
ALTER ROLE "intdash-api-broker" PASSWORD '<生成したパスワード>';
CREATE DATABASE "intdash-api-broker" OWNER intdash;

CREATE ROLE "intdash-api-auth" WITH LOGIN;
ALTER ROLE "intdash-api-auth" PASSWORD '<生成したパスワード>';
CREATE DATABASE "intdash-api-auth" OWNER intdash;

CREATE ROLE "intdash-api-measurement" WITH LOGIN;
ALTER ROLE "intdash-api-measurement" PASSWORD '<生成したパスワード>';
CREATE DATABASE "intdash-api-measurement" OWNER intdash;

CREATE ROLE "intdash-api-tenant" WITH LOGIN;
ALTER ROLE "intdash-api-tenant" PASSWORD '<生成したパスワード>';
CREATE DATABASE "intdash-api-tenant" OWNER intdash;

CREATE ROLE "intdash-api-media" WITH LOGIN;
ALTER ROLE "intdash-api-media" PASSWORD '<生成したパスワード>';
CREATE DATABASE "intdash-api-media" OWNER intdash;

CREATE ROLE "intdash-api-webhook" WITH LOGIN;
ALTER ROLE "intdash-api-webhook" PASSWORD '<生成したパスワード>';
CREATE DATABASE "intdash-api-webhook" OWNER intdash;

CREATE ROLE "vm2m-data-viz-backend" WITH LOGIN;
ALTER ROLE "vm2m-data-viz-backend" PASSWORD '<生成したパスワード>';
CREATE DATABASE "vm2m-data-viz-backend" OWNER intdash;

注釈

セキュリティを向上させる場合はすべてのロールに対して別々のパスワードでも可能です。その場合は values.yaml を変更してください。 詳細については設定リファレンス Kubernetes(Helm チャート) を参照してください。

2.4.2.2. NATS

  1. ユーザー情報を設定します。NATS の設定ファイルに authorization セクションを設定します。パスワードは、 natsclinats server passwd コマンドを使用して生成します。

     ...
    
    authorization: {
        user: intdash,
        password: <nats server passwd で生成したBcrypt文字列>
    }
     ...
    

2.4.2.3. JetStream

  1. ユーザー情報を設定します。NATS の設定ファイルに authorization セクションを設定します。パスワードは natsclinats server passwd コマンドを使用して生成します。

     ...
    
    authorization: {
        user: intdash,
        password: <nats server passwd で生成したBcrypt文字列>
    }
     ...
    

2.4.2.4. S3(minio)

  1. S3バケットを作成します。intdashはMeasurement ServiceとMedia Serviceで1つずつバケットを使用するため、それぞれ作成します。S3を使用できない場合は S3完全互換のOSSである minio を使用します。特別な理由がない限りはS3を推奨します。

    1. 次のコマンドでバケットを作成します。Media Service用のバケット intdash-media-service と Measurement Service用のバケット intdash-measurement-service を作成します。

      export REGION=<リージョン名:例 ap-northeast-1やus-east-1など>
      
      aws s3api create-bucket \
        --bucket intdash-media-service \
        --create-bucket-configuration LocationConstraint=${REGION}
      
      aws s3api create-bucket \
        --bucket intdash-measurement-service \
        --create-bucket-configuration LocationConstraint=${REGION}
      

      注釈

      バケット作成時のオプションは適宜カスタマイズして作成してください。

2.4.2.5. InfluxDB

  1. influx コマンドで対話型シェルを開きます。

influx
  1. 次のコマンドでユーザーを作成します。

> CREATE USER intdash WITH PASSWORD '<任意のパスワード>' WITH ALL PRIVILEGES;
> auth
username: intdash
password: <パスワード入力>
> CREATE DATABASE "intdash-measurement" WITH SHARD DURATION 1h;

2.4.3. 構築手順

  1. コンテナイメージはAWS Marketplaceにて提供されます。最初にAWSアカウントからコンテナ製品をサブスクライブします

  2. 次のコマンド使用し、Docker Registry 及び Helm Registry へログインします。

    export IMAGE_REPOSITORY_BASE=<Dockerレジストリ:例 <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com>
    export REGION=<リージョン名:例 ap-northeast-1やus-east-1など>
    
    aws ecr get-login-password \
      --region ${REGION} | docker login --username AWS \
      --password-stdin "${IMAGE_REPOSITORY_BASE}"
    aws ecr get-login-password \
     --region ${REGION} | helm registry login \
     --username AWS \
     --password-stdin "${IMAGE_REPOSITORY_BASE}"
    

    注釈

    awsへ認証していない場合は、aws configure を実行し、認証情報を設定してください。

  3. クラスタを構築します。

  1. ローカル環境にKubernetesクラスタを構築します。 kind を使用するため、あらかじめインストールしてください。

  2. クラスタを作成します。 kind-cluster.yaml という名前の次の内容のファイルを作成します。

    kind: Cluster
    name: intdash
    apiVersion: kind.x-k8s.io/v1alpha4
    nodes:
    - role: control-plane
      kubeadmConfigPatches:
      - |
        kind: InitConfiguration
        nodeRegistration:
          kubeletExtraArgs:
            node-labels: "ingress-ready=true"
      extraPortMappings:
      - containerPort: 80
        hostPort: 80
        protocol: TCP
      - containerPort: 443
        hostPort: 443
        protocol: TCP
      # QUIC用のポート
      - containerPort: 32443
        hostPort: 11443
        protocol: UDP
    

注釈

Docker Rootless Modeを使用している場合、特権ポートの公開には設定が必要です。 Exposing privileged ports を参照してください。

  1. 作成したファイルを使用して、次のコマンドを実行します。

    # クラスタの作成
    kind create cluster --config=./kind-cluster.yaml
    # クラスタ情報の表示
    kubectl cluster-info --context kind-intdash
    # クラスタのコンテキストを使用
    kubectl config use-context kind-intdash
    
  2. Ingress NGINX Controller を有効にします。Helmチャートを利用します。まず次の内容で nginx-values.yaml を作成します。これには kind 用のパッチも含まれています。

    controller:
      updateStrategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 1
      hostPort:
        enabled: true
      terminationGracePeriodSeconds: 0
      service:
        type: NodePort
      watchIngressWithoutClass: true
    
      nodeSelector:
        ingress-ready: "true"
      tolerations:
        - key: "node-role.kubernetes.io/master"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
    
      publishService:
        enabled: false
      extraArgs:
        publish-status-address: localhost
    

    注釈

    ChartのValuesについては、 Ingres NGINX ControlerのCharts を参照してください。設定のカスタマイズは可能ですが、intdashサーバーとしての動作に影響がないようにしてください。

  3. クラスタにNGINX Ingress Controllerを適用します。

helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace -f ./nginx-values.yaml

# 作成完了まで待機
kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=90s
  1. (S3を使用する場合のみ)クラスタ上にS3用のサービスアカウントを作成します。

    1. 次の内容で policy.json を保存します。

      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "s3:*"
            ],
            "Resource": "arn:aws:s3:::<Media Serviceのバケット名:例 intdash-media-service>"
          },
          {
            "Effect": "Allow",
            "Action": [
              "s3:*"
            ],
            "Resource": "arn:aws:s3:::<Measurement Serviceのバケット名:例 intdash-measurement-service>"
          }
        ]
      }
      

    注釈

    バケット名は前述の手順で作成したバケット名を指定してください。

    1. IAMポリシーを作成します。

      aws iam create-policy \
      --policy-name IntdashServiceS3IAMPolicy \
      --policy-document file://policy.json
      
      # 作成されたポリシーの情報が出力されます。
      
    2. サービスアカウントを作成します。

    1. EC2インスタンス上にkindクラスタを構築している場合、インスタンスにロールを割り当てます。 詳細については Amazon EC2 の IAM ロール を参照してください。

    2. EC2インスタンス以外の場合は、IAMロールをアタッチしたIAMユーザーを作成し、IAMユーザーのアクセスキーとアクセスシークレットをアプリケーションの設定ファイルに記述します。

    export USER_NAME=<任意のユーザー名:例 test-user>
    export POLICY_ARN=<前の手順で作成したIAMポリシーのARNを指定します:例 arn:aws:iam::xxxxxxxxxxxx:policy/IntdashServiceS3IAMPolicy>。
    aws iam create-user --user-name "${USER_NAME}"
    aws iam attach-user-policy --user-name "${USER_NAME}" --policy-arn "${POLICY_ARN}"
    aws iam create-access-key --user-name "${USER_NAME}"
    
    # 出力されたアクセスKeyIdとSecretAccessKeyを設定ファイルに記述します。
    
  2. 構築するための変数を設定します。以降はこれらの変数が設定されている前提で進めます。

    export CHARTS_VERSION=<チャートのバージョン>
    export IMAGE_REPOSITORY_BASE=<アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com
    
  3. (kindのみ) ノードからイメージをPullできるようにシークレットを作成します。

    TOKEN=$(aws ecr get-login-password --region ap-northeast-1)
    kubectl create secret docker-registry intdash-ecr-token \
      --docker-server="${IMAGE_REPOSITORY_BASE}" \
      --docker-username="AWS" \
      --docker-password="${TOKEN}"
    
  4. あらかじめ用意しておいたサーバー証明書を登録します。

  1. 次のコマンドでサーバー証明書のシークレットを作成します。

export SERVER_CERT=<サーバー証明書のファイルのパス>
export SERVER_CERT_KEY=<サーバー証明書のキー>

kubectl create secret tls intdash-tls \
  --cert=${SERVER_CERT} \
  --key=${SERVER_CERT_KEY}

注釈

cert-manager などを利用することも可能です。運用に応じて変更してください。

  1. Helmチャートの設定ファイルを作成します。まず、共通設定の base.yaml を作成します。

    image:
      registry: "" <---- イメージレジストリ:例 <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com
    ingress:
      host: "" <---- ホスト名:例 example.com
      enabled: true
      tls: true
    intdashService:
      config:
        postgres:
          address: ""    <---- PostgreSQLのアドレス:例 postgresql:5432
          password: ""   <---- PostgreSQLのパスワード
        jet-stream:
          url: ""        <---- JetStreamのURL:例 nats://jet-stream:4222
          password: ""   <---- JetStreamのパスワード
        nats:
          url: ""        <---- NatsのURL:例 nats://nats:4222
          password: ""   <---- Natsのパスワード
        data-point-write-dbs:
          0:
            driver: influx
        data-point-read-dbs:
          0:
            driver: influx
        influxdbs:
          0:
            address: ""   <---- InfluxDBのアドレス:例 http://influxdb:8086
            dbname: ""    <---- InfluxDBのDB名
            username: ""  <---- InfluxDBのユーザー
            password: ""  <---- InfluxDBのパスワード
        oauth2:
          issuer-base: ""              <---- https://<ホスト名:例 example.com>
          sign-in-page-url: ""         <---- https://<ホスト名:例 example.com>/console/signin/
          change-password-page-url: "" <---- https://<ホスト名:例 example.com>/oauth2/authorization/api/password-change/
          web-client-redirect-base-urls:
            - ""    <---- https://<ホスト名:例 example.com>
        user-email:
          verification-page-uri: ""    <---- https://<ホスト名:例 example.com>/console/email/activate/
        user-password:
          recovery-page-uri: ""        <---- https://<ホスト名:例 example.com>/
        upload:
          s3-storage:
            # 変更があるときのみ
            # bucket-name: ""  <---- Measurement Serviceが使用するバケット名:例 intdash-measurement-service
            # minio のみ
            # endpoint: ""     <---- ストレージのエンドポイント:例 http://storage:9000
            # 下記は必要に応じて設定する。
            # region = 'ap-northeast-1'
            # access-key = ''
            # secret-access-key = ''
            # force-path-style = true
        media-filmed:
          storage:
            type: s3
            s3:
              # 変更があるときのみ
              # bucket-name: "" <---- Media Serviceが使用するバケット名:例 intdash-media-service
              # minio のみ
              # endpoint: ""    <---- ストレージのエンドポイント:例 http://storage-minio:9000
              # 下記は必要に応じて設定する。
              # region = 'ap-northeast-1'
              # access-key = ''
              # secret-access-key = ''
              # force-path-style = true
          jet-stream:
            url: ""        <---- JetStreamのURL:例 nats://jet-stream:4222
            password: ""   <---- JetStreamのパスワード
        tenant:
          enable: true
          basic-password: ""   <---- ランダムで生成したパスワード
        quicNodePort: 32443    <---- QUICのノードポート
    intdashWebTenants:
      config:
        basic-auth:
          password: ""   <---- ランダムで生成したパスワード
        private-intdash-api:
          basic-auth:
            password: ""   <---- tenant.basic-passwordで設定したパスワード
    

    注釈

    Helmチャートのvalues.yamlの詳細については、 設定リファレンス を参照してください。

9 . 環境に応じた設定ファイルを作成します。

  1. kind.yaml を作成します。

    ingress:
      ingressClassName: "nginx"
      secretName: "intdash-tls"
      annotations:
        nginx.ingress.kubernetes.io/app-root: /console/
    imagePullSecrets:
      - name: intdash-ecr-token
    # QUICを公開するための設定
    intdashApiBroker:
      quicNodePort: 32443  <---- kindでexportしたポートを指定
    
  1. 次のコマンドでクラスタにHelmチャートをインストールします。

export ENV_VALUES_YAML=<環境に応じたファイル: 例 aws.yaml>
helm install intdash oci://"${IMAGE_REPOSITORY_BASE}"/charts/intdash --version "${CHARTS_VERSION}" -f ./base.yaml -f ${ENV_VALUES_YAML}
  1. しばらく待つとサインインURLと初期ユーザーパスワードの表示方法が標準出力に出力されます。初期ユーザーパスワードとアクセスURLは控えておきます。

Intdash is installed successfully!

  URL:       https://<ホスト名:例 example.com>
  Tenant UI: https://<ホスト名:例 example.com>/internal/tenants


You can login with username: intdash and the password generated during the installation. You can find the password by running:

  kubectl -n default get secret intdash-api-auth-password -o jsonpath="{.data.BOOTSTRAP_USER_PASSWORD}" | base64 --decode

Also you can login to Tenant UI with username: intdash and the password generated during the installation. You can find the password by running:

  kubectl -n default get secret intdash-web-tenants-basic-auth -o jsonpath="{.data.password}" | base64 --decode
  1. クラスタの準備が完了するまで待ちます。

kubectl wait --timeout=600s --for=condition=available deployment/intdash-api-tenant
  1. 構築後の設定を行います。

    1. NGINX Ingress Controller を再起動します。

    kubectl rollout restart -n ingress-nginx deployment ingress-nginx-controller
    
    1. 名前解決ができるようにDNSの設定をします。運用に応じて設定してください。

  2. Webブラウザーで https://<ホスト名:例 example.com>/ にアクセスします。

  3. 次の内容でサインインします。

  • ユーザー名:intdash

  • パスワード:<kubectl -n default get secret intdash-api-auth-password -o jsonpath="{.data.BOOTSTRAP_USER_PASSWORD}" | base64 --decode で出力されたパスワード>

  1. サインインが完了し、アプリケーションの画面が表示されれば構築完了です。

注釈

kindを使用したローカル環境でアプリケーションにアクセスできない場合は、以下のようにintdashフロントエンドアプリケーションのみを削除し再度 helm upgrade を実行してください。

kubectl delete deployments.apps \
   intdash-web-gateway \
   intdash-web-admin-console \
   intdash-web-authentication \
   intdash-web-client-auth \
   intdash-web-edge-finder \
   intdash-web-meas-hub \
   intdash-web-media-explorer \
   intdash-web-my-page \
   intdash-web-project-console \
   intdash-web-shared-assets \
   intdash-web-tenants \
   intdash-web-client-auth-redirector

helm upgrade intdash oci://"${IMAGE_REPOSITORY_BASE}"/charts/intdash \
  --version "${CHARTS_VERSION}" \
  -f ./base.yaml -f ${ENV_VALUES_YAML}