クイック スタート: Terraform を使用して Azure Kubernetes Service (AKS) クラスターをデプロイする

Azure Kubernetes Service (AKS) は、クラスターをすばやくデプロイおよび管理することができる、マネージド Kubernetes サービスです。 このクイック スタートでは次の作業を行います。

  • Terraform を使用して AKS クラスターを配置します。
  • 小売シナリオをシミュレートするマイクロサービスのグループと、Web フロントエンドを使用して、サンプルのマルチコンテナー アプリケーションを実行します。

Note

AKS クラスターの迅速なプロビジョニングを開始するため、この記事には、評価のみを目的とした既定の設定でクラスターをデプロイする手順が含まれています。 運用環境に対応したクラスターをデプロイする前に、ベースライン参照アーキテクチャを理解して、ビジネス要件にどの程度合致しているかを検討することをお勧めします。

開始する前に

Note

Azure Linux ノード プールが一般提供 (GA) になりました。 利点とデプロイの手順については、AKS 用 Azure Linux コンテナー ホストの概要に関する記事を参照してください。

Azure アカウントへのログイン

まず、Azure アカウントにログインし、次のセクションで説明する方法のいずれかを使用して認証します。

Terraform と Azure の認証シナリオ

Terraform は、Azure CLI を使用した Azure に対する認証のみをサポートしています。 Azure PowerShell を使用した認証はサポートされていません。 そのため、Terraform の作業を行うときには Azure PowerShell モジュールを使用できますが、まず Azure CLI を使用して Azure に対する認証を行う必要があります。

この記事では、次のシナリオで Azure に対して Terraform を認証する方法について説明します。 Azure に対して Terraform を認証するオプションの詳細については、「Azure CLI を使用した認証」を参照してください。

Microsoft アカウントを使用して Azure に対する認証を行う

Microsoft アカウントは、Azure などの Microsoft サービスにサインインするために使用されるユーザー名 (メール アドレスとその資格情報に関連付けられている) です。 Microsoft アカウントは 1 つ以上の Azure サブスクリプションに関連付けることができ、そのいずれかのサブスクリプションが既定値になります。

以下の手順で方法を説明します。

  • Microsoft アカウントを使用して Azure にインタラクティブにサインインします
  • アカウントに関連付けられている Azure サブスクリプションを一覧表示します (既定値を含む)
  • 現在のサブスクリプションを設定します。
  1. Azure CLI にアクセスできるコマンド ラインを開きます。

  2. パラメーターを指定せずに az login を実行し、指示に従って Azure にサインインします。

    az login
    

    重要なポイント:

    • サインインが成功すると、az login により、ログインした Microsoft アカウントに関連付けられている Azure サブスクリプションの一覧 (既定のサブスクリプションを含む) が表示されます。
  3. 現在の Azure サブスクリプションを確認するには、az account show を実行します。

    az account show
    
  4. 特定の Microsoft アカウントのすべての Azure サブスクリプションの名前と ID を表示するには、az account list を実行します。

    az account list --query "[?user.name=='<microsoft_account_email>'].{Name:name, ID:id, Default:isDefault}" --output Table
    

    重要なポイント:

    • <microsoft_account_email> プレースホルダーを、Azure サブスクリプションを一覧表示する Microsoft アカウントのメール アドレスに置き換えます。
    • Hotmail や Outlook などの Live アカウントを使用している場合は、完全修飾メール アドレスの指定が必要になることがあります。 たとえば、メール アドレスが admin@hotmail.com の場合は、プレースホルダーを live.com#admin@hotmail.com に置き換える必要があります。
  5. 特定の Azure サブスクリプションを使用するには、az account set を実行します。

    az account set --subscription "<subscription_id_or_subscription_name>"
    

    重要なポイント:

    • <subscription_id_or_subscription_name> プレースホルダーを、使用するサブスクリプションの ID または名前に置き換えます。
    • az account set を呼び出すと、指定した Azure サブスクリプションに切り替えた結果が表示されません。 ただし、az account show を使用して、現在の Azure サブスクリプションが変更されたことを確認できます。
    • 前の手順で az account list コマンドを実行している場合、既定の Azure サブスクリプションが、az account set で指定したサブスクリプションに変更されていることがわかります。

サービス プリンシパルの作成

Azure サービスをデプロイまたは使用する自動化ツール (Terraform など) のアクセス許可は、常に制限されている必要があります。 Azureは、完全な権限を持つユーザーとしてアプリケーションにサインインさせる代わりに、サービス プリンシパルを提供します。

最も一般的なパターンは、Azure に対話形式でサインインし、サービス プリンシパルを作成し、サービス プリンシパルをテストして、そのサービス プリンシパルを (対話形式またはスクリプトから) 今後の認証に使用することです。

  1. サービス プリンシパルを作成するには、Azure にサインインします。 Microsoft アカウントを使用して Azure に対して認証を行った後で、ここに戻ります。

  2. Git Bash からサービス プリンシパルを作成している場合は、MSYS_NO_PATHCONV 環境変数を設定します (Cloud Shell を使用している場合、この手順は必要ありません。)

    export MSYS_NO_PATHCONV=1    
    

    重要なポイント:

    • MSYS_NO_PATHCONV 環境変数は、グローバルに (すべてのターミナル セッションに対して) 設定することも、ローカルで (現在のセッションのみに) 設定することもできます。 サービス プリンシパルの作成は頻繁に行うものではないため、サンプルでは現在のセッションの値を設定します。 この環境変数をグローバルに設定するには、~/.bashrc ファイルに設定を追加します。
  3. サービス プリンシパルを作成するため、az ad sp create-for-rbac を実行します。

    az ad sp create-for-rbac --name <service_principal_name> --role Contributor --scopes /subscriptions/<subscription_id>
    

    重要なポイント:

    • <service-principal-name> を、ご使用の環境のカスタム名に置き換えることも、パラメーターを完全に省略することもできます。 パラメーターを省略する場合、サービス プリンシパル名は現在の日付と時刻に基づいて生成されます。
    • 正常に完了すると、az ad sp create-for-rbac によっていくつかの値が表示されます。 appIdpassword、および tenant の値は、次のステップで使用します。
    • このパスワードは、紛失した場合、取得できません。 したがって、パスワードは安全な場所に保管してください。 パスワードを忘れた場合は、サービス プリンシパルの資格情報をリセットできます。
    • この記事では、共同作成者ロールを指定したサービス プリンシパルが使用されています。 ロールベースのアクセス制御 (RBAC) ロールの詳細については、「RBAC: 組み込みロール」を参照してください。
    • サービス プリンシパルの作成時の出力には、機密性の高い資格情報が含まれています。 これらの資格情報をコードに含めないようにするか、資格情報をソース管理にチェックインしてください。
    • Azure CLI でサービス プリンシパルを作成するときのオプションの詳細については、記事「Azure CLI で Azure サービス プリンシパルを作成する」を参照してください。

環境変数でサービス プリンシパルの資格情報を指定する

サービス プリンシパルを作成したら、環境変数を使用して、その Terraform への資格情報を指定できます。

  1. 次の環境変数を追加して、~/.bashrc ファイルを編集します。

    export ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
    export ARM_TENANT_ID="<azure_subscription_tenant_id>"
    export ARM_CLIENT_ID="<service_principal_appid>"
    export ARM_CLIENT_SECRET="<service_principal_password>"
    
  2. ~/.bashrc スクリプトを実行するために、source ~/.bashrc (または同等の省略形である . ~/.bashrc) を実行します。 また、スクリプトを自動的に実行するために Cloud Shell を終了してからもう一度開くこともできます。

    . ~/.bashrc
    
  3. 環境変数を設定したら、次のように値を確認できます。

    printenv | grep ^ARM*
    

重要なポイント:

  • 他の環境変数と同様に、Terraform スクリプトから Azure サブスクリプションの値にアクセスするには、${env.<environment_variable>} という構文を使用します。 たとえば、ARM_SUBSCRIPTION_ID の値にアクセスするには、${env.ARM_SUBSCRIPTION_ID} を指定します。
  • Terraform 実行プランを作成して適用すると、サービス プリンシパルに関連付けられている Azure サブスクリプションが変更されます。 1 つの Azure サブスクリプションにログインしていて、環境変数が 2 つ目の Azure サブスクリプションを指している場合、これは混乱を招くことがあります。 これを説明する次の例を見てみましょう。 たとえば、SubA と SubB という 2 つの Azure サブスクリプションがあるとします。 現在の Azure サブスクリプションが SubA であり (az account show で特定)、環境変数が SubB を指している場合、Terraform によって行われたすべての変更は SubB に適用されます。 そのため、SubB サブスクリプションにログインし、Azure CLI コマンドか Azure PowerShell コマンドを実行して、変更内容を表示する必要があります。

Terraform プロバイダー ブロックでサービス プリンシパルの資格情報を指定する

Azure プロバイダー ブロックでは、Azure サブスクリプションの認証情報を指定できるようにする構文が定義されます。

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "~>2.0"
    }
  }
}

provider "azurerm" {
  features {}

  subscription_id   = "<azure_subscription_id>"
  tenant_id         = "<azure_subscription_tenant_id>"
  client_id         = "<service_principal_appid>"
  client_secret     = "<service_principal_password>"
}

# Your code goes here

注意事項

Terraform 構成ファイルで Azure サブスクリプションの資格情報を指定する機能は、特にテスト時に便利です。 ただし、信頼されていない個人が表示できるクリアテキスト ファイルに資格情報を格納することは推奨されません。

Terraform コードを実装する

注意

この記事のサンプル コードは、Azure Terraform GitHub リポジトリにあります。 Terraform の現在および以前のバージョンのテスト結果を含むログ ファイルを表示できます。

Terraform を使用して Azure リソースを管理する方法を示すその他の記事とサンプル コードを参照してください

  1. サンプルの Terraform コードのテストに使用できるディレクトリを作成し、それを現在のディレクトリにします。

  2. providers.tf という名前のファイルを作成し、次のコードを挿入します。

    terraform {
      required_version = ">=1.0"
    
      required_providers {
        azapi = {
          source  = "azure/azapi"
          version = "~>1.5"
        }
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
        time = {
          source  = "hashicorp/time"
          version = "0.9.1"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  3. ssh.tf という名前のファイルを作成し、次のコードを挿入します。

    resource "random_pet" "ssh_key_name" {
      prefix    = "ssh"
      separator = ""
    }
    
    resource "azapi_resource_action" "ssh_public_key_gen" {
      type        = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      resource_id = azapi_resource.ssh_public_key.id
      action      = "generateKeyPair"
      method      = "POST"
    
      response_export_values = ["publicKey", "privateKey"]
    }
    
    resource "azapi_resource" "ssh_public_key" {
      type      = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      name      = random_pet.ssh_key_name.id
      location  = azurerm_resource_group.rg.location
      parent_id = azurerm_resource_group.rg.id
    }
    
    output "key_data" {
      value = jsondecode(azapi_resource_action.ssh_public_key_gen.output).publicKey
    }
    
  4. main.tf という名前のファイルを作成し、次のコードを挿入します。

    # Generate random resource group name
    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
    }
    
    resource "random_pet" "azurerm_kubernetes_cluster_name" {
      prefix = "cluster"
    }
    
    resource "random_pet" "azurerm_kubernetes_cluster_dns_prefix" {
      prefix = "dns"
    }
    
    resource "azurerm_kubernetes_cluster" "k8s" {
      location            = azurerm_resource_group.rg.location
      name                = random_pet.azurerm_kubernetes_cluster_name.id
      resource_group_name = azurerm_resource_group.rg.name
      dns_prefix          = random_pet.azurerm_kubernetes_cluster_dns_prefix.id
    
      identity {
        type = "SystemAssigned"
      }
    
      default_node_pool {
        name       = "agentpool"
        vm_size    = "Standard_D2_v2"
        node_count = var.node_count
      }
      linux_profile {
        admin_username = var.username
    
        ssh_key {
          key_data = jsondecode(azapi_resource_action.ssh_public_key_gen.output).publicKey
        }
      }
      network_profile {
        network_plugin    = "kubenet"
        load_balancer_sku = "standard"
      }
    }
    
  5. variables.tf という名前のファイルを作成し、次のコードを挿入します。

    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      default     = "rg"
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "node_count" {
      type        = number
      description = "The initial quantity of nodes for the node pool."
      default     = 3
    }
    
    variable "msi_id" {
      type        = string
      description = "The Managed Service Identity ID. Set this value if you're running this example using Managed Identity as the authentication method."
      default     = null
    }
    
    variable "username" {
      type        = string
      description = "The admin username for the new cluster."
      default     = "azureadmin"
    }
    
  6. outputs.tf という名前のファイルを作成し、次のコードを挿入します。

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "kubernetes_cluster_name" {
      value = azurerm_kubernetes_cluster.k8s.name
    }
    
    output "client_certificate" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config[0].client_certificate
      sensitive = true
    }
    
    output "client_key" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config[0].client_key
      sensitive = true
    }
    
    output "cluster_ca_certificate" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config[0].cluster_ca_certificate
      sensitive = true
    }
    
    output "cluster_password" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config[0].password
      sensitive = true
    }
    
    output "cluster_username" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config[0].username
      sensitive = true
    }
    
    output "host" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config[0].host
      sensitive = true
    }
    
    output "kube_config" {
      value     = azurerm_kubernetes_cluster.k8s.kube_config_raw
      sensitive = true
    }
    

Terraform を初期化する

terraform init を実行して、Terraform のデプロイを初期化します。 このコマンドによって、Azure リソースを管理するために必要な Azure プロバイダーがダウンロードされます。

terraform init -upgrade

重要なポイント:

  • -upgrade パラメーターは、必要なプロバイダー プラグインを、構成のバージョン制約に準拠する最新バージョンにアップグレードします。

Terraform 実行プランを作成する

terraform plan を実行して、実行プランを作成します。

terraform plan -out main.tfplan

重要なポイント:

  • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
  • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。

Terraform 実行プランを適用する

terraform apply を実行して、クラウド インフラストラクチャに実行プランを適用します。

terraform apply main.tfplan

重要なポイント:

  • terraform apply コマンドの例は、以前に terraform plan -out main.tfplan が実行されたことを前提としています。
  • -out パラメーターに別のファイル名を指定した場合は、terraform apply の呼び出しで同じファイル名を使用します。
  • -out パラメーターを使用しなかった場合は、パラメーターを指定せずに terraform apply を呼び出します。

結果を確認する

  1. 次のコマンドを使用して Azure リソース グループ名を取得します。

    resource_group_name=$(terraform output -raw resource_group_name)
    
  2. az aks list コマンドを使用して、新しい Kubernetes クラスターの名前を表示します。

    az aks list \
      --resource-group $resource_group_name \
      --query "[].{\"K8s cluster name\":name}" \
      --output table
    
  3. Terraform の状態から Kubernetes 構成を取得し、次のコマンドを使用して kubectl が読み取れるファイルに保存します。

    echo "$(terraform output kube_config)" > ./azurek8s
    
  4. 次の コマンドを使用して、前のコマンドで ASCII EOT 文字が追加されなかったことを確認します。

    cat ./azurek8s
    

    重要なポイント:

    • 先頭に << EOT、末尾に EOT が表示される場合、ファイルからこれらの文字を削除します。 そうしないと、error: error loading config file "./azurek8s": yaml: line 2: mapping values are not allowed in this context というエラー メッセージが表示される場合があります。
  5. 次のコマンドを使用して kubectl が正しい構成を取得できるように環境変数を設定します。

    export KUBECONFIG=./azurek8s
    
  6. kubectl get nodes コマンドを使用してクラスターの正常性を確認します。

    kubectl get nodes
    

重要なポイント:

  • AKS クラスターを作成したとき、クラスター ノードとポッドの両方の正常性メトリックを取得するための監視が有効になりました。 これらの正常性メトリックは、Azure portal で利用できます。 コンテナーの正常性の監視の詳細については、Azure Kubernetes Service の正常性の監視に関するページを参照してください。
  • Terraform 実行プランを適用したときに出力として分類されるいくつかのキー値。 たとえば、ホスト アドレス、AKS クラスター ユーザー名、AKS クラスター パスワードが出力されます。

アプリケーションの配置

アプリケーションをデプロイするには、マニフェスト ファイルを使用して、AKS ストア アプリケーションの実行に必要なすべてのオブジェクトを作成します。 Kubernetes のマニフェスト ファイルでは、どのコンテナー イメージを実行するかなど、クラスターの望ましい状態を定義します。 マニフェストには、次の Kubernetes のデプロイとサービスが含まれています。

Azure Store サンプル アーキテクチャのスクリーンショット。

  • ネットショップ: 顧客が製品を見て注文するための Web アプリケーション。
  • 製品サービス: 製品情報が表示されます。
  • 注文サービス: 注文を行います。
  • Rabbit MQ: 注文キューのメッセージ キュー。

Note

運用環境の永続ストレージを使用せずに Rabbit MQ などのステートフル コンテナーを実行することはお勧めしません。 これらはわかりやすくするためにここで使用しますが、Azure CosmosDB や Azure Service Bus などのマネージド サービスを使用することをお勧めします。

  1. aks-store-quickstart.yaml という名前のファイルを作成し、そこに次のマニフェストをコピーします。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: rabbitmq
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: rabbitmq
      template:
        metadata:
          labels:
            app: rabbitmq
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          containers:
          - name: rabbitmq
            image: mcr.microsoft.com/mirror/docker/library/rabbitmq:3.10-management-alpine
            ports:
            - containerPort: 5672
              name: rabbitmq-amqp
            - containerPort: 15672
              name: rabbitmq-http
            env:
            - name: RABBITMQ_DEFAULT_USER
              value: "username"
            - name: RABBITMQ_DEFAULT_PASS
              value: "password"
            resources:
              requests:
                cpu: 10m
                memory: 128Mi
              limits:
                cpu: 250m
                memory: 256Mi
            volumeMounts:
            - name: rabbitmq-enabled-plugins
              mountPath: /etc/rabbitmq/enabled_plugins
              subPath: enabled_plugins
          volumes:
          - name: rabbitmq-enabled-plugins
            configMap:
              name: rabbitmq-enabled-plugins
              items:
              - key: rabbitmq_enabled_plugins
                path: enabled_plugins
    ---
    apiVersion: v1
    data:
      rabbitmq_enabled_plugins: |
        [rabbitmq_management,rabbitmq_prometheus,rabbitmq_amqp1_0].
    kind: ConfigMap
    metadata:
      name: rabbitmq-enabled-plugins            
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: rabbitmq
    spec:
      selector:
        app: rabbitmq
      ports:
        - name: rabbitmq-amqp
          port: 5672
          targetPort: 5672
        - name: rabbitmq-http
          port: 15672
          targetPort: 15672
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: order-service
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: order-service
      template:
        metadata:
          labels:
            app: order-service
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          containers:
          - name: order-service
            image: ghcr.io/azure-samples/aks-store-demo/order-service:latest
            ports:
            - containerPort: 3000
            env:
            - name: ORDER_QUEUE_HOSTNAME
              value: "rabbitmq"
            - name: ORDER_QUEUE_PORT
              value: "5672"
            - name: ORDER_QUEUE_USERNAME
              value: "username"
            - name: ORDER_QUEUE_PASSWORD
              value: "password"
            - name: ORDER_QUEUE_NAME
              value: "orders"
            - name: FASTIFY_ADDRESS
              value: "0.0.0.0"
            resources:
              requests:
                cpu: 1m
                memory: 50Mi
              limits:
                cpu: 75m
                memory: 128Mi
          initContainers:
          - name: wait-for-rabbitmq
            image: busybox
            command: ['sh', '-c', 'until nc -zv rabbitmq 5672; do echo waiting for rabbitmq; sleep 2; done;']
            resources:
              requests:
                cpu: 1m
                memory: 50Mi
              limits:
                cpu: 75m
                memory: 128Mi    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: order-service
    spec:
      type: ClusterIP
      ports:
      - name: http
        port: 3000
        targetPort: 3000
      selector:
        app: order-service
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: product-service
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: product-service
      template:
        metadata:
          labels:
            app: product-service
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          containers:
          - name: product-service
            image: ghcr.io/azure-samples/aks-store-demo/product-service:latest
            ports:
            - containerPort: 3002
            resources:
              requests:
                cpu: 1m
                memory: 1Mi
              limits:
                cpu: 1m
                memory: 7Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: product-service
    spec:
      type: ClusterIP
      ports:
      - name: http
        port: 3002
        targetPort: 3002
      selector:
        app: product-service
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store-front
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: store-front
      template:
        metadata:
          labels:
            app: store-front
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          containers:
          - name: store-front
            image: ghcr.io/azure-samples/aks-store-demo/store-front:latest
            ports:
            - containerPort: 8080
              name: store-front
            env: 
            - name: VUE_APP_ORDER_SERVICE_URL
              value: "http://order-service:3000/"
            - name: VUE_APP_PRODUCT_SERVICE_URL
              value: "http://product-service:3002/"
            resources:
              requests:
                cpu: 1m
                memory: 200Mi
              limits:
                cpu: 1000m
                memory: 512Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-front
    spec:
      ports:
      - port: 80
        targetPort: 8080
      selector:
        app: store-front
      type: LoadBalancer
    

    YAML マニフェスト ファイルの内訳については、「デプロイと YAML マニフェスト」を参照してください。

    YAML ファイルをローカルに作成して保存する場合は、[ファイルのアップロード/ダウンロード] ボタンを選択し、ローカル ファイル システムからファイルを選択することで、CloudShell の既定のディレクトリにマニフェスト ファイルをアップロードできます。

  2. kubectl apply コマンドを使用してアプリケーションをデプロイし、ご利用の YAML マニフェストの名前を指定します。

    kubectl apply -f aks-store-quickstart.yaml
    

    次の出力例は、デプロイとサービスを示しています。

    deployment.apps/rabbitmq created
    service/rabbitmq created
    deployment.apps/order-service created
    service/order-service created
    deployment.apps/product-service created
    service/product-service created
    deployment.apps/store-front created
    service/store-front created
    

アプリケーションをテストする

アプリケーションが実行されると、Kubernetes サービスによってアプリケーション フロント エンドがインターネットに公開されます。 このプロセスが完了するまでに数分かかることがあります。

  1. kubectl get pods コマンドを使用して、デプロイされたポッドの状態を確認します。 続行する前に、すべてのポッドを Running の状態にします。

    kubectl get pods
    
  2. ストア フロント アプリケーションのパブリック IP アドレスを確認します。 kubectl get service コマンドと --watch 引数を使用して、進行状況を監視します。

    kubectl get service store-front --watch
    

    store-front サービスの [EXTERNAL-IP] の出力は、最初は pending と表示されます。

    NAME          TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
    store-front   LoadBalancer   10.0.100.10   <pending>     80:30025/TCP   4h4m
    
  3. EXTERNAL-IP アドレスが保留中から実際のパブリック IP アドレスに変わったら、CTRL-C を使用して kubectl ウォッチ プロセスを停止します。

    次の出力例は、サービスに割り当てられている有効なパブリック IP アドレスを示しています。

    NAME          TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
    store-front   LoadBalancer   10.0.100.10   20.62.159.19   80:30025/TCP   4h5m
    
  4. Azure Store アプリが動作していることを確認するには、Web ブラウザーを開いてサービスの外部 IP アドレスにアクセスします。

    AKS Store サンプル アプリケーションのスクリーンショット。

リソースをクリーンアップする

AKS リソースを削除する

Terraform を使用して作成したリソースが不要になった場合は、次の手順を実行します。

  1. terraform plan を実行して、destroy フラグを指定します。

    terraform plan -destroy -out main.destroy.tfplan
    

    重要なポイント:

    • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
    • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。
  2. terraform apply を実行して、実行プランを適用します。

    terraform apply main.destroy.tfplan
    

サービス プリンシパルを削除する

  1. 次のコマンドを使用して、サービス プリンシパル ID を取得します。

    sp=$(terraform output -raw sp)
    
  2. az ad sp delete コマンドを使用して、サービス プリンシパルを削除します。

    az ad sp delete --id $sp
    

Azure Developer CLI テンプレートを複製する

Azure Developer CLI を使用すると、Azure-Samples リポジトリからサンプルをすばやくダウンロードできます。 このクイック スタートでは、aks-store-demo アプリケーションをダウンロードします。 一般的なユースケースの詳細については、azd の概要を参照してください。

  1. --template パラメーターを含む azd init コマンドを使用する Azure-Samples リポジトリから AKS ストア デモ テンプレートを複製します。

    azd init --template Azure-Samples/aks-store-demo
    
  2. aks-terraform-1 のように、英数字とハイフンのみを使用したプロジェクトの環境名を入力します。

    Enter a new environment name: aks-terraform-1
    

Azure Cloud アカウントにサインインする

azd テンプレートには、サービスを作成するために必要なすべてのコードが含まれていますが、AKS 上でアプリケーションをホストするには、Azure アカウントにサインインする必要があります。

  1. azd auth login コマンドを使用してアカウントにサインインします。

    azd auth login
    
  2. 出力に表示されるデバイス コードをコピーし、Enter キーを押してサインインします。

    Start by copying the next code: XXXXXXXXX
    Then press enter and continue to log in from your browser...
    

    重要

    ネットワーク外の仮想マシンまたは GitHub コードスペースを使用している場合、一部の Azure セキュリティ ポリシーでは、azd auth login でサインインしようとすると競合が発生します。 こちらの問題が発生した場合は、提供される AZD 認証ワークロードに従います。これには、azd auth login を実行した後にリダイレクトされた localhost URL への curl 要求の使用が含まれます。

  3. 組織のサインイン ページで資格情報を使用して認証します。

  4. ご自身が Azure CLI から接続しようとしていることを確認します。

  5. "Device code authentication completed. Logged in to Azure." というメッセージが元のターミナルに表示されることを確認します。

    Waiting for you to complete authentication in the browser...
    Device code authentication completed.
    Logged in to Azure.
    

AZD 認証の回避策

この回避策では、Azure CLI をインストールする必要があります。

  1. ターミナル ウィンドウを開き、--scope パラメーターを https://graph.microsoft.com/.default に設定して az login コマンドを使用して Azure CLI でログインします。

    az login --scope https://graph.microsoft.com/.default
    

    次の例に示すように、ブラウザー アクセス トークンを作成するには、新しいタブの認証ページにリダイレクトする必要があります。

    https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?clientid=<your_client_id>.
    
  2. azd auth login でサインインしようとした後に受信した Web ページの localhost URL をコピーします。

  3. 新しいターミナル ウィンドウで、次の curl 要求を使用してログインします。 <localhost> プレースホルダーは、前の手順でコピーした localhost URL に置き換えます。

    curl <localhost>
    

    ログインが成功すると、次の例に示すように HTML Web ページが出力されます。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="refresh" content="60;url=https://docs.microsoft.com/cli/azure/">
        <title>Login successfully</title>
        <style>
            body {
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            }
    
            code {
                font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
                display: inline-block;
                background-color: rgb(242, 242, 242);
                padding: 12px 16px;
                margin: 8px 0px;
            }
        </style>
    </head>
    <body>
        <h3>You have logged into Microsoft Azure!</h3>
        <p>You can close this window, or we will redirect you to the <a href="https://docs.microsoft.com/cli/azure/">Azure CLI documentation</a> in 1 minute.</p>
        <h3>Announcements</h3>
        <p>[Windows only] Azure CLI is collecting feedback on using the <a href="https://learn.microsoft.com/windows/uwp/security/web-account-manager">Web Account Manager</a> (WAM) broker for the login experience.</p>
        <p>You may opt-in to use WAM by running the following commands:</p>
        <code>
            az config set core.allow_broker=true<br>
            az account clear<br>
            az login
        </code>
    </body>
    </html>
    
  4. 現在のターミナルを閉じて、元のターミナルを開きます。 サブスクリプションの JSON リストが表示されます。

  5. 使用するサブスクリプションの id フィールドをコピーします。

  6. az account set コマンドを使用してサブスクリプションを設定します。

    az account set --subscription <subscription_id>
    

クラスターのリソースの作成とデプロイ

アプリケーションをデプロイするには、azd up コマンドを使用して、AKS Store アプリケーションの実行に必要なすべてのオブジェクトを作成します。

  • azure.yaml ファイルは、どのコンテナー イメージをフェッチするかなど、クラスターの望ましい状態を定義し、次の Kubernetes デプロイとサービスを含みます。

Azure Store のサンプル アーキテクチャを示す図。

  • ネットショップ: 顧客が製品を見て注文するための Web アプリケーション。
  • 製品サービス: 製品情報が表示されます。
  • 注文サービス: 注文を行います。
  • Rabbit MQ: 注文キューのメッセージ キュー。

Note

運用環境の永続ストレージを使用せずに Rabbit MQ などのステートフル コンテナーを実行することはお勧めしません。 これらはわかりやすくするためにここで使用しますが、Azure CosmosDB や Azure Service Bus などのマネージド サービスを使用することをお勧めします。

アプリケーション リソースのデプロイ

このクイックスタートの azd テンプレートは、AKS クラスターと Azure キー コンテナーを含む新しいリソース グループを作成します。 キー コンテナーはクライアント シークレットを保存し、pets 名前空間のサービスを実行します。

  1. azd up コマンドを使用して、すべてのアプリケーション リソースを作成します。

    azd up
    

    azd upazd-hooks フォルダー内のすべてのフックを実行し、アプリケーション サービスの事前登録、プロビジョニング、デプロイを行います。

    フックをカスタマイズして、azd ワークフロー ステージにカスタム コードを追加します。 詳細については、azd フックのリファレンスを参照してください。

  2. 課金に使用する Azure サブスクリプションを選択します。

    ? Select an Azure Subscription to use:  [Use arrows to move, type to filter]
    > 1. My Azure Subscription (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
    
  3. アプリケーションをデプロイするリージョンを選択します。

    Select an Azure location to use:  [Use arrows to move, type to filter]
      1.  (South America) Brazil Southeast (brazilsoutheast)
      2.  (US) Central US (centralus)
      3.  (US) East US (eastus)
    > 43. (US) East US 2 (eastus2)
      4.  (US) East US STG (eastusstg)
      5.  (US) North Central US (northcentralus)
      6.  (US) South Central US (southcentralus)
    

    azd は自動的に事前プロビジョニングおよび事後プロビジョニング フックを実行し、アプリケーションのリソースを作成します。 このプロセスが完了するまでに数分かかることがあります。 完了すると、次の例のような出力が表示されます:

    SUCCESS: Your workflow to provision and deploy to Azure completed in 9 minutes 40 seconds.
    

Terraform プランを生成する

Azure Developer テンプレート内の /infra/terraform フォルダーには、Terraform プランの生成に使用されるすべてのコードが含まれています。

Terraform は、azd のプロビジョニング手順の一部として、terraform apply を使用してコマンドをデプロイし、実行します。 完了すると、次の例のような出力が表示されます:

Plan: 5 to add, 0 to change, 0 to destroy.
...
Saved the plan to: /workspaces/aks-store-demo/.azure/aks-terraform-azd/infra/terraform/main.tfplan

アプリケーションをテストする

アプリケーションが実行されると、Kubernetes サービスによってアプリケーション フロント エンドがインターネットに公開されます。 このプロセスが完了するまでに数分かかることがあります。

  1. kubectl set-context コマンドを使用して、名前空間をデモ名前空間 pets として設定します。

    kubectl config set-context --current --namespace=pets
    
  2. kubectl get pods コマンドを使用して、デプロイされたポッドの状態を確認します。 続行する前に、すべてのポッドを Running の状態にします。

    kubectl get pods
    
  3. ストア フロント アプリケーションのパブリック IP アドレスを確認し、--watch 引数を含む kubectl get service コマンドを使用した進捗状況を監視します。

    kubectl get service store-front --watch
    

    store-front サービスの [EXTERNAL-IP] の出力は、最初は pending と表示されます。

    NAME          TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
    store-front   LoadBalancer   10.0.100.10   <pending>     80:30025/TCP   4h4m
    
  4. EXTERNAL-IP アドレスが保留中から実際のパブリック IP アドレスに変わったら、CTRL-C を使用して kubectl ウォッチ プロセスを停止します。

    次のサンプル出力は、サービスに割り当てられている有効なパブリック IP アドレスを示しています。

    NAME          TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
    store-front   LoadBalancer   10.0.100.10   20.62.159.19   80:30025/TCP   4h5m
    
  5. Azure Store アプリが動作していることを確認するには、Web ブラウザーを開いてサービスの外部 IP アドレスにアクセスします。

    AKS Store サンプル アプリケーションのスクリーンショット。

クラスターを削除する

クイックスタートが完了したら、Azure の課金を避けるために、不要なリソースをクリーンアップしてください。

  1. azd down コマンドを使用し、クイックスタートで作成したリソースをすべて削除します。

    azd down
    
  2. y を入力し、Enter を押すことで、サブスクリプションからすべての使用済みリソースを削除する決定を確認します。

    ? Total resources to delete: 14, are you sure you want to continue? (y/N)
    
  3. y を入力し、Enter を押すことで、消去でクイックスタート変数を再利用できるようになります。

    [Warning]: These resources have soft delete enabled allowing them to be recovered for a period or time after deletion. During this period, their names can't be reused. In the future, you can use the argument --purge to skip this confirmation.
    

Azure での Terraform のトラブルシューティング

Azure で Terraform を使用する場合の一般的な問題のトラブルシューティング

次のステップ

このクイック スタートでは、Kubernetes クラスターをデプロイし、シンプルな複数コンテナー アプリケーションをそこにデプロイしました。 このサンプル アプリケーションはデモ専用であり、Kubernetes アプリケーションのすべてのベスト プラクティスを表すわけではありません。 実稼動用に AKS を使用した完全なソリューションを作成するうえでのガイダンスについては、AKS ソリューション ガイダンスに関する記事を参照してください。

AKS の詳細を確認し、完全なコードからデプロイの例までを確認するには、Kubernetes クラスターのチュートリアルに進んでください。