記事一覧はこちら
業務ではdeployment manager
というGCPから公式が提供している、Google Cloudリソースの作成と管理を自動化するインフラストラクチャデプロイサービスを利用して、Kubernetesクラスターやノードプールの作成を行っています。
ですが、GCPの環境構築においてはTerraformを利用している企業さんがかなり多いという認識をしております。 せっかくなのでプライベートでクラスターを作成する際には、Terraformを利用してみたいと思います。
作成したい構成
結構ケチケチしている性分なので、なるべく安くしたいところ…!
- Google Kubernetes Engineのゾーンクラスタ
- n1-standard1のノードプール
- f1-microは30日間分無料なのだけれどスペックが満たせない
無料トライアルでもらえる$300のクレジットを利用して、はみ出したGCEとロードバランサの料金を払いたいと思います。
…待って。Stackdriverの料金もここに乗っかりそう🤔 Stackdriverのログも保存させないように設定を変更させておかないと!と思っていたのですが、50GBまでは無料なので一旦無視します。
TerraformでProvisionする準備
参考
https://learn.hashicorp.com/terraform/gcp/introlearn.hashicorp.com
CLIをインストール
Download Terraform - Terraform by HashiCorp にアクセスして、アーキテクチャ/OSを選択し、CLIのリンクアドレスをコピーする。
$ wget https://releases.hashicorp.com/terraform/0.14.7/terraform_0.14.7_darwin_amd64.zip $ unzip terraform_0.14.7_darwin_amd64.zip $ vi $HOME/.zshrc # CLIのバイナリにPATHを通しておく export PATH=$HOME/.terraform/bin:$PATH $ terraform # 叩けるか確認 Usage: terraform [-version] [-help] <command> [args] ...(省略)
GCPをセットアップ
- 必要であれば、https://console.cloud.google.com/projectcreate からプロジェクトを作成する
My First Project
という名前でデフォルトで用意されるプロジェクトがあったのでそちらを利用- https://console.cloud.google.com/cloud-resource-manager からプロジェクトIDを参照できる、後でプロジェクトIDを利用する
- Compute Engine API のコンソールからこれを有効化
- ServiceAccount Keyの作成を行う
試しにTerraformでリソースを作成してみる
下記のように、ファイルを作成する。
terraform { required_providers { google = { source = "hashicorp/google" version = "~> 3.58" } } } // リソースの作成と管理を担当するproviderを設定する // 複数のクラウドベンダなどを利用する場合には、複数のproviderブロックが存在しうる provider "google" { credentials = file("<クレデンシャルキーのファイル>.json") project = "<PROJECT_ID>" region = "us-central1" zone = "us-central1-c" } // インフラストラクチャ内にあるリソースを定義 // ブロック開始前の構成は、<リソースタイプ> <リソース名> となっていて、 // リソースタイプ google_compute_network の接頭辞がproviderを表す。 // <リソースタイプ>.<リソース名> はリソースIDとして扱われ、他のリソースから参照できる resource "google_compute_network" "vpc_network" { name = "terraform-network" }
下記のようにターミナルで操作を進めていく。
新しい設定の場合もしくはバージョン管理化にあるファイルをチェックアウトした後には、terraform init
を実行する。このコマンドは、ローカルの設定やデータを初期化する。これは、main.tf
のあるディレクトリで実行する。
terraform plan
でこの設定を適用した場合に、どのような操作が行われるかが確認できる。kubectl
における--dry-run
オプションのようなもの。
terraform apply
で実際にリソースの作成/変更/削除が行われる。
$ terraform init Initializing the backend... Initializing provider plugins... - Checking for available provider plugins... - Downloading plugin for provider "google" (hashicorp/google) 3.5.0... Terraform has been successfully initialized! ...(省略) $ terraform plan ...(省略) Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # google_compute_network.vpc_network will be created + resource "google_compute_network" "vpc_network" { + auto_create_subnetworks = true + delete_default_routes_on_create = false + gateway_ipv4 = (known after apply) + id = (known after apply) + ipv4_range = (known after apply) + name = "terraform-network" + project = (known after apply) + routing_mode = (known after apply) + self_link = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. $ terraform apply ...(省略) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes google_compute_network.vpc_network: Creating...(省略)
実際に出来ているのが確認できました!
インスタンスの作成もやってみる。下記の設定をmain.tf
に付け加える。f1-micro
なのでAlways Free枠です。お値段はかかりません。
resource "google_compute_instance" "vm_instance" { name = "terraform-instance" machine_type = "f1-micro" boot_disk { initialize_params { image = "debian-cloud/debian-9" } } network_interface { // ここで別のリソースの参照ができる network = google_compute_network.vpc_network.name access_config { } } }
最後にお片付けをしておきましょう
$ terraform destroy
Kubernetesクラスタを作成する
https://www.terraform.io/docs/providers/google/guides/using_gke_with_terraform.htmlwww.terraform.io
https://www.terraform.io/docs/providers/google/r/container_cluster.htmlwww.terraform.io
クラスターを作成する上で下記の2つのような方針を考えています。
kubectl
コマンドで必要となるkubeconfigはgcloud container clusters get-credentials cluster-name
にて取得する- terraformのデフォルトはルートベースでのクラスター作成だが、今回はGCPのデフォルトであるVPC-Nativeのクラスターを作成する
実際にファイルを作成してapply
する前に APIの有効化をやっておくべき。
ファイルは下記のように作成した
terraform { required_providers { google = { source = "hashicorp/google" version = "~> 3.58" } } } provider "google" { credentials = file("<クレデンシャルキーのファイル>.json") project = "<PROJECT_ID>" region = "us-central1" zone = "us-central1-c" } resource "google_container_cluster" "primary" { name = "my-gke-cluster" // ゾーンを指定するとゾーンクラスタ、リージョンを指定するとリージョナルクラスタ location = "us-central1-c" // ノードプールのリソース設定を包含すると密結合になり変更が難しくなる場合がある remove_default_node_pool = true initial_node_count = 1 // ↑がtrueのとき使用されないが"1"をセットしておく必要あり network = "default" subnetwork = "default" // VPC-Nativeの場合には指定 ip_allocation_policy { cluster_ipv4_cidr_block = "/16" // podのIPアドレス範囲 services_ipv4_cidr_block = "/22" // ServiceのIPアドレス範囲 } // private_cluster_config も入れたほうが良い // usernameとpasswordを空で作ればBasic認証はdisableになる // このブロックを指定しなければ、GCPのユーザ名を利用し自動生成する master_auth { username = "" password = "" client_certificate_config { issue_client_certificate = false } } } resource "google_container_node_pool" "primary_preemptible_nodes" { name = "my-node-pool" location = "us-central1-c" cluster = google_container_cluster.primary.name // node_countと同時に使用するべきではない autoscaling { min_node_count = 0 max_node_count = 1 } management { auto_repair = true // ノードの自動修復は有効化 auto_upgrade = false // 自動アップグレードは無効化 } node_config { preemptible = true machine_type = "n1-standard-1" labels = { app = "web" } // taintsも設定できるが、このフィールドの変更がノード再生成のトリガーと // なるので、ここで管理すべきではない metadata = { disable-legacy-endpoints = "true" } oauth_scopes = [ "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring", ] } }
いざ!Provisionだ!
$ terraform apply $ gcloud container clusters get-credentials my-gke-cluster $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.112.0.1 <none> 443/TCP 11m
kubectl
が通りました!コンソールも確認してみましょう!想定どおりです!
感想
普段利用しているdeployment-managerよりもシンプルで分かりやすい印象を受けました。
テンプレート化して変数とか当て込んだりしようとすると構成がもう少し複雑になってしまうのかもしれませんが、各クラウドベンダが同じ記法でインフラストラクチャを構成できるのは魅力ですね。