- 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 ファイルをデプロイする
-
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...."
}
]
}
}
}
- テンプレートをデプロイします。
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
を取得できます。
CLUSTER_NAME
変数、RESOURCE_GROUP
変数、およびSUBSCRIPTION_ID
変数を設定します。CLUSTER_NAME="myNexusK8sCluster" RESOURCE_GROUP="myResourceGroup" SUBSCRIPTION_ID=<set the correct subscription_id>
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)
次のコマンドは、指定された Nexus Kubernetes クラスターの Kubernetes API サーバーに接続できる connectedk8s プロキシを起動します。
az connectedk8s proxy -n $CLUSTER_NAME -g $MANAGED_RESOURCE_GROUP &
kubectl
を使用して、クラスターに要求を送信します。kubectl get pods -A
これで、すべてのノードの一覧が含まれているクラスターからの応答が表示されます。
注
"アクセス トークンをクライアント プロキシに投稿できませんでした。MSI に接続できませんでした" というエラー メッセージが表示された場合は、az login
を実行して Azure で再認証する必要がある場合があります。
エージェント プールを追加する
前の手順で作成したクラスターには、ノード プールが 1 つあります。 Bicep ファイルを使用して 2 つ目のエージェント プールを追加しましょう。 次の例では、myNexusK8sCluster-nodepool-2
という名前のエージェント プールを作成します。
- テンプレートを確認します。
エージェント プール テンプレートを追加する前に、その構造を理解するためにコンテンツを確認しましょう。
// 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
という名前のテンプレート ファイルを確認して保存したら、次のセクションに進んでテンプレートをデプロイします。
-
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>"
}
}
}
- テンプレートをデプロイします。
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 をデプロイできるようになりました。