Partilhar via


Guia de início rápido: implantar um cluster do Kubernetes do Azure Nexus usando o Bicep

  • Implante um cluster Kubernetes do Azure Nexus usando o Bicep.

Bicep é uma linguagem específica de domínio (DSL) que usa sintaxe declarativa para implantar recursos do Azure. Fornece sintaxe concisa, segurança de tipos fiável e suporte para reutilização de código. O Bicep oferece a melhor experiência de criação para suas soluções de infraestrutura como código no Azure.

Pré-requisitos

Se não tiver uma conta do Azure, crie uma conta gratuita antes de começar.

  • Instale a versão mais recente das extensões necessárias da CLI do Azure.

  • Este artigo requer a versão 2.61.0 ou posterior da CLI do Azure. Se estiver usando o Azure Cloud Shell, a versão mais recente já está instalada.

  • Se você tiver várias assinaturas do Azure, selecione a ID de assinatura apropriada na qual os recursos devem ser cobrados usando o az account comando.

  • Consulte a tabela VM SKU na seção de referência para obter a lista de SKUs de VM suportadas.

  • Consulte as versões suportadas do Kubernetes para obter a lista de versões suportadas do Kubernetes.

  • Crie um grupo de recursos usando o comando az group create. Um grupo de recursos do Azure é um grupo lógico no qual os recursos do Azure são implantados e gerenciados. Ao criar um grupo de recursos, você será solicitado a especificar um local. Esse local é o local de armazenamento dos metadados do grupo de recursos e onde os recursos são executados no Azure se você não especificar outra região durante a criação do recurso. O exemplo seguinte cria um grupo de recursos com o nome myResourceGroup na localização eastus.

    az group create --name myResourceGroup --___location eastus
    

    O exemplo de saída a seguir é semelhante à criação bem-sucedida do grupo de recursos:

    {
      "id": "/subscriptions/<guid>/resourceGroups/myResourceGroup",
      "___location": "eastus",
      "managedBy": null,
      "name": "myResourceGroup",
      "properties": {
        "provisioningState": "Succeeded"
      },
      "tags": null
    }
    
  • Para implementar um ficheiro Bicep ou modelo ARM, precisa de permissão de escrita nos recursos que está a implementar e permissão para todas as operações no tipo de recurso Microsoft.Resources/deployments. Por exemplo, para implantar um cluster, você precisa das permissões Microsoft.NetworkCloud/kubernetesclusters/write e Microsoft.Resources/deployments/*. Para obter uma lista de funções e permissões, veja Funções incorporadas do Azure.

  • Você precisa da custom ___location ID do recurso do cluster do Azure Operator Nexus.

  • Você precisa criar várias redes de acordo com seus requisitos específicos de carga de trabalho, e é essencial ter os endereços IP apropriados disponíveis para suas cargas de trabalho. Para garantir uma implementação sem problemas, é aconselhável consultar as equipas de apoio relevantes para obter assistência.

  • Este início rápido assume que possui um entendimento básico dos conceitos do Kubernetes. Para obter mais informações, consulte Conceitos principais do Kubernetes para o Serviço Kubernetes do Azure (AKS).

Revise o arquivo Bicep

Antes de implantar o modelo do Kubernetes, vamos revisar o conteúdo para entender sua estrutura.

// 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
      }
    }
  }
}

Depois de revisar e salvar o arquivo de modelo chamado kubernetes-deploy.bicep, vá para a próxima seção para implantar o modelo.

Desdobrar o arquivo Bicep

  1. Crie um arquivo chamado kubernetes-deploy-parameters.json e adicione os parâmetros necessários no formato JSON. Você pode usar o exemplo a seguir como ponto de partida. Substitua os valores pelos seus.
{
  "$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. Implemente o modelo.
    az deployment group create \
      --resource-group myResourceGroup \
      --template-file kubernetes-deploy.bicep \
      --parameters @kubernetes-deploy-parameters.json

Se não houver capacidade suficiente para implantar os nós de cluster solicitados, uma mensagem de erro será exibida. No entanto, esta mensagem não fornece detalhes sobre a capacidade disponível. Ele afirma que a criação do cluster não pode prosseguir devido à capacidade insuficiente.

Observação

O cálculo de capacidade leva em conta todo o cluster de plataforma, em vez de ser limitado a racks individuais. Portanto, se um pool de agentes for criado em uma zona (onde um rack é igual a uma zona) com capacidade insuficiente, mas outra zona tiver capacidade suficiente, a criação do cluster continuará, mas acabará expirando. Essa abordagem para verificação de capacidade só faz sentido se uma zona específica não for especificada durante a criação do cluster ou pool de agentes.

Analisar os recursos implementados

Após a conclusão da implantação, você pode exibir os recursos usando a CLI ou o portal do Azure.

Para exibir os detalhes do myNexusK8sCluster cluster no myResourceGroup grupo de recursos, execute o seguinte comando da CLI do Azure:

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

Além disso, para obter uma lista de nomes de pool de agentes associados ao cluster myNexusK8sCluster no grupo de recursos myResourceGroup, pode usar o seguinte comando da CLI do Azure.

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

Ligar ao cluster

Agora que o cluster Nexus Kubernetes foi criado com êxito e conectado ao Azure Arc, você pode se conectar facilmente a ele usando o recurso de conexão de cluster. A conexão de cluster permite que você acesse e gerencie seu cluster com segurança de qualquer lugar, tornando-o conveniente para tarefas interativas de desenvolvimento, depuração e administração de cluster.

Para obter informações mais detalhadas sobre as opções disponíveis, consulte Ligar-se a um cluster Kubernetes do Azure Operator Nexus.

Observação

Quando você cria um cluster Nexus Kubernetes, o Nexus cria automaticamente um grupo de recursos gerenciado dedicado a armazenar os recursos do cluster, dentro desse grupo, o recurso de cluster conectado ao Arc é estabelecido.

Para aceder ao cluster, necessita configurar a ligação kubeconfig do cluster. Depois de iniciar sessão na CLI do Azure com a entidade Microsoft Entra relevante, pode obter o kubeconfig necessário para comunicar com o cluster a partir de qualquer lugar, mesmo fora da firewall que o rodeia.

  1. Definir CLUSTER_NAME, RESOURCE_GROUP e SUBSCRIPTION_ID variáveis.

    CLUSTER_NAME="myNexusK8sCluster"
    RESOURCE_GROUP="myResourceGroup"
    SUBSCRIPTION_ID=<set the correct subscription_id>
    
  2. Consultar grupo de recursos gerenciados com az e armazenar em 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. O comando a seguir inicia um proxy connectedk8s que permite que você se conecte ao servidor de API do Kubernetes para o cluster Nexus Kubernetes especificado.

    az connectedk8s proxy -n $CLUSTER_NAME  -g $MANAGED_RESOURCE_GROUP &
    
  4. Use kubectl para enviar solicitações para o cluster:

    kubectl get pods -A
    

    Agora você deve ver uma resposta do cluster contendo a lista de todos os nós.

Observação

Se vir a mensagem de erro "Falha ao postar token de acesso ao proxy do cliente Falha ao se conectar ao MSI", talvez seja necessário executar um az login para reautenticar com o Azure.

Adicionar um pool de agentes

O cluster criado na etapa anterior tem um único pool de nós. Vamos adicionar um segundo pool de agentes usando o arquivo Bicep. O exemplo a seguir cria um pool de agentes chamado myNexusK8sCluster-nodepool-2:

  1. Analise o modelo.

Antes de adicionar o modelo de pool de agentes, vamos revisar o conteúdo para entender sua estrutura.

// 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'
    }
  }
}

Depois de revisar e salvar o arquivo de modelo chamado kubernetes-add-agentpool.bicep, vá para a próxima seção para implantar o modelo.

  1. Crie um arquivo chamado kubernetes-nodepool-parameters.json e adicione os parâmetros necessários no formato JSON. Você pode usar o exemplo a seguir como ponto de partida. Substitua os valores pelos seus.
{
    "$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. Implemente o modelo.
    az deployment group create \
      --resource-group myResourceGroup \
      --template-file kubernetes-add-agentpool.bicep \
      --parameters @kubernetes-nodepool-parameters.json

Observação

Você pode adicionar vários pools de agentes durante a criação inicial do próprio cluster usando as configurações iniciais do pool de agentes. No entanto, se você quiser adicionar pools de agentes após a criação inicial, poderá utilizar o comando acima para criar pools de agentes adicionais para seu cluster Nexus Kubernetes.

O exemplo de saída a seguir se assemelha à criação bem-sucedida do pool de agentes.

$ 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

Limpeza de recursos

Quando não for mais necessário, exclua o grupo de recursos. O grupo de recursos e todos os recursos no grupo de recursos são excluídos.

Use o comando az group delete para remover o grupo de recursos, o cluster Kubernetes e todos os recursos relacionados, exceto os recursos de rede do Operator Nexus.

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

Próximos passos

Agora você pode implantar os CNFs diretamente por meio da conexão de cluster ou por meio do Azure Operator Service Manager.