概要
「Infrastructure as Code」ということで、Terraform を用いて Azure Kubernetes Service (AKS) with Azure CNI の環境を構築してみました。 with CNI環境はAKSの本番環境です。こちらの記事 は Azure CLIで作成しましたが、今回はTerraformでの作成となります。
ローカル環境
- macOS Monterey 12.3
- python 3.8.12
- Azure CLI 2.34.1
- terraform v1.0.11
前提条件
- Azure環境がすでに用意されていること(テナント/サブスクリプション)
- ローカル環境に「azure cli」がインストールされていること
- ローカル環境に「terraform」環境が構成されていること
- TerraformでAzure上に環境構築するためのサービスプリンシパルが作成されており、Terraform のためのローカル環境変数が定義されていること
AKS with Azure CNI 環境の構築
terraform 定義ファイルの作成
プロバイダの定義
main.tf
# プロバイダーの定義
terraform {
required_providers {
azurerm = "~> 2.33"
}
}
provider "azurerm" {
features {}
tenant_id = var.ARM_TENANT_ID
subscription_id = var.ARM_SUBSCRIPTION_ID
client_id = var.ARM_CLIENT_ID
client_secret = var.ARM_CLIENT_SECRET
}
# リソースグループ
resource "azurerm_resource_group" "this" {
name = var.resource_group_name
location = var.region
tags = var.tags_def
}
パラメータ定義ファイル
variables.tf
# 環境変数(Azureサービスプリンシパル)
variable ARM_TENANT_ID {}
variable ARM_SUBSCRIPTION_ID {}
variable ARM_CLIENT_ID {}
variable ARM_CLIENT_SECRET {}
# タグ情報
variable tags_def {
default = {
owner = "ituru"
period = "2022-04-28"
CostCenter = "PSG2"
Environment = "CPDemo"
}
}
# 各種パラメータ
variable region {} // 利用リージョン
variable resource_group_name {} // リソースグループ名
variable vnet_name {} // vNet名
variable vnet_address_space {} // vNetアドレス範囲
variable subnet_name {} // サブネット名
variable subnet_address {} // サブネットアドレス
variable dns_service_ip {} // サービス用DNSアドレス
variable docker_address {} // Dockerブリッジアドレス
variable service_address {} // サービス用ネットワークアドレス
variable aks_cluster_name {} // AKSクラスタ名
variable dns_prefix {} // DNSプレフィックス
variable default_node_pool_name {} // ノードプール名
variable enable_auto_scaling {} // 自動拡張可否
variable vm_size {} // 仮想マシンサイズ
variable node_count {} // 起動時ノード数
variable max_count {} // 最大ノード数
variable min_count {} // 最小ノード数
パラメータ値定義ファイル
terraform.tfvars
# 環境変数の定義(Azureサービスプリンシパル)
ARM_TENANT_ID = "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz"
ARM_SUBSCRIPTION_ID = "xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz"
ARM_CLIENT_ID = "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx"
ARM_CLIENT_SECRET = "hogehogehogehogehogehogehogehogege"
# パラメータ値の定義
region = "japaneast" // 利用リージョン
resource_group_name = "rg_ituru_aks01" // リソースグループ名
vnet_name = "vnet_ituru_aks01" // vNet名
vnet_address_space = "10.0.0.0/16" // vNetアドレス範囲
subnet_name = "snet_ituru_aks01" // サブネット名
subnet_address = "10.0.1.0/24" // サブネットアドレス
dns_service_ip = "10.1.0.10" // サービス用DNSアドレス
docker_address = "172.17.0.1/16" // Dockerブリッジアドレス
service_address = "10.1.0.0/24" // サービス用ネットワークアドレス
aks_cluster_name = "aks_ituru_cp01" // AKSクラスタ名
dns_prefix = "cpcluster01" // DNSプレフィックス
default_node_pool_name = "cpdemo01" // ノードプール名
enable_auto_scaling = "true" // 自動拡張可否
vm_size = "Standard_D2_v2" // 仮想マシンサイズ
node_count = "3" // 起動時ノード数
max_count = "5" // 最大ノード数
min_count = "3" // 最小ノード数
Azure Kubernetes Service (AKS) 定義ファイル
aks.tf
# AKS
resource "azurerm_kubernetes_cluster" "this" {
name = var.aks_cluster_name
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
dns_prefix = var.dns_prefix
tags = var.tags_def
default_node_pool {
name = var.default_node_pool_name
vm_size = var.vm_size
node_count = var.node_count
vnet_subnet_id = azurerm_subnet.internal.id
type = "VirtualMachineScaleSets"
tags = var.tags_def
enable_auto_scaling = var.enable_auto_scaling
max_count = var.max_count
min_count = var.min_count
}
service_principal {
client_id = var.ARM_CLIENT_ID
client_secret = var.ARM_CLIENT_SECRET
}
network_profile {
network_plugin = "azure"
network_policy = "calico"
dns_service_ip = var.dns_service_ip
docker_bridge_cidr = var.docker_address
service_cidr = var.service_address
load_balancer_sku = "Standard"
}
lifecycle {
prevent_destroy = true
}
}
Azure CNI 定義ファイル
network.tf
// 仮想ネットワーク
resource "azurerm_virtual_network" "this" {
name = var.vnet_name
address_space = [var.vnet_address_space]
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
tags = var.tags_def
}
// サブネット
resource "azurerm_subnet" "internal" {
name = var.subnet_name
resource_group_name = azurerm_resource_group.this.name
virtual_network_name = azurerm_virtual_network.this.name
address_prefixes = [var.subnet_address]
}
Output 定義ファイル
output.tf
# AKSクラスタのクライアント証明書を出力
output "client_certificate" {
value = azurerm_kubernetes_cluster.this.kube_config.0.client_certificate
}
# AKSクラスタのkubeconfigを出力
output "kube_config" {
value = azurerm_kubernetes_cluster.this.kube_config_raw
sensitive = true
}
# AKSクラスタのFQDNを出力
output "fqdn" {
value = azurerm_kubernetes_cluster.this.fqdn
}
# AKSクラスタのIDを出力
output "cluster_id" {
value = azurerm_kubernetes_cluster.this.id
}
terraform の実行
## init
$ terraform init
:
Terraform has been successfully initialized!
## plan
$ terraform plan
:
Plan: 4 to add, 0 to change, 0 to destroy.
## apply
$ terraform apply
:
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Output 出力結果
Outputs:
client_certificate = "LS0tLS1..........................FURS0tLS0tCg=="
cluster_id = "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_aks01/providers/Microsoft.ContainerService/managedClusters/aks_ituru_cp01"
fqdn = "cpcluster01-adf56c0d.hcp.japaneast.azmk8s.io"
kube_config = <sensitive>
ローカルの作業ディレクトの状況
$ tree -a
.
├── .terraform
│ └── providers
│ └── registry.terraform.io
│ └── hashicorp
│ └── azurerm
│ └── 2.99.0
│ └── darwin_amd64
│ └── terraform-provider-azurerm_v2.99.0_x5
├── .terraform.lock.hcl
├── aks.tf
├── main.tf
├── network.tf
├── outputs.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
└── variables.tf
terraform 実行後の確認
Azure CLI からの確認
## 作成先サブスクリプションへの接続
$ az account set --subscription '<Subscription_Name>'
## AKSクラスタの表示
$ az aks list -g rg_ituru_aks01 -o table
Name Location ResourceGroup KubernetesVersion ProvisioningState Fqdn
-------------- ---------- --------------- ------------------- ------------------- --------------------------------------------
aks_ituru_cp01 japaneast rg_ituru_aks01 1.21.9 Succeeded cpcluster01-adf56c0d.hcp.japaneast.azmk8s.io
## AKS node pool の表示
$ az aks nodepool list -g rg_ituru_aks01 --cluster-name aks_ituru_cp01 -o table
Name OsType KubernetesVersion VmSize Count MaxPods ProvisioningState Mode
-------- -------- ------------------- -------------- ------- --------- ------------------- ------
cpdemo01 Linux 1.21.9 Standard_D2_v2 3 30 Succeeded System
AKSクラスタの操作
## クラスタの起動
$ az aks start -g rg_ituru_aks01 -n aks_ituru_cp01
## クラスタの停止
$ az aks stop -g rg_ituru_aks01 -n aks_ituru_cp01
ローカル環境からクラスタ接続のための認証情報の取得
$ az aks get-credentials --resource-group rg_ituru_aks01 --name aks_ituru_cp01
~/.kube/configファイルに接続情報が書き込まれることで、ローカル環境からクラスタ操作できるようになります。
AKSクラスタの確認
テスト用のPod起動
$ kubectl run --image=centos:centos7 --restart=Never --rm -it test -- bash
If you don't see a command prompt, try pressing enter.
[root@test /]#
[root@test /]# curl ifconfig.me
20.89.26.110
別コンソールを立ち上げて、Podの確認
## ノードの確認
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
aks-cpdemo01-17154442-vmss000003 Ready agent 3m41s v1.21.9 10.0.1.4 <none> Ubuntu 18.04.6 LTS 5.4.0-1073-azure containerd://1.4.12+azure-3
aks-cpdemo01-17154442-vmss000004 Ready agent 3m30s v1.21.9 10.0.1.35 <none> Ubuntu 18.04.6 LTS 5.4.0-1073-azure containerd://1.4.12+azure-3
aks-cpdemo01-17154442-vmss000005 Ready agent 3m41s v1.21.9 10.0.1.66 <none> Ubuntu 18.04.6 LTS 5.4.0-1073-azure containerd://1.4.12+azure-3
## Podの確認
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test 1/1 Running 0 76s 10.0.1.39 aks-cpdemo01-17154442-vmss000004 <none> <none>
作成したリソースの削除
## destroy
$ terraform destroy --auto-approve
まとめ
Terraform でサクッと Azure Kubernetes Service (AKS) with Azure CNI構成を作成できました。 Azure Portal や Azure CLI で構築するのもいいですが、IaC化もいいですね。