次の方法で共有


クイック スタート: Bicep を使用して Azure Nexus Kubernetes クラスターをデプロイする

  • Bicep を使用して Azure Nexus Kubernetes クラスターをデプロイします。

Bicep は、宣言型の構文を使用して Azure リソースをデプロイするドメイン固有言語 (DSL) です。 簡潔な構文、信頼性の高いタイプ セーフ、およびコードの再利用のサポートが提供されます。 Bicep により、Azure のコード ソリューションとしてのインフラストラクチャに最適な作成エクスペリエンスが実現します。

[前提条件]

Azure アカウントをお持ちでない場合は、開始する前に無料アカウントを作成してください。

  • Azure Cloud Shell で Bash 環境を使用します。 詳細については、「Azure Cloud Shell の概要」を参照してください。

  • CLI 参照コマンドをローカルで実行する場合は、Azure CLI を インストール します。 Windows または macOS で実行している場合は、Docker コンテナーで Azure CLI を実行することを検討してください。 詳細については、「Docker コンテナーで Azure CLI を実行する方法」を参照してください。

    • ローカル インストールを使用する場合は、az login コマンドを使用して Azure CLI にサインインします。 認証プロセスを完了するには、ターミナルに表示される手順に従います。 その他のサインイン オプションについては、「 Azure CLI を使用した Azure への認証」を参照してください。

    • メッセージが表示されたら、最初に使用するときに Azure CLI 拡張機能をインストールします。 拡張機能の詳細については、「Azure CLI で拡張機能を使用および管理する」を参照してください。

    • az version を実行し、インストールされているバージョンおよび依存ライブラリを検索します。 最新バージョンにアップグレードするには、az upgrade を実行します。

  • 必要な Azure CLI 拡張機能の最新バージョンをインストールします。

  • この記事では、Azure CLI のバージョン 2.61.0 以降が必要です。 Azure Cloud Shell を使用している場合は、最新バージョンが既にインストールされています。

  • 複数の Azure サブスクリプションをお持ちの場合は、az account コマンドを使用して、リソースを課金する適切なサブスクリプション ID を選択してください。

  • サポートされている VM SKU のリストについては、参照セクションの VM SKU の表を参照してください。

  • サポートされている Kubernetes バージョンの一覧については、サポートされている Kubernetes バージョンに関するページを参照してください。

  • az group create コマンドを使用してリソース グループを作成します。 Azure リソース グループは、Azure リソースが展開され管理される論理グループです。 リソース グループを作成する際は、場所の指定を求めるプロンプトが表示されます。 この場所は、リソース グループのメタデータが格納される場所です。また、リソースの作成時に別のリージョンを指定しない場合は、Azure でリソースが実行される場所でもあります。 次の例では、 myResourceGroup という名前のリソース グループを eastus の場所に作成します。

    az group create --name myResourceGroup --___location eastus
    

    リソース グループが正常に作成された場合の出力の例は、次のようになります。

    {
      "id": "/subscriptions/<guid>/resourceGroups/myResourceGroup",
      "___location": "eastus",
      "managedBy": null,
      "name": "myResourceGroup",
      "properties": {
        "provisioningState": "Succeeded"
      },
      "tags": null
    }
    
  • Bicep ファイルまたは ARM テンプレートをデプロイするには、デプロイ対象のリソースに対する書き込みアクセス権が必要であり、さらに、Microsoft.Resources/deployments リソース タイプでのすべての操作に対するアクセス権が必要です。 たとえば、クラスターをデプロイするには、Microsoft.NetworkCloud/kubernetesclusters/write および Microsoft.Resources/deployments/* アクセス許可が必要です。 ロールとアクセス許可の一覧については、Azure の組み込みロールに関するページを参照してください。

  • Azure Operator Nexus クラスターの custom ___location リソース ID が必要です。

  • 特定のワークロード要件に従ってさまざまなネットワークを作成する必要があり、ワークロードに適切な IP アドレスを使用できるようにすることが重要です。 円滑な実装を行うには、関連するサポート チームに問い合わせて支援を求めることをお勧めします。

  • このクイックスタートは、Kubernetes の基本的な概念を理解していることを前提としています。 詳細については、「Azure Kubernetes Services (AKS) における Kubernetes の中心概念」を参照してください。

Bicep ファイルを確認する

Kubernetes テンプレートをデプロイする前に、その構造を理解するためにコンテンツを確認しましょう。

// Azure parameters

@description('The name of Nexus Kubernetes cluster')
param kubernetesClusterName string

@description('The Azure region where the cluster is to be deployed')
param ___location string = resourceGroup().___location

@description('The custom ___location of the Nexus instance')
param extendedLocation string

@description('The metadata tags to be associated with the cluster resource')
param tags object = {}

@description('The username for the administrative account on the cluster')
param adminUsername string = 'azureuser'

@description('The object IDs of Azure Active Directory (AAD) groups that will have administrative access to the cluster')
param adminGroupObjectIds array = []

// Networking Parameters

@description('The Azure Resource Manager (ARM) id of the network to be used as the Container Networking Interface (CNI) network')
param cniNetworkId string

@description('The ARM id of the network to be used for cloud services network')
param cloudServicesNetworkId string

@description('The CIDR blocks used for Nexus Kubernetes PODs in the cluster')
param podCidrs array = ['10.244.0.0/16']

@description('The CIDR blocks used for k8s service in the cluster')
param serviceCidrs array = ['10.96.0.0/16']

@description('The IP address of the DNS service in the cluster')
param dnsServiceIp string = '10.96.0.10'

@description('The Layer 2 networks associated with the initial agent pool')
param agentPoolL2Networks array = []
// {
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN'
// }

@description('The Layer 3 networks associated with the initial agent pool')
param agentPoolL3Networks array = []
// {
//   ipamEnabled: 'True/False'
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN|IPVLAN'
// }

@description('The trunked networks associated with the initial agent pool')
param agentPoolTrunkedNetworks array = []
// {
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN'
// }

@description('The Layer 2 networks associated with the cluster')
param l2Networks array = []
// {
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN'
// }

@description('The Layer 3 networks associated with the cluster')
param l3Networks array = []
// {
//   ipamEnabled: 'True/False'
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN|IPVLAN'
// }

@description('The trunked networks associated with the cluster')
param trunkedNetworks array = []
// {
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN'
// }

@description('The LoadBalancer IP address pools associated with the cluster')
param ipAddressPools array = []
// {
//   addresses: [
//     'string'
//   ]
//   autoAssign: 'True/False'
//   name: 'string'
//   onlyUseHostIps: 'True/False'
// }

// Cluster Configuration Parameters

@description('The version of Kubernetes to be used in the Nexus Kubernetes cluster')
param kubernetesVersion string = 'v1.27.1'

@description('The number of control plane nodes to be deployed in the cluster')
param controlPlaneCount int = 1

@description('The zones/racks used for placement of the control plane nodes')
param controlPlaneZones array = []
// "string" Example: ["1", "2", "3"]

@description('The zones/racks used for placement of the agent pool nodes')
param agentPoolZones array = []
// "string" Example: ["1", "2", "3"]

@description('The size of the control plane nodes')
param controlPlaneVmSkuName string = 'NC_G6_28_v1'

@description('The number of worker nodes to be deployed in the initial agent pool')
param systemPoolNodeCount int = 1

@description('The size of the worker nodes')
param workerVmSkuName string = 'NC_P10_56_v1'

@description('The configurations for the initial agent pool')
param initialPoolAgentOptions object = {}
// {
//   "hugepagesCount": integer,
//   "hugepagesSize": "2M/1G"
// }

@description('The cluster wide SSH public key that will be associated with the given user for secure remote login')
param sshPublicKeys array = []
// {
//   keyData: "ssh-rsa AAAAA...."
// },
// {
//   keyData: "ssh-rsa AAAAA...."
// }

@description('The control plane SSH public key that will be associated with the given user for secure remote login')
param controlPlaneSshKeys array = []
// {
//   keyData: "ssh-rsa AAAAA...."
// },
// {
//   keyData: "ssh-rsa AAAAA...."
// }

@description('The agent pool SSH public key that will be associated with the given user for secure remote login')
param agentPoolSshKeys array = []
// {
//   keyData: "ssh-rsa AAAAA...."
// },
// {
//   keyData: "ssh-rsa AAAAA...."
// }

@description('The labels to assign to the nodes in the cluster for identification and organization')
param labels array = []
// {
//   key: 'string'
//   value: 'string'
// }
@description('The taints to apply to the nodes in the cluster to restrict which pods can be scheduled on them')
param taints array = []
// {
//   key: 'string'
//   value: 'string:NoSchedule|PreferNoSchedule|NoExecute'
// }
@description('The association of IP address pools to the communities and peers, allowing for announcement of IPs.')
param bgpAdvertisements array = []

@description('"The list of additional BgpPeer entities that the Kubernetes cluster will peer with. All peering must be explicitly defined.')
param bgpPeers array = []

@description('The indicator to specify if the load balancer peers with the network fabric.')
param fabricPeeringEnabled string = 'False'


resource kubernetescluster 'Microsoft.NetworkCloud/kubernetesClusters@2025-02-01' = {
  name: kubernetesClusterName
  ___location: ___location
  tags: tags
  extendedLocation: {
    name: extendedLocation
    type: 'CustomLocation'
  }
  properties: {
    kubernetesVersion: kubernetesVersion
    managedResourceGroupConfiguration: {
      name: '${uniqueString(resourceGroup().name)}-${kubernetesClusterName}'
      ___location: ___location
    }
    aadConfiguration: {
      adminGroupObjectIds: adminGroupObjectIds
    }
    administratorConfiguration: {
      adminUsername: adminUsername
      sshPublicKeys: empty(sshPublicKeys) ? [] : sshPublicKeys
    }
    initialAgentPoolConfigurations: [
      {
        name: '${kubernetesClusterName}-nodepool-1'
        administratorConfiguration: {
          adminUsername: adminUsername
          sshPublicKeys: empty(agentPoolSshKeys) ? [] : agentPoolSshKeys
        }
        count: systemPoolNodeCount
        vmSkuName: workerVmSkuName
        mode: 'System'
        labels: empty(labels) ? null : labels
        taints: empty(taints) ? null : taints
        agentOptions: empty(initialPoolAgentOptions) ? null : initialPoolAgentOptions
        attachedNetworkConfiguration: {
          l2Networks: empty(agentPoolL2Networks) ? null : agentPoolL2Networks
          l3Networks: empty(agentPoolL3Networks) ? null : agentPoolL3Networks
          trunkedNetworks: empty(agentPoolTrunkedNetworks) ? null : agentPoolTrunkedNetworks
        }
        availabilityZones: empty(agentPoolZones) ? null : agentPoolZones
        upgradeSettings: {
          maxSurge: '1'
        }
      }
    ]
    controlPlaneNodeConfiguration: {
      administratorConfiguration: {
        adminUsername: adminUsername
        sshPublicKeys: empty(controlPlaneSshKeys) ? [] : controlPlaneSshKeys
      }
      count: controlPlaneCount
      vmSkuName: controlPlaneVmSkuName
      availabilityZones: empty(controlPlaneZones) ? null : controlPlaneZones
    }
    networkConfiguration: {
      cniNetworkId: cniNetworkId
      cloudServicesNetworkId: cloudServicesNetworkId
      dnsServiceIp: dnsServiceIp
      podCidrs: podCidrs
      serviceCidrs: serviceCidrs
      attachedNetworkConfiguration: {
        l2Networks: empty(l2Networks) ? null : l2Networks
        l3Networks: empty(l3Networks) ? null : l3Networks
        trunkedNetworks: empty(trunkedNetworks) ? null : trunkedNetworks
      }
      bgpServiceLoadBalancerConfiguration: {
        bgpAdvertisements: empty(bgpAdvertisements) ? null : bgpAdvertisements
        bgpPeers: empty(bgpPeers) ? null : bgpPeers
        fabricPeeringEnabled: fabricPeeringEnabled
        ipAddressPools: empty(ipAddressPools) ? null : ipAddressPools
      }
    }
  }
}

kubernetes-deploy.bicep という名前のテンプレート ファイルを確認して保存したら、次のセクションに進んでテンプレートをデプロイします。

Bicep ファイルをデプロイする

  1. kubernetes-deploy-parameters.json という名前のファイルを作成し、必要なパラメーターを JSON 形式で追加します。 開始点として、次の例を使用できます。 値は実際の値に置き換えてください。
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "kubernetesClusterName":{
      "value": "myNexusK8sCluster"
    },
    "adminGroupObjectIds": {
      "value": [
        "00000000-0000-0000-0000-000000000000"
      ]
    },
    "cniNetworkId": {
      "value": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.NetworkCloud/l3Networks/<l3Network-name>"
    },
    "cloudServicesNetworkId": {
      "value": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.NetworkCloud/cloudServicesNetworks/<csn-name>"
    },
    "extendedLocation": {
      "value": "/subscriptions/<subscription_id>/resourceGroups/<managed_resource_group>/providers/microsoft.extendedlocation/customlocations/<custom-___location-name>"
    },
    "___location": {
      "value": "eastus"
    },
    "sshPublicKeys": {
      "value": [
        {
          "keyData": "ssh-rsa AAAAA...."
        },
        {
          "keyData": "ssh-rsa BBBBB...."
        }
      ]
    }
  }
}
  1. テンプレートをデプロイします。
    az deployment group create \
      --resource-group myResourceGroup \
      --template-file kubernetes-deploy.bicep \
      --parameters @kubernetes-deploy-parameters.json

要求されたクラスター ノードをデプロイするのに十分な容量がない場合は、エラー メッセージが表示されます。 ただし、このメッセージでは、使用可能な容量に関する詳細は提供されません。 容量が不足しているため、クラスターの作成を続行できないことが示されています。

容量の計算では、個々のラックに限定されるのではなく、プラットフォーム クラスター全体が考慮されます。 そのため、容量が不十分なゾーン (ラックがゾーンと等しい) にエージェント プールが作成されていても、別のゾーンに十分な容量がある場合、クラスターの作成は続行されますが、最終的にはタイムアウトになります。容量をチェックするこの方法は、クラスターまたはエージェント プールの作成時に特定のゾーンが指定されていない場合にのみ有効です。

デプロイされているリソースを確認する

デプロイが完了したら、CLI または Azure portal を使用してリソースを表示できます。

myNexusK8sCluster リソース グループ内の myResourceGroup クラスターの詳細を表示するには、次の Azure CLI コマンドを実行します。

az networkcloud kubernetescluster show \
  --name myNexusK8sCluster \
  --resource-group myResourceGroup

さらに、myNexusK8sCluster リソース グループ内の myResourceGroup クラスターに関連付けられているエージェント プール名の一覧を取得するには、次の Azure CLI コマンドを使用できます。

az networkcloud kubernetescluster agentpool list \
  --kubernetes-cluster-name myNexusK8sCluster \
  --resource-group myResourceGroup \
  --output table

クラスターに接続する

Nexus Kubernetes クラスターが正常に作成され、Azure Arc に接続されたので、クラスター接続機能を使用して簡単に接続できます。 クラスター接続を使用すると、どこからでもクラスターに安全にアクセスして管理できるため、対話型の開発、デバッグ、クラスター管理タスクに便利です。

使用可能なオプションの詳細については、「Azure Operator Nexus Kubernetes クラスターに接続する」を参照してください。

Nexus Kubernetes クラスターを作成すると、Nexus によってクラスター リソースの格納専用の管理対象リソース グループが自動的に作成され、このグループ内に Arc 接続クラスター リソースが確立されます。

クラスターにアクセスするには、クラスター接続 kubeconfig を設定する必要があります。 関連する Microsoft Entra エンティティを使用して Azure CLI にログインした後、それを囲むファイアウォールの外側であっても、どこからでもクラスターと通信するために必要な kubeconfig を取得できます。

  1. CLUSTER_NAME 変数、RESOURCE_GROUP 変数、および SUBSCRIPTION_ID 変数を設定します。

    CLUSTER_NAME="myNexusK8sCluster"
    RESOURCE_GROUP="myResourceGroup"
    SUBSCRIPTION_ID=<set the correct subscription_id>
    
  2. az を使用して管理対象リソース グループにクエリを実行し、MANAGED_RESOURCE_GROUP に格納します

     az account set -s $SUBSCRIPTION_ID
     MANAGED_RESOURCE_GROUP=$(az networkcloud kubernetescluster show -n $CLUSTER_NAME -g $RESOURCE_GROUP --output tsv --query managedResourceGroupConfiguration.name)
    
  3. 次のコマンドは、指定された Nexus Kubernetes クラスターの Kubernetes API サーバーに接続できる connectedk8s プロキシを起動します。

    az connectedk8s proxy -n $CLUSTER_NAME  -g $MANAGED_RESOURCE_GROUP &
    
  4. kubectl を使用して、クラスターに要求を送信します。

    kubectl get pods -A
    

    これで、すべてのノードの一覧が含まれているクラスターからの応答が表示されます。

"アクセス トークンをクライアント プロキシに投稿できませんでした。MSI に接続できませんでした" というエラー メッセージが表示された場合は、az login を実行して Azure で再認証する必要がある場合があります。

エージェント プールを追加する

前の手順で作成したクラスターには、ノード プールが 1 つあります。 Bicep ファイルを使用して 2 つ目のエージェント プールを追加しましょう。 次の例では、myNexusK8sCluster-nodepool-2 という名前のエージェント プールを作成します。

  1. テンプレートを確認します。

エージェント プール テンプレートを追加する前に、その構造を理解するためにコンテンツを確認しましょう。

// Azure Parameters
@description('The name of Nexus Kubernetes cluster')
param kubernetesClusterName string

@description('The Azure region where the cluster is to be deployed')
param ___location string = resourceGroup().___location

@description('The custom ___location of the Nexus instance')
param extendedLocation string

@description('Tags to be associated with the resource')
param tags object = {}

@description('The username for the administrative account on the cluster')
param adminUsername string = 'azureuser'

@description('The agent pool SSH public key that will be associated with the given user for secure remote login')
param agentPoolSshKeys array = []
// {
//   keyData: "ssh-rsa AAAAA...."
// },
// {
//   keyData: "ssh-rsa AAAAA...."
// }

// Cluster Configuration Parameters
@description('Number of nodes in the agent pool')
param agentPoolNodeCount int = 1

@description('Agent pool name')
param agentPoolName string = 'nodepool-2'

@description('VM size of the agent nodes')
param agentVmSku string = 'NC_P10_56_v1'

@description('The zones/racks used for placement of the agent pool nodes')
param agentPoolZones array = []
// "string" Example: ["1", "2", "3"]

@description('Agent pool mode')
param agentPoolMode string = 'User'

@description('The configurations for the initial agent pool')
param agentOptions object = {}
// {
//   "hugepagesCount": integer,
//   "hugepagesSize": "2M/1G"
// }

@description('The labels to assign to the nodes in the cluster for identification and organization')
param labels array = []
// {
//   key: 'string'
//   value: 'string'
// }
@description('The taints to apply to the nodes in the cluster to restrict which pods can be scheduled on them')
param taints array = []
// {
//   key: 'string'
//   value: 'string:NoSchedule|PreferNoSchedule|NoExecute'
// }

// Networking Parameters
@description('The Layer 2 networks to connect to the agent pool')
param l2Networks array = []
// {
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN|IPVLAN'
// }

@description('The Layer 3 networks to connect to the agent pool')
param l3Networks array = []
// {
//   ipamEnabled: 'True/False'
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN|IPVLAN'
// }

@description('The trunked networks to connect to the agent pool')
param trunkedNetworks array = []
// {
//   networkId: 'string'
//   pluginType: 'SRIOV|DPDK|OSDevice|MACVLAN|IPVLAN'
// }

resource agentPools 'Microsoft.NetworkCloud/kubernetesClusters/agentPools@2025-02-01' = {
  name: '${kubernetesClusterName}/${kubernetesClusterName}-${agentPoolName}'
  ___location: ___location
  tags: tags
  extendedLocation: {
    name: extendedLocation
    type: 'CustomLocation'
  }
  properties: {
    administratorConfiguration: {
      adminUsername: adminUsername
      sshPublicKeys: empty(agentPoolSshKeys) ? null : agentPoolSshKeys
    }
    attachedNetworkConfiguration: {
      l2Networks: empty(l2Networks) ? null : l2Networks
      l3Networks: empty(l3Networks) ? null : l3Networks
      trunkedNetworks: empty(trunkedNetworks) ? null : trunkedNetworks
    }
    count: agentPoolNodeCount
    mode: agentPoolMode
    vmSkuName: agentVmSku
    labels: empty(labels) ? null : labels
    taints: empty(taints) ? null : taints
    agentOptions: empty(agentOptions) ? null : agentOptions
    availabilityZones: empty(agentPoolZones) ? null : agentPoolZones
    upgradeSettings: {
      maxSurge: '1'
    }
  }
}

kubernetes-add-agentpool.bicep という名前のテンプレート ファイルを確認して保存したら、次のセクションに進んでテンプレートをデプロイします。

  1. kubernetes-nodepool-parameters.json という名前のファイルを作成し、必要なパラメーターを JSON 形式で追加します。 開始点として、次の例を使用できます。 値は実際の値に置き換えてください。
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "kubernetesClusterName":{
        "value": "myNexusK8sCluster"
      },
      "extendedLocation": {
        "value": "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/microsoft.extendedlocation/customlocations/<custom-___location-name>"
      }
    }
  }
  1. テンプレートをデプロイします。
    az deployment group create \
      --resource-group myResourceGroup \
      --template-file kubernetes-add-agentpool.bicep \
      --parameters @kubernetes-nodepool-parameters.json

初期エージェント プール構成を使用して、クラスター自体の初期作成時に複数のエージェント プールを追加できます。 ただし、初期作成後にエージェント プールを追加する場合は、上記のコマンドを使用して、Nexus Kubernetes クラスター用の追加のエージェント プールを作成できます。

エージェント プールが正常に作成された場合の出力の例は、次のようになります。

$ az networkcloud kubernetescluster agentpool list --kubernetes-cluster-name myNexusK8sCluster --resource-group myResourceGroup --output table
This command is experimental and under development. Reference and support levels: https://aka.ms/CLI_refstatus
Count    Location    Mode    Name                          ProvisioningState    ResourceGroup    VmSkuName
-------  ----------  ------  ----------------------------  -------------------  ---------------  -----------
1        eastus      System  myNexusK8sCluster-nodepool-1  Succeeded            myResourceGroup  NC_P10_56_v1
1        eastus      User    myNexusK8sCluster-nodepool-2  Succeeded            myResourceGroup  NC_P10_56_v1

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

不要になったら、リソース グループを削除します。 リソース グループとリソース グループ内のすべてのリソースが削除されます。

az group delete コマンドを使用すると、リソース グループおよび Kubernetes クラスターと、関連するすべてのリソース (Operator Nexus ネットワーク リソース以外) が削除されます。

az group delete --name myResourceGroup --yes --no-wait

次のステップ

直接、またはクラスター接続Azure Operator Service Manager を介して、CNF をデプロイできるようになりました。