😸

TerraformでGCP上にKubernetesクラスター(GKE)をデプロイし、ロードバランサー経由でアクセスする

2023/11/16に公開

記事の内容

TerraformでGCP上にKubernetesクラスター(GKE)をデプロイして、そのクラスターに対してロードバランサー経由でアクセスする方法を解説します。

記事を読むと得られるもの

  • Terraformでネットワークを作る方法
  • GKEをTerraformで作る方法

記事の長さ

3分で読めます

クラスターを構築する

Network

最初に、Kubernetesクラスターが動作するNetworkをTerraformで作成します。


resource "google_compute_network" "this" {
  project                 = var.project_id
  name                    = "main-network"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "this" {
  project       = var.project_id
  name          = "main-subnetwork"
  ip_cidr_range = "10.2.0.0/16"
  region        = "asia-northeast1"
  network       = google_compute_network.this.id
  secondary_ip_range {
    range_name    = "pod-ip-range"
    ip_cidr_range = "10.10.0.0/16"
  }
  secondary_ip_range {
    range_name    = "service-ip-range"
    ip_cidr_range = "10.20.0.0/16"
  }
}

上記Terraform Resourceをapplyすると、VPCネットワークが作成されます。

GKE

次に先ほど作成したネットワーク上に、GKEクラスターを作成します。


resource "google_project_service" "compute" {
  project = var.project_id
  service = "compute.googleapis.com"
}
resource "google_project_service" "container" {
  project = var.project_id
  service = "container.googleapis.com"
}

data "google_client_config" "default" {}

provider "kubernetes" {
  host                   = "https://${module.gke_cluster.endpoint}"
  token                  = data.google_client_config.default.access_token
  cluster_ca_certificate = base64decode(module.gke_cluster.ca_certificate)
}

module "gke_cluster" {
  source     = "terraform-google-modules/kubernetes-engine/google"
  project_id = var.project_id

  name                        = "cluster"
  regional                    = true
  region                      = "asia-northeast1"
  network                     = google_compute_network.this.name
  subnetwork                  = google_compute_subnetwork.this.name
  ip_range_pods               = "pod-ip-range"
  ip_range_services           = "service-ip-range"
  create_service_account      = true
  enable_cost_allocation      = true
  enable_binary_authorization = false
  gcs_fuse_csi_driver         = true

  depends_on = [
    google_project_service.compute,
    google_project_service.container,
  ]
}

上記Terraform Resourceをapplyすると、VPCネットワーク上で動作するKubernetesクラスターが作成されます。

Kubernetesに接続できるようにcredentialsを取得する

作成したGKEクラスターをkubectlコマンドで操作できるように、credentialsを取得します。

$ gcloud container clusters get-credentials test-cluster --region asia-northeast1

これでローカル環境からGKEを操作できるようになりました

$ kubectl get ns
NAME              STATUS   AGE
default           Active   9m50s
gmp-public        Active   9m3s
gmp-system        Active   9m3s
kube-node-lease   Active   9m50s
kube-public       Active   9m50s
kube-system       Active   9m51s

Kubernetes内にサービスを構築する

GKEクラスターが起動したので、そのクラスター内で動作するサービスを実装し、インターネットからロードバランサー経由でアクセスできるようにします。

Nginxサービスの起動

テストのための実装なので、Nginxサーバーをサービスとして起動します。

nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: ClusterIP
  selector:
    name: nginx
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80

上記ファイルをkubectlでapplyします。

$ kubectl apply -f nginx.yaml
service/nginx created
pod/nginx created

$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          25s
$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.20.0.1      <none>        443/TCP   14m
nginx        ClusterIP   10.20.225.74   <none>        80/TCP    34s

正常に、nginx Podが起動していることを確認できました。

Ingressで外部に公開する

最後に、起動したNginx PodをIngress(ロードバランサー)経由でインターネットに公開します。

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: "gce"
    kubernetes.io/ingress.allow-http: "true"
spec:
  defaultBackend:
    service:
      name: nginx
      port:
        number: 80

上記ファイルをapplyすることでIngressを作成し、GCP上にロードバランサーを作成します。

$ kubectl apply -f ingress.yaml
Warning: annotation "kubernetes.io/ingress.class" is deprecated, please use 'spec.ingressClassName' instead
ingress.networking.k8s.io/ingress created

$ kubectl get ingress
NAME      CLASS    HOSTS   ADDRESS         PORTS   AGE
ingress   <none>   *       xxx.xxx.xxx.xxx   80      103s

※少し時間がかかりますが、正常に作成されると、API ADDRESSが表示されます。

アクセス

最後に、正常にインターネットからアクセスできるかどうかをcurlコマンドでテストします。

$ curl http://xxx.xxx.xxx.xxx:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

※xは実際のIPアドレスにしてください

Sample Sources

こちらにサンプルソースを配置しております。

https://github.com/rara-tan/zenn-gcp-terraform-gke

note

勉強法やキャリア構築法など、エンジニアに役立つ記事をnoteで配信しています。

https://note.com/ring_belle/membership

Discussion