Azure Kubernetes Service (AKS) のクラスターでノード プールを管理する

Azure Kubernetes Service (AKS) で同じ構成のノードは、ノード プールにグループ化できます。 これらのノード プールには、お使いのアプリケーションを実行する基になる VM が含まれています。 AKS クラスターを作成するときは、ノードの初期数とそのサイズ (SKU) を定義します。 アプリケーションの要求が変わると、ノード プールの設定を変更することが必要になる場合があります。 たとえば、ノード プール内のノードの数をスケーリングしたり、ノード プールの Kubernetes バージョンをアップグレードしたりする必要がある場合があります。

この記事では、AKS クラスターで 1 つ以上のノード プールを管理する方法について説明します。

開始する前に

制限事項

複数のノード プールをサポートする AKS クラスターを作成および管理する場合には、次の制限があります。

  • Azure Kubernetes Service (AKS) のクォータ、仮想マシンのサイズの制限、およびリージョンの可用性」を参照してください。
  • システム プール には少なくとも 1 つのノードを含める必要があり、ユーザー ノード プールには 0 以上のノードを含めることができます。
  • VM を作成した後にノード プールの VM サイズを変更することはできません。
  • クラスターの作成時に複数のノード プールを作成する場合は、ノード プールで使用されるすべての Kubernetes のバージョンが、コントロール プレーンに設定されたバージョンと一致している必要があります。 ノード プールごとの操作を使用して、クラスターをプロビジョニングした後に更新を行うことができます。
  • クラスターまたはノード プールでアップグレード操作とスケーリング操作を同時に実行することはできません。 同時に実行しようとすると、エラーが発生します。 ターゲット リソースに対する次の要求を行う前に、各操作の種類をその同じリソースで完了する必要があります。 詳細については、トラブルシューティング ガイドを参照してください。

単一 ノード プールをアップグレードする

Note

ノード プールの OS イメージのバージョンは、クラスターの Kubernetes バージョンに関連付けられています。 OS イメージは、クラスターのアップグレードの後でのみアップグレードされます。

この例では、 mynodepool ノード プールをアップグレードします。 ノード プールは 2 つあるため、az aks nodepool upgrade コマンドを使用してアップグレードする必要があります。

  1. az aks get-upgrades コマンドを使用して、使用可能なアップグレードを確認します。

    az aks get-upgrades --resource-group myResourceGroup --name myAKSCluster
    
  2. az aks nodepool upgrade コマンドを使用して mynodepool ノード プールをアップグレードします。

    az aks nodepool upgrade \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name mynodepool \
        --kubernetes-version KUBERNETES_VERSION \
        --no-wait
    
  3. az aks nodepool list コマンドを使用し、お使いのノード プールの状態を一覧表示します。

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    次の出力例では、mynodepoolUpgrading 状態であることを示しています:

    [
      {
        ...
        "count": 3,
        ...
        "name": "mynodepool",
        "orchestratorVersion": "KUBERNETES_VERSION",
        ...
        "provisioningState": "Upgrading",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      },
      {
        ...
        "count": 2,
        ...
        "name": "nodepool1",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Succeeded",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      }
    ]
    

    ノードを指定したバージョンにアップグレードするには数分かかります。

AKS クラスター内のノード プールは、すべて同じ Kubernetes のバージョンにアップグレードするのがベスト プラクティスです。 az aks upgrade の既定の動作では、この配置を実現するために、すべてのノード プールがコントロール プレーンと共にアップグレードされます。 個々のノード プールをアップグレードできる機能によりローリング アップグレードの実行が可能になり、アプリケーションのアップタイムを維持するノード プール間のポッドを前述の制約内でスケジュールできます。

複数のノード プールを使用することでクラスターのコントロール プレーンをアップグレードする

Note

Kubernetes は、標準のセマンティック バージョニングのバージョン管理スキームを使用します。 バージョン番号は x.y.z として表されます。ここで、x はメジャー バージョン、y はマイナー バージョン、z は修正プログラムのバージョンです。 たとえば、バージョン 1.12.6 の場合は、1 がメジャー バージョン、12 がマイナー バージョン、6 が修正プログラムのバージョンです。 コントロール プレーンの Kubernetes バージョンと初期ノード プールは、クラスター作成時に設定されます。 その他のノード プールには、クラスターに追加されるときに Kubernetes バージョンが設定されます。 Kubernetes バージョンは、ノード プール間、およびノード プールとコントロール プレーン間では異なる場合があります。

AKS クラスターには、Kubernetes バージョンが関連付けられている 次の2 つのクラスター リソース オブジェクトがあります:

  1. クラスターのコントロール プレーンの Kubernetes バージョン、および
  2. Kubernetes バージョンのノード プール。

コントロール プレーンは、1 つまたは複数のノード プールにマップされます。 アップグレード操作の動作は、どの Azure CLI コマンドを使用するかによって異なります。

  • az aks upgrade は、コントロール プレーンとクラスター内のすべてのノード プールを同じ Kubernetes バージョンにアップグレードします。
  • --control-plane-only フラグを使用すると、az aks upgrade ではクラスター コントロール プレーンのみがアップグレードされ、すべてのノード プールは変更されません。
  • az aks nodepool upgrade は、指定された Kubernetes バージョンのターゲット ノード プールのみがアップグレードされます。

アップグレードの検証規則

クラスターのコントロール プレーンとノード プールの Kubernetes のアップグレードは、次の規則のセットを使用して検証されます:

  • ノード プールをアップグレードするための有効なバージョンの規則:

    • ノード プールのバージョンは、コントロール プレーンと同じ "メジャー" バージョンである必要があります。
    • ノード プールの "マイナー" バージョンは、コントロール プレーンのバージョンの 2 つ以内の "マイナー" バージョンでなければなりません。
    • ノード プールのバージョンを、コントロールの major.minor.patch バージョンよりも大きくすることはできません。
  • アップグレード操作を送信するための規則:

    • コントロール プレーンでも、ノード プールでも、Kubernetes バージョンをダウングレードすることはできません。
    • ノード プールの Kubernetes バージョンが指定されていない場合、動作は使用中のクライアントによって異なります。 Resource Manager テンプレートでは、宣言はノード プールに対して定義されている既存のバージョンにフォールバックします。 何も設定されていない場合は、コントロール プレーン バージョンを使用してフォールバックします。
    • 1 つのコントロール プレーンまたはノード プール リソースに対して複数の操作を同時に送信することはできません。 コントロール プレーンまたはノード プールは、特定の時点でアップグレードまたはスケールできます。

ノード プールの手動でのスケーリング

お使いのアプリケーションのワークロードに対する需要の変化に伴い、ノード プール内のノード数をスケーリングしなければならなくなる場合があります。 ノード数は増やすことも減らすことも可能です。

  1. ノード プール内のノード数をスケーリングするには、az aks node pool scale コマンドを使用します。

    az aks nodepool scale \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name mynodepool \
        --node-count 5 \
        --no-wait
    
  2. az aks node pool list コマンドを使用し、お使いのノード プールの状態を一覧表示します。

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    次の出力例では、mynodepool が 5 ノードの新しいカウントで Scaling の状態であることを示しています:

    [
      {
        ...
        "count": 5,
        ...
        "name": "mynodepool",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Scaling",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      },
      {
        ...
        "count": 2,
        ...
        "name": "nodepool1",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Succeeded",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      }
    ]
    

    スケーリングの操作の完了には、数分かかります。

クラスター オートスケーラーを有効にすることで特定のノード プールを自動的にスケーリングする

AKS には、クラスター オートスケーラーと呼ばれる機能を使用してノード プールを自動的にスケーリングするための独立した機能が用意されています。 この機能は、ノード プールごとに一意の最小スケール数と最大スケール数で有効にすることができます。

詳細については、「クラスター オートスケーラーの使用」 を参照してください。

容量予約グループをノード プールに関連付ける

ワークロードの需要が変化するにつれて、既存の容量予約グループをノード プールに関連付けて、ノード プールに割り当てられた容量を保証できます。

AKS で容量予約グループを使用するための前提条件

  • CLI バージョン 2.56 以降と API バージョン 2023-10-01 以降を使用します。

  • 容量予約グループは既に存在して、最小 1 つの容量予約が含まれている必要があります。そうでない場合、ノード プールは警告を伴ってクラスターに追加され、容量予約グループは関連付けられません。 詳しくは、容量予約グループ に関する記事をご覧ください。

  • 容量予約グループ (CRG) を含むリソース グループのユーザー割り当てマネージド ID を作成する必要があります。 システム割り当てマネージド ID は、この機能では機能しません。 次の例では、環境変数を独自の値に置き換えます。

    IDENTITY_NAME=myID
    RG_NAME=myResourceGroup
    CLUSTER_NAME=myAKSCluster
    VM_SKU=Standard_D4s_v3
    NODE_COUNT=2
    LOCATION=westus2
    az identity create --name $IDENTITY_NAME --resource-group $RG_NAME  
    IDENTITY_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RG_NAME --query identity.id -o tsv)
    
  • 上記で作成したユーザー割り当て ID に Contributor ロールを割り当てる必要があります。 詳細については、「Azure ロールを割り当てる手順」を参照してください。

  • 新しいクラスターを作成し、新しく作成した ID を割り当てます。

      az aks create --resource-group $RG_NAME --name $CLUSTER_NAME --location $LOCATION \
          --node-vm-size $VM_SKU --node-count $NODE_COUNT \
          --assign-identity $IDENTITY_ID --enable-managed-identity         
    
  • update コマンドを使用して、既存のマネージド クラスターでユーザーマネージド ID を割り当てることもできます。

      az aks update --resource-group $RG_NAME --name $CLUSTER_NAME --location $LOCATION \
              --node-vm-size $VM_SKU --node-count $NODE_COUNT \
              --assign-identity $IDENTITY_ID --enable-managed-identity         
    

既存の容量予約グループをノード プールに関連付ける

az aks nodepool add コマンドを使用して既存の容量予約グループをノード プールに関連付け、--crg-id フラグを使用して容量予約グループを指定します。 次の例では、"myCRG" という名前の CRG があることを前提としています。

RG_NAME=myResourceGroup
CLUSTER_NAME=myAKSCluster
NODEPOOL_NAME=myNodepool
CRG_NAME=myCRG
CRG_ID=$(az capacity reservation group show --capacity-reservation-group $CRG_NAME --resource-group $RG_NAME --query id -o tsv)
az aks nodepool add --resource-group $RG_NAME --cluster-name $CLUSTER_NAME --name $NODEPOOL_NAME --crg-id $CRG_ID

既存の容量予約グループをシステム ノード プールに関連付ける

既存の容量予約グループをシステム ノード プールに関連付けるには、クラスターの作成時に、クラスターをユーザー割り当て ID に関連付け、CRG の共同作成者ロールと CRG 自体を関連付けます。 --assign-identity--crg-id フラグで az aks create コマンドを使用します。

IDENTITY_NAME=myID
RG_NAME=myResourceGroup
CLUSTER_NAME=myAKSCluster
NODEPOOL_NAME=myNodepool
CRG_NAME=myCRG
CRG_ID=$(az capacity reservation group show --capacity-reservation-group $CRG_NAME --resource-group $RG_NAME --query id -o tsv)
IDENTITY_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RG_NAME --query identity.id -o tsv)
az aks create --resource-group $RG_NAME --cluster-name $CLUSTER_NAME --crg-id $CRG_ID --assign-identity $IDENTITY_ID --enable-managed-identity

Note

ノード プールのコマンドを削除すると、そのノード プールが削除される前に、関連付けられている容量予約グループからノード プールが暗黙的に解除されます。 クラスターのコマンドを削除すると、クラスター内のすべてのノード プールが、関連付けられている容量予約グループから暗黙的に関連付け解除されます。

Note

既存のノード プールを容量予約グループで更新することはできません。 推奨される方法は、ノード プールの作成時に容量予約グループを関連付ける方法です。

ノード プールの VM サイズの指定

VM のサイズと機能が異なるノード プールを作成する必要がある場合があります。 たとえば、大きな CPU またはメモリのノードが含まれるノード プール、または GPU をサポートするノード プールが作成されます。 次の手順では、taints と tolerations を使用 して、Kubernetes スケジューラにこれらのノードで実行されるポッドに対するアクセスを制限する方法を通知します。

次の例では、Standard_NC6s_v3 の VM サイズを使用する GPU ベースのノード プールを作成します。 これらの VM は NVIDIA Tesla K80 カードを搭載しています。 詳細については、「Azure で使用可能な Linux 仮想マシンのサイズ」を参照してください。

  1. az aks node pool add コマンドを使用して、ノード プールを作成します。 gpunodepool を名前として指定し、 --node-vm-size パラメーターを使用して Standard_NC6 サイズを指定します。

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunodepool \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --no-wait
    
  2. az aks nodepool list コマンドを使用して、ノードプールの状態を確認します。

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    次の出力例では、gpunodepool ノードプールが、指定された VmSize のノードを 作成 していることを示しています:

    [
      {
        ...
        "count": 1,
        ...
        "name": "gpunodepool",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Creating",
        ...
        "vmSize": "Standard_NC6s_v3",
        ...
      },
      {
        ...
        "count": 2,
        ...
        "name": "nodepool1",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Succeeded",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      }
    ]
    

    gpunodepool が正常に作成されるには、数分かかります。

テイント、ラベル、またはタグをノード プールに指定する

ノード プールを作成するときに、テイント、ラベル、タグを追加できます。 テイント、ラベル、タグを追加すると、そのノード プール内のすべてのノードもそのテイント、ラベル、タグを取得します。

重要

ノードへの テイント、ラベル、タグの追加は、az aks nodepool を使用してノードプール全体に対して行う必要があります。 テイント、ラベル、またはタグをノード プール内の個々のノードに適用するために、kubectl を使用することはお勧めしません。

ノード プールのテイントの設定

  1. az aks nodepool add コマンドを使用して、テイントを含むノード プールを 作成します。 名前 taintnp を指定し、--node-taints パラメーターを使用してテイントに sku=gpu:NoSchedule を指定します。

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name taintnp \
        --node-count 1 \
        --node-taints sku=gpu:NoSchedule \
        --no-wait
    
  2. az aks nodepool list コマンドを使用して、ノードプールの状態を確認します。

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    次の出力例では、taintnp ノード プールが、指定された nodeTaints を持つノードを 作成 していることが示されています:

    [
      {
        ...
        "count": 1,
        ...
        "name": "taintnp",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Creating",
        ...
        "nodeTaints":  [
          "sku=gpu:NoSchedule"
        ],
        ...
      },
     ...
    ]
    

テイントの情報は、ノードのスケジューリング規則を処理するために Kubernetes に表示されます。 Kubernetes スケジューラでは、テイントと tolerations(容認) を使用して、ノードで実行できるワークロードを制限できます。

  • テイントは、ノードに適用されて、特定のポッドのみをそのノードでスケジュールできることを示します。
  • tolerations(容認) は、ポッドに適用されて、ポッドがノードのテイントを "許容する" ことを許可します。

Kubernetes での高度なスケジューラ機能の詳細については、「Azure Kubernetes Service (AKS) での高度なスケジューラ機能に関するベスト プラクティス」を参照してください。

ノード プールの許容範囲を設定する

前の手順では、ノード プールの作成時に sku=gpu:NoSchedule テイントを適用しました。 次の YAML マニフェストの例では、Kubernetes スケジューラがそのノードプール内のノードで NGINX ポッドを実行できるように許容範囲を使用しています。

  1. nginx-toleration.yaml という名前のファイルを作成し、次の例の YAML 内にコピーします。

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
     - image: mcr.microsoft.com/oss/nginx/nginx:1.15.9-alpine
        name: mypod
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 1
            memory: 2G
      tolerations:
     - key: "sku"
        operator: "Equal"
        value: "gpu"
        effect: "NoSchedule"
    
  2. kubectl apply コマンドを使用してポッドをスケジュールします。

    kubectl apply -f nginx-toleration.yaml
    

    ポッドのスケジュールおよび NGINX イメージのプルには、数秒かかります。

  3. kubectl describe pod コマンドを使用して、その状態を確認します。

    kubectl describe pod mypod
    

    次の縮約された出力例では、sku = gpu:NoSchedule toleration を適用しています。 イベント セクションで、スケジューラによってポッドが aks-taintnp-28993262-vmss000000 ノードに割り当てられています:

    [...]
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                     node.kubernetes.io/unreachable:NoExecute for 300s
                     sku=gpu:NoSchedule
    Events:
      Type    Reason     Age    From                Message
      ----    ------     ----   ----                -------
      Normal  Scheduled  4m48s  default-scheduler   Successfully assigned default/mypod to aks-taintnp-28993262-vmss000000
      Normal  Pulling    4m47s  kubelet             pulling image "mcr.microsoft.com/oss/nginx/nginx:1.15.9-alpine"
      Normal  Pulled     4m43s  kubelet             Successfully pulled image "mcr.microsoft.com/oss/nginx/nginx:1.15.9-alpine"
      Normal  Created    4m40s  kubelet             Created container
      Normal  Started    4m40s  kubelet             Started container
    

    taintnp のノードでスケジュールできるのは、この tolerations(容認) が適用されているポッドのみです。 その他のポッドは、nodepool1 ノード プールにスケジュールされます。 追加のノード プールを作成した場合、テイントと容認を使用して、それらのノード リソースにどのようなポッドをスケジュールするか制限できます。

ノード プールのラベルの設定

詳細については、「Azure Kubernetes Service (AKS) クラスターでラベルを使用する」 をご覧ください。

ノード プールの Azure タグの設定

詳細については、「Azure Kubernetes Service (AKS) での Azure タグの使用」 を参照してください。

Resource Manager テンプレートを使用したノード プールの管理

作成する Azure Resource Manager テンプレートを使用してリソースを作成および管理する場合、テンプレート内の設定を更新し、再デプロイしてリソースを更新できます。 AKS 内のノード プールでは、AKS クラスターが作成されると、初期ノード プール プロファイルは更新できません。 この動作は、既存の Resource Manager テンプレートの更新、ノード プールへの変更、テンプレートを再デプロイすることができないことを意味します。 代わりに、既存の AKS クラスターのノード プールを更新する別の Resource Manager テンプレートを作成する必要があります。

  1. 例えば aks-agentpools.json などのテンプレートを作成し、次のマニフェスト例を貼り付けます。 必要に応じて値を編集してください。 このテンプレートの例は、次の設定を構成します。

    • 3 つのノードを実行するように、myagentpool という Linux ノード プールを更新します。
    • Kubernetes バージョン 1.15.7 を実行するように、ノード プール内のノードを設定します。
    • Standard_DS2_v2 とノード サイズを定義します。
    {
        "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "clusterName": {
                "type": "string",
                "metadata": {
                    "description": "The name of your existing AKS cluster."
                }
            },
            "location": {
                "type": "string",
                "metadata": {
                    "description": "The location of your existing AKS cluster."
                }
            },
            "agentPoolName": {
                "type": "string",
                "defaultValue": "myagentpool",
                "metadata": {
                    "description": "The name of the agent pool to create or update."
                }
            },
            "vnetSubnetId": {
                "type": "string",
                "defaultValue": "",
                "metadata": {
                    "description": "The Vnet subnet resource ID for your existing AKS cluster."
                }
            }
        },
        "variables": {
            "apiVersion": {
                "aks": "2020-01-01"
            },
            "agentPoolProfiles": {
                "maxPods": 30,
                "osDiskSizeGB": 0,
                "agentCount": 3,
                "agentVmSize": "Standard_DS2_v2",
                "osType": "Linux",
                "vnetSubnetId": "[parameters('vnetSubnetId')]"
            }
        },
        "resources": [
            {
                "apiVersion": "2020-01-01",
                "type": "Microsoft.ContainerService/managedClusters/agentPools",
                "name": "[concat(parameters('clusterName'),'/', parameters('agentPoolName'))]",
                "location": "[parameters('location')]",
                "properties": {
                    "maxPods": "[variables('agentPoolProfiles').maxPods]",
                    "osDiskSizeGB": "[variables('agentPoolProfiles').osDiskSizeGB]",
                    "count": "[variables('agentPoolProfiles').agentCount]",
                    "vmSize": "[variables('agentPoolProfiles').agentVmSize]",
                    "osType": "[variables('agentPoolProfiles').osType]",
                    "type": "VirtualMachineScaleSets",
                    "vnetSubnetID": "[variables('agentPoolProfiles').vnetSubnetId]",
                    "orchestratorVersion": "1.15.7"
                }
            }
        ]
    }
    
  2. az deployment group create コマンドを使用してテンプレートをデプロイします。

    az deployment group create \
        --resource-group myResourceGroup \
        --template-file aks-agentpools.json
    

    ヒント

    次の例に示すように、テンプレートに tag プロパティを追加することで、ノード プールにタグを追加できます:

    ...
    "resources": [
    {
      ...
      "properties": {
        ...
        "tags": {
          "name1": "val1"
        },
        ...
      }
    }
    ...
    

    Resource Manager テンプレートで定義するノード プール設定および操作に応じて、AKS クラスターの更新には数分かかる場合があります。

次のステップ