Zenn
Open11

GKEを構築して色々セットアップする

daylightdaylight

雑にGKEを構築して、ArgoCDなど諸々セットアップしていく。

成果物

https://github.com/daylight55/google-cloud-labo

目標: ArgoCD PullRequestGeneratorを使用したReviewAppsの検証

やる予定

  1. GKEをTerraformで構築
  2. ExternalSecretセットアップ
  3. ExternalDNSセットアップ
  4. Gateway APIセットアップ
  5. CertManagerセットアップ Certificate Managerをセットアップ
  6. ArgoCDセットアップ
  7. ArgoCD Application作成
  8. PullRequest Generatorの検証
daylightdaylight

1. GKEをTerraformで構築

成果物
https://github.com/daylight55/google-cloud-terraform/tree/main

今の所1ディレクトリのみだが、今後を見越してTerragruntで気持ち丁寧にやってみた。

tfstateのバケット作成

https://github.com/daylight55/google-cloud-terraform/tree/main/_tfstate

APIで作成するくらいなら、とTerraformで作成。このバケットのtfstateはローカルに置いておく。

cp terraform.tfvars.example terraform.tfvars

# Edit terraform.tfvars
vi terraform.tfvars

terraform apply
/_tfstate/terraform.tfvars
project        = "xxx"
tfstate_bucket = "xxx-tfstate"

VPC & GKE etc...作成

https://github.com/daylight55/google-cloud-terraform/tree/main/gke

cp terraform.tfvars.example terraform.tfvars

# Edit terraform.tfvars
vi terraform.tfvars

terragrunt run-all plan

terragrunt run-all apply
/terraform.tfvars
project        = "xxx"
region         = "us-west1"
zone           = "us-west1-c"
prefix         = "daylight-labo"
tfstate_bucket = "xxx-tfstate"

GKEに接続

コンテキスト準備

gcloud config set project xxx
gcloud config set compute/region us-west1
gcloud config set compute/zone us-west1-c

K8sの認証情報取得

gcloud container clusters get-credentials daylight-labo-cluster --zone us-west1-c

コマンド実行確認。OK。

$ kubectl cluster-info
Kubernetes control plane is running at ...
daylightdaylight

2. ExternalSecretsセットアップ

機密情報をK8sに渡したくなるケースが予測されるので、先んじてExternal Secretをセットアップする。

成果物

Terraform定義の修正・追加

GKEにWorkloadIdentity Poolの設定修正

https://github.com/daylight55/google-cloud-terraform/blob/ae9500e98fc5522b808051de2f061ac5137f9aa0/gke/gke.tf#L11-L13

サンプルとしてSecretManagerリソースも作成しておく。

resource "google_secret_manager_secret" "example" {
  secret_id = "external-secrets-example"

  replication {
    auto {}
  }
}

resource "google_secret_manager_secret_version" "example" {
  secret      = google_secret_manager_secret.example.id
  secret_data = "example-secret-value"
}

ServiceAccount作成

SAの作成などもろもろ。サンプルのSecret Managerも作成。

https://github.com/daylight55/google-cloud-terraform/tree/ae9500e98fc5522b808051de2f061ac5137f9aa0/append

Workload Identity FederationによってGoogle Cloud Service AccountをKubernetes Service Accountから権限借用する。

External Secretの定義作成

helmfile定義諸々を作成

k8s
├── common
│   └── namespace.yaml
├── external-secrets
│   ├── extra
│   │   └── secretStore.yaml
│   ├── helmfile.yaml
│   └── values.yaml
└── sample
    └── external-secret.yaml

Apply

applyしていく

namespace

cd k8s
kubectl apply -f common

確認

kubectl get ns

External Secrets Operator

事前に作成したService Accountを利用するため、Workload Identity Federation用のAnnotationを付与したKSAも作成。

cd external-secrets
helmfile template | kubectl apply -f -

確認。

kubectl get pod -n external-secrets

Sampleリソース

External Secretリソースが正常にデプロイ出来たことの確認。

cd ../sample
kubectl apply -f external-secret.yaml
external-secrets.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: sample-external-secrets-example
  namespace: sample
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: ClusterSecretStore
    name: gcp-secret-manager
  target:
    name: external-secrets-example
    creationPolicy: Owner
  data:
    - secretKey: external-secrets-example
      remoteRef:
        key: external-secrets-example
        version: latest

作成できたか確認する。

$ kubectl get secret external-secrets-example -n sample -o jsonpath="{.data.external-secrets-example}" | base64 -d; echo
example-secret-value

OK

daylightdaylight

3. ExternalDNSセットアップ


ArgoCDのWeb UI用にDNSレコードの連携を楽にしたいので、External DNSもセットアップする。

ここで問題に気付く。Google Domainsは提供終了していたのだ!
さらに、移行先として買ったはずのCloudflareのドメインは有効期限が切れていた!

Cloudflareのドメイン取得 & APIトークン発行

折角なので新しいドメイン名にして、再購入。

APIトークンも発行。

CloudflareのドメインをCloudDNSに権限以上するイメージ

構成図はこんな感じ。

Cloudflare NSレコード & CloudDNS & Service Account作成

https://github.com/daylight55/google-cloud-terraform/blob/f0aa4b1224f747d40260e0395e55ca494b3b2aa4/append/dns.tf

CloudflareにCloudDNSのホストゾーンのNSレコードを登録し、サブドメインを権限移譲する。

レコードの作成を確認。

ExternalDNSをデプロイ

https://github.com/daylight55/google-cloud-terraform/tree/main/k8s/external-dns

external-dns
├── helmfile.yaml
└── values.yaml

applyしていく。

cd k8s
kubectl apply -f common
cd external-dns
helmfile template | kubectl apply -f -

ここで動作確認するには、先にGateway APIがセットアップされている方がいいことに気づく!

daylightdaylight

DNSSECを有効にしていたためサブドメインの移譲が上手くいかなかったよう。

DNSSECも使えるように試行錯誤したが、解消できなかったため、一旦無効化する。

daylightdaylight

4. Gateway APIセットアップ

Terraform定義修正

GKEのGateway APIを有効化

Gateway APIリソースデプロイ

Gatewayリソースを作成
https://github.com/daylight55/google-cloud-terraform/tree/main/k8s/gateway-api

cd k8s
kubectl apply -f common
cd gateway-api
helmfile template | kubectl apply -f -

Gateway APIの動作確認

cd ../sample
kubectl apply -f external-dns

リクエストOK

$ curl --resolve nginx.labo.daylight55.com:80:34.8.27.5 http://nginx.labo.daylight55.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
daylightdaylight

5. Certificate Managerをセットアップ

当初はCertManagerを考えていたが、GKEではGoogle Certificate ManagerによってTLS証明書はネイティブに連携可能なことを思い出した。

TerraformでCertificate Managerリソースを作成

試行錯誤したが、これで作成できた!

https://github.com/daylight55/google-cloud-labo/blob/f4ddab961515eacc481fcee508462c13c2538508/terraform/certificate-manager/main.tf
5〜10分ほど待つと証明書のプロビジョニングが完了した。

Gateway APIからCertManagerを利用

ワイルドカード証明書を利用するGatewayリソースをデプロイする。Terraformで作成したCertMapを指すannotationを追加すれば良い。
https://github.com/daylight55/google-cloud-labo/blob/f4ddab961515eacc481fcee508462c13c2538508/k8s/gateway-api/manifest/gateway.yaml

HTTPRouteを上記のGatewayを利用する定義に修正
https://github.com/daylight55/google-cloud-labo/blob/f4ddab961515eacc481fcee508462c13c2538508/k8s/sample/external-dns/test.yaml#L34-L52

アクセスする。やっとできたーーーーーー ☸️
https://nginx.labo.daylight55.com/

daylightdaylight

6. ArgoCDセットアップ

ようやく本願のArgoCD構築に入る。Deploy keyでリポジトリ連携はし、Github OAuthでログインできるようにしていこうと思う。

ログインするとコメントできます