第 5 章 管理托管的 control plane
5.1. 在 AWS 上管理托管的 control plane
当您为 Amazon Web Services (AWS) 上的 OpenShift Container Platform 使用托管的 control plane 时,基础架构要求会因设置而异。
5.1.1. 管理 AWS 基础架构和 IAM 权限的先决条件
要在 Amazon Web Services (AWS) 上为 OpenShift Container Platform 配置托管的 control plane,您必须满足以下要求:
- 在创建托管集群前,配置了托管的 control plane。
- 您创建了 AWS Identity and Access Management (IAM) 角色和 AWS 安全令牌服务(STS) 凭证。
5.1.1.1. AWS 的基础架构要求
当您在 Amazon Web Services (AWS) 上使用托管的 control plane 时,基础架构要求适合以下类别:
- 任意 AWS 帐户中的 HyperShift Operator 的 Prerequired 和 unmanaged 基础架构
- 托管集群 AWS 帐户中的 Prerequired 和 unmanaged 基础架构
- 在管理 AWS 帐户中托管 control planes 管理的基础架构
- 在托管集群 AWS 帐户中托管 control plane 管理的基础架构
- 托管集群 AWS 帐户中的 Kubernetes 管理基础架构
Prerequired 表示托管 control plane 需要 AWS 基础架构才能正常工作。Unmanaged 意味着没有 Operator 或控制器为您创建基础架构。
5.1.1.2. AWS 帐户中的 HyperShift Operator 的非受管基础架构
任意 Amazon Web Services (AWS) 帐户取决于托管的 control plane 服务的供应商。
在自我管理的托管 control plane 中,集群服务提供商控制 AWS 帐户。集群服务提供商是托管集群 control plane 并负责运行时间的管理员。在托管的 control plane 中,AWS 帐户属于红帽。
在 HyperShift Operator 的预必需和非受管基础架构中,为管理集群 AWS 帐户应用以下基础架构要求:
一个 S3 存储桶
- OpenID Connect(OIDC)
路由 53 托管区域
- 托管集群的私有和公共条目的域
5.1.1.3. 管理 AWS 帐户的非受管基础架构要求
当您的基础架构在托管集群 Amazon Web Services (AWS) 帐户中预必需且非受管时,所有访问模式的基础架构要求如下:
- 一个 VPC
- 一个 DHCP 选项
两个子网
- 作为内部数据平面子网的专用子网
- 允许从数据平面访问互联网的公共子网
- 一个互联网网关
- 一个弹性 IP
- 一个 NAT 网关
- 一个安全组 (worker 节点)
- 两个路由表(一个私有和一个公共)
- 两个 Route 53 托管区
以下项目有足够的配额:
- 公共托管集群的一个 Ingress 服务负载均衡器
- 私有托管集群的一个私有链接端点
要使私有链接网络正常工作,托管集群 AWS 帐户中的端点区必须与管理集群 AWS 帐户中的服务端点解析的实例区匹配。在 AWS 中,区域名称是别名,如 us-east-2b,它不一定映射到不同帐户中的同一区域。因此,要使私有链接正常工作,管理集群在其区域的所有区域中都有子网或 worker。
5.1.1.4. 管理 AWS 帐户的基础架构要求
当您的基础架构由管理 AWS 帐户中的托管 control plane 管理时,基础架构要求会因集群是公共、私有还是组合而异。
对于具有公共集群的帐户,基础架构要求如下:
网络负载均衡器:负载均衡器 Kube API 服务器
- Kubernetes 创建一个安全组
卷
- 对于 etcd (根据是否为高可用性,一个或三个)
- 对于 OVN-Kube
对于带有私有集群的帐户,基础架构要求如下:
- 网络负载均衡器:负载均衡器私有路由器
- 端点服务(专用链接)
对于具有公共和私有集群的帐户,基础架构要求如下:
- 网络负载均衡器:负载均衡器公共路由器
- 网络负载均衡器:负载均衡器私有路由器
- 端点服务(专用链接)
卷
- 对于 etcd (根据是否为高可用性,一个或三个)
- 对于 OVN-Kube
5.1.1.5. 托管集群中的 AWS 帐户的基础架构要求
当您的基础架构由托管集群 Amazon Web Services (AWS) 帐户中托管的 control plane 管理时,基础架构要求会根据集群是公共、私有还是组合而有所不同。
对于具有公共集群的帐户,基础架构要求如下:
-
节点池必须具有定义
Role
和RolePolicy
的 EC2 实例。
对于带有私有集群的帐户,基础架构要求如下:
- 每个可用区有一个私有链接端点
- 节点池的 EC2 实例
对于具有公共和私有集群的帐户,基础架构要求如下:
- 每个可用区有一个私有链接端点
- 节点池的 EC2 实例
5.1.1.6. 托管集群 AWS 帐户中的 Kubernetes 管理基础架构
当 Kubernetes 在托管集群 Amazon Web Services (AWS) 帐户中管理您的基础架构时,基础架构要求如下:
- 默认入口的网络负载均衡器
- registry 的 S3 存储桶
5.1.2. Identity and Access Management (IAM) 权限
在托管 control plane 的上下文中,使用者负责创建 Amazon 资源名称 (ARN) 角色。consumer 是生成权限文件的自动化过程。消费者可以是 CLI 或 OpenShift Cluster Manager。托管 control plane 可以达到最低特权组件的原则,这意味着每个组件都使用自己的角色来运行或创建 Amazon Web Services (AWS) 对象,角色仅限于产品正常工作所需的内容。
托管的集群接收 ARN 角色作为输入,消费者为每个组件创建一个 AWS 权限配置。因此,组件可以通过 STS 和预配置的 OIDC IDP 进行身份验证。
以下角色由 control plane 上运行的托管 control plane 中的一些组件使用,并在数据平面上运行:
-
controlPlaneOperatorARN
-
imageRegistryARN
-
ingressARN
-
kubeCloudControllerARN
-
nodePoolManagementARN
-
storageARN
-
networkARN
以下示例显示了对托管集群的 IAM 角色的引用:
... endpointAccess: Public region: us-east-2 resourceTags: - key: kubernetes.io/cluster/example-cluster-bz4j5 value: owned rolesRef: controlPlaneOperatorARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-control-plane-operator imageRegistryARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-openshift-image-registry ingressARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-openshift-ingress kubeCloudControllerARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-cloud-controller networkARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-cloud-network-config-controller nodePoolManagementARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-node-pool storageARN: arn:aws:iam::820196288204:role/example-cluster-bz4j5-aws-ebs-csi-driver-controller type: AWS ...
以下示例中显示了托管 control plane 使用的角色:
ingressARN
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "elasticloadbalancing:DescribeLoadBalancers", "tag:GetResources", "route53:ListHostedZones" ], "Resource": "\*" }, { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets" ], "Resource": [ "arn:aws:route53:::PUBLIC_ZONE_ID", "arn:aws:route53:::PRIVATE_ZONE_ID" ] } ] }
imageRegistryARN
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:DeleteBucket", "s3:PutBucketTagging", "s3:GetBucketTagging", "s3:PutBucketPublicAccessBlock", "s3:GetBucketPublicAccessBlock", "s3:PutEncryptionConfiguration", "s3:GetEncryptionConfiguration", "s3:PutLifecycleConfiguration", "s3:GetLifecycleConfiguration", "s3:GetBucketLocation", "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucketMultipartUploads", "s3:AbortMultipartUpload", "s3:ListMultipartUploadParts" ], "Resource": "\*" } ] }
storageARN
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:AttachVolume", "ec2:CreateSnapshot", "ec2:CreateTags", "ec2:CreateVolume", "ec2:DeleteSnapshot", "ec2:DeleteTags", "ec2:DeleteVolume", "ec2:DescribeInstances", "ec2:DescribeSnapshots", "ec2:DescribeTags", "ec2:DescribeVolumes", "ec2:DescribeVolumesModifications", "ec2:DetachVolume", "ec2:ModifyVolume" ], "Resource": "\*" } ] }
networkARN
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:DescribeInstanceStatus", "ec2:DescribeInstanceTypes", "ec2:UnassignPrivateIpAddresses", "ec2:AssignPrivateIpAddresses", "ec2:UnassignIpv6Addresses", "ec2:AssignIpv6Addresses", "ec2:DescribeSubnets", "ec2:DescribeNetworkInterfaces" ], "Resource": "\*" } ] }
kubeCloudControllerARN
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "ec2:DescribeInstances", "ec2:DescribeImages", "ec2:DescribeRegions", "ec2:DescribeRouteTables", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVolumes", "ec2:CreateSecurityGroup", "ec2:CreateTags", "ec2:CreateVolume", "ec2:ModifyInstanceAttribute", "ec2:ModifyVolume", "ec2:AttachVolume", "ec2:AuthorizeSecurityGroupIngress", "ec2:CreateRoute", "ec2:DeleteRoute", "ec2:DeleteSecurityGroup", "ec2:DeleteVolume", "ec2:DetachVolume", "ec2:RevokeSecurityGroupIngress", "ec2:DescribeVpcs", "elasticloadbalancing:AddTags", "elasticloadbalancing:AttachLoadBalancerToSubnets", "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer", "elasticloadbalancing:CreateLoadBalancer", "elasticloadbalancing:CreateLoadBalancerPolicy", "elasticloadbalancing:CreateLoadBalancerListeners", "elasticloadbalancing:ConfigureHealthCheck", "elasticloadbalancing:DeleteLoadBalancer", "elasticloadbalancing:DeleteLoadBalancerListeners", "elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:DescribeLoadBalancerAttributes", "elasticloadbalancing:DetachLoadBalancerFromSubnets", "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:ModifyLoadBalancerAttributes", "elasticloadbalancing:RegisterInstancesWithLoadBalancer", "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer", "elasticloadbalancing:AddTags", "elasticloadbalancing:CreateListener", "elasticloadbalancing:CreateTargetGroup", "elasticloadbalancing:DeleteListener", "elasticloadbalancing:DeleteTargetGroup", "elasticloadbalancing:DescribeListeners", "elasticloadbalancing:DescribeLoadBalancerPolicies", "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DescribeTargetHealth", "elasticloadbalancing:ModifyListener", "elasticloadbalancing:ModifyTargetGroup", "elasticloadbalancing:RegisterTargets", "elasticloadbalancing:SetLoadBalancerPoliciesOfListener", "iam:CreateServiceLinkedRole", "kms:DescribeKey" ], "Resource": [ "\*" ], "Effect": "Allow" } ] }
nodePoolManagementARN
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "ec2:AllocateAddress", "ec2:AssociateRouteTable", "ec2:AttachInternetGateway", "ec2:AuthorizeSecurityGroupIngress", "ec2:CreateInternetGateway", "ec2:CreateNatGateway", "ec2:CreateRoute", "ec2:CreateRouteTable", "ec2:CreateSecurityGroup", "ec2:CreateSubnet", "ec2:CreateTags", "ec2:DeleteInternetGateway", "ec2:DeleteNatGateway", "ec2:DeleteRouteTable", "ec2:DeleteSecurityGroup", "ec2:DeleteSubnet", "ec2:DeleteTags", "ec2:DescribeAccountAttributes", "ec2:DescribeAddresses", "ec2:DescribeAvailabilityZones", "ec2:DescribeImages", "ec2:DescribeInstances", "ec2:DescribeInternetGateways", "ec2:DescribeNatGateways", "ec2:DescribeNetworkInterfaces", "ec2:DescribeNetworkInterfaceAttribute", "ec2:DescribeRouteTables", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "ec2:DescribeVpcAttribute", "ec2:DescribeVolumes", "ec2:DetachInternetGateway", "ec2:DisassociateRouteTable", "ec2:DisassociateAddress", "ec2:ModifyInstanceAttribute", "ec2:ModifyNetworkInterfaceAttribute", "ec2:ModifySubnetAttribute", "ec2:ReleaseAddress", "ec2:RevokeSecurityGroupIngress", "ec2:RunInstances", "ec2:TerminateInstances", "tag:GetResources", "ec2:CreateLaunchTemplate", "ec2:CreateLaunchTemplateVersion", "ec2:DescribeLaunchTemplates", "ec2:DescribeLaunchTemplateVersions", "ec2:DeleteLaunchTemplate", "ec2:DeleteLaunchTemplateVersions" ], "Resource": [ "\*" ], "Effect": "Allow" }, { "Condition": { "StringLike": { "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" } }, "Action": [ "iam:CreateServiceLinkedRole" ], "Resource": [ "arn:*:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing" ], "Effect": "Allow" }, { "Action": [ "iam:PassRole" ], "Resource": [ "arn:*:iam::*:role/*-worker-role" ], "Effect": "Allow" } ] }
controlPlaneOperatorARN
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:CreateVpcEndpoint", "ec2:DescribeVpcEndpoints", "ec2:ModifyVpcEndpoint", "ec2:DeleteVpcEndpoints", "ec2:CreateTags", "route53:ListHostedZones" ], "Resource": "\*" }, { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets", "route53:ListResourceRecordSets" ], "Resource": "arn:aws:route53:::%s" } ] }
5.1.3. 创建 AWS 基础架构和 IAM 资源分离
默认情况下,hcp create cluster aws
命令使用托管集群创建云基础架构并应用它。您可以单独创建云基础架构部分,以便您可以使用 hcp create cluster aws
命令只创建集群,或者在应用前呈现它进行修改。
要单独创建云基础架构部分,您需要创建 Amazon Web Services (AWS) 基础架构,创建 AWS Identity and Access (IAM) 资源并创建集群。
5.1.3.1. 单独创建 AWS 基础架构
要创建 Amazon Web Services (AWS) 基础架构,您需要为集群创建 Virtual Private Cloud (VPC) 和其他资源。您可以使用 AWS 控制台或基础架构自动化和置备工具。有关使用 AWS 控制台的说明,请参阅 AWS 文档中的创建 VPC 和其他 VPC 资源。
VPC 必须包含用于外部访问的私有和公共子网和资源,如网络地址转换(NAT)网关和互联网网关。除了 VPC 外,还需要集群入口的一个私有托管区。如果您要创建使用 PrivateLink (Private
或 PublicAndPrivate
访问模式)的集群,则需要一个额外的托管区用于 PrivateLink。
使用以下示例配置为托管集群创建 AWS 基础架构:
--- apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: clusters spec: {} status: {} --- apiVersion: v1 data: .dockerconfigjson: xxxxxxxxxxx kind: Secret metadata: creationTimestamp: null labels: hypershift.openshift.io/safe-to-delete-with-cluster: "true" name: <pull_secret_name> 1 namespace: clusters --- apiVersion: v1 data: key: xxxxxxxxxxxxxxxxx kind: Secret metadata: creationTimestamp: null labels: hypershift.openshift.io/safe-to-delete-with-cluster: "true" name: <etcd_encryption_key_name> 2 namespace: clusters type: Opaque --- apiVersion: v1 data: id_rsa: xxxxxxxxx id_rsa.pub: xxxxxxxxx kind: Secret metadata: creationTimestamp: null labels: hypershift.openshift.io/safe-to-delete-with-cluster: "true" name: <ssh-key-name> 3 namespace: clusters --- apiVersion: hypershift.openshift.io/v1beta1 kind: HostedCluster metadata: creationTimestamp: null name: <hosted_cluster_name> 4 namespace: clusters spec: autoscaling: {} configuration: {} controllerAvailabilityPolicy: SingleReplica dns: baseDomain: <dns_domain> 5 privateZoneID: xxxxxxxx publicZoneID: xxxxxxxx etcd: managed: storage: persistentVolume: size: 8Gi storageClassName: gp3-csi type: PersistentVolume managementType: Managed fips: false infraID: <infra_id> 6 issuerURL: <issuer_url> 7 networking: clusterNetwork: - cidr: 10.132.0.0/14 machineNetwork: - cidr: 10.0.0.0/16 networkType: OVNKubernetes serviceNetwork: - cidr: 172.31.0.0/16 olmCatalogPlacement: management platform: aws: cloudProviderConfig: subnet: id: <subnet_xxx> 8 vpc: <vpc_xxx> 9 zone: us-west-1b endpointAccess: Public multiArch: false region: us-west-1 rolesRef: controlPlaneOperatorARN: arn:aws:iam::820196288204:role/<infra_id>-control-plane-operator imageRegistryARN: arn:aws:iam::820196288204:role/<infra_id>-openshift-image-registry ingressARN: arn:aws:iam::820196288204:role/<infra_id>-openshift-ingress kubeCloudControllerARN: arn:aws:iam::820196288204:role/<infra_id>-cloud-controller networkARN: arn:aws:iam::820196288204:role/<infra_id>-cloud-network-config-controller nodePoolManagementARN: arn:aws:iam::820196288204:role/<infra_id>-node-pool storageARN: arn:aws:iam::820196288204:role/<infra_id>-aws-ebs-csi-driver-controller type: AWS pullSecret: name: <pull_secret_name> release: image: quay.io/openshift-release-dev/ocp-release:4.16-x86_64 secretEncryption: aescbc: activeKey: name: <etcd_encryption_key_name> type: aescbc services: - service: APIServer servicePublishingStrategy: type: LoadBalancer - service: OAuthServer servicePublishingStrategy: type: Route - service: Konnectivity servicePublishingStrategy: type: Route - service: Ignition servicePublishingStrategy: type: Route - service: OVNSbDb servicePublishingStrategy: type: Route sshKey: name: <ssh_key_name> status: controlPlaneEndpoint: host: "" port: 0 --- apiVersion: hypershift.openshift.io/v1beta1 kind: NodePool metadata: creationTimestamp: null name: <node_pool_name> 10 namespace: clusters spec: arch: amd64 clusterName: <hosted_cluster_name> management: autoRepair: true upgradeType: Replace nodeDrainTimeout: 0s platform: aws: instanceProfile: <instance_profile_name> 11 instanceType: m6i.xlarge rootVolume: size: 120 type: gp3 subnet: id: <subnet_xxx> type: AWS release: image: quay.io/openshift-release-dev/ocp-release:4.16-x86_64 replicas: 2 status: replicas: 0
- 1
- 将
<pull_secret_name>
替换为 pull secret 的名称。 - 2
- 将
<etcd_encryption_key_name>
替换为 etcd 加密密钥的名称。 - 3
- 将
<ssh_key_name>
替换为 SSH 密钥的名称。 - 4
- 将
<hosted_cluster_name>
替换为托管集群的名称。 - 5
- 将
<dns_domain>
替换为您的基本 DNS 域,如example.com
。 - 6
- 将
<infra_id>
替换为用于标识与托管集群关联的 IAM 资源的值。 - 7
- 将
<issuer_url>
替换为您的签发者 URL,其结尾是infra_id
值。例如,https://example-hosted-us-west-1.s3.us-west-1.amazonaws.com/example-hosted-infra-id
。 - 8
- 将
<subnet_xxx>
替换为您的子网 ID。私有和公共子网都需要标记。对于公共子网,使用kubernetes.io/role/elb=1
。对于私有子网,使用kubernetes.io/role/internal-elb=1
。 - 9
- 将
<vpc_xxx>
替换为您的 VPC ID。 - 10
- 将
<node_pool_name>
替换为NodePool
资源的名称。 - 11
- 将
<instance_profile_name>
替换为 AWS 实例的名称。
5.1.3.2. 创建 AWS IAM 资源
在 Amazon Web Services (AWS) 中,您必须创建以下 IAM 资源:
- IAM 中的 OpenID Connect (OIDC)身份提供程序,这是启用 STS 身份验证所必需的。
- 七个角色,它们分别用于与提供程序交互的每个组件,如 Kubernetes 控制器管理器、集群 API 供应商和 registry
- 实例配置集,这是分配给集群所有 worker 实例的配置集
5.1.3.3. 单独创建托管集群
您可以在 Amazon Web Services (AWS) 上单独创建托管集群。
要单独创建托管集群,请输入以下命令:
$ hcp create cluster aws \ --infra-id <infra_id> \1 --name <hosted_cluster_name> \2 --sts-creds <path_to_sts_credential_file> \3 --pull-secret <path_to_pull_secret> \4 --generate-ssh \5 --node-pool-replicas 3 --role-arn <role_name> 6
- 1
- 将
<infra_id>
替换为您在create infra aws
命令中指定的相同 ID。这个值标识与托管集群关联的 IAM 资源。 - 2
- 将
<hosted_cluster_name>
替换为托管集群的名称。 - 3
- 将
<path_to_sts_credential_file>
替换为您在create infra aws
命令中指定的相同名称。 - 4
- 将
<path_to_pull_secret
> 替换为包含有效 OpenShift Container Platform pull secret 的文件名称。 - 5
--generate-ssh
标志是可选的,但最好包括,它在 SSH 到您的 worker 时需要。为您生成 SSH 密钥,并作为 secret 存储在与托管集群相同的命名空间中。- 6
- 将
<role_name>
替换为 Amazon Resource Name (ARN),例如arn:aws:iam::820196288204:role/myrole
。指定 Amazon Resource Name (ARN),例如arn:aws:iam::820196288204:role/myrole
。有关 ARN 角色的更多信息,请参阅"Identity and Access Management (IAM) 权限"。
您还可以在命令中添加 --render
标志,并将输出重定向到文件,您可以在其中编辑资源,然后再将它们应用到集群。
运行命令后,以下资源将应用到集群:
- 一个命名空间
- 带有 pull secret 的 secret
-
A
HostedCluster
-
A
NodePool
- control plane 组件的三个 AWS STS secret
-
如果指定了
--generate-ssh
标志,则一个 SSH 密钥 secret。