Skip to content

[Qmonus SDK] マイグレーション準備

Qmonus SDKで実装したアプリケーションのパイプラインをマイグレーションするにあたって、以下の手順に示す事前準備を実施してください。

QVS Configの更新

お使いのQVS Config (.solarray/${env}/config.yml) がaxis-edgeリポジトリを参照している場合、以下のコマンドを実行しqmonusを参照するよう更新してください。

bash
# Config (環境) の数だけ実施
sed -i 's|axis-edge/design-patterns/|qmonus/design-patterns/|g' .solarray/stg/config.yml

また、QVS Config中で、remoteAppConfig定義をしている場合、以下の通り、remoteRepoConfigのCloud Native Adapterに変更してください。

yaml
@@ -1,8 +1,13 @@ designPatterns:
-remoteAppConfigs:
-  - name: solarray-appconfig # fixed value for axis design pattern
-    repository: github.com/qmonus/non-func-test_configs
-    revision: d4a0e8174e143810b69bb209097cfac5e52f4f2f
+  - pattern: github.com/qmonus/design-pattern/call:remoteRepoConfig
+    params:
+      name: solarray-appconfig
+      namespace: $(params.namespace)
+      nameSuffix: $(params.version)
+      repository: github.com/qmonus/sample_configs
+      revision: d4a0e8174e143810b69bb209097cfac5e52f4f2f

サービスアカウント(terraform)のロール確認

お使いのGoogle Cloud Projectに登録されているサービスアカウント(terraform)にKubernetes Engine 管理者 ロールが付与されていることを確認してください。

付与されていない場合、 Kubernetes Engine 管理者 ロールを付与してください。

Google Cloud サービスアカウント(terraform)のロール確認

TerraformによるGoogle Cloudリソースの整備

Qmonus VS v3でQmonus SDKをデプロイするために、Terraformを使って事前にGoogle Cloudリソースを準備します。 なお、KUJIRA基盤または共通AXIS基盤を利用している場合、基盤側で対応済みのためこの事前準備は不要です。

INFO

各リソースの導入背景は以下の通りです。

Mutating Webhook FW 設定

  • ReplicaSet Follower ControllerでMutating Webhookを利用しており、Controllerの待受ポートが8443,9443となっている。そのため、Kubernetes MasterからReplicaSet Follower ControllerへのMutating Webhookが着弾できるようにFWの8443, 9443ポートを許可するFirewall設定を実施する。

Argo Rollouts 導入

  • Argo Rolloutsとは高度なBlue/GreenやCanary等のデプロイ手法やProgressive Deliveryの機能をKubernetes上するフレームワークです。
  • Qmonus VS v3ではQmonus SDKのBlue/GreenデプロイをArgo Rolloutsによって実現するため、Argo Rollouts ControllerをGKEに導入します。

ReplicaSet Follower CRD(Custom Resource Definition)導入

  • Qmonus SDKをBlue/Greenデプロイする際にArgo Rollouts単体だと実現できない機能を提供するQmonusチームが作成したReplicaSet FollowerリソースのCRDをGKEに導入する。

Cert Manager 導入

  • ReplicaSet FollowerリソースのCRUD時にMutating Webhookが発火され、ReplicaSet Followerのコントローラで待ち受ける。そこで利用するTLS証明書の作成に利用するためGKEに導入する。

External Secret Operator 導入

  • Qmonus VS v2ではExternal Secretの利用にKES(Kubernetes External Secret)を利用していたが、KESがDeprecatedになったため、後継のESO(External Secret Operator)をGKEに導入する。
  • KESはQmonus VS Workflowで導入していたがESOの導入はWorkflowではなくTerraform(helm)にて導入する。

GKE Master Authorized Networks 設定

  • GKE Masterへのコントロール プレーン承認済みネットワークに、Qmonus VS v3の送信元IPアドレス(34.146.44.32/32, 35.200.92.31/32)を追加する。

以下、具体的なTerraformの修正・実行手順を示します。

core.tf 修正

  • PROJECTNAME/gcp/environment/ENVIRONMENT01/core.tf にFWルールを追加します。
  • target_tagsは初期構築時にGKE Nodeに設定しておく必要があります。(構築後に設定しようとするとGKE Nodeの再作成が走る)
  • そのため、VS v3マイグレーション実施ユーザはGKE Nodeに自動で割り振られるtarget_tagsをGoogle Cloudのコンソールで確認して設定します。
  • target_tags確認方法
    • Google Cloudコンソール > Compute Engine > VMインスタンスを選択します。 Google Cloud core.tf 修正手順
    • gke-xxxから始まるインスタンスを選択します。(複数台存在しているのでどれでもよい) Google Cloud core.tf 修正手順
    • ネットワークタグに表示されているものが今回利用するtarget_tagsです。(今回だとtarget_tags=gke-qmonus-solution-stg01-master-0d78e4ac-nodeとなる。) Google Cloud core.tf 修正手順
bash
# Allow to access from kubernetes master to replicaset follower controller
resource "google_compute_firewall" "qmonus_sdk_replicaset_follower_webhook" {
  name    = "qmonus-sdk-replicaset-follower-webhook"
  network = google_compute_network.qmonus01.self_link

  allow {
    protocol = "tcp"
    ports = [
      "8443",
      "9443",
    ]
  }

  direction = "INGRESS"
  priority  = 1002
  source_ranges = [
    var.google_container_cluster["qmonus01_master_ipv4_cidr_block"],
    var.google_container_cluster["qmonus02_master_ipv4_cidr_block"],
  ]

  target_tags = [<Google Cloudコンソールで確認したネットワークタ>] # ここにGoogle Cloudコンソールから取得したtarget_tags=gke-qmonus-solution-stg01-master-0d78e4ac-nodeを入れる。
}
  • PROJECTNAME/gcp/environment/ENVIRONMENT01/core.tf に External Secret Operatorのサービスアカウントを追加及びKubernetes External Secretとの紐付けを行います。(Stagingの例)
bash
# This SA is used to access SecretManager
module "service_account_external_secrets_operator" {
  source     = "../../modules/service_account"
  account_id = "external-secrets-operator"
  roles      = var.service_account_external_secrets_operator_roles
  project    = var.stg01_project
}

# Bind Kubernetes SA used by external secrets operator with Google SA
resource "google_service_account_iam_binding" "external-secrets-operator" {
  service_account_id = module.service_account_external_secrets_operator.name
  role               = "roles/iam.serviceAccountTokenCreator"
  members = [for s in var.external_secrets_operator_workload_id :
    "serviceAccount:${var.stg01_project}.svc.id.goog[${s}]"
  ]
  # Workload Identity must be configured prior to service account binding
  depends_on = [
    google_container_cluster.qmonus01
  ]
}

kubernetes_cluster.tf 修正

bash
...
master_authorized_networks_config {
    cidr_blocks {
      display_name = "Testbed UG30"
      cidr_block   = "115.69.226.68/32"
    }
    cidr_blocks {
      display_name = "NAT External Address of This Project#1 Tokyo"
      cidr_block   = "${google_compute_address.nat_external_address01.0.address}/32"
    }
    cidr_blocks {
      display_name = "NAT External Address of This Project#2 Tokyo"
      cidr_block   = "${google_compute_address.nat_external_address01.1.address}/32"
    }
    cidr_blocks {
      display_name = "NAT External Address of This Project#1 Osaka"
      cidr_block   = "${google_compute_address.nat_external_address02.0.address}/32"
    }
    cidr_blocks {
      display_name = "NAT External Address of This Project#2 Osaka"
      cidr_block   = "${google_compute_address.nat_external_address02.1.address}/32"
    }
    cidr_blocks {
      display_name = "NAT External Address of Qmonus VS Tekton Prod#1 V2"
      cidr_block   = var.ingress_api_gateway_allowed_cidrs_qmonus_vs.0
    }
    cidr_blocks {
      display_name = "NAT External Address of Qmonus VS Tekton Prod#2 V2"
      cidr_block   = var.ingress_api_gateway_allowed_cidrs_qmonus_vs.1
    }
    cidr_blocks {
      display_name = "NAT External Address of Qmonus VS Tekton Prod#1 V3" # この送信元IPアドレスを追加
      cidr_block   = var.ingress_api_gateway_allowed_cidrs_qmonus_vs.2
    }
    cidr_blocks {
      display_name = "NAT External Address of Qmonus VS Tekton Prod#2 V3" # この送信元IPアドレスを追加
      cidr_block   = var.ingress_api_gateway_allowed_cidrs_qmonus_vs.3
    }
  }
...

variables.tf の修正

  • PROJECTNAME/gcp/environment/ENVIRONMENT01/variables.tf に External Secret Operatorに割り当てるRole及び紐付けるKubernetes External Secretについて記載する。
bash
variable "service_account_external_secrets_operator_roles" {
  default = [
    "roles/secretmanager.secretAccessor",
  ]
}

# Used for access to secret manager by external secrets operator
# https://external-secrets.io/
variable "external_secrets_operator_workload_id" {
  default = [
    "qmonus-system/gcp-secret-manager",
  ]
}

Terraform 実行 (Google Cloud)

  • ローカル端末にてTerraformを実行して上記設定をGoogle Cloudリソースに反映します。
bash
# Terraformのリソースが置いてあるディレクトリに移動
cd qmonus-terraform/<プロジェクト>/gcp/environments/<環境>

# Terraformのinit
terraform init

# TerraformのDryrun
terraform plan

# TerraformのApply
terraform apply

GKEリソースを作成するTerrafom 作成

  • GKEリソースを作成するTerraformはVS v3マイグレーションユーザは今回初めて作成します。
  • Qmonus Terraformリポジトリのbase-templateディレクトリ(https://github.com/qmonus/qmonus-terraform/tree/main/base-template)からkubernetesディレクトリをコピーし、自身のプロジェクトのTerraformディレクトリ(gcpディレクトリと同じ階層)に配置します。
bash
.
├── <project names>
   ├── gcp # 既に各ユーザのディレクトリに存在している
   ├── environments
   ├── stg01
   ├── meta.tf
   ├── resources.tf
   └── variables.tf
   └── prod01
       ├── meta.tf
       ├── resources.tf
       └── variables.tf
   └── modules
       ├── kubernetes_engine
       ├── service_account
       ├── storage_bucket
       └── storage_bucket_iam_member
   └── kubernetes # 今回新たに追加するディレクトリ
       └── environments
           ├── stg01
   ├── crd.tf
   ├── meta.tf
   ├── resources.tf
   └── variables.tf
           └── prod01
               ├── crd.tf
               ├── meta.tf
               ├── resources.tf
               └── variables.tf

crd.tf 修正

  • PROJECTNAME/kubernetes/environments/ENVIRONMENT01/crd.tf にてcreate_namespaceをtrue->falseへ変更します。
  • 新規構築の場合、qmonus-systemというNamespaceが下記コードにて作成されるが、Qmonus VS v2を利用中のユーザは既にKubernetes External Secretを導入するWorkflowにてNamespaceは作成済みのため、Terraformで作成しないようにします。
bash
# external secret crd and cluster secret store resource
resource "helm_release" "external_secrets" {
    name       = "external-secrets"
    namespace  = "${var.external_secrets.namespace}"
    repository = "https://charts.external-secrets.io"
    chart      = "external-secrets"
    version    = "${var.external_secrets.version}"
    create_namespace = false # ここをtrue -> falseに変更する

    set {
        name  = "serviceAccount.create"
        value = false
    }

    lifecycle {
        prevent_destroy = true
    }
}

meta.tf 修正

  • PROJECTNAME/kubernetes/environments/ENVIRONMENT01/meta.tf のbucket名を記載します。
  • 既にgcpディレクトリ配下のmeta.tfファイル(PROJECTNAME/gcp/environment/stg01/meta.tf)にGoogle Cloud環境を構築した際のbucket名が記載されているので参考にします。
bash
provider "google" {
  alias = "tokengen"
}

provider "google" {
  access_token = data.google_service_account_access_token.tf_sa.access_token
  project      = var.stg01_project
  region       = var.region.tokyo
}

terraform {
  required_version = "1.1.7"

  backend "gcs" {
    bucket = "tf-state-kubernetes-${var.sdp_name}-${var.product_code}-stg" # Defined by manually #ここを手動で変更する
  }

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "4.15.0"
    }
    kubectl = {
      source  = "gavinbunney/kubectl"
      version = ">= 1.7.0"
    }
  }
}

Terraform State保存用Bucket作成

  • ローカル端末にて下記のコマンドを実行しGoogle CloudにTerraformのStateを保存するBucketを作成します。
bash
# NTT Com内ではPRODUCT_CODEにプロダクトコード(e.g., fic/dsigw/icms...etc)を入れてください
# プロダクトコードは eri.fic.nstechcloud.com などにおける fic の箇所に相当する名称です
# FICの場合はプロダクトコードがFIC,SDP名がERIと定義します

PRODUCT_CODE=<プロダクトコードを記載ください>
SDP_NAME=<SDP名を記載ください>
TERRAFORM_KUBERNETES_BUCKET_NAME="tf-state-kubernetes-${SDP_NAME}-${PRODUCT_CODE}-stg"
SERVICE_SRE_MAINTENANCE_GROUP=<サービス開発チームにてTerraformを実行できるユーザを入れたGoogle Groupのメールアドレスを記載ください> (e.g., [email protected]

# Create Terraform State Bucket
gsutil mb -p "${GCP_PROJECT_ID}" -l asia gs://"${TERRAFORM_KUBERNETES_BUCKET_NAME}"
gsutil versioning set on gs://"${TERRAFORM_KUBERNETES_BUCKET_NAME}"

# Grant bucket write permissions for terraform user group
gsutil acl ch -g "${SERVICE_SRE_MAINTENANCE_GROUP}":WRITE gs://"${TERRAFORM_KUBERNETES_BUCKET_NAME}"

Terraform 実行 (Kubernetes)

  • ローカル端末にてTerraformを実行してGKE上にリソース(Argo Rollouts/ReplicaSet Follower/Cert Manager/External Secret)を作成します。
  • Terraformを介してGKEにアクセスしてリソースを作成するため、GKEのMaster Endpointにアクセスできる環境で実行ください。
  • 作成したmeta.tfで宣言しているTerraform v1.1.7を利用ください。
bash
# Terraformのリソースが置いてあるディレクトリに移動
cd qmonus-terraform/<プロジェクト>/kubernetes/environments/<環境>

# Terraformのinit
terraform init

# TerraformのDryrun
terraform plan

# TerraformのApply
terraform apply