使用托管标识创建 Azure Red Hat OpenShift 群集(预览版)

本文介绍如何使用托管标识部署 Azure Red Hat OpenShift 群集。

重要

目前,此 Azure Red Hat OpenShift 功能仅在预览版中提供。 预览功能是可选择启用的自助功能。 预览版按原样可用性提供,并被排除在服务级别协议和有限保修范围之外。 我们只能尽最大努力为 Azure Red Hat OpenShift 预览版提供部分客户支持。 因此,这些功能并不适合用于生产。

Azure Red Hat OpenShift 是一种托管 OpenShift 服务,支持托管标识和工作负荷标识。 托管标识和工作负荷标识通过提供短期令牌,而不是使用持有客户端密钥凭据的服务主体的长期凭据,在保护工作负荷和应用程序时有效地帮助降低风险。

有关详细信息,请参见:

先决条件

确保使用 Azure CLI 2.67.0 或更高版本。 使用 az--version 来查找已安装的 Azure CLI 版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

Azure Red Hat OpenShift 至少需要 44 个核心才能创建 OpenShift 群集。 新 Azure 订阅的默认 Azure 资源配额不符合此要求。 若要请求增加资源限制,请参阅增加 VM 系列 vCPU 配额

44 个核心用于以下用途:

  • 启动计算机:8 个核心
  • 控制平面(主机):24 核
  • 计算(工作机器):12 个核心

安装完成后,将删除启动计算机,群集总共使用 36 个核心。 有关详细信息,请参阅 在 Azure 上安装

例如,若要查看最小支持的虚拟机系列 SKU“标准 DSv5”的当前订阅配额:

LOCATION=eastus
az vm list-usage -l $LOCATION \
--query "[?contains(name.value, 'standardDSv5Family')]" -o table

下载 Azure Red Hat OpenShift 扩展轮文件(仅预览版)

若要运行本文中的命令,请先从 https://aka.ms/az-aroext-latest中下载 Azure Red Hat OpenShift 扩展滚轮文件。 若要安装扩展,请运行以下命令:

az extension add -s <path to downloaded whl file>

验证你的权限

本文将创建一个资源组,其中包含群集的虚拟网络和托管标识。 若要创建资源组,您需要对包含该资源组或订阅拥有贡献者权限和用户访问管理员权限,或拥有所有者权限。

还需要具备足够的 Microsoft Entra 权限(作为租户的成员用户或被分配 应用程序管理员角色的来宾)来创建一组托管标识,并为群集分配角色。 有关详细信息,请参阅 成员和来宾 ,以及 向具有 Microsoft Entra ID 的用户分配管理员和非管理员角色

注册资源提供程序

某些 Azure 资源提供程序(包括 Azure Red Hat OpenShift 资源提供程序)需要注册才能正常运行。 注册资源提供程序会在订阅中创建一个服务主体,该主体授权资源提供程序执行某些作,例如资源创建。 有关资源提供程序注册的详细信息,请参阅 注册资源提供程序

  1. 如果有多个 Azure 订阅,请指定相关订阅 ID:

    az account set --subscription <SUBSCRIPTION ID>
    
  2. 注册 Microsoft.RedHatOpenShift 资源提供程序:

    az provider register -n Microsoft.RedHatOpenShift --wait
    
  3. 注册 Microsoft.Compute 资源提供程序:

    az provider register -n Microsoft.Compute --wait
    
  4. 注册 Microsoft.Storage 资源提供程序:

    az provider register -n Microsoft.Storage --wait
    
  5. 注册 Microsoft.Authorization 资源提供程序:

    az provider register -n Microsoft.Authorization --wait
    

获取 Red Hat 拉取机密(可选)

注释

Azure Red Hat OpenShift 拉取机密不会更改 Red Hat OpenShift 许可证的成本。

Red Hat 拉取机密使群集能够访问 Red Hat 容器注册表和 OperatorHub 中的其他内容(例如运算符)。 此步骤是可选的,但建议执行。 如果决定稍后添加拉取机密,请按照本指南操作。 即使拉取机密包含该字段,也会从你的机密中移除字段 cloud.openshift.com。 此字段会启用一个额外的监视功能,该功能会将数据发送到 RedHat,因此默认情况下已禁用。 若要启用此功能,请参阅 “启用远程运行状况报告”。

  1. 导航到 Red Hat OpenShift 群集管理器门户并登录。

    需要登录到 Red Hat 帐户,或使用业务电子邮件创建新的 Red Hat 帐户并接受条款和条件。

  2. 选择 “下载拉取机密”,然后下载要用于 Azure Red Hat OpenShift 群集的拉取机密。

    将已保存的 pull-secret.txt 文件保存在安全的位置。 在每次创建群集时,如果需要创建包含 Red Hat 或认证合作伙伴的示例或操作员的群集,则会使用该文件。

    运行 az aro create 命令时,可以使用 --pull-secret @pull-secret.txt 参数引用拉取机密。 从存储 az aro create 文件的目录执行 pull-secret.txt。 否则,将 @pull-secret.txt 替换为 @/path/to/my/pull-secret.txt

    如果要复制拉取机密或在其他脚本中引用它,则应将拉取机密的格式设置为有效的 JSON 字符串。

为群集准备自定义域(可选)

运行 az aro create 命令时,可以使用 --___domain foo.example.com 参数为群集指定自定义域。

注释

通过 Azure CLI 创建群集时,添加域名是可选的。 通过门户添加群集时,需要域名(或用作 OpenShift 控制台和 API 服务器的自动生成 DNS 名称的一部分的前缀)。 有关详细信息,请参阅 快速入门:使用 Azure 门户部署 Azure Red Hat OpenShift 群集

如果为群集提供自定义域,请注意以下几点:

  • 创建群集后,必须在 DNS 服务器中为 --___domain 指定的 DNS 服务器创建两条 DNS A 记录:
    • api - 指向 API 服务器 IP 地址
    • *.apps - 指向入口 IP 地址
    • 创建群集后,通过执行 az aro show -n -g --query '{api:apiserverProfile.ip, ingress:ingressProfiles[0].ip}' 命令检索这些值。
  • OpenShift 控制台可以通过像 https://console-openshift-console.apps.example.com 这样的 URL 访问,而不是通过内置域 https://console-openshift-console.apps.<random>.<___location>.aroapp.io
  • 默认情况下,OpenShift 对自定义域 *.apps.example.com 上创建的所有路由使用自签名证书。 如果在连接到群集后选择使用自定义 DNS,则需要按照 OpenShift 文档为 入口控制器配置自定义 CA和为API 服务器配置自定义 CA

安装

可以使用 Azure CLI 或 Bicep 来部署利用托管标识的 Azure Red Hat OpenShift 群集。

使用 Azure CLI 安装

本部分介绍如何使用 Azure CLI 创建利用托管标识的 Azure Red Hat OpenShift 群集。

创建包含两个空子网的虚拟网络

创建包含两个空子网的虚拟网络。 如果有满足需求的现有虚拟网络,请跳过此步骤。

有关网络和要求的信息,请参阅 Azure Red Hat OpenShift 的网络

  1. 在执行 az 命令的 shell 环境中,需要设置以下变量。

    LOCATION=eastus                 # the ___location of your cluster
    RESOURCEGROUP=aro-rg            # the name of the resource group where you want to create your cluster
    CLUSTER=cluster                 # the name of your cluster
    
  2. 创建资源组。

    Azure 资源组是用于部署和管理 Azure 资源的逻辑组。 创建资源组时,系统会要求你指定一个位置。 此位置是存储资源组元数据的位置,如果在创建资源期间未指定其他区域,则资源在 Azure 中运行的位置。 使用 az group create 命令创建资源组。

    注释

    Azure Red Hat OpenShift 在可以创建 Azure 资源组的所有区域中都不可用。 有关支持 Azure Red Hat OpenShift 的位置的信息,请参阅可用区域

    az group create \
      --___location $LOCATION \
      --name $RESOURCEGROUP
    
  3. 在以前创建的同一资源组中创建虚拟网络、主节点子网和工作子网。

    Azure Red Hat OpenShift 群集需要一个虚拟网络,其中包含主节点和工作节点的两个空子网。 可以创建新的虚拟网络,也可以使用现有的虚拟网络。

    az network vnet create \
       --resource-group $RESOURCEGROUP \
       --name aro-vnet \
       --address-prefixes 10.0.0.0/22
    
    az network vnet subnet create \
       --resource-group $RESOURCEGROUP \
       --vnet-name aro-vnet \
       --name master \
       --address-prefixes 10.0.0.0/23
    
    az network vnet subnet create \
       --resource-group $RESOURCEGROUP \
       --vnet-name aro-vnet \
       --name worker \
       --address-prefixes 10.0.2.0/23
    

创建所需的用户指定的托管身份标识

  1. 创建以下必需的身份。 Azure Red Hat OpenShift 需要 9 个托管标识,每个标识都需要分配有一个内置角色:

    • 与核心 OpenShift 操作员相关的七个托管标识。
    • Azure Red Hat OpenShift 服务操作员的托管标识。
    • 另一个用于启用这些标识的群集标识。

    托管标识组件包括:

    • OpenShift 映像注册表运算符(image-registry)
    • OpenShift 网络运营商 (cloud-network-config)
    • OpenShift 磁盘存储操作器(磁盘 CSI 驱动程序)
    • OpenShift 文件存储运算符(file-csi-driver)
    • OpenShift 群集入口运算符 (入口)
    • OpenShift Cloud Controller Manager (cloud-controller-manager)
    • OpenShift 机器 API 操作员 (machine-api)
    • Azure Red Hat OpenShift 服务操作员(aro-operator)

    有八个不同的托管标识和相应的内置角色,这些角色表示 Azure Red Hat OpenShift 的每个组件执行其职责所需的权限。 此外,平台需要另一个标识(群集标识),以便为之前提到的托管身份组件(aro-cluster)进行联合凭证的创建。

    有关 Red Hat OpenShift 群集作员的详细信息,请参阅 群集作员参考

    有关 Azure Red Hat OpenShift 中的托管标识的详细信息,请参阅 了解 Azure Red Hat OpenShift 中的托管标识

    创建所需的身份

    az identity create \
    --resource-group $RESOURCEGROUP \
    --name aro-cluster
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name cloud-controller-manager
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name ingress
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name machine-api
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name disk-csi-driver
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name cloud-network-config
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name image-registry
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name file-csi-driver
    
    az identity create \
    --resource-group $RESOURCEGROUP \
    --name aro-operator
    
  2. 为每个作员标识、群集标识和第一方服务主体创建所需的角色分配。

    注释

    本文假定只有主节点子网和工作节点子网存在。 如果在安装时配置了更多群集子网,则需要为需要该子网的作员授予角色分配范围。

    主子网和辅助角色子网的以下角色分配假定没有附加网络安全组(NSG)、路由表或网络地址转换(NAT)网关。 如果将其中任何一个网络资源引入安装,则需要创建更多角色分配,以便为这些额外的网络资源授予作员标识权限。 对于需要为以下子网或虚拟网络分配角色的每个操作员,还需要为额外的网络资源分配角色。

    SUBSCRIPTION_ID=$(az account show --query 'id' -o tsv)
    
    # assign cluster identity permissions over identities previously created
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/aro-operator"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cloud-controller-manager"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ingress"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/machine-api"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/disk-csi-driver"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cloud-network-config"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/image-registry"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-cluster --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/ef318e2a-8334-4a05-9e4a-295a196c6a6e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/file-csi-driver"
    
    # assign vnet-level permissions for operators that require it, and subnets-level permission for operators that require it
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name cloud-controller-manager --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/a1f96423-95ce-4224-ab27-4e3dc72facd4" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name cloud-controller-manager --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/a1f96423-95ce-4224-ab27-4e3dc72facd4" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name ingress --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/0336e1d3-7a87-462b-b6db-342b63f7802c" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name ingress --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/0336e1d3-7a87-462b-b6db-342b63f7802c" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name machine-api --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/0358943c-7e01-48ba-8889-02cc51d78637" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name machine-api --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/0358943c-7e01-48ba-8889-02cc51d78637" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name cloud-network-config --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/be7a6435-15ae-4171-8f30-4a343eff9e8f" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name file-csi-driver --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/0d7aedc0-15fd-4a67-a412-efad370c947e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name file-csi-driver --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/0d7aedc0-15fd-4a67-a412-efad370c947e" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-operator --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/4436bae4-7702-4c84-919b-c4069ff25ee2" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master"
    
    az role assignment create \
        --assignee-object-id "$(az identity show --resource-group $RESOURCEGROUP --name aro-operator --query principalId -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/4436bae4-7702-4c84-919b-c4069ff25ee2" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker"
    
    az role assignment create \
        --assignee-object-id "$(az ad sp list --display-name "Azure Red Hat OpenShift RP" --query '[0].id' -o tsv)" \
        --assignee-principal-type ServicePrincipal \
        --role "/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7" \
        --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCEGROUP/providers/Microsoft.Network/virtualNetworks/aro-vnet"
    

创建群集

若要创建群集,请运行以下命令,这些命令显示在选项下。 如果选择使用以下任一选项,请相应地修改命令:

  • 选项 1:可以 传递 Red Hat 拉取机密,使群集能够访问 Red Hat 容器注册表以及其他内容。 将 --pull-secret @pull-secret.txt 参数添加到命令中。
  • 选项 2:可以使用 自定义域。 将 --___domain foo.example.com 参数添加到命令中,将 foo.example.com 替换为你自己的自定义域。

使用所需的环境变量创建群集。 对于每个 --assign-platform-workload-identity 参数,第一个参数表示键,该键指定 Azure Red Hat OpenShift 资源提供程序要用于给定身份的 OpenShift 操作器。 第二个参数表示对身份本身的引用。

az aro create \
    --resource-group $RESOURCEGROUP \
    --name $CLUSTER \
    --vnet aro-vnet \
    --master-subnet master \
    --worker-subnet worker \
    --version <VERSION> \
    --enable-managed-identity \
    --assign-cluster-identity aro-cluster \
    --assign-platform-workload-identity file-csi-driver file-csi-driver \
    --assign-platform-workload-identity cloud-controller-manager cloud-controller-manager \
    --assign-platform-workload-identity ingress ingress \
    --assign-platform-workload-identity image-registry image-registry \
    --assign-platform-workload-identity machine-api machine-api \
    --assign-platform-workload-identity cloud-network-config cloud-network-config \
    --assign-platform-workload-identity aro-operator aro-operator \
    --assign-platform-workload-identity disk-csi-driver disk-csi-driver

作为一个选项,如果标识资源存在于其他 区域资源组中,则可以传递要创建的完整资源 ID。 请参阅以下示例:

az aro create \
    --resource-group $RESOURCEGROUP \
    --name $CLUSTER \
    --vnet aro-vnet \
    --master-subnet master \
    --worker-subnet worker \
    --version <VERSION> \
    --enable-managed-identity \
    --assign-cluster-identity /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/aro-cluster \
    --assign-platform-workload-identity file-csi-driver /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/file-csi-driver \
    --assign-platform-workload-identity cloud-controller-manager /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cloud-controller-manager \
    --assign-platform-workload-identity ingress /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ingress \
    --assign-platform-workload-identity image-registry /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/image-registry \
    --assign-platform-workload-identity machine-api /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/machine-api \
    --assign-platform-workload-identity cloud-network-config /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cloud-network-config \
    --assign-platform-workload-identity aro-operator /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/aro-operator \
    --assign-platform-workload-identity disk-csi-driver /subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCEGROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/disk-csi-driver

选择其他 Azure Red Hat OpenShift 版本

创建群集时,可以选择使用特定版本的 Azure Red Hat OpenShift。 首先,使用 CLI 查询可用的 Azure Red Hat OpenShift 版本:

az aro get-versions --___location <REGION>

选择版本后,使用 --version 命令中的 az aro create 参数指定它。

使用 Bicep 进行安装

本部分介绍如何使用 Bicep 创建利用托管标识的 Azure Red Hat OpenShift 群集。

  1. 示例 Bicep 模板 (位于步骤 5 之后)保存到文件。

  2. 在计划执行 az 命令的 shell 环境中设置以下变量。

    LOCATION=eastus                     # the ___location of your cluster
    RESOURCEGROUP=aro-rg                # the name of the resource group where you want to create your cluster
    CLUSTER=cluster                     # the name of your cluster
    VERSION=4.15.35                     # the version of the cluster
    PULL_SECRET=$(cat pull-secret.txt)  # the Red Hat pull secret JSON, provided as file or string
    
  3. 创建一个资源组来保存群集资源和群集虚拟网络和标识。

    az group create --name $RESOURCEGROUP --___location $LOCATION
    
  4. 对于资源提供程序,请检查订阅的第一方服务主体对象 ID。

    ARO_RP_SP_OBJECT_ID=$(az ad sp list --display-name "Azure Red Hat OpenShift RP" --query '[0].id' -o tsv)
    
  5. 应用 Bicep 模板:

    az deployment group create \
        --name aroDeployment \
        --resource-group $RESOURCEGROUP \
        --template-file azuredeploy.bicep \
        --parameters ___location=$LOCATION \
        --parameters version=$VERSION \
        --parameters clusterName=$CLUSTER \
        --parameters rpObjectId=$ARO_RP_SP_OBJECT_ID
        (--parameters ___domain=$DOMAIN) \ #optional
        (--parameters pullSecret=$PULL_SECRET) # optional
    

示例 Bicep 模板

注释

本文假定只有主节点子网和工作节点子网存在。 如果在安装时配置了更多群集子网,则需要为需要该子网的作员授予角色分配范围。

主子网和辅助角色子网的以下角色分配假定没有附加网络安全组(NSG)、路由表或网络地址转换(NAT)网关。 如果将其中任何一个网络资源引入安装,则需要创建更多角色分配,以便为这些额外的网络资源授予作员标识权限。 对于需要为以下子网或虚拟网络分配角色的每个操作员,还需要为额外的网络资源分配角色。

@description('Location')
param ___location string = resourceGroup().___location

@description('Domain Prefix')
param ___domain string

@description('Version of the OpenShift cluster')
param version string

@description('Pull secret from cloud.redhat.com. The json should be input as a string')
@secure()
param pullSecret string = ''

@description('Name of ARO vNet')
param clusterVnetName string = 'aro-vnet'

@description('ARO vNet Address Space')
param clusterVnetCidr string = '10.100.0.0/15'

@description('Worker node subnet address space')
param workerSubnetCidr string = '10.100.70.0/23'

@description('Master node subnet address space')
param masterSubnetCidr string = '10.100.76.0/24'

@description('Master Node VM Type')
param masterVmSize string = 'Standard_D8s_v3'

@description('Worker Node VM Type')
param workerVmSize string = 'Standard_D4s_v3'

@description('Worker Node Disk Size in GB')
@minValue(128)
param workerVmDiskSize int = 128

@description('Cidr for Pods')
param podCidr string = '10.128.0.0/14'

@metadata({
 description: 'Cidr of service'
})
param serviceCidr string = '172.30.0.0/16'

@description('Unique name for the cluster')
param clusterName string

@description('Api Server Visibility')
@allowed([
 'Private'
 'Public'
])
param apiServerVisibility string = 'Public'

@description('Ingress Visibility')
@allowed([
 'Private'
 'Public'
])
param ingressVisibility string = 'Public'

@description('The ObjectID of the Resource Provider Service Principal')
param rpObjectId string

@description('Specify if FIPS validated crypto modules are used')
@allowed([
 'Enabled'
 'Disabled'
])
param fips string = 'Disabled'

@description('Specify if master VMs are encrypted at host')
@allowed([
 'Enabled'
 'Disabled'
])
param masterEncryptionAtHost string = 'Disabled'

@description('Specify if worker VMs are encrypted at host')
@allowed([
 'Enabled'
 'Disabled'
])
param workerEncryptionAtHost string = 'Disabled'

var resourceGroupId = '/subscriptions/${subscription().subscriptionId}/resourceGroups/aro-${___domain}-${___location}'
var masterSubnetId=resourceId('Microsoft.Network/virtualNetworks/subnets', clusterVnetName, 'master')
var workerSubnetId=resourceId('Microsoft.Network/virtualNetworks/subnets', clusterVnetName, 'worker')

resource vnet 'Microsoft.Network/virtualNetworks@2023-06-01' = {
 name: clusterVnetName
 ___location: ___location
 properties: {
   addressSpace: { addressPrefixes: [ clusterVnetCidr ] }
   subnets: [
     {
       name: 'master'
       properties: {
         addressPrefixes: [ masterSubnetCidr ]
         serviceEndpoints: [ { service: 'Microsoft.ContainerRegistry' } ]
       }
     }
     {
       name: 'worker'
       properties: {
         addressPrefixes: [ workerSubnetCidr ]
         serviceEndpoints: [ { service: 'Microsoft.ContainerRegistry' } ]
       }
     }
   ]
 }
}

resource workerSubnet 'Microsoft.Network/virtualNetworks/subnets@2020-08-01' existing = {
 parent: vnet
 name: 'worker'
}

resource masterSubnet 'Microsoft.Network/virtualNetworks/subnets@2020-08-01' existing = {
 parent: vnet
 name: 'master'
}

// create required identities

resource cloudControllerManager 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'cloud-controller-manager'
   ___location: ___location
}

resource ingress 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'ingress'
   ___location: ___location
}

resource machineApi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'machine-api'
   ___location: ___location
}

resource diskCsiDriver 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'disk-csi-driver'
   ___location: ___location
}

resource cloudNetworkConfig 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'cloud-network-config'
   ___location: ___location
}

resource imageRegistry 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'image-registry'
   ___location: ___location
}

resource fileCsiDriver 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'file-csi-driver'
   ___location: ___location
}

resource aroOperator 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'aro-operator'
   ___location: ___location
}

resource clusterMsi 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
   name: 'cluster'
   ___location: ___location
}

// create required role assignments on vnet / subnets

resource cloudControllerManagerMasterSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(masterSubnet.id, 'cloud-controller-manager')
   scope: masterSubnet
   properties: {
       principalId: cloudControllerManager.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a1f96423-95ce-4224-ab27-4e3dc72facd4')
       principalType: 'ServicePrincipal'
   }
}

resource cloudControllerManagerWorkerSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
 name: guid(workerSubnet.id, 'cloud-controller-manager')
 scope: workerSubnet
 properties: {
     principalId: cloudControllerManager.properties.principalId
     roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a1f96423-95ce-4224-ab27-4e3dc72facd4')
     principalType: 'ServicePrincipal'
 }
}

resource ingressMasterSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(masterSubnet.id, 'ingress')
   scope: masterSubnet
   properties: {
       principalId: ingress.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0336e1d3-7a87-462b-b6db-342b63f7802c')
       principalType: 'ServicePrincipal'
   }
}

resource ingressWorkerSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
 name: guid(workerSubnet.id, 'ingress')
 scope: workerSubnet
 properties: {
     principalId: ingress.properties.principalId
     roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0336e1d3-7a87-462b-b6db-342b63f7802c')
     principalType: 'ServicePrincipal'
 }
}

resource machineApiMasterSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(masterSubnet.id, 'machine-api')
   scope: masterSubnet
   properties: {
       principalId: machineApi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0358943c-7e01-48ba-8889-02cc51d78637')
       principalType: 'ServicePrincipal'
   }
}

resource machineApiWorkerSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(workerSubnet.id, 'machine-api')
   scope: workerSubnet
   properties: {
       principalId: machineApi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0358943c-7e01-48ba-8889-02cc51d78637')
       principalType: 'ServicePrincipal'
   }
}

resource cloudNetworkConfigVnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(vnet.id, 'cloud-network-config')
   scope: vnet
   properties: {
       principalId: cloudNetworkConfig.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'be7a6435-15ae-4171-8f30-4a343eff9e8f')
       principalType: 'ServicePrincipal'
   }
}

resource fileCsiDriverMasterSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(masterSubnet.id, 'file-csi-driver')
   scope: masterSubnet
   properties: {
       principalId: fileCsiDriver.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0d7aedc0-15fd-4a67-a412-efad370c947e')
       principalType: 'ServicePrincipal'
   }
}

resource fileCsiDriverWorkerSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
 name: guid(workerSubnet.id, 'file-csi-driver')
 scope: workerSubnet
 properties: {
     principalId: fileCsiDriver.properties.principalId
     roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0d7aedc0-15fd-4a67-a412-efad370c947e')
     principalType: 'ServicePrincipal'
 }
}

resource aroOperatorMasterSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(masterSubnet.id, 'aro-operator')
   scope: masterSubnet
   properties: {
       principalId: aroOperator.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4436bae4-7702-4c84-919b-c4069ff25ee2')
       principalType: 'ServicePrincipal'
   }
}

resource aroOperatorWorkerSubnetRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
 name: guid(workerSubnet.id, 'aro-operator')
 scope: workerSubnet
 properties: {
     principalId: aroOperator.properties.principalId
     roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4436bae4-7702-4c84-919b-c4069ff25ee2')
     principalType: 'ServicePrincipal'
 }
}

// create required role assignments on cluster MSI

resource clusterMsiRoleAssignmentCloudControllerManager 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(cloudControllerManager.id, 'cluster')
   scope: cloudControllerManager
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentIngress 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(ingress.id, 'cluster')
   scope: ingress
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentMachineApi 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(machineApi.id, 'cluster')
   scope: machineApi
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentDiskCsiDriver 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(diskCsiDriver.id, 'cluster')
   scope: diskCsiDriver
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentCloudNetworkConfig 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(cloudNetworkConfig.id, 'cluster')
   scope: cloudNetworkConfig
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentCloudImageRegistry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(imageRegistry.id, 'cluster')
   scope: imageRegistry
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentCloudFileCsiDriver 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(fileCsiDriver.id, 'cluster')
   scope: fileCsiDriver
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

resource clusterMsiRoleAssignmentCloudAroOperator 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(aroOperator.id, 'cluster')
   scope: aroOperator
   properties: {
       principalId: clusterMsi.properties.principalId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ef318e2a-8334-4a05-9e4a-295a196c6a6e')
       principalType: 'ServicePrincipal'
   }
}

// create first party role assignment over the vnet

resource fpspRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
   name: guid(vnet.id, rpObjectId)
   scope: vnet
   properties: {
       principalId: rpObjectId
       roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')
       principalType: 'ServicePrincipal'
   }
}

// create cluster

resource cluster 'Microsoft.RedHatOpenShift/openShiftClusters@2024-08-12-preview' = {
   name: clusterName
   ___location: ___location
   properties: {
       clusterProfile: {
           ___domain: ___domain
           #disable-next-line use-resource-id-functions
           resourceGroupId: resourceGroupId
           version: version
           fipsValidatedModules: fips
           pullSecret: pullSecret
       }
       networkProfile: {podCidr: podCidr, serviceCidr: serviceCidr}
       masterProfile: {
           vmSize: masterVmSize
           subnetId: masterSubnetId
           encryptionAtHost: masterEncryptionAtHost
       }
       workerProfiles: [{
           name: 'worker'
           count: 3
           diskSizeGB: workerVmDiskSize
           vmSize: workerVmSize
           subnetId: workerSubnetId
           encryptionAtHost: workerEncryptionAtHost
       }]
       apiserverProfile: {visibility: apiServerVisibility}
       ingressProfiles: [{name: 'default', visibility: ingressVisibility}]
       platformWorkloadIdentityProfile: {
           platformWorkloadIdentities: {
               'cloud-controller-manager': {resourceId: cloudControllerManager.id}
               ingress: {resourceId: ingress.id}
               'machine-api': {resourceId: machineApi.id}
               'disk-csi-driver': {resourceId: diskCsiDriver.id}
               'cloud-network-config': {resourceId: cloudNetworkConfig.id}
               'image-registry': {resourceId: imageRegistry.id}
               'file-csi-driver': {resourceId: fileCsiDriver.id}
               'aro-operator': {resourceId: aroOperator.id}
           }
       }
   }
   identity: {
       type: 'UserAssigned'
       userAssignedIdentities: {
           '${clusterMsi.id}': {}
       }
   }
}

清除

若要删除托管标识群集,请运行以下命令:

az aro delete -n $CLUSTER -g $RESOURCEGROUP

请注意,此删除命令不会清理在安装过程中创建的群集分配的托管标识。 需要手动删除标识和角色分配。