前回はAWS上にArgo CDを構築しました。今回はGCPにArgo CDをデプロイしていきたいと思います。
必要なもの
- Googleアカウント
- GCPプロジェクト
- gcloud CLI
- Terraform
- Helm
- kubectl
- argocd(CLI)
請求先アカウントが設定済みのGCPプロジェクトを用意してください。GKEを動かすためには請求先アカウントを設定しておく必要があります。
gcloud CLI, Terraform, Helm, kubectl, argocdは公式ドキュメントにインストール方法が記載されています。以下のドキュメントを参考にインストールをお願いします。
Terraformのバージョンはv1.3.3を使用しました。
gcloudコマンドでGCPプロジェクトを操作できるように、gcloud auth login
とgcloud config set project PROJECT_ID
で対象のプロジェクトを設定してください。手順は以下です。
GCP
新しいGCPプロジェクトを作って試したところ、TerraformやExternalDNSでGCPのリソースを操作するには以下の権限が必要になりました。
gcloud services enable container.googleapis.com gcloud services enable dns.googleapis.com
GKE
以下のテキストをmain.tf
というファイル名で保存してください。これはGKEクラスターを作るためのコードで、test
という名前のGKEクラスターが起動してきます。
variable "project" {} variable "region" {} terraform { required_providers { google = { source = "hashicorp/google" version = "4.41.0" } } } provider "google" { project = var.project region = var.region } resource "random_id" "suffix" { byte_length = 4 } resource "google_service_account" "edns" { account_id = "edns-${random_id.suffix.hex}" } resource "google_project_iam_member" "edns" { project = var.project role = "roles/dns.admin" member = "serviceAccount:${google_service_account.edns.email}" } resource "google_service_account_iam_member" "edns" { service_account_id = google_service_account.edns.name role = "roles/iam.workloadIdentityUser" # kube-system Namespaceに作成されたexternal-dnsサービスアカウントをGCPのサービスアカウントに紐づける member = "serviceAccount:${var.project}.svc.id.goog[kube-system/external-dns]" } resource "google_service_account" "gke" { account_id = "gkesa-${random_id.suffix.hex}" } locals { gke_roles = [ "roles/logging.admin", "roles/monitoring.admin", ] } resource "google_project_iam_member" "gke" { project = var.project count = length(local.gke_roles) role = element(local.gke_roles, count.index) member = "serviceAccount:${google_service_account.gke.email}" } resource "google_container_cluster" "primary" { name = "test" location = var.region remove_default_node_pool = true initial_node_count = 1 workload_identity_config { workload_pool = "${var.project}.svc.id.goog" } } resource "google_container_node_pool" "primary" { name = "test-node-pool" location = var.region cluster = google_container_cluster.primary.name node_count = 1 management { auto_repair = true auto_upgrade = true } node_config { preemptible = true machine_type = "e2-medium" service_account = google_service_account.gke.email oauth_scopes = [ "https://www.googleapis.com/auth/cloud-platform" ] workload_metadata_config { mode = "GKE_METADATA" } } }
ExternalDNSがCloud DNSを操作するためにWorkload Identityという機能を使用しています。詳細は以下をご覧ください。
以下のテキストをterraform.tfvars
というファイルに保存してください。
REPLACE ME
となっているところに、今回操作するGCPのプロジェクトIDをいれてください。
region
は変更しても構いませんが、この記事ではasia-northeast1
という前提で進めていきます。
project = "REPLACE ME" region = "asia-northeast1"
main.tf
とterraform.tfvars
を保存したディレクトリで以下のコマンドを実行してください。
terraform init
現状のインフラとコードの差分をチェックします。
terraform plan
GKEクラスターを作成します。
terraform apply
kubectlが使えるように、今回起動したGKEクラスターをkubeconfigに追加します。
gcloud container clusters get-credentials test --region asia-northeast1
以下のコマンドを実行し、Server Versionが取得できれば成功です。
kubectl version --short
Argo CD
Argo CDをHelmからインストールするので、HelmにArgo CDのリポジトリを追加します。
helm repo add argo https://argoproj.github.io/argo-helm
Argo CDをargocd
というネームスペースにインストールします。
helm upgrade --install argocd argo/argo-cd --namespace argocd --create-namespace
ポートフォワードで接続できるようにします。後ほどALB経由で接続できるようにするので、これは一時的なものです。
kubectl port-forward service/argocd-server -n argocd 8080:443
Argo CDのadminパスワードを取得します。
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
argocdコマンドでログインします。Username
にはadmin
、Password
には先ほど取得したadminパスワード
を入力してください。
argocd login localhost:8080 --insecure
http://localhost:8080 にアクセスするとWEB UIからログインすることもできます。
ExternalDNS
ExternalDNSは、Kubernetesリソースを介して動的にCloud DNSにDNSレコードを追加、削除します。
Argo CDにアプリケーションとして追加します。
REPLACE ME
はCloud DNSで管理している実在のドメインにしてください。
domain=REPLACE ME txtownerid=test gsa=$(gcloud iam service-accounts list --filter='email:(edns-*)' --format='value(email)') argocd app create external-dns \ --repo https://kubernetes-sigs.github.io/external-dns/ \ --helm-chart external-dns \ --revision 1.11.0 \ --dest-namespace kube-system \ --dest-server https://kubernetes.default.svc \ --helm-set "domainFilters[0]=$domain" \ --helm-set "txtOwnerId=$txtownerid" \ --helm-set policy=sync \ --helm-set serviceAccount.create=true \ --helm-set serviceAccount.name=external-dns \ --helm-set "serviceAccount.annotations.iam\.gke\.io/gcp-service-account=$gsa" \ --helm-set provider=google
デプロイします。
argocd app sync external-dns
Argo CDをCloud Load Balancing経由でアクセスできるようにする
Argo CDで使うSSL証明書を発行します。REPLACE ME
の部分は、Argo CDに設定するドメインに置き換えて、managed-certificate.yaml
というファイルに保存してください。
apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: argocd-cert spec: domains: - REPLACE ME
デプロイします。
kubectl apply -f managed-certificate.yaml -n argocd
Argo CDで使うLBの設定を行います。以下のテキストをfrontend-config.yaml
というファイルに保存してください。
apiVersion: networking.gke.io/v1beta1 kind: FrontendConfig metadata: name: argocd-frontend-config spec: redirectToHttps: enabled: true
デプロイします。
kubectl apply -f frontend-config.yaml -n argocd
Argo CDのIngressを有効にします。
domain={{SUBDOMAIN}} helm upgrade -i argocd argo/argo-cd \ -n argocd --create-namespace \ --set 'server.service.type=NodePort' \ --set 'server.service.annotations.cloud\.google\.com/neg={"ingress": true}' \ --set 'server.ingress.enabled=true' \ --set "server.ingress.hosts[0]=$domain" \ --set "server.ingress.annotations.external-dns\.alpha\.kubernetes\.io/hostname=$domain" \ --set "server.ingress.annotations.kubernetes\.io/ingress\.class=gce" \ --set "server.ingress.annotations.networking\.gke\.io/managed-certificates=argocd-cert" \ --set "server.ingress.annotations.networking\.gke\.io/v1beta1\.FrontendConfig=argocd-frontend-config" \ --set 'server.extraArgs[0]=--insecure'
IngressからGCPのLBを起動するにはIngressのAnnotationsに設定を追加します。詳細は以下です。
https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress?hl=ja
SSLのプロビジョニングに1時間程度かかりますので気長にお待ちください。
片付け
片付けをするには少し順序があります。これはArgo CDで管理しているExternalDNSがArgo CDのドメインを管理しており、かつ、Argo CDのログイン先がLBの方に向いているからです。Argo CDを先にアンインストールするとExternalDNSが残ってしまいますし、アプリの方を先にアンインストールするとargocdコマンドが使えなくなってしまいます。
以下の手順に沿って、片付けを進めてください。
IngressをOFFにしてLBとサブドメインを解放します。
helm upgrade --install argocd argo/argo-cd --namespace argocd --create-namespace --set 'server.service.type=NodePort' --set 'server.ingress.enabled=false'
LBとドメインが削除されたのを確認してください。どちらもなくなっていればargocdコマンドが使えなくなっているので、ポートフォワードに切り替えます。
kubectl port-forward service/argocd-server -n argocd 8080:443
argocdコマンドのログイン先も変更します。
argocd login --insecure localhost:8080
アプリを削除します。
argocd app delete external-dns
SSLやFrontendConfigを削除します。
kubectl delete -f managed-certificate.yaml -n argocd kubectl delete -f frontend-config.yaml -n argocd
Argo CDをアンインストールします。
helm uninstall --namespace argocd argocd
GKEを削除します。
terraform destroy
以上で片付けは完了です。