Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se describe cómo crear un Red Hat OpenShift en Azure con un clúster de planos de control hospedados (HCP) mediante el CLI de Azure o un archivo Bicep.
El archivo Bicep define todos los recursos Azure necesarios para el clúster, incluida la infraestructura de red, las identidades administradas, las asignaciones de roles, la configuración del clúster y el grupo de nodos.
Los comandos de la CLI crean todos los recursos de Azure necesarios para el clúster, incluida la infraestructura de red, las identidades administradas, las asignaciones de roles, la configuración del clúster y el grupo de nodos.
Prerequisites
Preparación del entorno
Antes de crear el clúster, compruebe que el entorno de Azure cumple los siguientes requisitos.
CLI de Azure
Asegúrese de usar la CLI de Azure, versión 2.67.0 o posterior.
Use az --version para comprobar la versión instalada.
Para la instalación o la actualización, consulte Instalación de la CLI de Azure.
Extensión de la CLI de ARO HCP
Instale la extensión.
az extension add --name aroComprueba que la extensión está instalada:
az aro hcp -h
Cuota de recursos
Red Hat OpenShift en Azure con planos de control hospedados requiere al menos 20 núcleos para crear y ejecutar un clúster. La cuota de recursos de Azure predeterminada para una nueva suscripción de Azure no cumple este requisito. Para solicitar un aumento en el límite de recursos, consulte Cuota estándar: Aumento de los límites por serie de máquinas virtuales. Compruebe que tiene suficiente cuota para la familia de máquinas virtuales que elija entre los tamaños de máquina virtual de nodo de trabajo admitidos.
Para comprobar la cuota actual de la familia de máquinas virtuales predeterminadas:
LOCATION=eastus
az vm list-usage -l $LOCATION \
--query "[?contains(name.value, 'standardDSv5Family')]" -o table
Permissions
Necesitas permisos de Colaborador y Administrador de acceso de usuarios, o permisos de Propietario, en el grupo de recursos o la suscripción donde creas el clúster. Estos permisos son necesarios para crear el grupo de recursos, la red virtual, las identidades administradas y las asignaciones de roles.
Para obtener más información, consulte Comprobación de los permisos.
Registro de proveedores de recursos
Registre los siguientes proveedores de recursos en la suscripción de Azure:
Microsoft.RedHatOpenShiftMicrosoft.ComputeMicrosoft.StorageMicrosoft.Authorization
Para comprobar si un proveedor de recursos está registrado:
az provider list --query "[?namespace=='Microsoft.RedHatOpenShift'].registrationState" \
--output table
Si encuentra algún proveedor de recursos que no esté registrado, regístrelos.
az provider register --namespace Microsoft.RedHatOpenShift --wait
az provider register --namespace Microsoft.Compute --wait
az provider register --namespace Microsoft.Storage --wait
az provider register --namespace Microsoft.Authorization --wait
Para obtener más información sobre cómo registrar proveedores de recursos, consulte Registro de los proveedores de recursos.
Establecimiento de variables de entorno
Establezca las siguientes variables de entorno para definir los nombres de los recursos que cree. Reemplace los valores de los marcadores de posición por los suyos propios.
# Azure resource location and subscription
LOCATION="<region>"
SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
CUSTOMER_RG_NAME="<resource-group-name>"
# Network resources
CUSTOMER_NSG="<nsg-name>"
CUSTOMER_VNET_NAME="<vnet-name>"
CUSTOMER_VNET_SUBNET1="<worker-subnet-name>"
CUSTOMER_VNET_INTEGRATION_SUBNET_NAME="<vnet-integration-subnet-name>"
# Cluster and node pool
CLUSTER_NAME="<cluster-name>"
MANAGED_RESOURCE_GROUP="${CLUSTER_NAME}-managed-rg"
NP_NAME="<node-pool-name>"
CLUSTER_VERSION="<major.minor>" # Example: 4.22
NP_VERSION="<major.minor.patch>" # Example: 4.22.1
Note
Para obtener más información sobre los requisitos de versión del clúster y del grupo de nodos, revise las combinaciones de versiones admitidas.
Note
Para obtener una lista de las regiones admitidas, consulte Elegir la región del clúster.
Creación de un grupo de recursos
Cree un grupo de recursos para contener el recurso de clúster, la red virtual y las identidades administradas.
az group create \
--name "${CUSTOMER_RG_NAME}" \
--subscription "${SUBSCRIPTION_ID}" \
--location "${LOCATION}"
Crear el archivo de Bicep
Cree un archivo denominado azuredeploy.bicep con el siguiente contenido.
Esta plantilla de Bicep define todos los recursos necesarios para implementar un Red Hat OpenShift en Azure con un clúster de planos de control hospedados, incluido el grupo de seguridad de red, la red virtual, las identidades administradas, las asignaciones de roles, Key Vault, la clave de cifrado de KMS, el clúster y el grupo de nodos.
La plantilla implementa un clúster con redes OVN-Kubernetes con rangos CIDR predeterminados, cifrado de etcd administrado por el cliente, conectividad saliente del Load Balancer y un único grupo de nodos con dos Standard_D8s_v6 nodos de trabajo.
Para personalizar la configuración del clúster o del grupo de nodos, consulte Bicep referencia de archivos.
Note
Si agrega reglas personalizadas al grupo de seguridad de red (NSG), asegúrese de que el grupo de seguridad de red permite el tráfico descrito en Tráfico de grupo de seguridad de red requerido.
@description('Network Security Group Name')
param customerNsgName string
@description('Virtual Network Name')
param customerVnetName string
@description('Subnet Name')
param customerVnetSubnetName string
@description('Virtual Network Integration Subnet Name')
param customerVirtualNetworkIntegrationSubnetName string
@description('Name of the cluster')
param clusterName string
@description('The cluster managed resource group name')
param managedResourceGroupName string
@description('The name of the node pool')
param nodePoolName string
@description('The OpenShift version for the cluster (X.Y format, e.g. 4.20)')
param clusterVersion string
@description('The OpenShift version for the node pool (X.Y.Z format, e.g. 4.20.8)')
param nodePoolVersion string
@description('Deploy ARO HCP with a private key vault')
param privateKeyVault bool
@description('API server visibility')
@allowed([
'Public'
'Private'
])
param apiVisibility string = 'Public'
@description('Default ingress type')
@allowed([
'Public'
'Private'
])
param ingressType string = 'Public'
@description('Cryptographic restrictions for kernel and userspace libraries (immutable after creation)')
@allowed(['None', 'FIPS'])
param cryptoRestrictions string = 'None'
var etcdEncryptionKeyName = 'etcd-data-kms-encryption-key'
var randomSuffix = toLower(uniqueString(clusterName))
var randomKeyVaultSuffix = toLower(uniqueString(resourceGroup().id))
var customerKeyVaultName string = 'cust-kv-${randomKeyVaultSuffix}'
var addressPrefix = '10.0.0.0/16'
var subnetPrefix = '10.0.0.0/24'
var virtualNetworkIntegrationSubnetPrefix = '10.0.1.0/24'
// Network Security Group
resource customerNsg 'Microsoft.Network/networkSecurityGroups@2023-05-01' = {
name: customerNsgName
location: resourceGroup().location
}
// Virtual network with worker subnet and VNet integration subnet
resource customerVnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: customerVnetName
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: [
addressPrefix
]
}
subnets: [
{
name: customerVnetSubnetName
properties: {
addressPrefix: subnetPrefix
networkSecurityGroup: {
id: customerNsg.id
}
}
}
{
name: customerVirtualNetworkIntegrationSubnetName
properties: {
addressPrefix: virtualNetworkIntegrationSubnetPrefix
networkSecurityGroup: {
id: customerNsg.id
}
delegations: [
{
name: 'aro-hcp-delegation'
properties: {
serviceName: 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters'
}
}
]
}
}
]
}
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' existing = {
name: customerVnetSubnetName
parent: customerVnet
}
resource vnetIntegrationSubnet 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' existing = {
name: customerVirtualNetworkIntegrationSubnetName
parent: customerVnet
}
resource customerKeyVault 'Microsoft.KeyVault/vaults@2024-12-01-preview' = {
name: customerKeyVaultName
location: resourceGroup().location
properties: {
enableRbacAuthorization: true
tenantId: subscription().tenantId
publicNetworkAccess: privateKeyVault ? 'Disabled' : 'Enabled'
sku: {
family: 'A'
name: 'standard'
}
}
}
resource etcdEncryptionKey 'Microsoft.KeyVault/vaults/keys@2024-12-01-preview' = {
parent: customerKeyVault
name: 'etcd-data-kms-encryption-key'
properties: {
kty: 'RSA'
keySize: 2048
}
}
resource privateEndpointDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = if (privateKeyVault) {
name: 'privatelink.vaultcore.azure.net'
location: 'global'
properties: {}
dependsOn: [
privateEndpoint
]
}
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-09-01' = if (privateKeyVault) {
name: 'kv-private-endpoint'
properties: {
privateLinkServiceConnections: [
{
name: 'kv-private-endpoint'
properties: {
privateLinkServiceId: customerKeyVault.id
groupIds: ['vault']
}
}
]
subnet: {
id: customerVnet.properties.subnets[0].id
}
}
location: resourceGroup().location
}
resource privateEndpointDnsGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2023-09-01' = if (privateKeyVault) {
name: 'kv-private-ep-dns-group'
parent: privateEndpoint
properties: {
privateDnsZoneConfigs: [
{
name: 'config1'
properties: {
privateDnsZoneId: privateEndpointDnsZone.id
}
}
]
}
dependsOn: [
privateDnsZoneVnetLink
]
}
resource privateDnsZoneVnetLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = if (privateKeyVault) {
name: uniqueString('kv-private-dns-zone-link')
parent: privateEndpointDnsZone
location: 'global'
properties: {
registrationEnabled: false
virtualNetwork: {
id: customerVnet.id
}
}
}
//
// Control plane identities
//
// Reader
var readerRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'acdd72a7-3385-48ef-bd42-f606fba81ae7'
)
//
// Cluster API Azure managed identity
//
resource clusterApiAzureMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-cluster-api-azure-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift with hosted control planes Cluster API Provider
var hcpClusterApiProviderRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'88366f10-ed47-4cc0-9fab-c8a06148393e'
)
resource hcpClusterApiProviderRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, clusterApiAzureMi.id, hcpClusterApiProviderRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: clusterApiAzureMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: hcpClusterApiProviderRoleId
}
}
resource serviceManagedIdentityReaderOnClusterApiAzureMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, clusterApiAzureMi.id)
scope: clusterApiAzureMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// KMS managed identity
//
resource kmsMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-kms-${randomSuffix}'
location: resourceGroup().location
}
// Key Vault Crypto User
var keyVaultCryptoUserRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'12338af0-0e69-4776-bea7-57ae8d297424'
)
resource keyVaultCryptoUserToKeyVaultRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, kmsMi.id, keyVaultCryptoUserRoleId, customerKeyVault.id)
scope: customerKeyVault
properties: {
principalId: kmsMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: keyVaultCryptoUserRoleId
}
}
resource serviceManagedIdentityReaderOnKmsMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, kmsMi.id)
scope: kmsMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// Control plane operator managed identity
//
resource controlPlaneMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-control-plane-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift with hosted control planes Control Plane Operator
var hcpControlPlaneOperatorRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'fc0c873f-45e9-4d0d-a7d1-585aab30c6ed'
)
resource hcpControlPlaneOperatorVnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, controlPlaneMi.id, hcpControlPlaneOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: controlPlaneMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: hcpControlPlaneOperatorRoleId
}
}
resource hcpControlPlaneOperatorNsgRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, controlPlaneMi.id, hcpControlPlaneOperatorRoleId, customerNsg.id)
scope: customerNsg
properties: {
principalId: controlPlaneMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: hcpControlPlaneOperatorRoleId
}
}
resource serviceManagedIdentityReaderOnControlPlaneMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, controlPlaneMi.id)
scope: controlPlaneMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// Cloud controller manager managed identity
//
resource cloudControllerManagerMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-cloud-controller-manager-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift Cloud Controller Manager
var cloudControllerManagerRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'a1f96423-95ce-4224-ab27-4e3dc72facd4'
)
resource cloudControllerManagerRoleNsgAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, cloudControllerManagerMi.id, cloudControllerManagerRoleId, customerNsg.id)
scope: customerNsg
properties: {
principalId: cloudControllerManagerMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: cloudControllerManagerRoleId
}
}
resource cloudControllerManagerRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, cloudControllerManagerMi.id, cloudControllerManagerRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: cloudControllerManagerMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: cloudControllerManagerRoleId
}
}
resource serviceManagedIdentityReaderOnCloudControllerManagerMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, cloudControllerManagerMi.id)
scope: cloudControllerManagerMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// Ingress managed identity
//
resource ingressMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-ingress-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift Cluster Ingress Operator
var ingressOperatorRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'0336e1d3-7a87-462b-b6db-342b63f7802c'
)
// Azure Red Hat OpenShift Image Registry Operator
var imageRegistryOperatorRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'8b32b316-c2f5-4ddf-b05b-83dacd2d08b5'
)
resource ingressOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, ingressMi.id, ingressOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: ingressMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: ingressOperatorRoleId
}
}
resource serviceManagedIdentityReaderOnIngressMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, ingressMi.id)
scope: ingressMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// Disk CSI driver managed identity
//
resource diskCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-disk-csi-driver-${randomSuffix}'
location: resourceGroup().location
}
resource serviceManagedIdentityReaderOnDiskCsiDriverMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, diskCsiDriverMi.id)
scope: diskCsiDriverMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// File CSI driver managed identity
//
resource fileCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-file-csi-driver-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift File Storage Operator
var fileStorageOperatorRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'0d7aedc0-15fd-4a67-a412-efad370c947e'
)
resource fileStorageOperatorRoleNsgAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, fileCsiDriverMi.id, fileStorageOperatorRoleId, customerNsg.id)
scope: customerNsg
properties: {
principalId: fileCsiDriverMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: fileStorageOperatorRoleId
}
}
resource fileStorageOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, fileCsiDriverMi.id, fileStorageOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: fileCsiDriverMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: fileStorageOperatorRoleId
}
}
resource serviceManagedIdentityReaderOnFileCsiDriverMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, fileCsiDriverMi.id)
scope: fileCsiDriverMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// Image registry managed identity
//
resource imageRegistryMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-image-registry-${randomSuffix}'
location: resourceGroup().location
}
resource serviceManagedIdentityReaderOnImageRegistryMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, imageRegistryMi.id)
scope: imageRegistryMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
resource imageRegistryOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, imageRegistryMi.id, imageRegistryOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: imageRegistryMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: imageRegistryOperatorRoleId
}
}
//
// Cloud network config managed identity
//
resource cloudNetworkConfigMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-cp-cloud-network-config-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift Network Operator
var networkOperatorRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'be7a6435-15ae-4171-8f30-4a343eff9e8f'
)
resource networkOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, cloudNetworkConfigMi.id, networkOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: cloudNetworkConfigMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: networkOperatorRoleId
}
}
resource serviceManagedIdentityReaderOnCloudNetworkMi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, readerRoleId, cloudNetworkConfigMi.id)
scope: cloudNetworkConfigMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: readerRoleId
}
}
//
// Data plane identities
//
// Azure Red Hat OpenShift Federated Credential
var federatedCredentialsRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'ef318e2a-8334-4a05-9e4a-295a196c6a6e'
)
resource dpDiskCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-dp-disk-csi-driver-${randomSuffix}'
location: resourceGroup().location
}
resource dpDiskCsiDriverMiFederatedCredentialsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, dpDiskCsiDriverMi.id, federatedCredentialsRoleId)
scope: dpDiskCsiDriverMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: federatedCredentialsRoleId
}
}
resource dpFileCsiDriverMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-dp-file-csi-driver-${randomSuffix}'
location: resourceGroup().location
}
resource dpFileCsiDriverMiFederatedCredentialsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, dpFileCsiDriverMi.id, federatedCredentialsRoleId)
scope: dpFileCsiDriverMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: federatedCredentialsRoleId
}
}
resource dpFileCsiDriverFileStorageOperatorRoleNsgAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, dpFileCsiDriverMi.id, fileStorageOperatorRoleId, customerNsg.id)
scope: customerNsg
properties: {
principalId: dpFileCsiDriverMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: fileStorageOperatorRoleId
}
}
resource dpFileCsiDriverFileStorageOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, dpFileCsiDriverMi.id, fileStorageOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: dpFileCsiDriverMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: fileStorageOperatorRoleId
}
}
resource dpImageRegistryMi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-dp-image-registry-${randomSuffix}'
location: resourceGroup().location
}
resource dpImageRegistryMiFederatedCredentialsRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, dpImageRegistryMi.id, federatedCredentialsRoleId)
scope: dpImageRegistryMi
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: federatedCredentialsRoleId
}
}
resource dpImageRegistryOperatorRoleVnetAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, dpImageRegistryMi.id, imageRegistryOperatorRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: dpImageRegistryMi.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: imageRegistryOperatorRoleId
}
}
//
// Service managed identity
//
resource serviceManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: '${clusterName}-service-managed-identity-${randomSuffix}'
location: resourceGroup().location
}
// Azure Red Hat OpenShift with hosted control planes Service Managed Identity
var hcpServiceManagedIdentityRoleId = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'c0ff367d-66d8-445e-917c-583feb0ef0d4'
)
resource serviceManagedIdentityRoleAssignmentVnet 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, hcpServiceManagedIdentityRoleId, customerVnet.id)
scope: customerVnet
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: hcpServiceManagedIdentityRoleId
}
}
resource serviceManagedIdentityRoleAssignmentNSG 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, serviceManagedIdentity.id, hcpServiceManagedIdentityRoleId, customerNsg.id)
scope: customerNsg
properties: {
principalId: serviceManagedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: hcpServiceManagedIdentityRoleId
}
}
// Cluster resource
resource hcp 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters@2026-09-01-preview' = {
name: clusterName
location: resourceGroup().location
properties: {
version: {
id: clusterVersion
channelGroup: 'stable'
}
dns: {}
network: {
networkType: 'OVNKubernetes'
podCidr: '10.128.0.0/14'
serviceCidr: '172.30.0.0/16'
machineCidr: '10.0.0.0/16'
hostPrefix: 23
}
etcd: {
dataEncryption: {
keyManagementMode: 'CustomerManaged'
customerManaged: {
encryptionType: 'KMS'
kms: {
activeKey: {
name: etcdEncryptionKeyName
version: last(split(etcdEncryptionKey.properties.keyUriWithVersion, '/'))
}
vaultName: customerKeyVaultName
visibility: privateKeyVault ? 'Private' : 'Public'
}
}
}
}
api: {
visibility: apiVisibility
}
ingress: {
type: ingressType
}
cryptoRestrictions: cryptoRestrictions
clusterImageRegistry: {
state: 'Enabled'
}
platform: {
managedResourceGroup: managedResourceGroupName
subnetId: subnet.id
vnetIntegrationSubnetId: vnetIntegrationSubnet.id
outboundType: 'LoadBalancer'
networkSecurityGroupId: customerNsg.id
operatorsAuthentication: {
userAssignedIdentities: {
controlPlaneOperators: {
'cluster-api-azure': clusterApiAzureMi.id
'control-plane': controlPlaneMi.id
'cloud-controller-manager': cloudControllerManagerMi.id
ingress: ingressMi.id
'disk-csi-driver': diskCsiDriverMi.id
'file-csi-driver': fileCsiDriverMi.id
'image-registry': imageRegistryMi.id
'cloud-network-config': cloudNetworkConfigMi.id
kms: kmsMi.id
}
dataPlaneOperators: {
'disk-csi-driver': dpDiskCsiDriverMi.id
'file-csi-driver': dpFileCsiDriverMi.id
'image-registry': dpImageRegistryMi.id
}
serviceManagedIdentity: serviceManagedIdentity.id
}
}
}
}
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${serviceManagedIdentity.id}': {}
'${clusterApiAzureMi.id}': {}
'${controlPlaneMi.id}': {}
'${cloudControllerManagerMi.id}': {}
'${ingressMi.id}': {}
'${diskCsiDriverMi.id}': {}
'${fileCsiDriverMi.id}': {}
'${imageRegistryMi.id}': {}
'${cloudNetworkConfigMi.id}': {}
'${kmsMi.id}': {}
}
}
dependsOn: [
hcpClusterApiProviderRoleVnetAssignment
keyVaultCryptoUserToKeyVaultRoleAssignment
hcpControlPlaneOperatorVnetRoleAssignment
hcpControlPlaneOperatorNsgRoleAssignment
cloudControllerManagerRoleNsgAssignment
cloudControllerManagerRoleVnetAssignment
ingressOperatorRoleVnetAssignment
fileStorageOperatorRoleNsgAssignment
fileStorageOperatorRoleVnetAssignment
networkOperatorRoleVnetAssignment
dpDiskCsiDriverMiFederatedCredentialsRoleAssignment
dpFileCsiDriverMiFederatedCredentialsRoleAssignment
dpImageRegistryMiFederatedCredentialsRoleAssignment
serviceManagedIdentityRoleAssignmentVnet
serviceManagedIdentityRoleAssignmentNSG
dpFileCsiDriverFileStorageOperatorRoleNsgAssignment
dpFileCsiDriverFileStorageOperatorRoleVnetAssignment
imageRegistryOperatorRoleVnetAssignment
dpImageRegistryOperatorRoleVnetAssignment
serviceManagedIdentityReaderOnControlPlaneMi
serviceManagedIdentityReaderOnCloudControllerManagerMi
serviceManagedIdentityReaderOnIngressMi
serviceManagedIdentityReaderOnDiskCsiDriverMi
serviceManagedIdentityReaderOnFileCsiDriverMi
serviceManagedIdentityReaderOnImageRegistryMi
serviceManagedIdentityReaderOnCloudNetworkMi
serviceManagedIdentityReaderOnClusterApiAzureMi
serviceManagedIdentityReaderOnKmsMi
]
}
// Node pool resource
resource nodepool 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters/nodePools@2026-09-01-preview' = {
parent: hcp
name: nodePoolName
location: resourceGroup().location
properties: {
version: {
id: nodePoolVersion
channelGroup: 'stable'
}
platform: {
subnetId: hcp.properties.platform.subnetId
vmSize: 'Standard_D8s_v6'
osDisk: {
sizeGiB: 64
diskStorageAccountType: 'StandardSSD_LRS'
}
}
replicas: 2
}
}
Desplegar el archivo Bicep
Implemente la plantilla de Bicep para crear el clúster y todos los recursos necesarios.
az deployment group create \
--name 'aro-hcp' \
--subscription "${SUBSCRIPTION_ID}" \
--resource-group "${CUSTOMER_RG_NAME}" \
--template-file azuredeploy.bicep \
--parameters \
customerNsgName="${CUSTOMER_NSG}" \
customerVnetName="${CUSTOMER_VNET_NAME}" \
customerVirtualNetworkIntegrationSubnetName="${CUSTOMER_VNET_INTEGRATION_SUBNET_NAME}" \
customerVnetSubnetName="${CUSTOMER_VNET_SUBNET1}" \
clusterName="${CLUSTER_NAME}" \
managedResourceGroupName="${MANAGED_RESOURCE_GROUP}" \
nodePoolName="${NP_NAME}" \
clusterVersion="${CLUSTER_VERSION}" \
nodePoolVersion="${NP_VERSION}" \
apiVisibility="<Public-or-Private>" \
ingressType="<Public-or-Private>" \
privateKeyVault=<true-or-false> \
cryptoRestrictions="<None-or-FIPS>"
Configure Public como apiVisibility para un servidor API accesible desde Internet, o como Private para un servidor API accesible solo a través de una conexión de red privada.
Establezca Public en ingressType para las rutas de aplicación accesibles desde Internet, o en Private para las rutas de aplicación accesibles solo a través de una conexión de red privada.
Establezca true en privateKeyVault para restringir el acceso a Key Vault a un punto de conexión privado, o en false para permitir el acceso público. Si establece privateKeyVault en true, la plantilla Bicep desactiva el acceso público a Key Vault, implementa los recursos de puntos de conexión privados y establece la visibilidad de Key Vault en Private en su clúster.
Establezca FIPS en cryptoRestrictions para restringir el clúster a módulos criptográficos validados por FIPS, o en None (predeterminado) para desplegarlo sin restricciones de FIPS. Esta configuración es inmutable después de la creación del clúster.
Note
El plano de control siempre se hospeda en un clúster habilitado para FIPS, independientemente de esta configuración. El cryptoRestrictions parámetro controla si los grupos de nodos de trabajo usan módulos criptográficos validados por FIPS.
La implementación suele tardar entre 15 y 20 minutos en completarse.
Comprobación de la implementación
Una vez finalizada la implementación, compruebe que el clúster y el grupo de nodos se crearon correctamente.
Compruebe que el clúster se creó correctamente.
az aro hcp cluster show \ --name "${CLUSTER_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --query "properties.provisioningState" \ --output tsvCuando el clúster esté listo, la salida es
Succeeded.Compruebe que el grupo de nodos se creó correctamente.
az aro hcp cluster nodepool show \ --cluster-name "${CLUSTER_NAME}" \ --name "${NP_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --query "properties.provisioningState" \ --output tsvCuando el grupo de nodos está listo, la salida es
Succeeded.
Creación de la infraestructura de red
Crea un grupo de seguridad de red, una red virtual con una subred de trabajadores y una subred de integración con red virtual con delegación.
Cree el grupo de seguridad de red (NSG).
Note
Si agrega reglas personalizadas al NSG, asegúrese de que permita el tráfico descrito en Tráfico requerido del grupo de seguridad de red.
az network nsg create \ --name "${CUSTOMER_NSG}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --location "${LOCATION}"Cree la red virtual con la subred de trabajo.
az network vnet create \ --name "${CUSTOMER_VNET_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --location "${LOCATION}" \ --address-prefixes 10.0.0.0/16 \ --subnet-name "${CUSTOMER_VNET_SUBNET1}" \ --subnet-prefixes 10.0.0.0/24 \ --nsg "${CUSTOMER_NSG}"Cree la subred de integración con la VNet con la delegación necesaria.
az network vnet subnet create \ --name "${CUSTOMER_VNET_INTEGRATION_SUBNET_NAME}" \ --vnet-name "${CUSTOMER_VNET_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --address-prefixes 10.0.1.0/24 \ --delegations Microsoft.RedHatOpenShift/hcpOpenShiftClustersObtenga los identificadores de los recursos de red.
NSG_ID=$(az network nsg show \ --name "${CUSTOMER_NSG}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --query id --output tsv) SUBNET_ID=$(az network vnet subnet show \ --name "${CUSTOMER_VNET_SUBNET1}" \ --vnet-name "${CUSTOMER_VNET_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --query id --output tsv) VNET_ID=$(az network vnet show \ --name "${CUSTOMER_VNET_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --query id --output tsv) VNET_INTEGRATION_SUBNET_ID=$(az network vnet subnet show \ --name "${CUSTOMER_VNET_INTEGRATION_SUBNET_NAME}" \ --vnet-name "${CUSTOMER_VNET_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --query id --output tsv)
Creación de las identidades administradas
Cree las identidades administradas asignadas por el usuario para los operadores de clúster y la identidad administrada del servicio. Para obtener una descripción de cada identidad y su propósito, consulte Identidades administradas necesarias y asignaciones de roles.
# Control plane operator identities
az identity create --name "${CLUSTER_NAME}-cp-cluster-api-azure" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-control-plane" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-cloud-controller-manager" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-ingress" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-image-registry" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-cp-cloud-network-config" --resource-group "${CUSTOMER_RG_NAME}"
# Data plane operator identities
az identity create --name "${CLUSTER_NAME}-dp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-dp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}"
az identity create --name "${CLUSTER_NAME}-dp-image-registry" --resource-group "${CUSTOMER_RG_NAME}"
# Service managed identity
az identity create --name "${CLUSTER_NAME}-service-managed-identity" --resource-group "${CUSTOMER_RG_NAME}"
Obtenga los identificadores de recursos y los identificadores de entidad de seguridad de las identidades administradas.
# Control plane identity resource IDs and principal IDs
CLUSTER_API_AZURE_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-cluster-api-azure" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CLUSTER_API_AZURE_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-cluster-api-azure" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
CONTROL_PLANE_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-control-plane" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CONTROL_PLANE_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-control-plane" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
CLOUD_CONTROLLER_MANAGER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-controller-manager" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CLOUD_CONTROLLER_MANAGER_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-controller-manager" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
INGRESS_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-ingress" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
INGRESS_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-ingress" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
DISK_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
FILE_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
FILE_CSI_DRIVER_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
IMAGE_REGISTRY_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
IMAGE_REGISTRY_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
CLOUD_NETWORK_CONFIG_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-network-config" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
CLOUD_NETWORK_CONFIG_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-cloud-network-config" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
# Data plane identity resource IDs and principal IDs
DP_DISK_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-dp-disk-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
DP_FILE_CSI_DRIVER_MI_ID=$(az identity show --name "${CLUSTER_NAME}-dp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
DP_FILE_CSI_DRIVER_MI_PID=$(az identity show --name "${CLUSTER_NAME}-dp-file-csi-driver" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
DP_IMAGE_REGISTRY_MI_ID=$(az identity show --name "${CLUSTER_NAME}-dp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
DP_IMAGE_REGISTRY_MI_PID=$(az identity show --name "${CLUSTER_NAME}-dp-image-registry" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
# Service managed identity resource ID and principal ID
SERVICE_MI_ID=$(az identity show --name "${CLUSTER_NAME}-service-managed-identity" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv)
SERVICE_MI_PID=$(az identity show --name "${CLUSTER_NAME}-service-managed-identity" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
Creación de las asignaciones de roles
Asigne los roles Azure necesarios a cada identidad administrada. Para obtener una descripción detallada de cada identidad y sus asignaciones de roles necesarias, consulte Identidades administradas requeridas y asignaciones de roles.
Establece los GUID de definición de roles.
READER_ROLE="acdd72a7-3385-48ef-bd42-f606fba81ae7" HCP_CLUSTER_API_PROVIDER_ROLE="88366f10-ed47-4cc0-9fab-c8a06148393e" HCP_CONTROL_PLANE_OPERATOR_ROLE="fc0c873f-45e9-4d0d-a7d1-585aab30c6ed" CLOUD_CONTROLLER_MANAGER_ROLE="a1f96423-95ce-4224-ab27-4e3dc72facd4" INGRESS_OPERATOR_ROLE="0336e1d3-7a87-462b-b6db-342b63f7802c" FILE_STORAGE_OPERATOR_ROLE="0d7aedc0-15fd-4a67-a412-efad370c947e" NETWORK_OPERATOR_ROLE="be7a6435-15ae-4171-8f30-4a343eff9e8f" FEDERATED_CREDENTIAL_ROLE="ef318e2a-8334-4a05-9e4a-295a196c6a6e" HCP_SERVICE_MI_ROLE="c0ff367d-66d8-445e-917c-583feb0ef0d4" IMAGE_REGISTRY_OPERATOR_ROLE="8b32b316-c2f5-4ddf-b05b-83dacd2d08b5"Asignar roles de operador del plano de control.
# Cluster API Azure → ARO HCP Cluster API Provider on the VNet az role assignment create --assignee-object-id "${CLUSTER_API_AZURE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CLUSTER_API_PROVIDER_ROLE}" --scope "${VNET_ID}" # Control Plane → ARO HCP Control Plane Operator on VNet and NSG az role assignment create --assignee-object-id "${CONTROL_PLANE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CONTROL_PLANE_OPERATOR_ROLE}" --scope "${VNET_ID}" az role assignment create --assignee-object-id "${CONTROL_PLANE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_CONTROL_PLANE_OPERATOR_ROLE}" --scope "${NSG_ID}" # Cloud Controller Manager → ARO Cloud Controller Manager on VNet and NSG az role assignment create --assignee-object-id "${CLOUD_CONTROLLER_MANAGER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${CLOUD_CONTROLLER_MANAGER_ROLE}" --scope "${NSG_ID}" az role assignment create --assignee-object-id "${CLOUD_CONTROLLER_MANAGER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${CLOUD_CONTROLLER_MANAGER_ROLE}" --scope "${VNET_ID}" # Ingress → ARO Cluster Ingress Operator on VNet az role assignment create --assignee-object-id "${INGRESS_MI_PID}" --assignee-principal-type ServicePrincipal --role "${INGRESS_OPERATOR_ROLE}" --scope "${VNET_ID}" # File CSI Driver → ARO File Storage Operator on VNet and NSG az role assignment create --assignee-object-id "${FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${NSG_ID}" az role assignment create --assignee-object-id "${FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${VNET_ID}" # Cloud Network Config → ARO Network Operator on VNet az role assignment create --assignee-object-id "${CLOUD_NETWORK_CONFIG_MI_PID}" --assignee-principal-type ServicePrincipal --role "${NETWORK_OPERATOR_ROLE}" --scope "${VNET_ID}" # Image Registry → ARO Image Registry Operator on VNet az role assignment create --assignee-object-id "${IMAGE_REGISTRY_MI_PID}" --assignee-principal-type ServicePrincipal --role "${IMAGE_REGISTRY_OPERATOR_ROLE}" --scope "${VNET_ID}"Asigne roles de identidad administrada de servicio.
# Service MI → ARO HCP Service Managed Identity on VNet and NSG az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_SERVICE_MI_ROLE}" --scope "${VNET_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${HCP_SERVICE_MI_ROLE}" --scope "${NSG_ID}" # Service MI → Reader on each control plane identity az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CLUSTER_API_AZURE_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CONTROL_PLANE_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CLOUD_CONTROLLER_MANAGER_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${INGRESS_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${DISK_CSI_DRIVER_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${FILE_CSI_DRIVER_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${IMAGE_REGISTRY_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${CLOUD_NETWORK_CONFIG_MI_ID}"Asigne roles de operador de plano de datos.
# Service MI → ARO Federated Credential on each data plane identity az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FEDERATED_CREDENTIAL_ROLE}" --scope "${DP_DISK_CSI_DRIVER_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FEDERATED_CREDENTIAL_ROLE}" --scope "${DP_FILE_CSI_DRIVER_MI_ID}" az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FEDERATED_CREDENTIAL_ROLE}" --scope "${DP_IMAGE_REGISTRY_MI_ID}" # Data Plane File CSI Driver → ARO File Storage Operator on VNet and NSG az role assignment create --assignee-object-id "${DP_FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${NSG_ID}" az role assignment create --assignee-object-id "${DP_FILE_CSI_DRIVER_MI_PID}" --assignee-principal-type ServicePrincipal --role "${FILE_STORAGE_OPERATOR_ROLE}" --scope "${VNET_ID}" # Data Plane Image Registry → ARO Image Registry Operator on VNet az role assignment create --assignee-object-id "${DP_IMAGE_REGISTRY_MI_PID}" --assignee-principal-type ServicePrincipal --role "${IMAGE_REGISTRY_OPERATOR_ROLE}" --scope "${VNET_ID}"
Configuración del cifrado etcd administrado por el cliente
Red Hat OpenShift en Azure con planos de control hospedados cifra los datos etcd mediante claves administradas por el cliente.
Creación de la identidad administrada de KMS
Establezca variables de entorno para la clave de Key Vault y KMS.
KEYVAULT_NAME="<key-vault-name>" KMS_KEY_NAME="etcd-kms-key"Cree la identidad administrada de KMS.
az identity create --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}"Obtenga el identificador de recurso y el identificador de entidad de seguridad de la identidad administrada de KMS.
KMS_MI_ID=$(az identity show --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}" --query id --output tsv) KMS_MI_PID=$(az identity show --name "${CLUSTER_NAME}-cp-kms" --resource-group "${CUSTOMER_RG_NAME}" --query principalId --output tsv)
Cree las asignaciones de roles de KMS
Asigne a la identidad administrada del servicio el rol Reader en la identidad administrada de KMS.
az role assignment create --assignee-object-id "${SERVICE_MI_PID}" --assignee-principal-type ServicePrincipal --role "${READER_ROLE}" --scope "${KMS_MI_ID}"
Creación de la clave Key Vault y KMS
Cree una Azure Key Vault con autorización RBAC y una clave de cifrado rsa de 2048 bits para el cifrado etcd administrado por el cliente.
Cree el almacén de claves.
az keyvault create \ --name "${KEYVAULT_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --location "${LOCATION}" \ --enable-rbac-authorization trueAsígnese el rol de usuario de Key Vault Crypto Officer. Este rol le concede los permisos para crear la clave de cifrado de KMS.
az role assignment create \ --role "Key Vault Crypto Officer" \ --assignee "$(az account show --query user.name -o tsv)" \ --scope "$(az keyvault show --name "${KEYVAULT_NAME}" --resource-group "${CUSTOMER_RG_NAME}" --query id -o tsv)"Cree la clave de cifrado de KMS.
az keyvault key create \ --vault-name "${KEYVAULT_NAME}" \ --name "${KMS_KEY_NAME}" \ --kty RSA \ --size 2048Obtenga la versión de la clave.
KMS_KEY_VERSION=$(az keyvault key show \ --vault-name "${KEYVAULT_NAME}" \ --name "${KMS_KEY_NAME}" \ --query "key.kid" --output tsv | rev | cut -d'/' -f1 | rev)Asigne el rol Key Vault Crypto User a la identidad administrada del KMS en Key Vault.
KEY_VAULT_CRYPTO_USER_ROLE="12338af0-0e69-4776-bea7-57ae8d297424" KEYVAULT_ID=$(az keyvault show --name "${KEYVAULT_NAME}" --query id --output tsv) az role assignment create \ --assignee-object-id "${KMS_MI_PID}" \ --assignee-principal-type ServicePrincipal \ --role "${KEY_VAULT_CRYPTO_USER_ROLE}" \ --scope "${KEYVAULT_ID}"
(Opcional) Restricción del acceso Key Vault a un punto de conexión privado
Si desea restringir Key Vault acceso a un punto de conexión privado, cree los siguientes recursos. Si no necesita un Key Vault privado, vaya a Creación del clúster.
Importante
Los pasos de esta sección configuran el acceso privado solo en Azure Key Vault. Cuando cree su clúster de Red Hat OpenShift en Azure con planos de control alojados, establezca también --vault-visibility Private. Ambas configuraciones deben coincidir.
Deshabilite el acceso a la red pública en el Key Vault.
az keyvault update \ --name "${KEYVAULT_NAME}" \ --resource-group "${CUSTOMER_RG_NAME}" \ --public-network-access DisabledCree un punto de conexión privado para el Key Vault.
az network private-endpoint create \ --name "kv-private-endpoint" \ --resource-group "${CUSTOMER_RG_NAME}" \ --vnet-name "${CUSTOMER_VNET_NAME}" \ --subnet "${CUSTOMER_VNET_SUBNET1}" \ --private-connection-resource-id "${KEYVAULT_ID}" \ --group-ids vault \ --connection-name "kv-private-endpoint"Cree una zona DNS privada y vincule a la red virtual.
az network private-dns zone create \ --name "privatelink.vaultcore.azure.net" \ --resource-group "${CUSTOMER_RG_NAME}" az network private-dns link vnet create \ --name "kv-private-dns-zone-link" \ --resource-group "${CUSTOMER_RG_NAME}" \ --zone-name "privatelink.vaultcore.azure.net" \ --virtual-network "${CUSTOMER_VNET_NAME}" \ --registration-enabled falseCree un grupo de zonas DNS para el punto de conexión privado.
az network private-endpoint dns-zone-group create \ --name "kv-private-ep-dns-group" \ --resource-group "${CUSTOMER_RG_NAME}" \ --endpoint-name "kv-private-endpoint" \ --private-dns-zone "privatelink.vaultcore.azure.net" \ --zone-name "config1"
Creación del clúster
Cree el Red Hat OpenShift en Azure con el clúster de planos de control hospedados mediante la infraestructura de red, las identidades administradas y las asignaciones de roles que configuró en los pasos anteriores.
Note
Para obtener información sobre todos los parámetros de clúster personalizables, consulte la ayuda del comando (az aro hcp cluster create -h).
Cree el clúster con el comando siguiente:
az aro hcp cluster create \
--name "${CLUSTER_NAME}" \
--resource-group "${CUSTOMER_RG_NAME}" \
--location "${LOCATION}" \
--version "${CLUSTER_VERSION}" \
--channel-group stable \
--subnet-id "${SUBNET_ID}" \
--vnet-integration-subnet-id "${VNET_INTEGRATION_SUBNET_ID}" \
--nsg "${NSG_ID}" \
--managed-resource-group-name "${MANAGED_RESOURCE_GROUP}" \
--kms-vault-name "${KEYVAULT_NAME}" \
--vault-visibility <Public-or-Private> \
--kms-active-key "{name:${KMS_KEY_NAME},version:${KMS_KEY_VERSION}}" \
--api-visibility <Public-or-Private> \
--ingress-visibility <Public-or-Private> \
--assign-service-managed-identity "${SERVICE_MI_ID}" \
--assign-control-plane-operator-identity cluster-api-azure "${CLUSTER_API_AZURE_MI_ID}" \
--assign-control-plane-operator-identity control-plane "${CONTROL_PLANE_MI_ID}" \
--assign-control-plane-operator-identity cloud-controller-manager "${CLOUD_CONTROLLER_MANAGER_MI_ID}" \
--assign-control-plane-operator-identity ingress "${INGRESS_MI_ID}" \
--assign-control-plane-operator-identity disk-csi-driver "${DISK_CSI_DRIVER_MI_ID}" \
--assign-control-plane-operator-identity file-csi-driver "${FILE_CSI_DRIVER_MI_ID}" \
--assign-control-plane-operator-identity image-registry "${IMAGE_REGISTRY_MI_ID}" \
--assign-control-plane-operator-identity cloud-network-config "${CLOUD_NETWORK_CONFIG_MI_ID}" \
--assign-control-plane-operator-identity kms "${KMS_MI_ID}" \
--assign-data-plane-operator-identity disk-csi-driver "${DP_DISK_CSI_DRIVER_MI_ID}" \
--assign-data-plane-operator-identity file-csi-driver "${DP_FILE_CSI_DRIVER_MI_ID}" \
--assign-data-plane-operator-identity image-registry "${DP_IMAGE_REGISTRY_MI_ID}"
Si ha restringido el Key Vault a un punto de conexión privado, establezca --vault-visibility en Private en en lugar de Public para que la configuración del clúster coincida con la configuración de red de Azure Key Vault.
Configure Public como --api-visibility para un servidor API accesible desde Internet, o como Private para un servidor API accesible solo a través de una conexión de red privada.
Establezca Public en --ingress-visibility para las rutas de aplicación accesibles desde Internet, o en Private para las rutas de aplicación accesibles solo a través de una conexión de red privada.
La implementación suele tardar entre 15 y 20 minutos en completarse.
Compruebe que el clúster se creó correctamente.
az aro hcp cluster show \
--name "${CLUSTER_NAME}" \
--resource-group "${CUSTOMER_RG_NAME}" \
--query "properties.provisioningState" \
--output tsv
Cuando el clúster esté listo, la salida es Succeeded.
Creación del grupo de nodos
Crea un grupo de nodos para añadir capacidad de proceso de trabajo a tu clúster.
El comando siguiente crea un grupo de nodos con dos Standard_D8s_v6 nodos de trabajo.
Importante
Antes de crear el grupo de nodos, compruebe que las reglas de NSG permiten el tráfico necesario descrito en Planear la red del clúster. Una regla de denegación coincidente puede impedir que el grupo de nodos complete el aprovisionamiento.
az aro hcp cluster nodepool create \
--cluster-name "${CLUSTER_NAME}" \
--name "${NP_NAME}" \
--resource-group "${CUSTOMER_RG_NAME}" \
--replicas 2 \
--vm-size Standard_D8s_v6 \
--version "${NP_VERSION}" \
--channel-group stable
Compruebe que el grupo de nodos se creó correctamente.
az aro hcp cluster nodepool show \
--cluster-name "${CLUSTER_NAME}" \
--name "${NP_NAME}" \
--resource-group "${CUSTOMER_RG_NAME}" \
--query "properties.provisioningState" \
--output tsv
Cuando el grupo de nodos está listo, la salida es Succeeded.
Referencia del archivo Bicep
El ejemplo Bicep archivo implementa un clúster con valores de configuración predeterminados. En esta sección se describe cada recurso y propiedad del archivo Bicep que puede personalizar antes de implementar.
Recursos de redes
El archivo Bicep define un grupo de seguridad de red (NSG), una red virtual con una subred de trabajo y una subred de integración con la red virtual, y la delegación de la subred de integración con la red virtual. Para conocer los requisitos de ajuste de tamaño, selección de ubicación y NSG de subred, consulte Planeamiento de la red del clúster.
Identidades administradas y asignaciones de roles
El archivo Bicep define una identidad administrada asignada por el usuario para cada operador de clúster de OpenShift y asignaciones de roles que conceden a cada identidad los permisos que necesita. Para obtener una descripción detallada de cada identidad y sus asignaciones de roles necesarias, consulte Identidades administradas requeridas y asignaciones de roles.
Recursos de cifrado de Etcd
El archivo Bicep incluye los siguientes recursos para el cifrado etcd administrado por el cliente:
-
Identidad administrada de KMS : una identidad administrada asignada por el usuario para acceder a la clave de KMS. Esta identidad requiere:
- Asignación del rol Key Vault Crypto User con ámbito en Azure Key Vault
- Asignación del rol Lector que concede a la identidad administrada del servicio acceso de lectura sobre la identidad administrada de KMS
- Azure Key Vault - Un Azure Key Vault con la autorización RBAC habilitada
- Clave de cifrado de KMS: clave RSA 2048 creada en el Key Vault
Si establece el parámetro privateKeyVault en true, el archivo Bicep también implementa los siguientes recursos para restringir el acceso a Key Vault a un extremo privado:
- Un punto de conexión privado para el Key Vault
- Una zona DNS privada (
privatelink.vaultcore.azure.net) - Grupo de zonas DNS privadas que asocia el punto de conexión privado a la zona DNS
- Vínculo de red virtual que conecta la zona DNS privada a la red virtual del clúster
Propiedades de recursos de clúster
El recurso de clúster (Microsoft.RedHatOpenShift/hcpOpenShiftClusters) define la configuración del clúster.
Para obtener más información sobre cada opción de configuración, consulte Elección de la configuración permanente del clúster.
| Propiedad | Required | Descripción |
|---|---|---|
version.id |
Sí | La versión menor de OpenShift que se va a instalar. Por ejemplo: 4.20. Para enumerar las versiones disponibles, consulte Enumerar las versiones disponibles de OpenShift. |
version.channelGroup |
Sí | Canal de actualización de OpenShift. La única opción admitida es stable. |
dns.baseDomainPrefix |
No | Prefijo personalizado para el nombre de dominio base del clúster. Longitud máxima de 15 caracteres. Debe comenzar con una letra minúscula y solo puede contener letras minúsculas, números y guiones (-). |
network.networkType |
No | El complemento de la interfaz de red de contenedores (CNI). Los valores válidos son OVNKubernetes (valor predeterminado) o Other. |
network.podCidr |
No | El intervalo de direcciones IP de los pods. Valor predeterminado: 10.128.0.0/14. |
network.serviceCidr |
No | El rango de direcciones IP para los servicios. Valor predeterminado: 172.30.0.0/16. |
network.machineCidr |
No | Rango de direcciones IP de los nodos de cómputo. Valor predeterminado: 10.0.0.0/16. |
network.hostPrefix |
No | Longitud del prefijo de subred asignado a cada nodo para sus pods. Valor predeterminado: 23. |
api.visibility |
No | Visibilidad del servidor de API. Los valores válidos son Public (valor predeterminado) o Private. Esta configuración es inmutable. |
api.authorizedCidrs |
No | Lista de bloques CIDR autorizados (solo IPv4) permitidos para acceder al servidor de API. Máximo de 500 entradas. |
ingress.type |
No | El tipo de entrada predeterminada del clúster. Los valores válidos son Public (valor predeterminado) o Private. Esta configuración es inmutable. |
cryptoRestrictions |
No | Restricciones criptográficas para bibliotecas del núcleo y del espacio de usuario. Los valores válidos son None (valor predeterminado) o FIPS. Cuando se establece en FIPS, todas las operaciones criptográficas usan módulos validados por FIPS y todos los grupos de nodos heredan la configuración de FIPS. Esta configuración es inmutable después de la creación del clúster. |
etcd.dataEncryption.keyManagementMode |
Sí | Modo de administración de claves de cifrado. El único valor admitido es CustomerManaged. |
etcd.dataEncryption.customerManaged.encryptionType |
Sí | Tipo de cifrado. El único valor admitido es KMS. |
etcd.dataEncryption.customerManaged.kms.vaultName |
Sí | Nombre del Azure Key Vault. |
etcd.dataEncryption.customerManaged.kms.visibility |
Sí | Cómo su clúster de Red Hat OpenShift en Azure con planos de control hospedados accede a Key Vault. Los valores válidos son Public y Private. Si configura esto en Private, también debe deshabilitar el acceso de red pública en el Key Vault y crear un punto de conexión privado en la red virtual del clúster. |
etcd.dataEncryption.customerManaged.kms.activeKey.name |
Sí | Nombre de la clave de cifrado. |
etcd.dataEncryption.customerManaged.kms.activeKey.version |
Sí | Versión de la clave de cifrado. |
clusterImageRegistry.state |
No | Estado del registro de imágenes interno. Los valores válidos son Enabled (valor predeterminado) o Disabled. |
platform.managedResourceGroup |
No | Nombre del grupo de recursos administrado. Longitud máxima de 90 caracteres. |
platform.subnetId |
Sí | El identificador de recurso de Azure de la subred de trabajo. |
platform.vnetIntegrationSubnetId |
Sí | El identificador de recurso de Azure de la subred de integración de VNet. |
platform.outboundType |
No | Modelo de conectividad saliente. El único valor admitido es loadBalancer. |
platform.networkSecurityGroupId |
Sí | El identificador de recurso de Azure del grupo de seguridad de red. |
platform.operatorsAuthentication |
Sí | Asignaciones de identidad administrada para los operadores de clúster. |
autoscaling.maxNodesTotal |
No | Número máximo de nodos que puede crear el escalador automático del clúster. Por defecto: 0 (sin límite). |
autoscaling.maxPodGracePeriodSeconds |
No | El número máximo de segundos para la terminación ordenada del pod antes de la reducción de escala. |
autoscaling.maxNodeProvisionTimeSeconds |
No | Los segundos máximos para el aprovisionamiento de nodos. Valor predeterminado: 900. |
autoscaling.podPriorityThreshold |
No | El umbral de prioridad por debajo del cual el autoescalador trata los pods como best-effort. Valor predeterminado: -10. |
imageDigestMirrors |
No | Entradas de espejo del resumen criptográfico de imágenes que redirigen la obtención de imágenes desde un registro de origen a registros espejo. Máximo de 240 entradas. |
nodeDrainTimeoutMinutes |
No | Período de gracia de purga de nodos predeterminado para todos los grupos de nodos, en minutos. Intervalo: 0 a 10080. Valor predeterminado: 0 (sin límite de tiempo). |
identity.type |
Sí | Tipo de identidad. Debe ser UserAssigned. |
identity.userAssignedIdentities |
Sí | Mapa de identificadores de recurso de identidad administrada asignada por el usuario. |
Propiedades de recursos del grupo de nodos
El recurso del grupo de nodos (Microsoft.RedHatOpenShift/hcpOpenShiftClusters/nodePools) define un grupo de nodos de trabajo que comparten la misma configuración.
| Propiedad | Required | Descripción |
|---|---|---|
version.id |
Sí | La versión de revisión de OpenShift para este grupo de nodos. Por ejemplo: 4.20.8. La versión del grupo de nodos debe ser una versión de parche dentro de la versión menor del clúster. Para enumerar las versiones disponibles, consulte Enumerar las versiones disponibles de OpenShift. |
version.channelGroup |
Sí | Canal de actualización de OpenShift. La única opción admitida es stable. |
platform.vmSize |
Sí | El tamaño de la máquina virtual de Azure para los nodos. Para enumerar los tamaños de máquina virtual disponibles, consulte Enumerar los tamaños de máquina virtual disponibles. |
platform.subnetId |
Sí | Identificador de recurso Azure de la subred. Si no especifica esta propiedad, el grupo de nodos usa la subred de trabajo del clúster. |
platform.osDisk.diskSizeGiB |
No | El tamaño del disco del sistema operativo en GiB. Mínimo: 16. |
platform.osDisk.diskStorageAccountType |
No | Tipo de cuenta de almacenamiento en disco. Los valores válidos son Premium_LRS, StandardSSD_LRS o Standard_LRS. |
platform.osDisk.encryptionSetId |
No | El ID de recurso de Azure de un DiskEncryptionSet para cifrar discos del sistema operativo. |
platform.osDisk.diskType |
No | Tipo de disco del sistema operativo. Los valores válidos son Managed y Ephemeral. |
platform.availabilityZone |
No | La zona de disponibilidad Azure para el grupo de nodos. |
platform.enableEncryptionAtHost |
No | Habilita el cifrado de nivel de host para máquinas virtuales. Valor predeterminado: false. |
replicas |
Condicional | Número de nodos. Obligatorio si autoScaling no está configurado. |
autoScaling.min |
Condicional | Número mínimo de nodos. Obligatorio si replicas no está configurado. |
autoScaling.max |
Condicional | Número máximo de nodos. Obligatorio si replicas no está configurado. |
autoRepair |
No | Habilita las comprobaciones de estado de los nodos. Valor predeterminado: true. |
labels |
No | Etiquetas de Kubernetes aplicadas a los nodos, como una matriz de pares clave-valor. |
taints |
No | Las marcas de Kubernetes aplicadas a los nodos. Cada marca tiene un key, value y effect (NoSchedule, PreferNoSchedule o NoExecute). |
nodeDrainTimeoutMinutes |
No | El periodo de gracia de drenaje de nodos para este grupo de nodos, en minutos. Invalida el valor predeterminado del clúster. Intervalo: 0 a 10080. |
Enumerar las versiones disponibles de OpenShift
El clúster version.id usa una versión secundaria (por ejemplo, 4.20), mientras que el grupo version.id de nodos usa una versión de revisión (por ejemplo, 4.20.8).
Para enumerar las versiones disponibles de OpenShift en su región, ejecute el siguiente comando:
az aro hcp get-versions --location "${LOCATION}" --output table
Enumerar los tamaños de máquina virtual disponibles
La disponibilidad de los tamaños de máquina virtual depende de la región Azure del clúster. Para enumerar los tamaños de máquina virtual disponibles en su región, ejecute el siguiente comando:
az vm list-sizes --location "${LOCATION}" --output table
Para obtener la lista de tamaños de máquina virtual de nodo de trabajo admitidos para Red Hat OpenShift en Azure con planos de control hospedados, consulte Tamaños de máquina virtual admitidos. Use la lista regional para confirmar que un tamaño admitido está disponible en la ubicación del clúster.