$ mkdir $HOME/clusterconfig
在OpenShift Container Platform 4.17版本中,您可以使用您提供的基础设施和安装发行版内容的内部镜像在Amazon Web Services (AWS)上安装集群。
虽然您可以使用镜像的安装发行版内容安装OpenShift Container Platform集群,但您的集群仍然需要互联网访问才能使用AWS API。 |
创建此基础设施的一种方法是使用提供的CloudFormation模板。您可以修改模板以自定义您的基础设施,或使用其中包含的信息根据您公司的策略创建AWS对象。
执行用户预配基础设施安装的步骤仅作为示例提供。使用您提供的基础设施安装集群需要了解云提供商和OpenShift Container Platform的安装过程。提供了一些CloudFormation模板来帮助完成这些步骤或帮助建模您自己的模板。您也可以通过其他方法创建所需资源;模板只是一个示例。 |
您已查看有关OpenShift Container Platform安装和更新过程的详细信息。
您阅读了有关选择集群安装方法并为用户准备集群的文档。
您已在镜像主机上创建镜像注册表并获得了OpenShift Container Platform版本的imageContentSources
数据。
由于安装介质位于镜像主机上,您可以使用该计算机完成所有安装步骤。 |
您已配置AWS账户来托管集群。
如果您在计算机上存储了AWS配置文件,则它不能使用您在使用多因素身份验证设备时生成的临时会话令牌。集群将继续使用您当前的AWS凭据来为集群的整个生命周期创建AWS资源,因此您必须使用基于密钥的长期凭据。要生成相应的密钥,请参阅AWS文档中的管理IAM用户的访问密钥。您可以在运行安装程序时提供密钥。 |
您已下载 AWS CLI 并将其安装到您的计算机上。请参阅 AWS 文档中的使用捆绑安装程序安装 AWS CLI(Linux、macOS 或 UNIX)。
如果您使用防火墙并计划使用遥测服务,则需要配置防火墙以允许您的集群需要访问的站点。
如果您正在配置代理,请务必也检查此站点列表。 |
如果您的环境中无法访问云身份和访问管理 (IAM) API,或者您不想将管理员级凭据密钥存储在kube-system
命名空间中,您可以手动创建和维护长期凭据。
在 OpenShift Container Platform 4.17 中,您可以执行无需主动连接到互联网即可获取软件组件的安装。受限网络安装可以使用安装程序预配的基础设施或用户预配的基础设施完成,具体取决于您要安装集群的云平台。
如果您选择在云平台上执行受限网络安装,您仍然需要访问其云 API。某些云功能(例如 Amazon Web Service 的 Route 53 DNS 和 IAM 服务)需要互联网访问。根据您的网络,在裸机硬件、Nutanix 或 VMware vSphere 上安装可能需要较少的互联网访问。
要完成受限网络安装,您必须创建一个镜像 OpenShift 镜像注册表内容并包含安装介质的注册表。您可以在可以访问互联网和封闭网络的镜像主机上创建此注册表,或者使用符合您限制的其他方法。
由于用户预配安装的配置复杂,建议您在尝试使用用户预配的基础设施进行受限网络安装之前,先完成标准的用户预配基础设施安装。完成此测试安装可能会更容易隔离和排除在受限网络中安装期间可能出现的任何问题。 |
要在 Amazon Web Services (AWS) 上使用用户预配的基础设施安装 OpenShift Container Platform,您必须生成安装程序部署集群所需的、并修改这些文件,以便集群仅创建它将使用的机器。您需要生成和自定义install-config.yaml
文件、Kubernetes 清单文件和 Ignition 配置文件。您还可以选择在安装的准备阶段先设置一个单独的var
分区。
/var
分区建议将 OpenShift Container Platform 的磁盘分区留给安装程序。但是,在某些情况下,您可能希望在您预期会增长的文件系统的一部分中创建单独的分区。
OpenShift Container Platform 支持添加单个分区以将存储附加到/var
分区或/var
的子目录。例如:
/var/lib/containers
:保存与容器相关的、随着向系统添加更多镜像和容器而可能增长的内容。
/var/lib/etcd
:保存您可能出于性能优化 etcd 存储等目的而希望单独保留的数据。
/var
:保存您可能出于审计等目的而希望单独保留的数据。
单独存储/var
目录的内容使您更容易根据需要扩展这些区域的存储,并在以后重新安装 OpenShift Container Platform 并保持数据完整。使用此方法,您无需再次拉取所有容器,也不需要在更新系统时复制大量的日志文件。
由于/var
必须在 Red Hat Enterprise Linux CoreOS (RHCOS) 的全新安装之前到位,因此以下过程通过创建一个在 OpenShift Container Platform 安装的openshift-install
准备阶段插入的机器配置清单来设置单独的/var
分区。
如果您按照此过程中的步骤创建单独的 |
创建一个目录来保存 OpenShift Container Platform 安装文件
$ mkdir $HOME/clusterconfig
运行openshift-install
以在manifest
和openshift
子目录中创建一组文件。根据提示回答系统问题。
$ openshift-install create manifests --dir $HOME/clusterconfig
? SSH Public Key ...
INFO Credentials loaded from the "myprofile" profile in file "/home/myuser/.aws/credentials"
INFO Consuming Install Config from target directory
INFO Manifests created in: $HOME/clusterconfig/manifests and $HOME/clusterconfig/openshift
可选:确认安装程序在clusterconfig/openshift
目录中创建了清单。
$ ls $HOME/clusterconfig/openshift/
99_kubeadmin-password-secret.yaml
99_openshift-cluster-api_master-machines-0.yaml
99_openshift-cluster-api_master-machines-1.yaml
99_openshift-cluster-api_master-machines-2.yaml
...
创建一个 Butane 配置文件来配置附加分区。例如,将文件命名为$HOME/clusterconfig/98-var-partition.bu
,将磁盘设备名称更改为worker
系统上存储设备的名称,并根据需要设置存储大小。此示例将/var
目录放在单独的分区上。
variant: openshift
version: 4.17.0
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 98-var-partition
storage:
disks:
- device: /dev/disk/by-id/<device_name> (1)
partitions:
- label: var
start_mib: <partition_start_offset> (2)
size_mib: <partition_size> (3)
number: 5
filesystems:
- device: /dev/disk/by-partlabel/var
path: /var
format: xfs
mount_options: [defaults, prjquota] (4)
with_mount_unit: true
1 | 您要分区的磁盘的存储设备名称。 |
2 | 向引导磁盘添加数据分区时,建议最小值为 25000 MiB(兆字节)。根文件系统会自动调整大小以填充所有可用空间,直至指定的偏移量。如果未指定值,或者指定的值小于建议的最小值,则生成的根文件系统将太小,并且将来重新安装 RHCOS 可能会覆盖数据分区的开头。 |
3 | 数据分区的大小(以兆字节为单位)。 |
4 | 必须为用于容器存储的文件系统启用prjquota 挂载选项。 |
创建单独的 |
从 Butane 配置文件创建清单,并将其保存到clusterconfig/openshift
目录。例如,运行以下命令:
$ butane $HOME/clusterconfig/98-var-partition.bu -o $HOME/clusterconfig/openshift/98-var-partition.yaml
再次运行openshift-install
以从manifest
和openshift
子目录中的一组文件创建 Ignition 配置文件。
$ openshift-install create ignition-configs --dir $HOME/clusterconfig
$ ls $HOME/clusterconfig/
auth bootstrap.ign master.ign metadata.json worker.ign
现在,您可以使用 Ignition 配置文件作为安装过程的输入来安装 Red Hat Enterprise Linux CoreOS (RHCOS) 系统。
生成和自定义安装程序部署集群所需的安装配置文件。
您已获得用户预配基础设施的 OpenShift Container Platform 安装程序和集群的拉取密钥。对于受限网络安装,这些文件位于您的镜像主机上。
您已检查您是否正在将集群部署到具有 Red Hat 发布的 Red Hat Enterprise Linux CoreOS (RHCOS) AMI 的 AWS 区域。如果您正在部署到需要自定义 AMI 的 AWS 区域(例如 AWS GovCloud 区域),则必须手动创建install-config.yaml
文件。
创建install-config.yaml
文件。
更改到包含安装程序的目录,并运行以下命令:
$ ./openshift-install create install-config --dir <installation_directory> (1)
1 | 对于<installation_directory> ,请指定存储安装程序创建文件的目录名称。 |
指定一个空目录。某些安装资源(例如引导 X.509 证书)的有效期较短,因此您不能重用安装目录。如果您想重用另一个集群安装中的单个文件,可以将它们复制到您的目录中。但是,安装资源的文件名可能会在不同版本之间发生变化。从早期 OpenShift Container Platform 版本复制安装文件时,请谨慎操作。 |
在提示符下,提供云的配置详细信息。
可选:选择一个 SSH 密钥来访问您的集群机器。
对于要执行安装调试或灾难恢复的生产 OpenShift Container Platform 集群,请指定您的 |
选择 aws 作为目标平台。
如果您计算机上没有存储 AWS 配置文件,请输入您配置为运行安装程序的用户对应的 AWS 访问密钥 ID 和秘密访问密钥。
AWS 访问密钥 ID 和秘密访问密钥存储在安装主机当前用户主目录下的 |
选择要将集群部署到的 AWS 区域。
为您的集群配置的 Route 53 服务选择基本域名。
输入集群的描述性名称。
编辑 install-config.yaml
文件,以提供受限网络安装所需的附加信息。
更新 pullSecret
值,使其包含注册表的身份验证信息。
pullSecret: '{"auths":{"<local_registry>": {"auth": "<credentials>","email": "[email protected]"}}}'
对于 <local_registry>
,指定镜像注册表用于提供内容的注册表域名,以及可选的端口,例如 registry.example.com
或 registry.example.com:5000
。对于 <credentials>
,指定镜像注册表的 Base64 编码用户名和密码。
添加 additionalTrustBundle
参数和值。该值必须是您用于镜像注册表的证书文件的内容。证书文件可以是现有的受信任证书颁发机构,也可以是您为镜像注册表生成的自签名证书。
additionalTrustBundle: |
-----BEGIN CERTIFICATE-----
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
-----END CERTIFICATE-----
添加镜像内容资源。
imageContentSources:
- mirrors:
- <local_registry>/<local_repository_name>/release
source: quay.io/openshift-release-dev/ocp-release
- mirrors:
- <local_registry>/<local_repository_name>/release
source: quay.io/openshift-release-dev/ocp-v4.0-art-dev
使用命令输出中的 imageContentSources
部分来镜像存储库或您从带入受限网络的媒体中镜像内容时使用的值。
可选:将发布策略设置为 Internal
publish: Internal
通过设置此选项,您可以创建一个内部 Ingress Controller 和一个私有负载均衡器。
可选:备份 install-config.yaml
文件。
|
有关 AWS 配置文件和凭据配置的更多信息,请参阅 AWS 文档中的 配置和凭据文件设置。
生产环境可能会拒绝直接访问互联网,而是提供 HTTP 或 HTTPS 代理。您可以通过在 install-config.yaml
文件中配置代理设置来配置新的 OpenShift Container Platform 集群以使用代理。
您拥有一个现有的 install-config.yaml
文件。
您已查看集群需要访问的站点,并确定其中任何站点是否需要绕过代理。默认情况下,所有集群出站流量都会被代理,包括对托管云提供商 API 的调用。如果需要,您可以将站点添加到 Proxy
对象的 spec.noProxy
字段以绕过代理。
对于 Amazon Web Services (AWS)、Google Cloud Platform (GCP)、Microsoft Azure 和 Red Hat OpenStack Platform (RHOSP) 上的安装, |
编辑您的 install-config.yaml
文件并添加代理设置。例如:
apiVersion: v1
baseDomain: my.domain.com
proxy:
httpProxy: http://<username>:<pswd>@<ip>:<port> (1)
httpsProxy: https://<username>:<pswd>@<ip>:<port> (2)
noProxy: ec2.<aws_region>.amazonaws.com,elasticloadbalancing.<aws_region>.amazonaws.com,s3.<aws_region>.amazonaws.com (3)
additionalTrustBundle: | (4)
-----BEGIN CERTIFICATE-----
<MY_TRUSTED_CA_CERT>
-----END CERTIFICATE-----
additionalTrustBundlePolicy: <policy_to_add_additionalTrustBundle> (5)
1 | 用于创建集群外部 HTTP 连接的代理 URL。URL 方案必须为 http 。 |
2 | 用于创建集群外部 HTTPS 连接的代理 URL。 |
3 | 要从代理中排除的目标域名、IP 地址或其他网络 CIDR 的逗号分隔列表。在域名前面加上 . 以仅匹配子域名。例如,.y.com 匹配 x.y.com ,但不匹配 y.com 。使用 * 可以绕过所有目标的代理。如果您已将 Amazon EC2 、Elastic Load Balancing 和 S3 VPC 端点添加到您的 VPC,则必须将这些端点添加到 noProxy 字段。 |
4 | 如果提供,安装程序将生成一个名为 user-ca-bundle 的 config map(位于 openshift-config 命名空间中),其中包含代理 HTTPS 连接所需的一个或多个附加 CA 证书。然后,集群网络操作员将创建一个 trusted-ca-bundle config map,并将这些内容与 Red Hat Enterprise Linux CoreOS (RHCOS) 信任捆绑包合并,此 config map 在 Proxy 对象的 trustedCA 字段中引用。除非代理的身份证书由 RHCOS 信任捆绑包中的机构签名,否则需要 additionalTrustBundle 字段。 |
5 | 可选:确定 Proxy 对象的配置策略,以在 trustedCA 字段中引用 user-ca-bundle config map。允许的值为 Proxyonly 和 Always 。使用 Proxyonly 仅在配置 http/https 代理时引用 user-ca-bundle config map。使用 Always 始终引用 user-ca-bundle config map。默认值为 Proxyonly 。 |
安装程序不支持代理 |
如果安装程序超时,请重新启动,然后使用安装程序的
|
保存文件并在安装 OpenShift Container Platform 时引用它。
安装程序将创建一个名为 cluster
的集群范围代理,该代理使用提供的 install-config.yaml
文件中的代理设置。如果没有提供代理设置,仍然会创建 cluster
Proxy
对象,但它将具有 nil spec
。
仅支持名为 |
由于您必须修改一些集群定义文件并手动启动集群机器,因此您必须生成集群配置机器所需的 Kubernetes 清单文件和 Ignition 配置文件。
安装配置文件转换为 Kubernetes 清单文件。清单文件打包到 Ignition 配置文件中,这些文件随后用于配置集群机器。
|
您已获得 OpenShift Container Platform 安装程序。对于受限网络安装,这些文件位于您的镜像主机上。
您已创建 install-config.yaml
安装配置文件。
切换到包含 OpenShift Container Platform 安装程序的目录,并为集群生成 Kubernetes 清单文件。
$ ./openshift-install create manifests --dir <installation_directory> (1)
1 | 对于 <安装目录> ,请指定包含您创建的 install-config.yaml 文件的安装目录。 |
删除定义控制平面机器的 Kubernetes 清单文件。
$ rm -f <installation_directory>/openshift/99_openshift-cluster-api_master-machines-*.yaml
通过删除这些文件,您可以阻止集群自动生成控制平面机器。
删除定义控制平面机器集的 Kubernetes 清单文件。
$ rm -f <installation_directory>/openshift/99_openshift-machine-api_master-control-plane-machine-set.yaml
删除定义工作机器的 Kubernetes 清单文件。
$ rm -f <installation_directory>/openshift/99_openshift-cluster-api_worker-machineset-*.yaml
如果您在用户预配的基础架构上安装集群时禁用了 |
由于您自己创建和管理工作机器,因此您无需初始化这些机器。
检查 <安装目录>/manifests/cluster-scheduler-02-config.yml
Kubernetes 清单文件中 mastersSchedulable
参数是否设置为 false
。此设置可防止将 Pod 调度到控制平面机器上。
打开 <安装目录>/manifests/cluster-scheduler-02-config.yml
文件。
找到 mastersSchedulable
参数并确保将其设置为 false
。
保存并退出文件。
可选:如果您不希望 Ingress Operator 代表您创建 DNS 记录,请从 <安装目录>/manifests/cluster-dns-02-config.yml
DNS 配置文件中删除 privateZone
和 publicZone
部分。
apiVersion: config.openshift.io/v1
kind: DNS
metadata:
creationTimestamp: null
name: cluster
spec:
baseDomain: example.openshift.com
privateZone: (1)
id: mycluster-100419-private-zone
publicZone: (1)
id: example.openshift.com
status: {}
1 | 完全删除此部分。 |
如果您这样做,您必须在后面的步骤中手动添加 Ingress DNS 记录。
要创建 Ignition 配置文件,请从包含安装程序的目录运行以下命令。
$ ./openshift-install create ignition-configs --dir <installation_directory> (1)
1 | 对于 <安装目录> ,请指定相同的安装目录。 |
在安装目录中为引导程序、控制平面和计算节点创建 Ignition 配置文件。kubeadmin-password
和 kubeconfig
文件创建在 ./<安装目录>/auth
目录中。
. ├── auth │ ├── kubeadmin-password │ └── kubeconfig ├── bootstrap.ign ├── master.ign ├── metadata.json └── worker.ign
Ignition 配置文件包含一个唯一的集群标识符,您可以使用它来唯一标识您在 Amazon Web Services (AWS) 中的集群。基础架构名称还用于在 OpenShift Container Platform 安装期间查找相应的 AWS 资源。提供的 CloudFormation 模板包含对此基础架构名称的引用,因此您必须提取它。
您已获得 OpenShift Container Platform 安装程序和集群的拉取密钥。
您已为您的集群生成 Ignition 配置文件。
您已安装 jq
包。
要从 Ignition 配置文件元数据中提取并查看基础架构名称,请运行以下命令。
$ jq -r .infraID <installation_directory>/metadata.json (1)
1 | 对于 <安装目录> ,请指定您存储安装文件的目录的路径。 |
openshift-vw9j6 (1)
1 | 此命令的输出是您的集群名称和一个随机字符串。 |
您必须在 Amazon Web Services (AWS) 中创建一个虚拟私有云 (VPC),供您的 OpenShift Container Platform 集群使用。您可以自定义 VPC 以满足您的要求,包括 VPN 和路由表。
您可以使用提供的 CloudFormation 模板和自定义参数文件来创建代表 VPC 的 AWS 资源堆栈。
如果您不使用提供的 CloudFormation 模板创建您的 AWS 基础架构,则必须查看提供的信息并手动创建基础架构。如果您的集群未正确初始化,您可能必须联系 Red Hat 支持人员并提供您的安装日志。 |
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
创建一个 JSON 文件,其中包含模板所需的参数值。
[
{
"ParameterKey": "VpcCidr", (1)
"ParameterValue": "10.0.0.0/16" (2)
},
{
"ParameterKey": "AvailabilityZoneCount", (3)
"ParameterValue": "1" (4)
},
{
"ParameterKey": "SubnetBits", (5)
"ParameterValue": "12" (6)
}
]
1 | VPC 的 CIDR 块。 |
2 | 以 x.x.x.x/16-24 格式指定 CIDR 块。 |
3 | 在其中部署 VPC 的可用区数量。 |
4 | 指定 1 到 3 之间的整数。 |
5 | 每个可用区中每个子网的大小。 |
6 | 指定 5 到 13 之间的整数,其中 5 是 /27 ,13 是 /19 。 |
从本主题的“VPC 的 CloudFormation 模板”部分复制模板,并将其另存为计算机上的 YAML 文件。此模板描述了集群所需的 VPC。
启动 CloudFormation 模板以创建代表 VPC 的 AWS 资源堆栈。
您必须在一行中输入命令。 |
$ aws cloudformation create-stack --stack-name <name> (1)
--template-body file://<template>.yaml (2)
--parameters file://<parameters>.json (3)
1 | <名称> 是 CloudFormation 堆栈的名称,例如 cluster-vpc 。如果您删除集群,则需要此堆栈的名称。 |
2 | <模板> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。 |
3 | <参数> 是 CloudFormation 参数 JSON 文件的相对路径和名称。 |
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-vpc/dbedae40-2fd3-11eb-820e-12a48460849f
确认模板组件存在。
$ aws cloudformation describe-stacks --stack-name <name>
StackStatus
显示 CREATE_COMPLETE
后,输出将显示以下参数的值。您必须将这些参数值提供给您运行以创建集群的其他 CloudFormation 模板。
VpcId
|
您的 VPC 的 ID。 |
PublicSubnetIds
|
新公共子网的 ID。 |
PrivateSubnetIds
|
新私有子网的 ID。 |
您可以使用以下 CloudFormation 模板部署 OpenShift Container Platform 集群所需的 VPC。
AWSTemplateFormatVersion: 2010-09-09
Description: Template for Best Practice VPC with 1-3 AZs
Parameters:
VpcCidr:
AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-4]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-24.
Default: 10.0.0.0/16
Description: CIDR block for VPC.
Type: String
AvailabilityZoneCount:
ConstraintDescription: "The number of availability zones. (Min: 1, Max: 3)"
MinValue: 1
MaxValue: 3
Default: 1
Description: "How many AZs to create VPC subnets for. (Min: 1, Max: 3)"
Type: Number
SubnetBits:
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/19-27.
MinValue: 5
MaxValue: 13
Default: 12
Description: "Size of each subnet to create within the availability zones. (Min: 5 = /27, Max: 13 = /19)"
Type: Number
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Network Configuration"
Parameters:
- VpcCidr
- SubnetBits
- Label:
default: "Availability Zones"
Parameters:
- AvailabilityZoneCount
ParameterLabels:
AvailabilityZoneCount:
default: "Availability Zone Count"
VpcCidr:
default: "VPC CIDR"
SubnetBits:
default: "Bits Per Subnet"
Conditions:
DoAz3: !Equals [3, !Ref AvailabilityZoneCount]
DoAz2: !Or [!Equals [2, !Ref AvailabilityZoneCount], Condition: DoAz3]
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
CidrBlock: !Ref VpcCidr
PublicSubnet:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [0, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]]
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref "AWS::Region"
PublicSubnet2:
Type: "AWS::EC2::Subnet"
Condition: DoAz2
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]]
AvailabilityZone: !Select
- 1
- Fn::GetAZs: !Ref "AWS::Region"
PublicSubnet3:
Type: "AWS::EC2::Subnet"
Condition: DoAz3
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [2, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]]
AvailabilityZone: !Select
- 2
- Fn::GetAZs: !Ref "AWS::Region"
InternetGateway:
Type: "AWS::EC2::InternetGateway"
GatewayToInternet:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
PublicRoute:
Type: "AWS::EC2::Route"
DependsOn: GatewayToInternet
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
PublicSubnetRouteTableAssociation2:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: DoAz2
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
PublicSubnetRouteTableAssociation3:
Condition: DoAz3
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PublicSubnet3
RouteTableId: !Ref PublicRouteTable
PrivateSubnet:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [3, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]]
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref "AWS::Region"
PrivateRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref VPC
PrivateSubnetRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
NAT:
DependsOn:
- GatewayToInternet
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId:
"Fn::GetAtt":
- EIP
- AllocationId
SubnetId: !Ref PublicSubnet
EIP:
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
Route:
Type: "AWS::EC2::Route"
Properties:
RouteTableId:
Ref: PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NAT
PrivateSubnet2:
Type: "AWS::EC2::Subnet"
Condition: DoAz2
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [4, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]]
AvailabilityZone: !Select
- 1
- Fn::GetAZs: !Ref "AWS::Region"
PrivateRouteTable2:
Type: "AWS::EC2::RouteTable"
Condition: DoAz2
Properties:
VpcId: !Ref VPC
PrivateSubnetRouteTableAssociation2:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: DoAz2
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable2
NAT2:
DependsOn:
- GatewayToInternet
Type: "AWS::EC2::NatGateway"
Condition: DoAz2
Properties:
AllocationId:
"Fn::GetAtt":
- EIP2
- AllocationId
SubnetId: !Ref PublicSubnet2
EIP2:
Type: "AWS::EC2::EIP"
Condition: DoAz2
Properties:
Domain: vpc
Route2:
Type: "AWS::EC2::Route"
Condition: DoAz2
Properties:
RouteTableId:
Ref: PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NAT2
PrivateSubnet3:
Type: "AWS::EC2::Subnet"
Condition: DoAz3
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [5, !Cidr [!Ref VpcCidr, 6, !Ref SubnetBits]]
AvailabilityZone: !Select
- 2
- Fn::GetAZs: !Ref "AWS::Region"
PrivateRouteTable3:
Type: "AWS::EC2::RouteTable"
Condition: DoAz3
Properties:
VpcId: !Ref VPC
PrivateSubnetRouteTableAssociation3:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: DoAz3
Properties:
SubnetId: !Ref PrivateSubnet3
RouteTableId: !Ref PrivateRouteTable3
NAT3:
DependsOn:
- GatewayToInternet
Type: "AWS::EC2::NatGateway"
Condition: DoAz3
Properties:
AllocationId:
"Fn::GetAtt":
- EIP3
- AllocationId
SubnetId: !Ref PublicSubnet3
EIP3:
Type: "AWS::EC2::EIP"
Condition: DoAz3
Properties:
Domain: vpc
Route3:
Type: "AWS::EC2::Route"
Condition: DoAz3
Properties:
RouteTableId:
Ref: PrivateRouteTable3
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NAT3
S3Endpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal: '*'
Action:
- '*'
Resource:
- '*'
RouteTableIds:
- !Ref PublicRouteTable
- !Ref PrivateRouteTable
- !If [DoAz2, !Ref PrivateRouteTable2, !Ref "AWS::NoValue"]
- !If [DoAz3, !Ref PrivateRouteTable3, !Ref "AWS::NoValue"]
ServiceName: !Join
- ''
- - com.amazonaws.
- !Ref 'AWS::Region'
- .s3
VpcId: !Ref VPC
Outputs:
VpcId:
Description: ID of the new VPC.
Value: !Ref VPC
PublicSubnetIds:
Description: Subnet IDs of the public subnets.
Value:
!Join [
",",
[!Ref PublicSubnet, !If [DoAz2, !Ref PublicSubnet2, !Ref "AWS::NoValue"], !If [DoAz3, !Ref PublicSubnet3, !Ref "AWS::NoValue"]]
]
PrivateSubnetIds:
Description: Subnet IDs of the private subnets.
Value:
!Join [
",",
[!Ref PrivateSubnet, !If [DoAz2, !Ref PrivateSubnet2, !Ref "AWS::NoValue"], !If [DoAz3, !Ref PrivateSubnet3, !Ref "AWS::NoValue"]]
]
PublicRouteTableId:
Description: Public Route table ID
Value: !Ref PublicRouteTable
PrivateRouteTableIds:
Description: Private Route table IDs
Value:
!Join [
",",
[
!Join ["=", [
!Select [0, "Fn::GetAZs": !Ref "AWS::Region"],
!Ref PrivateRouteTable
]],
!If [DoAz2,
!Join ["=", [!Select [1, "Fn::GetAZs": !Ref "AWS::Region"], !Ref PrivateRouteTable2]],
!Ref "AWS::NoValue"
],
!If [DoAz3,
!Join ["=", [!Select [2, "Fn::GetAZs": !Ref "AWS::Region"], !Ref PrivateRouteTable3]],
!Ref "AWS::NoValue"
]
]
]
您必须在 Amazon Web Services (AWS) 中配置网络和经典或网络负载均衡,以便您的 OpenShift Container Platform 集群可以使用。
您可以使用提供的 CloudFormation 模板和自定义参数文件来创建 AWS 资源堆栈。该堆栈代表 OpenShift Container Platform 集群所需的网络和负载均衡组件。该模板还创建托管区域和子网标签。
您可以在单个虚拟私有云 (VPC) 中多次运行模板。
如果您不使用提供的 CloudFormation 模板创建您的 AWS 基础架构,则必须查看提供的信息并手动创建基础架构。如果您的集群未正确初始化,您可能必须联系 Red Hat 支持人员并提供您的安装日志。 |
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
您已在 AWS 中创建和配置了 VPC 和关联的子网。
获取您在集群的 install-config.yaml
文件中指定的 Route 53 基本域的托管区域 ID。您可以通过运行以下命令获取有关托管区域的详细信息。
$ aws route53 list-hosted-zones-by-name --dns-name <route53_domain> (1)
1 | 对于<route53_domain> ,请指定在生成集群的install-config.yaml 文件时使用的 Route 53 基础域名。 |
mycluster.example.com. False 100
HOSTEDZONES 65F8F38E-2268-B835-E15C-AB55336FCBFA /hostedzone/Z21IXYZABCZ2A4 mycluster.example.com. 10
在示例输出中,托管区域 ID 为Z21IXYZABCZ2A4
。
创建一个 JSON 文件,其中包含模板所需的参数值。
[
{
"ParameterKey": "ClusterName", (1)
"ParameterValue": "mycluster" (2)
},
{
"ParameterKey": "InfrastructureName", (3)
"ParameterValue": "mycluster-<random_string>" (4)
},
{
"ParameterKey": "HostedZoneId", (5)
"ParameterValue": "<random_string>" (6)
},
{
"ParameterKey": "HostedZoneName", (7)
"ParameterValue": "example.com" (8)
},
{
"ParameterKey": "PublicSubnets", (9)
"ParameterValue": "subnet-<random_string>" (10)
},
{
"ParameterKey": "PrivateSubnets", (11)
"ParameterValue": "subnet-<random_string>" (12)
},
{
"ParameterKey": "VpcId", (13)
"ParameterValue": "vpc-<random_string>" (14)
}
]
1 | 一个简短的、具有代表性的集群名称,用于主机名等。 |
2 | 指定在生成集群的install-config.yaml 文件时使用的集群名称。 |
3 | 集群的 Ignition 配置文件中编码的集群基础设施名称。 |
4 | 指定从 Ignition 配置文件元数据中提取的基础设施名称,其格式为<cluster-name>-<random-string> 。 |
5 | 用于注册目标的 Route 53 公共区域 ID。 |
6 | 指定 Route 53 公共区域 ID,其格式类似于Z21IXYZABCZ2A4 。您可以从 AWS 控制台获取此值。 |
7 | 用于注册目标的 Route 53 区域。 |
8 | 指定在生成集群的install-config.yaml 文件时使用的 Route 53 基础域名。请勿包含 AWS 控制台中显示的尾随句点(.)。 |
9 | 为您的 VPC 创建的公共子网。 |
10 | 指定 VPC 的 CloudFormation 模板输出中的PublicSubnetIds 值。 |
11 | 为您的 VPC 创建的私有子网。 |
12 | 指定 VPC 的 CloudFormation 模板输出中的PrivateSubnetIds 值。 |
13 | 为集群创建的 VPC。 |
14 | 指定 VPC 的 CloudFormation 模板输出中的VpcId 值。 |
复制本主题“网络和负载均衡器的 CloudFormation 模板”部分中的模板,并将其另存为计算机上的 YAML 文件。此模板描述了集群所需的网络和负载均衡对象。
如果将集群部署到 AWS 政府或秘密区域,则必须更新 CloudFormation 模板中的 |
启动 CloudFormation 模板以创建提供网络和负载均衡组件的 AWS 资源堆栈。
您必须在一行中输入命令。 |
$ aws cloudformation create-stack --stack-name <name> (1)
--template-body file://<template>.yaml (2)
--parameters file://<parameters>.json (3)
--capabilities CAPABILITY_NAMED_IAM (4)
1 | <name> 是 CloudFormation 堆栈的名称,例如cluster-dns 。如果删除集群,则需要此堆栈的名称。 |
2 | <模板> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。 |
3 | <参数> 是 CloudFormation 参数 JSON 文件的相对路径和名称。 |
4 | 必须显式声明CAPABILITY_NAMED_IAM 功能,因为提供的模板会创建一些AWS::IAM::Role 资源。 |
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-dns/cd3e5de0-2fd4-11eb-5cf0-12be5c33a183
确认模板组件存在。
$ aws cloudformation describe-stacks --stack-name <name>
StackStatus
显示 CREATE_COMPLETE
后,输出将显示以下参数的值。您必须将这些参数值提供给您运行以创建集群的其他 CloudFormation 模板。
PrivateHostedZoneId
|
私有 DNS 的托管区域 ID。 |
ExternalApiLoadBalancerName
|
外部 API 负载均衡器的完整名称。 |
InternalApiLoadBalancerName
|
内部 API 负载均衡器的完整名称。 |
ApiServerDnsName
|
API 服务器的完整主机名。 |
RegisterNlbIpTargetsLambda
|
Lambda ARN,有助于注册/注销这些负载均衡器的 IP 目标。 |
ExternalApiTargetGroupArn
|
外部 API 目标组的 ARN。 |
InternalApiTargetGroupArn
|
内部 API 目标组的 ARN。 |
InternalServiceTargetGroupArn
|
内部服务目标组的 ARN。 |
您可以使用以下 CloudFormation 模板来部署 OpenShift Container Platform 集群所需的网络对象和负载均衡器。
AWSTemplateFormatVersion: 2010-09-09
Description: Template for OpenShift Cluster Network Elements (Route53 & LBs)
Parameters:
ClusterName:
AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$
MaxLength: 27
MinLength: 1
ConstraintDescription: Cluster name must be alphanumeric, start with a letter, and have a maximum of 27 characters.
Description: A short, representative cluster name to use for host names and other identifying names.
Type: String
InfrastructureName:
AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$
MaxLength: 27
MinLength: 1
ConstraintDescription: Infrastructure name must be alphanumeric, start with a letter, and have a maximum of 27 characters.
Description: A short, unique cluster ID used to tag cloud resources and identify items owned or used by the cluster.
Type: String
HostedZoneId:
Description: The Route53 public zone ID to register the targets with, such as Z21IXYZABCZ2A4.
Type: String
HostedZoneName:
Description: The Route53 zone to register the targets with, such as example.com. Omit the trailing period.
Type: String
Default: "example.com"
PublicSubnets:
Description: The internet-facing subnets.
Type: List<AWS::EC2::Subnet::Id>
PrivateSubnets:
Description: The internal subnets.
Type: List<AWS::EC2::Subnet::Id>
VpcId:
Description: The VPC-scoped resources will belong to this VPC.
Type: AWS::EC2::VPC::Id
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Cluster Information"
Parameters:
- ClusterName
- InfrastructureName
- Label:
default: "Network Configuration"
Parameters:
- VpcId
- PublicSubnets
- PrivateSubnets
- Label:
default: "DNS"
Parameters:
- HostedZoneName
- HostedZoneId
ParameterLabels:
ClusterName:
default: "Cluster Name"
InfrastructureName:
default: "Infrastructure Name"
VpcId:
default: "VPC ID"
PublicSubnets:
default: "Public Subnets"
PrivateSubnets:
default: "Private Subnets"
HostedZoneName:
default: "Public Hosted Zone Name"
HostedZoneId:
default: "Public Hosted Zone ID"
Resources:
ExtApiElb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Join ["-", [!Ref InfrastructureName, "ext"]]
IpAddressType: ipv4
Subnets: !Ref PublicSubnets
Type: network
IntApiElb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Join ["-", [!Ref InfrastructureName, "int"]]
Scheme: internal
IpAddressType: ipv4
Subnets: !Ref PrivateSubnets
Type: network
IntDns:
Type: "AWS::Route53::HostedZone"
Properties:
HostedZoneConfig:
Comment: "Managed by CloudFormation"
Name: !Join [".", [!Ref ClusterName, !Ref HostedZoneName]]
HostedZoneTags:
- Key: Name
Value: !Join ["-", [!Ref InfrastructureName, "int"]]
- Key: !Join ["", ["kubernetes.io/cluster/", !Ref InfrastructureName]]
Value: "owned"
VPCs:
- VPCId: !Ref VpcId
VPCRegion: !Ref "AWS::Region"
ExternalApiServerRecord:
Type: AWS::Route53::RecordSetGroup
Properties:
Comment: Alias record for the API server
HostedZoneId: !Ref HostedZoneId
RecordSets:
- Name:
!Join [
".",
["api", !Ref ClusterName, !Join ["", [!Ref HostedZoneName, "."]]],
]
Type: A
AliasTarget:
HostedZoneId: !GetAtt ExtApiElb.CanonicalHostedZoneID
DNSName: !GetAtt ExtApiElb.DNSName
InternalApiServerRecord:
Type: AWS::Route53::RecordSetGroup
Properties:
Comment: Alias record for the API server
HostedZoneId: !Ref IntDns
RecordSets:
- Name:
!Join [
".",
["api", !Ref ClusterName, !Join ["", [!Ref HostedZoneName, "."]]],
]
Type: A
AliasTarget:
HostedZoneId: !GetAtt IntApiElb.CanonicalHostedZoneID
DNSName: !GetAtt IntApiElb.DNSName
- Name:
!Join [
".",
["api-int", !Ref ClusterName, !Join ["", [!Ref HostedZoneName, "."]]],
]
Type: A
AliasTarget:
HostedZoneId: !GetAtt IntApiElb.CanonicalHostedZoneID
DNSName: !GetAtt IntApiElb.DNSName
ExternalApiListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn:
Ref: ExternalApiTargetGroup
LoadBalancerArn:
Ref: ExtApiElb
Port: 6443
Protocol: TCP
ExternalApiTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 10
HealthCheckPath: "/readyz"
HealthCheckPort: 6443
HealthCheckProtocol: HTTPS
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
Port: 6443
Protocol: TCP
TargetType: ip
VpcId:
Ref: VpcId
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60
InternalApiListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn:
Ref: InternalApiTargetGroup
LoadBalancerArn:
Ref: IntApiElb
Port: 6443
Protocol: TCP
InternalApiTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 10
HealthCheckPath: "/readyz"
HealthCheckPort: 6443
HealthCheckProtocol: HTTPS
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
Port: 6443
Protocol: TCP
TargetType: ip
VpcId:
Ref: VpcId
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60
InternalServiceInternalListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn:
Ref: InternalServiceTargetGroup
LoadBalancerArn:
Ref: IntApiElb
Port: 22623
Protocol: TCP
InternalServiceTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 10
HealthCheckPath: "/healthz"
HealthCheckPort: 22623
HealthCheckProtocol: HTTPS
HealthyThresholdCount: 2
UnhealthyThresholdCount: 2
Port: 22623
Protocol: TCP
TargetType: ip
VpcId:
Ref: VpcId
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60
RegisterTargetLambdaIamRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ["-", [!Ref InfrastructureName, "nlb", "lambda", "role"]]
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: !Join ["-", [!Ref InfrastructureName, "master", "policy"]]
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
[
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets",
]
Resource: !Ref InternalApiTargetGroup
- Effect: "Allow"
Action:
[
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets",
]
Resource: !Ref InternalServiceTargetGroup
- Effect: "Allow"
Action:
[
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets",
]
Resource: !Ref ExternalApiTargetGroup
RegisterNlbIpTargets:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role:
Fn::GetAtt:
- "RegisterTargetLambdaIamRole"
- "Arn"
Code:
ZipFile: |
import json
import boto3
import cfnresponse
def handler(event, context):
elb = boto3.client('elbv2')
if event['RequestType'] == 'Delete':
elb.deregister_targets(TargetGroupArn=event['ResourceProperties']['TargetArn'],Targets=[{'Id': event['ResourceProperties']['TargetIp']}])
elif event['RequestType'] == 'Create':
elb.register_targets(TargetGroupArn=event['ResourceProperties']['TargetArn'],Targets=[{'Id': event['ResourceProperties']['TargetIp']}])
responseData = {}
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, event['ResourceProperties']['TargetArn']+event['ResourceProperties']['TargetIp'])
Runtime: "python3.11"
Timeout: 120
RegisterSubnetTagsLambdaIamRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ["-", [!Ref InfrastructureName, "subnet-tags-lambda-role"]]
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: !Join ["-", [!Ref InfrastructureName, "subnet-tagging-policy"]]
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
[
"ec2:DeleteTags",
"ec2:CreateTags"
]
Resource: "arn:aws:ec2:*:*:subnet/*"
- Effect: "Allow"
Action:
[
"ec2:DescribeSubnets",
"ec2:DescribeTags"
]
Resource: "*"
RegisterSubnetTags:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role:
Fn::GetAtt:
- "RegisterSubnetTagsLambdaIamRole"
- "Arn"
Code:
ZipFile: |
import json
import boto3
import cfnresponse
def handler(event, context):
ec2_client = boto3.client('ec2')
if event['RequestType'] == 'Delete':
for subnet_id in event['ResourceProperties']['Subnets']:
ec2_client.delete_tags(Resources=[subnet_id], Tags=[{'Key': 'kubernetes.io/cluster/' + event['ResourceProperties']['InfrastructureName']}]);
elif event['RequestType'] == 'Create':
for subnet_id in event['ResourceProperties']['Subnets']:
ec2_client.create_tags(Resources=[subnet_id], Tags=[{'Key': 'kubernetes.io/cluster/' + event['ResourceProperties']['InfrastructureName'], 'Value': 'shared'}]);
responseData = {}
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, event['ResourceProperties']['InfrastructureName']+event['ResourceProperties']['Subnets'][0])
Runtime: "python3.11"
Timeout: 120
RegisterPublicSubnetTags:
Type: Custom::SubnetRegister
Properties:
ServiceToken: !GetAtt RegisterSubnetTags.Arn
InfrastructureName: !Ref InfrastructureName
Subnets: !Ref PublicSubnets
RegisterPrivateSubnetTags:
Type: Custom::SubnetRegister
Properties:
ServiceToken: !GetAtt RegisterSubnetTags.Arn
InfrastructureName: !Ref InfrastructureName
Subnets: !Ref PrivateSubnets
Outputs:
PrivateHostedZoneId:
Description: Hosted zone ID for the private DNS, which is required for private records.
Value: !Ref IntDns
ExternalApiLoadBalancerName:
Description: Full name of the external API load balancer.
Value: !GetAtt ExtApiElb.LoadBalancerFullName
InternalApiLoadBalancerName:
Description: Full name of the internal API load balancer.
Value: !GetAtt IntApiElb.LoadBalancerFullName
ApiServerDnsName:
Description: Full hostname of the API server, which is required for the Ignition config files.
Value: !Join [".", ["api-int", !Ref ClusterName, !Ref HostedZoneName]]
RegisterNlbIpTargetsLambda:
Description: Lambda ARN useful to help register or deregister IP targets for these load balancers.
Value: !GetAtt RegisterNlbIpTargets.Arn
ExternalApiTargetGroupArn:
Description: ARN of the external API target group.
Value: !Ref ExternalApiTargetGroup
InternalApiTargetGroupArn:
Description: ARN of the internal API target group.
Value: !Ref InternalApiTargetGroup
InternalServiceTargetGroupArn:
Description: ARN of the internal service target group.
Value: !Ref InternalServiceTargetGroup
如果将集群部署到 AWS 政府或秘密区域,则必须更新
|
有关列出公共托管区域的更多信息,请参阅 AWS 文档中的列出公共托管区域。
必须在 Amazon Web Services (AWS) 中为 OpenShift Container Platform 集群创建安全组和角色。
您可以使用提供的 CloudFormation 模板和自定义参数文件来创建 AWS 资源堆栈。该堆栈代表 OpenShift Container Platform 集群所需的安全性组和角色。
如果您不使用提供的 CloudFormation 模板创建您的 AWS 基础架构,则必须查看提供的信息并手动创建基础架构。如果您的集群未正确初始化,您可能必须联系 Red Hat 支持人员并提供您的安装日志。 |
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
您已在 AWS 中创建和配置了 VPC 和关联的子网。
创建一个 JSON 文件,其中包含模板所需的参数值。
[
{
"ParameterKey": "InfrastructureName", (1)
"ParameterValue": "mycluster-<random_string>" (2)
},
{
"ParameterKey": "VpcCidr", (3)
"ParameterValue": "10.0.0.0/16" (4)
},
{
"ParameterKey": "PrivateSubnets", (5)
"ParameterValue": "subnet-<random_string>" (6)
},
{
"ParameterKey": "VpcId", (7)
"ParameterValue": "vpc-<random_string>" (8)
}
]
1 | 集群的 Ignition 配置文件中编码的集群基础设施名称。 |
2 | 指定从 Ignition 配置文件元数据中提取的基础设施名称,其格式为<cluster-name>-<random-string> 。 |
3 | VPC 的 CIDR 块。 |
4 | 指定您为以x.x.x.x/16-24 形式定义的 VPC 使用的 CIDR 块参数。 |
5 | 为您的 VPC 创建的私有子网。 |
6 | 指定 VPC 的 CloudFormation 模板输出中的PrivateSubnetIds 值。 |
7 | 为集群创建的 VPC。 |
8 | 指定 VPC 的 CloudFormation 模板输出中的VpcId 值。 |
复制本主题“安全对象的 CloudFormation 模板”部分中的模板,并将其另存为计算机上的 YAML 文件。此模板描述了集群所需的安全性组和角色。
启动 CloudFormation 模板以创建代表安全组和角色的 AWS 资源堆栈。
您必须在一行中输入命令。 |
$ aws cloudformation create-stack --stack-name <name> (1)
--template-body file://<template>.yaml (2)
--parameters file://<parameters>.json (3)
--capabilities CAPABILITY_NAMED_IAM (4)
1 | <name> 是 CloudFormation 堆栈的名称,例如cluster-sec 。如果删除集群,则需要此堆栈的名称。 |
2 | <模板> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。 |
3 | <参数> 是 CloudFormation 参数 JSON 文件的相对路径和名称。 |
4 | 必须显式声明CAPABILITY_NAMED_IAM 功能,因为提供的模板会创建一些AWS::IAM::Role 和AWS::IAM::InstanceProfile 资源。 |
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-sec/03bd4210-2ed7-11eb-6d7a-13fc0b61e9db
确认模板组件存在。
$ aws cloudformation describe-stacks --stack-name <name>
StackStatus
显示 CREATE_COMPLETE
后,输出将显示以下参数的值。您必须将这些参数值提供给您运行以创建集群的其他 CloudFormation 模板。
MasterSecurityGroupId
|
主安全组 ID |
WorkerSecurityGroupId
|
工作节点安全组 ID |
MasterInstanceProfile
|
主 IAM 实例配置文件 |
WorkerInstanceProfile
|
工作节点 IAM 实例配置文件 |
您可以使用以下 CloudFormation 模板来部署 OpenShift Container Platform 集群所需的安全性对象。
AWSTemplateFormatVersion: 2010-09-09
Description: Template for OpenShift Cluster Security Elements (Security Groups & IAM)
Parameters:
InfrastructureName:
AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$
MaxLength: 27
MinLength: 1
ConstraintDescription: Infrastructure name must be alphanumeric, start with a letter, and have a maximum of 27 characters.
Description: A short, unique cluster ID used to tag cloud resources and identify items owned or used by the cluster.
Type: String
VpcCidr:
AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-4]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-24.
Default: 10.0.0.0/16
Description: CIDR block for VPC.
Type: String
VpcId:
Description: The VPC-scoped resources will belong to this VPC.
Type: AWS::EC2::VPC::Id
PrivateSubnets:
Description: The internal subnets.
Type: List<AWS::EC2::Subnet::Id>
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Cluster Information"
Parameters:
- InfrastructureName
- Label:
default: "Network Configuration"
Parameters:
- VpcId
- VpcCidr
- PrivateSubnets
ParameterLabels:
InfrastructureName:
default: "Infrastructure Name"
VpcId:
default: "VPC ID"
VpcCidr:
default: "VPC CIDR"
PrivateSubnets:
default: "Private Subnets"
Resources:
MasterSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Cluster Master Security Group
SecurityGroupIngress:
- IpProtocol: icmp
FromPort: 0
ToPort: 0
CidrIp: !Ref VpcCidr
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref VpcCidr
- IpProtocol: tcp
ToPort: 6443
FromPort: 6443
CidrIp: !Ref VpcCidr
- IpProtocol: tcp
FromPort: 22623
ToPort: 22623
CidrIp: !Ref VpcCidr
VpcId: !Ref VpcId
WorkerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Cluster Worker Security Group
SecurityGroupIngress:
- IpProtocol: icmp
FromPort: 0
ToPort: 0
CidrIp: !Ref VpcCidr
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref VpcCidr
VpcId: !Ref VpcId
MasterIngressEtcd:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: etcd
FromPort: 2379
ToPort: 2380
IpProtocol: tcp
MasterIngressVxlan:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Vxlan packets
FromPort: 4789
ToPort: 4789
IpProtocol: udp
MasterIngressWorkerVxlan:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Vxlan packets
FromPort: 4789
ToPort: 4789
IpProtocol: udp
MasterIngressGeneve:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Geneve packets
FromPort: 6081
ToPort: 6081
IpProtocol: udp
MasterIngressWorkerGeneve:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Geneve packets
FromPort: 6081
ToPort: 6081
IpProtocol: udp
MasterIngressIpsecIke:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: IPsec IKE packets
FromPort: 500
ToPort: 500
IpProtocol: udp
MasterIngressIpsecNat:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: IPsec NAT-T packets
FromPort: 4500
ToPort: 4500
IpProtocol: udp
MasterIngressIpsecEsp:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: IPsec ESP packets
IpProtocol: 50
MasterIngressWorkerIpsecIke:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: IPsec IKE packets
FromPort: 500
ToPort: 500
IpProtocol: udp
MasterIngressWorkerIpsecNat:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: IPsec NAT-T packets
FromPort: 4500
ToPort: 4500
IpProtocol: udp
MasterIngressWorkerIpsecEsp:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: IPsec ESP packets
IpProtocol: 50
MasterIngressInternal:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: tcp
MasterIngressWorkerInternal:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: tcp
MasterIngressInternalUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: udp
MasterIngressWorkerInternalUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: udp
MasterIngressKube:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Kubernetes kubelet, scheduler and controller manager
FromPort: 10250
ToPort: 10259
IpProtocol: tcp
MasterIngressWorkerKube:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Kubernetes kubelet, scheduler and controller manager
FromPort: 10250
ToPort: 10259
IpProtocol: tcp
MasterIngressIngressServices:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: tcp
MasterIngressWorkerIngressServices:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: tcp
MasterIngressIngressServicesUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: udp
MasterIngressWorkerIngressServicesUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt MasterSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: udp
WorkerIngressVxlan:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Vxlan packets
FromPort: 4789
ToPort: 4789
IpProtocol: udp
WorkerIngressMasterVxlan:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Vxlan packets
FromPort: 4789
ToPort: 4789
IpProtocol: udp
WorkerIngressGeneve:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Geneve packets
FromPort: 6081
ToPort: 6081
IpProtocol: udp
WorkerIngressMasterGeneve:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Geneve packets
FromPort: 6081
ToPort: 6081
IpProtocol: udp
WorkerIngressIpsecIke:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: IPsec IKE packets
FromPort: 500
ToPort: 500
IpProtocol: udp
WorkerIngressIpsecNat:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: IPsec NAT-T packets
FromPort: 4500
ToPort: 4500
IpProtocol: udp
WorkerIngressIpsecEsp:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: IPsec ESP packets
IpProtocol: 50
WorkerIngressMasterIpsecIke:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: IPsec IKE packets
FromPort: 500
ToPort: 500
IpProtocol: udp
WorkerIngressMasterIpsecNat:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: IPsec NAT-T packets
FromPort: 4500
ToPort: 4500
IpProtocol: udp
WorkerIngressMasterIpsecEsp:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: IPsec ESP packets
IpProtocol: 50
WorkerIngressInternal:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: tcp
WorkerIngressMasterInternal:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: tcp
WorkerIngressInternalUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: udp
WorkerIngressMasterInternalUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Internal cluster communication
FromPort: 9000
ToPort: 9999
IpProtocol: udp
WorkerIngressKube:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Kubernetes secure kubelet port
FromPort: 10250
ToPort: 10250
IpProtocol: tcp
WorkerIngressWorkerKube:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Internal Kubernetes communication
FromPort: 10250
ToPort: 10250
IpProtocol: tcp
WorkerIngressIngressServices:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: tcp
WorkerIngressMasterIngressServices:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: tcp
WorkerIngressIngressServicesUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt WorkerSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: udp
WorkerIngressMasterIngressServicesUDP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt WorkerSecurityGroup.GroupId
SourceSecurityGroupId: !GetAtt MasterSecurityGroup.GroupId
Description: Kubernetes ingress services
FromPort: 30000
ToPort: 32767
IpProtocol: udp
MasterIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: !Join ["-", [!Ref InfrastructureName, "master", "policy"]]
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "ec2:AttachVolume"
- "ec2:AuthorizeSecurityGroupIngress"
- "ec2:CreateSecurityGroup"
- "ec2:CreateTags"
- "ec2:CreateVolume"
- "ec2:DeleteSecurityGroup"
- "ec2:DeleteVolume"
- "ec2:Describe*"
- "ec2:DetachVolume"
- "ec2:ModifyInstanceAttribute"
- "ec2:ModifyVolume"
- "ec2:RevokeSecurityGroupIngress"
- "elasticloadbalancing:AddTags"
- "elasticloadbalancing:AttachLoadBalancerToSubnets"
- "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer"
- "elasticloadbalancing:CreateListener"
- "elasticloadbalancing:CreateLoadBalancer"
- "elasticloadbalancing:CreateLoadBalancerPolicy"
- "elasticloadbalancing:CreateLoadBalancerListeners"
- "elasticloadbalancing:CreateTargetGroup"
- "elasticloadbalancing:ConfigureHealthCheck"
- "elasticloadbalancing:DeleteListener"
- "elasticloadbalancing:DeleteLoadBalancer"
- "elasticloadbalancing:DeleteLoadBalancerListeners"
- "elasticloadbalancing:DeleteTargetGroup"
- "elasticloadbalancing:DeregisterInstancesFromLoadBalancer"
- "elasticloadbalancing:DeregisterTargets"
- "elasticloadbalancing:Describe*"
- "elasticloadbalancing:DetachLoadBalancerFromSubnets"
- "elasticloadbalancing:ModifyListener"
- "elasticloadbalancing:ModifyLoadBalancerAttributes"
- "elasticloadbalancing:ModifyTargetGroup"
- "elasticloadbalancing:ModifyTargetGroupAttributes"
- "elasticloadbalancing:RegisterInstancesWithLoadBalancer"
- "elasticloadbalancing:RegisterTargets"
- "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer"
- "elasticloadbalancing:SetLoadBalancerPoliciesOfListener"
- "kms:DescribeKey"
Resource: "*"
MasterInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Roles:
- Ref: "MasterIamRole"
WorkerIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: !Join ["-", [!Ref InfrastructureName, "worker", "policy"]]
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "ec2:DescribeInstances"
- "ec2:DescribeRegions"
Resource: "*"
WorkerInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Roles:
- Ref: "WorkerIamRole"
Outputs:
MasterSecurityGroupId:
Description: Master Security Group ID
Value: !GetAtt MasterSecurityGroup.GroupId
WorkerSecurityGroupId:
Description: Worker Security Group ID
Value: !GetAtt WorkerSecurityGroup.GroupId
MasterInstanceProfile:
Description: Master IAM Instance Profile
Value: !Ref MasterInstanceProfile
WorkerInstanceProfile:
Description: Worker IAM Instance Profile
Value: !Ref WorkerInstanceProfile
在 OpenShift Container Platform 中,流元数据以 JSON 格式提供有关 RHCOS 的标准化元数据,并将元数据注入集群。流元数据是一种稳定的格式,支持多种架构,旨在实现自文档化以维护自动化。
您可以使用openshift-install
的coreos print-stream-json
子命令访问流元数据格式中的引导映像信息。此命令提供了一种以可脚本化、机器可读的格式打印流元数据的方法。
对于用户预配的安装,openshift-install
二进制文件包含对已测试可与 OpenShift Container Platform(例如 AWS AMI)一起使用的 RHCOS 引导映像版本的引用。
要解析流元数据,请使用以下方法之一:
从 Go 程序中,使用官方的stream-metadata-go
库,网址为https://github.com/coreos/stream-metadata-go。您还可以查看库中的示例代码。
从其他编程语言(如 Python 或 Ruby)中,使用您首选编程语言的 JSON 库。
从处理 JSON 数据的命令行实用程序(如jq
)中。
打印 AWS 区域(如us-west-1
)的当前x86_64
或aarch64
AMI。
$ openshift-install coreos print-stream-json | jq -r '.architectures.x86_64.images.aws.regions["us-west-1"].image'
ami-0d3e625f84626bbda
$ openshift-install coreos print-stream-json | jq -r '.architectures.aarch64.images.aws.regions["us-west-1"].image'
ami-0af1d3b7fa5be2131
此命令的输出是您指定架构和us-west-1
区域的 AWS AMI ID。AMI 必须属于与集群相同的区域。
Red Hat 提供适用于您可以为 OpenShift Container Platform 节点手动指定的各种 AWS 区域和实例架构的 Red Hat Enterprise Linux CoreOS (RHCOS) AMI。
通过导入您自己的 AMI,您还可以安装到没有发布 RHCOS AMI 的区域。 |
AWS 区域 | AWS AMI |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AWS 区域 | AWS AMI |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在 OpenShift Container Platform 集群初始化期间使用时,必须在 Amazon Web Services (AWS) 中创建引导节点。方法如下:
提供一个位置,用于将bootstrap.ign
Ignition 配置文件提供给您的集群。此文件位于您的安装目录中。提供的 CloudFormation 模板假设您的集群的 Ignition 配置文件是从 S3 存储桶提供的。如果您选择从其他位置提供文件,则必须修改模板。
使用提供的 CloudFormation 模板和自定义参数文件来创建 AWS 资源堆栈。该堆栈表示 OpenShift Container Platform 安装所需的引导节点。
如果您不使用提供的 CloudFormation 模板来创建引导节点,则必须查看提供的信息并手动创建基础设施。如果您的集群未正确初始化,您可能必须联系 Red Hat 支持人员并提供您的安装日志。 |
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
您已在 AWS 中创建和配置了 VPC 和关联的子网。
您已在 AWS 中创建和配置了 DNS、负载均衡器和侦听器。
您已在 AWS 中创建了集群所需的安全性组和角色。
运行以下命令创建存储桶:
$ aws s3 mb s3://<cluster-name>-infra (1)
1 | <cluster-name>-infra 是存储桶名称。创建install-config.yaml 文件时,请将<cluster-name> 替换为为集群指定的名称。 |
则必须对您的 S3 存储桶使用预签名 URL,而不是s3://
模式。
部署到具有与 AWS SDK 不同的端点的区域。
部署代理。
提供您自己的自定义端点。
运行以下命令将bootstrap.ign
Ignition 配置文件上传到存储桶:
$ aws s3 cp <installation_directory>/bootstrap.ign s3://<cluster-name>-infra/bootstrap.ign (1)
1 | 对于 <安装目录> ,请指定您存储安装文件的目录的路径。 |
运行以下命令验证文件是否已上传:
$ aws s3 ls s3://<cluster-name>-infra/
2019-04-03 16:15:16 314878 bootstrap.ign
引导 Ignition 配置文件确实包含密钥,例如 X.509 密钥。以下步骤为 S3 存储桶提供了基本安全性。要提供额外的安全性,您可以启用 S3 存储桶策略,以仅允许某些用户(例如 OpenShift IAM 用户)访问存储桶包含的对象。您可以完全避免使用 S3,并从引导机器可以访问的任何地址提供您的引导 Ignition 配置文件。 |
创建一个 JSON 文件,其中包含模板所需的参数值。
[
{
"ParameterKey": "InfrastructureName", (1)
"ParameterValue": "mycluster-<random_string>" (2)
},
{
"ParameterKey": "RhcosAmi", (3)
"ParameterValue": "ami-<random_string>" (4)
},
{
"ParameterKey": "AllowedBootstrapSshCidr", (5)
"ParameterValue": "0.0.0.0/0" (6)
},
{
"ParameterKey": "PublicSubnet", (7)
"ParameterValue": "subnet-<random_string>" (8)
},
{
"ParameterKey": "MasterSecurityGroupId", (9)
"ParameterValue": "sg-<random_string>" (10)
},
{
"ParameterKey": "VpcId", (11)
"ParameterValue": "vpc-<random_string>" (12)
},
{
"ParameterKey": "BootstrapIgnitionLocation", (13)
"ParameterValue": "s3://<bucket_name>/bootstrap.ign" (14)
},
{
"ParameterKey": "AutoRegisterELB", (15)
"ParameterValue": "yes" (16)
},
{
"ParameterKey": "RegisterNlbIpTargetsLambdaArn", (17)
"ParameterValue": "arn:aws:lambda:<aws_region>:<account_number>:function:<dns_stack_name>-RegisterNlbIpTargets-<random_string>" (18)
},
{
"ParameterKey": "ExternalApiTargetGroupArn", (19)
"ParameterValue": "arn:aws:elasticloadbalancing:<aws_region>:<account_number>:targetgroup/<dns_stack_name>-Exter-<random_string>" (20)
},
{
"ParameterKey": "InternalApiTargetGroupArn", (21)
"ParameterValue": "arn:aws:elasticloadbalancing:<aws_region>:<account_number>:targetgroup/<dns_stack_name>-Inter-<random_string>" (22)
},
{
"ParameterKey": "InternalServiceTargetGroupArn", (23)
"ParameterValue": "arn:aws:elasticloadbalancing:<aws_region>:<account_number>:targetgroup/<dns_stack_name>-Inter-<random_string>" (24)
}
]
1 | 集群的 Ignition 配置文件中编码的集群基础设施名称。 |
2 | 指定从 Ignition 配置文件元数据中提取的基础设施名称,其格式为<cluster-name>-<random-string> 。 |
3 | 根据您选择的体系结构,当前用于引导节点的 Red Hat Enterprise Linux CoreOS (RHCOS) AMI。 |
4 | 指定有效的AWS::EC2::Image::Id 值。 |
5 | 允许 SSH 访问引导节点的 CIDR 块。 |
6 | 以 x.x.x.x/16-24 格式指定 CIDR 块。 |
7 | 与您的 VPC 关联的公共子网,用于将引导节点启动到其中。 |
8 | 指定 VPC 的 CloudFormation 模板输出中的PublicSubnetIds 值。 |
9 | 主安全性组 ID(用于注册临时规则) |
10 | 从安全性组和角色的 CloudFormation 模板的输出中指定MasterSecurityGroupId 值。 |
11 | 将创建的 VPC 资源所属的 VPC。 |
12 | 指定 VPC 的 CloudFormation 模板输出中的VpcId 值。 |
13 | 用于获取引导 Ignition 配置文件的位置。 |
14 | 以s3://<bucket_name>/bootstrap.ign 的形式指定 S3 存储桶和文件名。 |
15 | 是否注册网络负载均衡器 (NLB)。 |
16 | 指定yes 或no 。如果您指定yes ,则必须提供 Lambda Amazon 资源名称 (ARN) 值。 |
17 | NLB IP 目标注册 Lambda 组的 ARN。 |
18 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定RegisterNlbIpTargetsLambda 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
19 | 外部 API 负载均衡器目标组的 ARN。 |
20 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定ExternalApiTargetGroupArn 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
21 | 内部 API 负载均衡器目标组的 ARN。 |
22 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定InternalApiTargetGroupArn 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
23 | 内部服务负载均衡器目标组的 ARN。 |
24 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定InternalServiceTargetGroupArn 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
从本主题的“引导机器的 CloudFormation 模板”部分复制模板,并将其另存为计算机上的 YAML 文件。此模板描述了集群所需的引导机器。
可选:如果您使用代理部署集群,则必须更新模板中的点火以添加ignition.config.proxy
字段。此外,如果您已将 Amazon EC2、弹性负载均衡和 S3 VPC 端点添加到您的 VPC,则必须将这些端点添加到noProxy
字段。
启动 CloudFormation 模板以创建表示引导节点的 AWS 资源堆栈:
您必须在一行中输入命令。 |
$ aws cloudformation create-stack --stack-name <name> (1)
--template-body file://<template>.yaml (2)
--parameters file://<parameters>.json (3)
--capabilities CAPABILITY_NAMED_IAM (4)
1 | <name> 是 CloudFormation 堆栈的名称,例如cluster-bootstrap 。如果您删除集群,则需要此堆栈的名称。 |
2 | <模板> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。 |
3 | <参数> 是 CloudFormation 参数 JSON 文件的相对路径和名称。 |
4 | 必须显式声明CAPABILITY_NAMED_IAM 功能,因为提供的模板会创建一些AWS::IAM::Role 和AWS::IAM::InstanceProfile 资源。 |
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-bootstrap/12944486-2add-11eb-9dee-12dace8e3a83
确认模板组件存在。
$ aws cloudformation describe-stacks --stack-name <name>
StackStatus
显示 CREATE_COMPLETE
后,输出将显示以下参数的值。您必须将这些参数值提供给您运行以创建集群的其他 CloudFormation 模板。
BootstrapInstanceId
|
引导实例 ID。 |
BootstrapPublicIp
|
引导节点公共 IP 地址。 |
BootstrapPrivateIp
|
引导节点私有 IP 地址。 |
您可以使用以下CloudFormation模板部署OpenShift Container Platform集群所需的引导机器。
AWSTemplateFormatVersion: 2010-09-09
Description: Template for OpenShift Cluster Bootstrap (EC2 Instance, Security Groups and IAM)
Parameters:
InfrastructureName:
AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$
MaxLength: 27
MinLength: 1
ConstraintDescription: Infrastructure name must be alphanumeric, start with a letter, and have a maximum of 27 characters.
Description: A short, unique cluster ID used to tag cloud resources and identify items owned or used by the cluster.
Type: String
RhcosAmi:
Description: Current Red Hat Enterprise Linux CoreOS AMI to use for bootstrap.
Type: AWS::EC2::Image::Id
AllowedBootstrapSshCidr:
AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|1[0-9]|2[0-9]|3[0-2]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/0-32.
Default: 0.0.0.0/0
Description: CIDR block to allow SSH access to the bootstrap node.
Type: String
PublicSubnet:
Description: The public subnet to launch the bootstrap node into.
Type: AWS::EC2::Subnet::Id
MasterSecurityGroupId:
Description: The master security group ID for registering temporary rules.
Type: AWS::EC2::SecurityGroup::Id
VpcId:
Description: The VPC-scoped resources will belong to this VPC.
Type: AWS::EC2::VPC::Id
BootstrapIgnitionLocation:
Default: s3://my-s3-bucket/bootstrap.ign
Description: Ignition config file location.
Type: String
AutoRegisterELB:
Default: "yes"
AllowedValues:
- "yes"
- "no"
Description: Do you want to invoke NLB registration, which requires a Lambda ARN parameter?
Type: String
RegisterNlbIpTargetsLambdaArn:
Description: ARN for NLB IP target registration lambda.
Type: String
ExternalApiTargetGroupArn:
Description: ARN for external API load balancer target group.
Type: String
InternalApiTargetGroupArn:
Description: ARN for internal API load balancer target group.
Type: String
InternalServiceTargetGroupArn:
Description: ARN for internal service load balancer target group.
Type: String
BootstrapInstanceType:
Description: Instance type for the bootstrap EC2 instance
Default: "i3.large"
Type: String
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Cluster Information"
Parameters:
- InfrastructureName
- Label:
default: "Host Information"
Parameters:
- RhcosAmi
- BootstrapIgnitionLocation
- MasterSecurityGroupId
- Label:
default: "Network Configuration"
Parameters:
- VpcId
- AllowedBootstrapSshCidr
- PublicSubnet
- Label:
default: "Load Balancer Automation"
Parameters:
- AutoRegisterELB
- RegisterNlbIpTargetsLambdaArn
- ExternalApiTargetGroupArn
- InternalApiTargetGroupArn
- InternalServiceTargetGroupArn
ParameterLabels:
InfrastructureName:
default: "Infrastructure Name"
VpcId:
default: "VPC ID"
AllowedBootstrapSshCidr:
default: "Allowed SSH Source"
PublicSubnet:
default: "Public Subnet"
RhcosAmi:
default: "Red Hat Enterprise Linux CoreOS AMI ID"
BootstrapIgnitionLocation:
default: "Bootstrap Ignition Source"
MasterSecurityGroupId:
default: "Master Security Group ID"
AutoRegisterELB:
default: "Use Provided ELB Automation"
Conditions:
DoRegistration: !Equals ["yes", !Ref AutoRegisterELB]
Resources:
BootstrapIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: !Join ["-", [!Ref InfrastructureName, "bootstrap", "policy"]]
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "ec2:Describe*"
Resource: "*"
- Effect: "Allow"
Action: "ec2:AttachVolume"
Resource: "*"
- Effect: "Allow"
Action: "ec2:DetachVolume"
Resource: "*"
- Effect: "Allow"
Action: "s3:GetObject"
Resource: "*"
BootstrapInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: "/"
Roles:
- Ref: "BootstrapIamRole"
BootstrapSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Cluster Bootstrap Security Group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref AllowedBootstrapSshCidr
- IpProtocol: tcp
ToPort: 19531
FromPort: 19531
CidrIp: 0.0.0.0/0
VpcId: !Ref VpcId
BootstrapInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref RhcosAmi
IamInstanceProfile: !Ref BootstrapInstanceProfile
InstanceType: !Ref BootstrapInstanceType
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
GroupSet:
- !Ref "BootstrapSecurityGroup"
- !Ref "MasterSecurityGroupId"
SubnetId: !Ref "PublicSubnet"
UserData:
Fn::Base64: !Sub
- '{"ignition":{"config":{"replace":{"source":"${S3Loc}"}},"version":"3.1.0"}}'
- {
S3Loc: !Ref BootstrapIgnitionLocation
}
RegisterBootstrapApiTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref ExternalApiTargetGroupArn
TargetIp: !GetAtt BootstrapInstance.PrivateIp
RegisterBootstrapInternalApiTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalApiTargetGroupArn
TargetIp: !GetAtt BootstrapInstance.PrivateIp
RegisterBootstrapInternalServiceTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalServiceTargetGroupArn
TargetIp: !GetAtt BootstrapInstance.PrivateIp
Outputs:
BootstrapInstanceId:
Description: Bootstrap Instance ID.
Value: !Ref BootstrapInstance
BootstrapPublicIp:
Description: The bootstrap node public IP address.
Value: !GetAtt BootstrapInstance.PublicIp
BootstrapPrivateIp:
Description: The bootstrap node private IP address.
Value: !GetAtt BootstrapInstance.PrivateIp
有关AWS区域的Red Hat Enterprise Linux CoreOS (RHCOS) AMI的详细信息,请参阅AWS基础设施的RHCOS AMI。
您必须在Amazon Web Services (AWS)中创建集群将使用的控制平面机器。
您可以使用提供的CloudFormation模板和自定义参数文件来创建一个代表控制平面节点的AWS资源堆栈。
CloudFormation模板创建表示三个控制平面节点的堆栈。 |
如果您不使用提供的CloudFormation模板来创建控制平面节点,则必须查看提供的信息并手动创建基础设施。如果您的集群未正确初始化,您可能需要联系Red Hat支持并提供您的安装日志。 |
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
您已在 AWS 中创建和配置了 VPC 和关联的子网。
您已在 AWS 中创建和配置了 DNS、负载均衡器和侦听器。
您已在 AWS 中创建了集群所需的安全性组和角色。
您已创建引导机器。
创建一个 JSON 文件,其中包含模板所需的参数值。
[
{
"ParameterKey": "InfrastructureName", (1)
"ParameterValue": "mycluster-<random_string>" (2)
},
{
"ParameterKey": "RhcosAmi", (3)
"ParameterValue": "ami-<random_string>" (4)
},
{
"ParameterKey": "AutoRegisterDNS", (5)
"ParameterValue": "yes" (6)
},
{
"ParameterKey": "PrivateHostedZoneId", (7)
"ParameterValue": "<random_string>" (8)
},
{
"ParameterKey": "PrivateHostedZoneName", (9)
"ParameterValue": "mycluster.example.com" (10)
},
{
"ParameterKey": "Master0Subnet", (11)
"ParameterValue": "subnet-<random_string>" (12)
},
{
"ParameterKey": "Master1Subnet", (11)
"ParameterValue": "subnet-<random_string>" (12)
},
{
"ParameterKey": "Master2Subnet", (11)
"ParameterValue": "subnet-<random_string>" (12)
},
{
"ParameterKey": "MasterSecurityGroupId", (13)
"ParameterValue": "sg-<random_string>" (14)
},
{
"ParameterKey": "IgnitionLocation", (15)
"ParameterValue": "https://api-int.<cluster_name>.<domain_name>:22623/config/master" (16)
},
{
"ParameterKey": "CertificateAuthorities", (17)
"ParameterValue": "data:text/plain;charset=utf-8;base64,ABC...xYz==" (18)
},
{
"ParameterKey": "MasterInstanceProfileName", (19)
"ParameterValue": "<roles_stack>-MasterInstanceProfile-<random_string>" (20)
},
{
"ParameterKey": "MasterInstanceType", (21)
"ParameterValue": "" (22)
},
{
"ParameterKey": "AutoRegisterELB", (23)
"ParameterValue": "yes" (24)
},
{
"ParameterKey": "RegisterNlbIpTargetsLambdaArn", (25)
"ParameterValue": "arn:aws:lambda:<aws_region>:<account_number>:function:<dns_stack_name>-RegisterNlbIpTargets-<random_string>" (26)
},
{
"ParameterKey": "ExternalApiTargetGroupArn", (27)
"ParameterValue": "arn:aws:elasticloadbalancing:<aws_region>:<account_number>:targetgroup/<dns_stack_name>-Exter-<random_string>" (28)
},
{
"ParameterKey": "InternalApiTargetGroupArn", (29)
"ParameterValue": "arn:aws:elasticloadbalancing:<aws_region>:<account_number>:targetgroup/<dns_stack_name>-Inter-<random_string>" (30)
},
{
"ParameterKey": "InternalServiceTargetGroupArn", (31)
"ParameterValue": "arn:aws:elasticloadbalancing:<aws_region>:<account_number>:targetgroup/<dns_stack_name>-Inter-<random_string>" (32)
}
]
1 | 集群的 Ignition 配置文件中编码的集群基础设施名称。 |
2 | 指定从 Ignition 配置文件元数据中提取的基础设施名称,其格式为<cluster-name>-<random-string> 。 |
3 | 基于您选择的架构,当前用于控制平面机器的Red Hat Enterprise Linux CoreOS (RHCOS) AMI。 |
4 | 指定AWS::EC2::Image::Id 值。 |
5 | 是否执行DNS etcd注册。 |
6 | 指定yes 或no 。如果您指定yes ,则必须提供托管区域信息。 |
7 | 用于注册etcd目标的Route 53私有区域ID。 |
8 | 指定DNS和负载均衡的CloudFormation模板输出中的PrivateHostedZoneId 值。 |
9 | 用于注册目标的 Route 53 区域。 |
10 | 指定<cluster_name>.<domain_name> ,其中<domain_name> 是您在为集群生成install-config.yaml 文件时使用的Route 53基础域。不要包含AWS控制台中显示的尾随句点(.)。 |
11 | 一个子网(最好是私有子网),用于在其上启动控制平面机器。 |
12 | 指定DNS和负载均衡的CloudFormation模板输出中的PrivateSubnets 值中的子网。 |
13 | 要与控制平面节点关联的主安全组ID。 |
14 | 从安全性组和角色的 CloudFormation 模板的输出中指定MasterSecurityGroupId 值。 |
15 | 从中获取控制平面Ignition配置文件的位置。 |
16 | 指定生成的Ignition配置文件位置,https://api-int.<cluster_name>.<domain_name>:22623/config/master 。 |
17 | 要使用的base64编码的证书颁发机构字符串。 |
18 | 指定安装目录中master.ign 文件中的值。此值为格式为data:text/plain;charset=utf-8;base64,ABC…xYz== 的长字符串。 |
19 | 要与控制平面节点关联的IAM配置文件。 |
20 | 指定安全组和角色的CloudFormation模板输出中的MasterInstanceProfile 参数值。 |
21 | 基于您选择的架构,要用于控制平面机器的AWS实例类型。 |
22 | 实例类型值对应于控制平面机器的最低资源要求。例如,m6i.xlarge 是AMD64的类型,m6g.xlarge 是ARM64的类型。 |
23 | 是否注册网络负载均衡器 (NLB)。 |
24 | 指定yes 或no 。如果您指定yes ,则必须提供 Lambda Amazon 资源名称 (ARN) 值。 |
25 | NLB IP 目标注册 Lambda 组的 ARN。 |
26 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定RegisterNlbIpTargetsLambda 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
27 | 外部 API 负载均衡器目标组的 ARN。 |
28 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定ExternalApiTargetGroupArn 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
29 | 内部 API 负载均衡器目标组的 ARN。 |
30 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定InternalApiTargetGroupArn 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
31 | 内部服务负载均衡器目标组的 ARN。 |
32 | 从 DNS 和负载均衡的 CloudFormation 模板的输出中指定InternalServiceTargetGroupArn 值。如果将集群部署到 AWS GovCloud 区域,请使用arn:aws-us-gov 。 |
从本主题的**用于控制平面机器的CloudFormation模板**部分复制模板,并将其另存为计算机上的YAML文件。此模板描述了集群所需的控制平面机器。
如果您指定m5
实例类型作为MasterInstanceType
的值,请将该实例类型添加到CloudFormation模板中的MasterInstanceType.AllowedValues
参数中。
启动CloudFormation模板以创建代表控制平面节点的AWS资源堆栈
您必须在一行中输入命令。 |
$ aws cloudformation create-stack --stack-name <name> (1)
--template-body file://<template>.yaml (2)
--parameters file://<parameters>.json (3)
1 | <name> 是CloudFormation堆栈的名称,例如cluster-control-plane 。如果您删除集群,则需要此堆栈的名称。 |
2 | <模板> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。 |
3 | <参数> 是 CloudFormation 参数 JSON 文件的相对路径和名称。 |
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-control-plane/21c7e2b0-2ee2-11eb-c6f6-0aa34627df4b
CloudFormation模板创建表示三个控制平面节点的堆栈。 |
确认模板组件存在。
$ aws cloudformation describe-stacks --stack-name <name>
您可以使用以下CloudFormation模板部署OpenShift Container Platform集群所需的控制平面机器。
AWSTemplateFormatVersion: 2010-09-09
Description: Template for OpenShift Cluster Node Launch (EC2 master instances)
Parameters:
InfrastructureName:
AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$
MaxLength: 27
MinLength: 1
ConstraintDescription: Infrastructure name must be alphanumeric, start with a letter, and have a maximum of 27 characters.
Description: A short, unique cluster ID used to tag nodes for the kubelet cloud provider.
Type: String
RhcosAmi:
Description: Current Red Hat Enterprise Linux CoreOS AMI to use for bootstrap.
Type: AWS::EC2::Image::Id
AutoRegisterDNS:
Default: ""
Description: unused
Type: String
PrivateHostedZoneId:
Default: ""
Description: unused
Type: String
PrivateHostedZoneName:
Default: ""
Description: unused
Type: String
Master0Subnet:
Description: The subnets, recommend private, to launch the master nodes into.
Type: AWS::EC2::Subnet::Id
Master1Subnet:
Description: The subnets, recommend private, to launch the master nodes into.
Type: AWS::EC2::Subnet::Id
Master2Subnet:
Description: The subnets, recommend private, to launch the master nodes into.
Type: AWS::EC2::Subnet::Id
MasterSecurityGroupId:
Description: The master security group ID to associate with master nodes.
Type: AWS::EC2::SecurityGroup::Id
IgnitionLocation:
Default: https://api-int.$CLUSTER_NAME.$DOMAIN:22623/config/master
Description: Ignition config file location.
Type: String
CertificateAuthorities:
Default: data:text/plain;charset=utf-8;base64,ABC...xYz==
Description: Base64 encoded certificate authority string to use.
Type: String
MasterInstanceProfileName:
Description: IAM profile to associate with master nodes.
Type: String
MasterInstanceType:
Default: m5.xlarge
Type: String
AutoRegisterELB:
Default: "yes"
AllowedValues:
- "yes"
- "no"
Description: Do you want to invoke NLB registration, which requires a Lambda ARN parameter?
Type: String
RegisterNlbIpTargetsLambdaArn:
Description: ARN for NLB IP target registration lambda. Supply the value from the cluster infrastructure or select "no" for AutoRegisterELB.
Type: String
ExternalApiTargetGroupArn:
Description: ARN for external API load balancer target group. Supply the value from the cluster infrastructure or select "no" for AutoRegisterELB.
Type: String
InternalApiTargetGroupArn:
Description: ARN for internal API load balancer target group. Supply the value from the cluster infrastructure or select "no" for AutoRegisterELB.
Type: String
InternalServiceTargetGroupArn:
Description: ARN for internal service load balancer target group. Supply the value from the cluster infrastructure or select "no" for AutoRegisterELB.
Type: String
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Cluster Information"
Parameters:
- InfrastructureName
- Label:
default: "Host Information"
Parameters:
- MasterInstanceType
- RhcosAmi
- IgnitionLocation
- CertificateAuthorities
- MasterSecurityGroupId
- MasterInstanceProfileName
- Label:
default: "Network Configuration"
Parameters:
- VpcId
- AllowedBootstrapSshCidr
- Master0Subnet
- Master1Subnet
- Master2Subnet
- Label:
default: "Load Balancer Automation"
Parameters:
- AutoRegisterELB
- RegisterNlbIpTargetsLambdaArn
- ExternalApiTargetGroupArn
- InternalApiTargetGroupArn
- InternalServiceTargetGroupArn
ParameterLabels:
InfrastructureName:
default: "Infrastructure Name"
VpcId:
default: "VPC ID"
Master0Subnet:
default: "Master-0 Subnet"
Master1Subnet:
default: "Master-1 Subnet"
Master2Subnet:
default: "Master-2 Subnet"
MasterInstanceType:
default: "Master Instance Type"
MasterInstanceProfileName:
default: "Master Instance Profile Name"
RhcosAmi:
default: "Red Hat Enterprise Linux CoreOS AMI ID"
BootstrapIgnitionLocation:
default: "Master Ignition Source"
CertificateAuthorities:
default: "Ignition CA String"
MasterSecurityGroupId:
default: "Master Security Group ID"
AutoRegisterELB:
default: "Use Provided ELB Automation"
Conditions:
DoRegistration: !Equals ["yes", !Ref AutoRegisterELB]
Resources:
Master0:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref RhcosAmi
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: "120"
VolumeType: "gp2"
IamInstanceProfile: !Ref MasterInstanceProfileName
InstanceType: !Ref MasterInstanceType
NetworkInterfaces:
- AssociatePublicIpAddress: "false"
DeviceIndex: "0"
GroupSet:
- !Ref "MasterSecurityGroupId"
SubnetId: !Ref "Master0Subnet"
UserData:
Fn::Base64: !Sub
- '{"ignition":{"config":{"merge":[{"source":"${SOURCE}"}]},"security":{"tls":{"certificateAuthorities":[{"source":"${CA_BUNDLE}"}]}},"version":"3.1.0"}}'
- {
SOURCE: !Ref IgnitionLocation,
CA_BUNDLE: !Ref CertificateAuthorities,
}
Tags:
- Key: !Join ["", ["kubernetes.io/cluster/", !Ref InfrastructureName]]
Value: "shared"
RegisterMaster0:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref ExternalApiTargetGroupArn
TargetIp: !GetAtt Master0.PrivateIp
RegisterMaster0InternalApiTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalApiTargetGroupArn
TargetIp: !GetAtt Master0.PrivateIp
RegisterMaster0InternalServiceTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalServiceTargetGroupArn
TargetIp: !GetAtt Master0.PrivateIp
Master1:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref RhcosAmi
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: "120"
VolumeType: "gp2"
IamInstanceProfile: !Ref MasterInstanceProfileName
InstanceType: !Ref MasterInstanceType
NetworkInterfaces:
- AssociatePublicIpAddress: "false"
DeviceIndex: "0"
GroupSet:
- !Ref "MasterSecurityGroupId"
SubnetId: !Ref "Master1Subnet"
UserData:
Fn::Base64: !Sub
- '{"ignition":{"config":{"merge":[{"source":"${SOURCE}"}]},"security":{"tls":{"certificateAuthorities":[{"source":"${CA_BUNDLE}"}]}},"version":"3.1.0"}}'
- {
SOURCE: !Ref IgnitionLocation,
CA_BUNDLE: !Ref CertificateAuthorities,
}
Tags:
- Key: !Join ["", ["kubernetes.io/cluster/", !Ref InfrastructureName]]
Value: "shared"
RegisterMaster1:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref ExternalApiTargetGroupArn
TargetIp: !GetAtt Master1.PrivateIp
RegisterMaster1InternalApiTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalApiTargetGroupArn
TargetIp: !GetAtt Master1.PrivateIp
RegisterMaster1InternalServiceTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalServiceTargetGroupArn
TargetIp: !GetAtt Master1.PrivateIp
Master2:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref RhcosAmi
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: "120"
VolumeType: "gp2"
IamInstanceProfile: !Ref MasterInstanceProfileName
InstanceType: !Ref MasterInstanceType
NetworkInterfaces:
- AssociatePublicIpAddress: "false"
DeviceIndex: "0"
GroupSet:
- !Ref "MasterSecurityGroupId"
SubnetId: !Ref "Master2Subnet"
UserData:
Fn::Base64: !Sub
- '{"ignition":{"config":{"merge":[{"source":"${SOURCE}"}]},"security":{"tls":{"certificateAuthorities":[{"source":"${CA_BUNDLE}"}]}},"version":"3.1.0"}}'
- {
SOURCE: !Ref IgnitionLocation,
CA_BUNDLE: !Ref CertificateAuthorities,
}
Tags:
- Key: !Join ["", ["kubernetes.io/cluster/", !Ref InfrastructureName]]
Value: "shared"
RegisterMaster2:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref ExternalApiTargetGroupArn
TargetIp: !GetAtt Master2.PrivateIp
RegisterMaster2InternalApiTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalApiTargetGroupArn
TargetIp: !GetAtt Master2.PrivateIp
RegisterMaster2InternalServiceTarget:
Condition: DoRegistration
Type: Custom::NLBRegister
Properties:
ServiceToken: !Ref RegisterNlbIpTargetsLambdaArn
TargetArn: !Ref InternalServiceTargetGroupArn
TargetIp: !GetAtt Master2.PrivateIp
Outputs:
PrivateIPs:
Description: The control-plane node private IP addresses.
Value:
!Join [
",",
[!GetAtt Master0.PrivateIp, !GetAtt Master1.PrivateIp, !GetAtt Master2.PrivateIp]
]
您可以为集群在Amazon Web Services (AWS)中创建工作节点。
您可以使用提供的CloudFormation模板和自定义参数文件来创建一个代表工作节点的AWS资源堆栈。
CloudFormation模板创建一个代表一个工作节点的堆栈。您必须为每个工作节点创建一个堆栈。 |
如果您不使用提供的CloudFormation模板来创建工作节点,则必须查看提供的信息并手动创建基础设施。如果您的集群未正确初始化,您可能需要联系Red Hat支持并提供您的安装日志。 |
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
您已在 AWS 中创建和配置了 VPC 和关联的子网。
您已在 AWS 中创建和配置了 DNS、负载均衡器和侦听器。
您已在 AWS 中创建了集群所需的安全性组和角色。
您已创建引导机器。
您已创建控制平面机器。
创建一个JSON文件,其中包含CloudFormation模板所需的参数值
[
{
"ParameterKey": "InfrastructureName", (1)
"ParameterValue": "mycluster-<random_string>" (2)
},
{
"ParameterKey": "RhcosAmi", (3)
"ParameterValue": "ami-<random_string>" (4)
},
{
"ParameterKey": "Subnet", (5)
"ParameterValue": "subnet-<random_string>" (6)
},
{
"ParameterKey": "WorkerSecurityGroupId", (7)
"ParameterValue": "sg-<random_string>" (8)
},
{
"ParameterKey": "IgnitionLocation", (9)
"ParameterValue": "https://api-int.<cluster_name>.<domain_name>:22623/config/worker" (10)
},
{
"ParameterKey": "CertificateAuthorities", (11)
"ParameterValue": "" (12)
},
{
"ParameterKey": "WorkerInstanceProfileName", (13)
"ParameterValue": "" (14)
},
{
"ParameterKey": "WorkerInstanceType", (15)
"ParameterValue": "" (16)
}
]
1 | 集群的 Ignition 配置文件中编码的集群基础设施名称。 |
2 | 指定从 Ignition 配置文件元数据中提取的基础设施名称,其格式为<cluster-name>-<random-string> 。 |
3 | 基于您选择的架构,当前用于工作节点的Red Hat Enterprise Linux CoreOS (RHCOS) AMI。 |
4 | 指定AWS::EC2::Image::Id 值。 |
5 | 一个子网(最好是私有子网),用于在其上启动工作节点。 |
6 | 指定DNS和负载均衡的CloudFormation模板输出中的PrivateSubnets 值中的子网。 |
7 | 要与工作节点关联的工作安全组ID。 |
8 | 指定安全组和角色的CloudFormation模板输出中的WorkerSecurityGroupId 值。 |
9 | 从中获取引导Ignition配置文件的位置。 |
10 | 指定生成的Ignition配置文件位置,https://api-int.<cluster_name>.<domain_name>:22623/config/worker 。 |
11 | 要使用的base64编码的证书颁发机构字符串。 |
12 | 指定安装目录中worker.ign 文件中的值。此值为格式为data:text/plain;charset=utf-8;base64,ABC…xYz== 的长字符串。 |
13 | 要与工作节点关联的IAM配置文件。 |
14 | 指定安全组和角色的CloudFormation模板输出中的WorkerInstanceProfile 参数值。 |
15 | 基于您选择的架构,要用于计算机器的AWS实例类型。 |
16 | 实例类型值对应于计算机器的最低资源要求。例如,m6i.large 是AMD64的类型,m6g.large 是ARM64的类型。 |
从本主题的**用于工作机器的CloudFormation模板**部分复制模板,并将其另存为计算机上的YAML文件。此模板描述了集群所需的网络对象和负载均衡器。
可选:如果您指定m5
实例类型作为WorkerInstanceType
的值,请将该实例类型添加到CloudFormation模板中的WorkerInstanceType.AllowedValues
参数中。
可选:如果您使用AWS Marketplace映像进行部署,请使用您从订阅中获得的AMI ID更新Worker0.type.properties.ImageID
参数。
使用 CloudFormation 模板创建代表工作节点的 AWS 资源堆栈
您必须在一行中输入命令。 |
$ aws cloudformation create-stack --stack-name <name> (1)
--template-body file://<template>.yaml \ (2)
--parameters file://<parameters>.json (3)
1 | <name> 是 CloudFormation 堆栈的名称,例如 cluster-worker-1 。如果您删除集群,则需要此堆栈的名称。 |
2 | <模板> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。 |
3 | <参数> 是 CloudFormation 参数 JSON 文件的相对路径和名称。 |
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-worker-1/729ee301-1c2a-11eb-348f-sd9888c65b59
CloudFormation 模板创建一个代表一个工作节点的堆栈。 |
确认模板组件存在。
$ aws cloudformation describe-stacks --stack-name <name>
继续创建工作堆栈,直到您为集群创建了足够的工作机器。您可以通过引用相同的模板和参数文件并指定不同的堆栈名称来创建其他工作堆栈。
您必须至少创建两台工作机器,因此您必须至少创建两个使用此 CloudFormation 模板的堆栈。 |
您可以使用以下 CloudFormation 模板部署 OpenShift Container Platform 集群所需的工作机器。
AWSTemplateFormatVersion: 2010-09-09
Description: Template for OpenShift Cluster Node Launch (EC2 worker instance)
Parameters:
InfrastructureName:
AllowedPattern: ^([a-zA-Z][a-zA-Z0-9\-]{0,26})$
MaxLength: 27
MinLength: 1
ConstraintDescription: Infrastructure name must be alphanumeric, start with a letter, and have a maximum of 27 characters.
Description: A short, unique cluster ID used to tag nodes for the kubelet cloud provider.
Type: String
RhcosAmi:
Description: Current Red Hat Enterprise Linux CoreOS AMI to use for bootstrap.
Type: AWS::EC2::Image::Id
Subnet:
Description: The subnets, recommend private, to launch the worker nodes into.
Type: AWS::EC2::Subnet::Id
WorkerSecurityGroupId:
Description: The worker security group ID to associate with worker nodes.
Type: AWS::EC2::SecurityGroup::Id
IgnitionLocation:
Default: https://api-int.$CLUSTER_NAME.$DOMAIN:22623/config/worker
Description: Ignition config file location.
Type: String
CertificateAuthorities:
Default: data:text/plain;charset=utf-8;base64,ABC...xYz==
Description: Base64 encoded certificate authority string to use.
Type: String
WorkerInstanceProfileName:
Description: IAM profile to associate with worker nodes.
Type: String
WorkerInstanceType:
Default: m5.large
Type: String
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Cluster Information"
Parameters:
- InfrastructureName
- Label:
default: "Host Information"
Parameters:
- WorkerInstanceType
- RhcosAmi
- IgnitionLocation
- CertificateAuthorities
- WorkerSecurityGroupId
- WorkerInstanceProfileName
- Label:
default: "Network Configuration"
Parameters:
- Subnet
ParameterLabels:
Subnet:
default: "Subnet"
InfrastructureName:
default: "Infrastructure Name"
WorkerInstanceType:
default: "Worker Instance Type"
WorkerInstanceProfileName:
default: "Worker Instance Profile Name"
RhcosAmi:
default: "Red Hat Enterprise Linux CoreOS AMI ID"
IgnitionLocation:
default: "Worker Ignition Source"
CertificateAuthorities:
default: "Ignition CA String"
WorkerSecurityGroupId:
default: "Worker Security Group ID"
Resources:
Worker0:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref RhcosAmi
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: "120"
VolumeType: "gp2"
IamInstanceProfile: !Ref WorkerInstanceProfileName
InstanceType: !Ref WorkerInstanceType
NetworkInterfaces:
- AssociatePublicIpAddress: "false"
DeviceIndex: "0"
GroupSet:
- !Ref "WorkerSecurityGroupId"
SubnetId: !Ref "Subnet"
UserData:
Fn::Base64: !Sub
- '{"ignition":{"config":{"merge":[{"source":"${SOURCE}"}]},"security":{"tls":{"certificateAuthorities":[{"source":"${CA_BUNDLE}"}]}},"version":"3.1.0"}}'
- {
SOURCE: !Ref IgnitionLocation,
CA_BUNDLE: !Ref CertificateAuthorities,
}
Tags:
- Key: !Join ["", ["kubernetes.io/cluster/", !Ref InfrastructureName]]
Value: "shared"
Outputs:
PrivateIP:
Description: The compute node private IP address.
Value: !GetAtt Worker0.PrivateIp
在 Amazon Web Services (AWS) 中创建所有必需的基础设施后,您可以启动初始化 OpenShift Container Platform 控制平面的引导序列。
您已配置 AWS 帐户。
您通过运行 aws configure
将您的 AWS 密钥和区域添加到您的本地 AWS 配置文件中。
您已为您的集群生成 Ignition 配置文件。
您已在 AWS 中创建和配置了 VPC 和关联的子网。
您已在 AWS 中创建和配置了 DNS、负载均衡器和侦听器。
您已在 AWS 中创建了集群所需的安全性组和角色。
您已创建引导机器。
您已创建控制平面机器。
您已创建工作节点。
更改到包含安装程序的目录,并启动初始化 OpenShift Container Platform 控制平面的引导过程
$ ./openshift-install wait-for bootstrap-complete --dir <installation_directory> \ (1)
--log-level=info (2)
1 | 对于 <安装目录> ,请指定您存储安装文件的目录的路径。 |
2 | 要查看不同的安装详细信息,请指定 warn 、debug 或 error 代替 info 。 |
INFO Waiting up to 20m0s for the Kubernetes API at https://api.mycluster.example.com:6443...
INFO API v1.30.3 up
INFO Waiting up to 30m0s for bootstrapping to complete...
INFO It is now safe to remove the bootstrap resources
INFO Time elapsed: 1s
如果命令退出时没有 FATAL
警告,则您的 OpenShift Container Platform 控制平面已初始化。
控制平面初始化后,它将设置计算节点并在 Operator 的形式下安装其他服务。 |
有关监视 OpenShift Container Platform 安装进度期间的安装、引导和控制平面日志的详细信息,请参见 监视安装进度。
有关解决与引导过程相关的问题的详细信息,请参见 收集引导节点诊断数据。
将机器添加到集群时,会为添加的每台机器生成两个挂起的证书签名请求 (CSR)。您必须确认这些 CSR 已批准,或者如有必要,自行批准它们。必须先批准客户端请求,然后再批准服务器请求。
您已将机器添加到集群。
确认集群识别机器
$ oc get nodes
NAME STATUS ROLES AGE VERSION
master-0 Ready master 63m v1.30.3
master-1 Ready master 63m v1.30.3
master-2 Ready master 64m v1.30.3
输出列出了您创建的所有机器。
在批准一些 CSR 之前,上述输出可能不包含计算节点(也称为工作节点)。 |
查看挂起的 CSR,并确保您看到为添加到集群的每台机器的客户端请求显示 Pending
或 Approved
状态
$ oc get csr
NAME AGE REQUESTOR CONDITION
csr-8b2br 15m system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending
csr-8vnps 15m system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending
...
在此示例中,两台机器正在加入集群。您可能会在列表中看到更多已批准的 CSR。
如果 CSR 未批准,在您添加的所有机器的挂起 CSR 都处于 Pending
状态后,请批准集群机器的 CSR
由于 CSR 会自动轮换,因此请在将机器添加到集群后一小时内批准您的 CSR。如果您在一小时内未批准它们,证书将轮换,并且每个节点将存在两个以上的证书。您必须批准所有这些证书。批准客户端 CSR 后,Kubelet 会为服务证书创建一个辅助 CSR,这需要手动批准。然后,如果 Kubelet 请求具有相同参数的新证书,则 |
对于在未启用机器 API 的平台(例如裸机和其他用户预配的基础设施)上运行的集群,您必须实现一种自动批准 kubelet 服务证书请求 (CSR) 的方法。如果未批准请求,则 |
要分别批准它们,请针对每个有效的 CSR 运行以下命令
$ oc adm certificate approve <csr_name> (1)
1 | <csr_name> 是当前 CSR 列表中 CSR 的名称。 |
要批准所有挂起的 CSR,请运行以下命令
$ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs --no-run-if-empty oc adm certificate approve
在批准一些 CSR 之前,某些 Operator 可能不可用。 |
现在您的客户端请求已批准,您必须检查添加到集群的每台机器的服务器请求
$ oc get csr
NAME AGE REQUESTOR CONDITION
csr-bfd72 5m26s system:node:ip-10-0-50-126.us-east-2.compute.internal Pending
csr-c57lv 5m26s system:node:ip-10-0-95-157.us-east-2.compute.internal Pending
...
如果剩余的 CSR 未批准且处于 Pending
状态,请批准集群机器的 CSR
要分别批准它们,请针对每个有效的 CSR 运行以下命令
$ oc adm certificate approve <csr_name> (1)
1 | <csr_name> 是当前 CSR 列表中 CSR 的名称。 |
要批准所有挂起的 CSR,请运行以下命令
$ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approve
批准所有客户端和服务器 CSR 后,机器将具有 Ready
状态。通过运行以下命令验证这一点
$ oc get nodes
NAME STATUS ROLES AGE VERSION
master-0 Ready master 73m v1.30.3
master-1 Ready master 73m v1.30.3
master-2 Ready master 74m v1.30.3
worker-0 Ready worker 11m v1.30.3
worker-1 Ready worker 11m v1.30.3
批准服务器 CSR 后,机器可能需要几分钟才能过渡到 |
控制平面初始化后,您必须立即配置某些 Operator,以便所有 Operator 都可用。
您的控制平面已初始化。
监视集群组件上线
$ watch -n5 oc get clusteroperators
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE
authentication 4.17.0 True False False 19m
baremetal 4.17.0 True False False 37m
cloud-credential 4.17.0 True False False 40m
cluster-autoscaler 4.17.0 True False False 37m
config-operator 4.17.0 True False False 38m
console 4.17.0 True False False 26m
csi-snapshot-controller 4.17.0 True False False 37m
dns 4.17.0 True False False 37m
etcd 4.17.0 True False False 36m
image-registry 4.17.0 True False False 31m
ingress 4.17.0 True False False 30m
insights 4.17.0 True False False 31m
kube-apiserver 4.17.0 True False False 26m
kube-controller-manager 4.17.0 True False False 36m
kube-scheduler 4.17.0 True False False 36m
kube-storage-version-migrator 4.17.0 True False False 37m
machine-api 4.17.0 True False False 29m
machine-approver 4.17.0 True False False 37m
machine-config 4.17.0 True False False 36m
marketplace 4.17.0 True False False 37m
monitoring 4.17.0 True False False 29m
network 4.17.0 True False False 38m
node-tuning 4.17.0 True False False 37m
openshift-apiserver 4.17.0 True False False 32m
openshift-controller-manager 4.17.0 True False False 30m
openshift-samples 4.17.0 True False False 32m
operator-lifecycle-manager 4.17.0 True False False 37m
operator-lifecycle-manager-catalog 4.17.0 True False False 37m
operator-lifecycle-manager-packageserver 4.17.0 True False False 32m
service-ca 4.17.0 True False False 38m
storage 4.17.0 True False False 37m
配置不可用的 Operator。
在 OpenShift Container Platform 安装期间,默认情况下,为 OperatorHub 配置了由 Red Hat 和社区项目提供的 Operator 目录内容。在受限制的网络环境中,您必须以集群管理员身份禁用默认目录。
通过将 disableAllDefaultSources: true
添加到 OperatorHub
对象来禁用默认目录的源
$ oc patch OperatorHub cluster --type json \
-p '[{"op": "add", "path": "/spec/disableAllDefaultSources", "value": true}]'
或者,您可以使用 Web 控制台管理目录源。在**管理** → **集群设置** → **配置** → **OperatorHub** 页面中,单击**源**选项卡,您可以在其中创建、更新、删除、禁用和启用各个源。 |
Amazon Web Services 提供默认存储,这意味着 Image Registry Operator 在安装后可用。但是,如果 Registry Operator 无法创建 S3 存储桶并自动配置存储,则您必须手动配置注册表存储。
显示了配置持久卷的说明,生产集群需要持久卷。在适用的情况下,将显示将空目录配置为存储位置的说明,该位置仅适用于非生产集群。
提供了其他说明,用于通过在升级期间使用 Recreate
展开策略来允许镜像注册表使用块存储类型。
安装期间,您的云凭据足以创建 Amazon S3 存储桶,并且 Registry Operator 将自动配置存储。
如果 Registry Operator 无法创建 S3 存储桶并自动配置存储,您可以使用以下过程创建 S3 存储桶并配置存储。
您在 AWS 上拥有一个使用用户预配的基础设施的集群。
对于 Amazon S3 存储,密钥预计包含两个密钥
REGISTRY_STORAGE_S3_ACCESSKEY
REGISTRY_STORAGE_S3_SECRETKEY
如果注册表操作员无法创建 S3 存储桶并自动配置存储,请使用以下步骤。
设置一个存储桶生命周期策略,用于中止超过一天的未完成分块上传。
在configs.imageregistry.operator.openshift.io/cluster
中填写存储配置
$ oc edit configs.imageregistry.operator.openshift.io/cluster
storage:
s3:
bucket: <bucket-name>
region: <region-name>
为了保护您在 AWS 中的注册表镜像,请阻止对 S3 存储桶的公共访问。 |
您必须为镜像注册表操作员配置存储。对于非生产集群,您可以将镜像注册表设置为一个空目录。如果您这样做,如果重新启动注册表,所有镜像都将丢失。
将镜像注册表存储设置为空目录
$ oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"storage":{"emptyDir":{}}}}'
仅为非生产集群配置此选项。 |
如果您在镜像注册表操作员初始化其组件之前运行此命令,则oc patch
命令将失败,并显示以下错误
Error from server (NotFound): configs.imageregistry.operator.openshift.io "cluster" not found
等待几分钟,然后再次运行该命令。
完成集群的初始操作员配置后,请从 Amazon Web Services (AWS) 中删除引导资源。
您已完成集群的初始操作员配置。
删除引导资源。如果您使用了 CloudFormation 模板,请删除其堆栈
使用 AWS CLI 删除堆栈
$ aws cloudformation delete-stack --stack-name <name> (1)
1 | <name> 是您的引导堆栈的名称。 |
使用AWS CloudFormation 控制台删除堆栈。
如果您删除了 DNS 区域配置,请手动创建指向 Ingress 负载均衡器的 DNS 记录。您可以创建通配符记录或特定记录。虽然以下步骤使用 A 记录,但您可以使用您需要的其他记录类型,例如 CNAME 或别名。
您在 Amazon Web Services (AWS) 上部署了一个 OpenShift Container Platform 集群,该集群使用您预配的基础架构。
您已安装 OpenShift CLI (oc
)。
您已安装 jq
包。
您已下载 AWS CLI 并将其安装在您的计算机上。请参阅使用捆绑安装程序安装 AWS CLI(Linux、macOS 或 Unix)。
确定要创建的路由。
要创建通配符记录,请使用*.apps.<cluster_name>.<domain_name>
,其中<cluster_name>
是您的集群名称,<domain_name>
是您的 OpenShift Container Platform 集群的 Route 53 基础域名。
要创建特定记录,您必须为集群使用的每个路由创建一个记录,如以下命令的输出所示
$ oc get --all-namespaces -o jsonpath='{range .items[*]}{range .status.ingress[*]}{.host}{"\n"}{end}{end}' routes
oauth-openshift.apps.<cluster_name>.<domain_name>
console-openshift-console.apps.<cluster_name>.<domain_name>
downloads-openshift-console.apps.<cluster_name>.<domain_name>
alertmanager-main-openshift-monitoring.apps.<cluster_name>.<domain_name>
prometheus-k8s-openshift-monitoring.apps.<cluster_name>.<domain_name>
检索 Ingress Operator 负载均衡器状态,并记下其使用的外部 IP 地址的值,该值显示在EXTERNAL-IP
列中
$ oc -n openshift-ingress get service router-default
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
router-default LoadBalancer 172.30.62.215 ab3...28.us-east-2.elb.amazonaws.com 80:31499/TCP,443:30693/TCP 5m
找到负载均衡器的托管区域 ID
$ aws elb describe-load-balancers | jq -r '.LoadBalancerDescriptions[] | select(.DNSName == "<external_ip>").CanonicalHostedZoneNameID' (1)
1 | 对于<external_ip> ,请指定您获得的 Ingress Operator 负载均衡器的外部 IP 地址的值。 |
Z3AADJGX6KTTL2
此命令的输出是负载均衡器托管区域 ID。
获取集群域的公共托管区域 ID
$ aws route53 list-hosted-zones-by-name \
--dns-name "<domain_name>" \ (1)
--query 'HostedZones[? Config.PrivateZone != `true` && Name == `<domain_name>.`].Id' (1)
--output text
1 | 对于<domain_name> ,请指定您的 OpenShift Container Platform 集群的 Route 53 基础域名。 |
/hostedzone/Z3URY6TWQ91KVV
您的域的公共托管区域 ID 显示在命令输出中。在此示例中,它是Z3URY6TWQ91KVV
。
将别名记录添加到您的私有区域
$ aws route53 change-resource-record-sets --hosted-zone-id "<private_hosted_zone_id>" --change-batch '{ (1)
> "Changes": [
> {
> "Action": "CREATE",
> "ResourceRecordSet": {
> "Name": "\\052.apps.<cluster_domain>", (2)
> "Type": "A",
> "AliasTarget":{
> "HostedZoneId": "<hosted_zone_id>", (3)
> "DNSName": "<external_ip>.", (4)
> "EvaluateTargetHealth": false
> }
> }
> }
> ]
> }'
1 | 对于<private_hosted_zone_id> ,请指定 CloudFormation 模板中 DNS 和负载均衡的输出值。 |
2 | 对于<cluster_domain> ,请指定您与 OpenShift Container Platform 集群一起使用的域名或子域名。 |
3 | 对于<hosted_zone_id> ,请指定您获得的负载均衡器的公共托管区域 ID。 |
4 | 对于<external_ip> ,请指定 Ingress Operator 负载均衡器的外部 IP 地址的值。确保在此参数值中包含尾随句点 (. )。 |
将记录添加到您的公共区域
$ aws route53 change-resource-record-sets --hosted-zone-id "<public_hosted_zone_id>"" --change-batch '{ (1)
> "Changes": [
> {
> "Action": "CREATE",
> "ResourceRecordSet": {
> "Name": "\\052.apps.<cluster_domain>", (2)
> "Type": "A",
> "AliasTarget":{
> "HostedZoneId": "<hosted_zone_id>", (3)
> "DNSName": "<external_ip>.", (4)
> "EvaluateTargetHealth": false
> }
> }
> }
> ]
> }'
1 | 对于<public_hosted_zone_id> ,请指定您域的公共托管区域。 |
2 | 对于<cluster_domain> ,请指定您与 OpenShift Container Platform 集群一起使用的域名或子域名。 |
3 | 对于<hosted_zone_id> ,请指定您获得的负载均衡器的公共托管区域 ID。 |
4 | 对于<external_ip> ,请指定 Ingress Operator 负载均衡器的外部 IP 地址的值。确保在此参数值中包含尾随句点 (. )。 |
在 Amazon Web Service (AWS) 用户预配的基础架构上启动 OpenShift Container Platform 安装后,监控部署直至完成。
您已删除在用户预配的 AWS 基础架构上的 OpenShift Container Platform 集群的引导节点。
您已安装oc
CLI。
从包含安装程序的目录中,完成集群安装
$ ./openshift-install --dir <installation_directory> wait-for install-complete (1)
1 | 对于 <安装目录> ,请指定您存储安装文件的目录的路径。 |
INFO Waiting up to 40m0s for the cluster at https://api.mycluster.example.com:6443 to initialize...
INFO Waiting up to 10m0s for the openshift-console route to be created...
INFO Install complete!
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/myuser/install_dir/auth/kubeconfig'
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.mycluster.example.com
INFO Login to the console with user: "kubeadmin", and password: "password"
INFO Time elapsed: 1s
|
在集群注册页面上注册您的集群。
您可以通过导出集群kubeconfig
文件以默认系统用户身份登录到您的集群。kubeconfig
文件包含有关集群的信息,CLI 使用这些信息将客户端连接到正确的集群和 API 服务器。该文件特定于集群,并在 OpenShift Container Platform 安装期间创建。
您已部署 OpenShift Container Platform 集群。
您已安装oc
CLI。
导出kubeadmin
凭据
$ export KUBECONFIG=<installation_directory>/auth/kubeconfig (1)
1 | 对于 <安装目录> ,请指定您存储安装文件的目录的路径。 |
验证您可以使用导出的配置成功运行oc
命令
$ oc whoami
system:admin
OpenShift Container Platform 安装后,默认情况下存在kubeadmin
用户。您可以使用 OpenShift Container Platform Web 控制台以kubeadmin
用户身份登录到您的集群。
您可以访问安装主机。
您已完成集群安装,并且所有集群操作员都可用。
从安装主机上的kubeadmin-password
文件中获取kubeadmin
用户的密码
$ cat <installation_directory>/auth/kubeadmin-password
或者,您可以从安装主机上的 |
列出 OpenShift Container Platform Web 控制台路由
$ oc get routes -n openshift-console | grep 'console-openshift'
或者,您可以从安装主机上的 |
console console-openshift-console.apps.<cluster_name>.<base_domain> console https reencrypt/Redirect None
在 Web 浏览器中导航到前面命令输出中详细说明的路由,并以kubeadmin
用户身份登录。
有关访问和了解 OpenShift Container Platform Web 控制台的更多详细信息,请参阅访问 Web 控制台。
更多关于遥测服务的信息,请参见关于远程健康监控
更多关于 AWS CloudFormation 堆栈的信息,请参见 AWS 文档中的堆栈操作。
验证安装.
为集群示例操作符和must-gather
工具配置镜像流。
了解如何在断开连接的环境中使用操作符生命周期管理器。
如果您用于安装集群的镜像注册表具有受信任的 CA,请通过配置额外的信任存储将其添加到集群中。
如有必要,您可以选择退出远程健康报告。
如有必要,请参见注册您的断开连接的集群
如有必要,您可以删除云提供商凭据。