Terraformを使用して、Kubernetesクラスターを管理する方法を解説

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/2947d632-f415-8536-1cac-48f040f9bfd7.png)

#はじめに

Kubernetes（K8s）は、最も人気のあるオープンソースのコンテナオーケストレーションおよびスケジューリングツールの1つです。 Googleが開発しましたが、Red Hat、Huawei、Microsoft、IBMなど、他の多くの独立した開発者や企業がこのツールの開発に貢献しています。

Kubernetesにはクライアントもしくはサーバーのアーキテクチャがあります。 Kubernetesクラスターでは、常にマスターとワーカーが見つかり、マスターは、制御ノードとして機能し、kube-scheduler、kube-apiserverなどの複数のコンポーネント、kube-controller-managerで構成されています。 デフォルトでは、Kubernetesクラスターにはマスターが1つありますが、マルチマスターのKubernetesクラスターをセットアップすることもできます。 どちらの場合も、マスターがワーカーノードを制御します。

以前はミニオンと呼ばれていたノードは、通常はVMであるワーカーマシンですが、ベアメタルマシンの場合もあります。各ノードは、マスターがポッドを管理するために使用する必要なサービスで構成されています。

- 例：Kubelet、コンテナランタイム、kube-proxy。

Kubernetesアーキテクチャを見ると、複雑なシステムであることがわかると思います。この複雑さは、このような回復力のある抽象的なシステムを作成するために何らかの形で必要になります。複雑さは機能的なだけでなく、Kubernetesクラスターのデプロイとメンテナンスにも潜在しています。

独自のKubernetesクラスタを作成するには、独自のリソースと証明書をプロビジョニングする必要があります。認証用に独自のKubernetes構成を生成し、データ暗号化を管理し、etcdクラスター、コントロールプレーン、ワーカーノード、マネージャーポッドネットワークルートをブートストラップし、DNSアドオンをセットアップし、スモークテストを行います。一部のオープンソースツールはこれを行うのに役立ちますが、それでも独自のKubernetesクラスターをデプロイして管理することは簡単な作業ではありません。これが、多くの企業がGKEのようなマネージドKubernetesクラスターの使いやすさを選択する理由です。

クラウド管理のクラスターを使用すると、クラスターとその依存関係を維持する必要がな九なるため、Kubernetesを簡単に使用できるようになります。 IaC（コードとしてのインフラストラクチャ）を使用すると、Kubernetesクラスターのブートストラップがさらに簡単になります。 また、さまざまなKubernetes環境を作成して維持できるため、多くの利点があるのが事実です。 インフラストラクチャをバージョン管理に追加して、チームや個人間で共有することもできます。

DevOpsの柱の1つは、セルフサービスインフラストラクチャです。 Terraformなどのツールを使用すると、インフラストラクチャテンプレートを作成および検証して、オンデマンドプロビジョニングに使用および再利用できます。 このブログ投稿では、Terraformを使用して、GKEクラスターのインフラストラクチャテンプレートを作成します。

#前提条件
開始する前に、有効なGoogleCloudアカウントが必要です。 2番目で紹介されるステップは、プロジェクトを選択または作成してKubernetes EngineAPIをアクティブ化することです。 プロジェクトにリンクされた請求先アカウントがあることを確認してください。

APIがアクティブ化されたら（数分かかる場合があります）、Google CloudSDKをインストールする必要があります。

SDKをインストールした後、CloudShellを使用してプロジェクトを設定していきます。

```
gcloud config set project &lt;project-id&gt;
```

Compute zoneを設定します。

```
gcloud config set compute/zone &lt;compute-zone&gt;
```

以下を使用して、使用可能なゾーンのリストを取得できることができます。

```
gcloud config set compute/zone compute-zone
```

これで、以下を使用してクラスターの作成をテストできます。

```
gcloud container clusters create &lt;cluster_name&gt;
```

TerraformはGoogleCloud PlatformAPIと相互作用します。 ここでの良い習慣は、Terraformのみが使用するサービスアカウントを作成することです。 これにより、制御が強化され、セキュリティの管理がより柔軟になります。

クラウドコンソールで、[IAM & Admin]-> [Service Accountｓ]をクリックし、[Create a Service Account]をクリックします。

サービスアカウントに名前を付け、「Project Editor」の役割を付けます。 このアカウントのJSONキーを生成してダウンロードし、それを実行して次の場所に保存するように求められます。

```
&lt;project&gt;/auth/serviceaccount.json
```

<project>は、Terraformテンプレートを作成するプロジェクトフォルダーです。 .gitignoreファイルを追加して、資格情報やその他の未使用のファイルを無視することもできます。‍

```
auth/* 
.terraform/*
```

さらに、Terraformをインストールする必要があります。 バイナリパッケージなので、複雑なことは何もありません。 バイナリをダウンロードして実行可能にしてください。 Terraformをダウンロードするには、公式ダウンロードページを使用し、OSを選択して、バイナリをダウンロードします。

```
wget https://releases.hashicorp.com/terraform/0.12.18/terraform_0.12.18_linux_amd64.zip
unzip terraform_0.12.18_linux_amd64.zip
sudo mv terraform /usr/bin/terraform
sudo chmod +x /usr/bin/terraform
```

#Terraformを使用した最初のGKEクラスターの作成
###Terraformプロバイダー
Terraformは、AWS、Azure、GCPなどの多くのクラウドプロバイダーとやり取りできますますので、クラウドごとに、認証と管理のためにクラウドAPIとインターフェイスするための一種のドライバーが必要です。 この「ドライバー」は通常、プロバイダーと呼ばれます。

GCPのプロバイダーを作成しましょう。 「provider.tf」ファイルを作成し、次のコードを貼り付けます。

```
provider "google" {
  credentials = "${file("./auth/serviceaccount.json")}"
  project     = "&lt;your_project_name&gt;"
  region      = "&lt;your_region&gt;"
}
```

以前に生成されたJSONキーを「auth / serviceaccout.json」に保存してから、次を使用して初期化を開始してください。

```
terraform init
```

これにより、プロジェクトが初期化され、GCPプロバイダーファイルがダウンロードされます。

```
Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "google" (hashicorp/google) 3.2.0...
```

###Terraformリソース
インフラストラクチャの仮想リソースの作成に移りましょう。 Terraformを使用すると、作成するクラウドリソースの名前と構成を定義できます。 この場合、GKEクラスターになります。

「gke.tf」というファイルを作成し、次のコードを貼り付けます。

```
resource "google_container_cluster" "primary" {
  name     = "&lt;cluster_name&gt;"
  network            = "default"
  location               = "&lt;location&gt;"
  initial_node_count = 1
  }
```

必ず<cluster_name>と<location>を実際の値に変更してください。

例：

```
resource "google_container_cluster" "primary" {
  name     = "my-gke-cluster"
  network            = "default"
  location               = "europe-west1"
  initial_node_count = 1
  }
```

###Terraformプラン
Terraformには宣言型DSLがあります。 これは、「tf」ファイルに目的の状態のみを記述することを意味し、Terraformはそれを達成する責任があります。 つまり、目的のインフラストラクチャを作成するために、実行モデルを段階的に説明する必要はありません。

コマンド「terraformplan」を使用すると、Terraformは実行プランを作成します。 プランを作成する前のリソースの状態と、目的の状態を比較してくれます。

###Terraformの適用

planコマンドを実行した後、Terraformは実行プランを説明するファイル（ローカルファイル）を生成しました。 これにより、applyコマンドは、リソース、つまり「my-gke-cluster」に適用する変更について知ることができます。

クラスターを作成するのはこれが初めてなので、更新するものはなく、すべてが初めて作成されます。

applyコマンドを実行してクラスターを作成しましょう。

```
terraform apply
```

GKEクラスターに関連するさまざまな構成を確認できるはずです。

```
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

#Terraformを使用したリソースの更新
このチュートリアルの前半部分では、単純なTerraformテンプレートを使用してKubernetesクラスターを作成しました。 クラスターを更新するには、Terraformを使用することもできます。 同じ「tf」ファイル（「gke.tf」）を使用して、クラスターの目的の状態で必要な構成を追加または更新します。

1つの「n1-standard-1」ノードを持つプリエンプティブノードのノードプールを追加し、Stackdriverサービスを有効にするとします。

次を追加してコードを更新する必要があります。

```
resource "google_container_node_pool" "primary_preemptible_nodes" {
  name       = "my-node-pool"
  location   = "europe-west1"
  cluster    = google_container_cluster.primary.name
  node_count = 1

  node_config {
    preemptible  = true
    machine_type = "n1-standard-1"

    metadata = {
      disable-legacy-endpoints = "true"
    }

    oauth_scopes = [
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
    ]
  }
}
```

これが最終的な "gke.tf"ファイルの形です:

```
resource "google_container_cluster" "primary" {
  name     = "my-gke-cluster"
  network            = "default"
  location               = "europe-west1"
  initial_node_count = 1
  }

resource "google_container_node_pool" "primary_preemptible_nodes" {
  name       = "my-node-pool"
  location   = "europe-west1"
  cluster    = google_container_cluster.primary.name
  node_count = 1

  node_config {
    preemptible  = true
    machine_type = "n1-standard-1"

    metadata = {
      disable-legacy-endpoints = "true"
    }

    oauth_scopes = [
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
    ]
  }
}
```

そして、次のように入力するのではなく、

```
..
"primary_preemptible_nodes" {
  name       = "my-node-pool"
  location   = "europe-west1"
  cluster    = "my-gke-cluster"
  node_count = 1
..
```

Terraform変数を使用し、以下を使用してみてください

```
..
"primary_preemptible_nodes" {
  name       = "my-node-pool"
  location   = "europe-west1"
  cluster    = google_container_cluster.primary.name
  node_count = 1
..
```

#Terraformを使用したクラスターの破棄
Terraformを使用してクラスターを作成しました。 同じツールは、状態に基づいてリソースを破棄する機能を提供します。 Terraformを使用してクラスターを破棄すると、その状態も更新されます。

クラスタを破棄するには、次を使用する必要があります。

```
terraform destroy
```

#まとめ

この記事では、GKEクラスターの作成を簡単で、再現可能なタスクにする方法を説明しました。

新しいクラスターを再作成せずにホットアップデートを追加したり、新しいクラスターを破棄して再作成するなど、GKEクラスターにカスタマイズを加えること出来るのです。

IaCとクラウドコンピューティングのパワーを組み合わせることは、開発者向けのセルフサービスを作成するための良い方法であり、テンプレートファイルに構成管理のレイヤーを追加すると、セルフサービスインフラストラクチャをより細かく制御できるようになります。

Prometheusを使用してKubernetesを監視することに興味がある方は、[Prometheus + Thanosを使用したHA Kubernetes監視](https://qiita.com/MetricFire/items/acdbfe0149639988285f)を確認してください。 
また、[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Managing%20a%20Kubernetes%20Cluster%20Using%20Terraform)の[無料トライアル](https://www.hostedgraphite.com/accounts/signup-metricfire/?signup=japan&utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Managing%20a%20Kubernetes%20Cluster%20Using%20Terraform)にジャンプして、Prometheusで監視を開始することもできます。 [デモを予約](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Managing%20a%20Kubernetes%20Cluster%20Using%20Terraform)して、監視のニーズについて直接お問い合わせください。