TerraformでAKSにKubernetesクラスタを構築する

Tags:

#Kubernetes #Azure #Terraform
このエントリーをはてなブックマークに追加

前回はTerraformでAzureリソースを作成するための準備の記事を書きましたが、今回は実際にTerraformでAzureリソースを作成してみました。

TerraformでAzureリソースを作成するときの前準備(Service PrincipalとStorage Account)

今回は以下のチュートリアルをやってみました。

チュートリアル:Terraform を使用して Azure Kubernetes Service で Kubernetes クラスターを作成する

Terraformを使ってAzureのKubernetesサービスであるAzure Kubernetes Service(AKS)のリソースを作成します。 

初期設定

まずはAzureリソースを作成するためにAzureプロバイダーの設定です。

provider "azurerm" {
  # The "feature" block is required for AzureRM provider 2.x. 
  # If you are using version 1.x, the "features" block is not allowed.
  version = "~>2.0"
  features {}
}

terraform {
  backend "azurerm" {}
}

AKSのリソースを作成する

ここからAKSのリソースを作成するためのtfファイルを書いていきます。

# リソースグループの作成
resource "azurerm_resource_group" "k8s" {
  name     = var.resource_group_name
  location = var.location
}

resource "random_id" "log_analytics_workspace_name_suffix" {
  byte_length = 8
}

# LogAnalyticsワークスペースの有効化
resource "azurerm_log_analytics_workspace" "test" {
  name                = "${var.log_analytics_workspace_name}-${random_id.log_analytics_workspace_name_suffix.dec}"
  location            = var.log_analytics_workspace_location
  resource_group_name = azurerm_resource_group.k8s.name
  sku                 = var.log_analytics_workspace_sku
}

# ContainerInsightsを有効化してLogAnalyticsにデータを送信する
resource "azurerm_log_analytics_solution" "test" {
  solution_name         = "ContainerInsights"
  location              = azurerm_log_analytics_workspace.test.location
  resource_group_name   = azurerm_resource_group.k8s.name
  workspace_resource_id = azurerm_log_analytics_workspace.test.id
  workspace_name        = azurerm_log_analytics_workspace.test.name

  plan {
    publisher = "Microsoft"
    product   = "OMSGallery/ContainerInsights"
  }
}

# AKSの作成
resource "azurerm_kubernetes_cluster" "k8s" {
  name                = var.cluster_name
  location            = azurerm_resource_group.k8s.location
  dns_prefix          = var.dns_prefix
  resource_group_name = azurerm_resource_group.k8s.name

  linux_profile {
    admin_username = "xxxxx"

    ssh_key {
      key_data = file(var.ssh_public_key)
    }
  }

# Nodeの設定
  default_node_pool {
    name       = "agentpool"
    node_count = var.agent_count
    vm_size    = "Standard_G1"
  }

  service_principal {
    client_id     = var.client_id
    client_secret = var.client_secret
  }

  addon_profile {
    oms_agent {
      enabled                    = true
      log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
    }
  }

  tags = {
    Environment = "Development"
  }
}

今回作成するAzureリソースはリソースグループ,LogAnalyticsとContainerInsight,AKSのリソースです。 リソースグループは作成するリソースをグループ化するためのです。 LogAnalyticsとContainerInsightは監視サービスです。

“azurerm_kubernetes_cluster”以下がAKSに関する設定です。 linux_profileではNodeにsshできるように公開鍵の設定が可能です。 また、default_node_poolの項目でKubernetes Nodeのインスタンスに関する設定が行えます。 vm_sizeでVMのインスタンスサイズを設定でき、node_countでNodeの数を設定できます。 vm_sizeがチュートリアルではStandard_DS1_v2というマシンサイズだったのですが、うまく作成できなかったため、Standard_G1というマシンサイズに変更しました。 addon_profileではログをLogAnalyticsに送信するためのエージェントを有効化しています。

変数の設定

variable "client_id" {}
variable "client_secret" {}

variable "agent_count" {
  default = 2
}

variable "ssh_public_key" {
  default = "xxxxxxxxx"
}

variable "dns_prefix" {
  default = "k8stest"
}

variable "cluster_name" {
  default = "k8stest"
}

variable "resource_group_name" {
  default = "azure-k8stest"
}

variable "location" {
  default = "Japan EAST"
}

variable "log_analytics_workspace_name" {
  default = "testLogAnalyticsWorkspace"
}

variable "log_analytics_workspace_location" {
  default = "Japan EAST"
}

variable "log_analytics_workspace_sku" {
  default = "PerGB2018"
}

tfファイルで利用する変数を設定します。 agent_countはAKSのnode poolの数になります。 ssh_public_keyには公開鍵のパスを書きます。 locationやlog_analytics_workspace_locationではリソースを作成するリージョンを設定しています。 チュートリアルではeastusリージョンにリソースを作成していましたが、今回は東日本リージョンにリソースを作成するように設定しました。

client_idとclient_secretは環境変数から値を読み込むように設定します。 TF_VAR_client_idとTF_VAR_client_secretという環境変数を設定することで変数の値としてTerraformが解釈してくれます。 値には準備編で作成した、サービスプリンシパルのclient_idとclient_secretを設定します。

出力の設定

terraform apply時に値が出力されるように設定をします。 主にクラスターの認証情報に関する情報を出力するように設定しておき、あとで利用します。

output "client_key" {
  value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_key
}

output "client_certificate" {
  value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate
}

output "cluster_ca_certificate" {
  value = azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate
}

output "cluster_username" {
  value = azurerm_kubernetes_cluster.k8s.kube_config.0.username
}

output "cluster_password" {
  value = azurerm_kubernetes_cluster.k8s.kube_config.0.password
}

output "kube_config" {
  value = azurerm_kubernetes_cluster.k8s.kube_config_raw
}

output "host" {
  value = azurerm_kubernetes_cluster.k8s.kube_config.0.host
}

リソースを作成し、Kubenetesクラスターにアクセスする

tfファイルを作成したら、あとはterraform plan,terraform applyするだけです。 applyするとkubernetesクラスターが作成されました。

次はkubectlコマンドを使ってkubernetesクラスターにアクセスします。

以下のコマンドを使って認証情報をファイルに出力し、kubectlコマンドに認証情報として渡します。。

echo "$(terraform output kube_config)" > ./azurek8s
export KUBECONFIG=./auzrek8s

これでkubectlからkubernetesクラスターにアクセスできるようになりました。

kubectl get nodes
NAME                                STATUS   ROLES   AGE    VERSION
aks-agentpool-21324540-vmss000000   Ready    agent   4d6h   v1.15.10
aks-agentpool-21324540-vmss000001   Ready    agent   4d6h   v1.15.10

試しにpodを一つ実行してみます。

kubectl run busybox --image=busybox --restart=Never -it -- echo "hello world"
hello world
無事pod上でhello worldを出力することができました。

まとめ

ブログとしてはかなり単調なものになりましたが、個人的に学びは多かったです。 TerraformでAKSにKubernetesクラスターを作成できるようになったので、 また何かKubernetes関連の技術を学ぶ時は適宜terraform applyしてテスト用のKubernetesクラスタとして使っていきたいです。

See Also