4.11.12. 在 AWS 中创建 bootstrap 节点

您必须在 Amazon Web Services (AWS) 中创建 bootstrap 节点,以便在 OpenShift Container Platform 集群初始化过程中使用。

您可以使用提供的 CloudFormation 模板和自定义参数文件来创建 AWS 资源堆栈。堆栈代表 OpenShift Container Platform 安装所需的 bootstrap 节点。

注意

如果不使用提供的 CloudFormation 模板来创建 bootstrap 节点,您必须检查提供的信息并手动创建基础架构。如果集群没有正确初始化,您可能需要联系红帽支持并提供您的安装日志。

先决条件

  • 已配置了一个 AWS 帐户。
  • 您可以通过运行 aws configure,将 AWS 密钥和区域添加到本地 AWS 配置集中。
  • 已为集群生成 Ignition 配置文件。
  • 您在 AWS 中创建并配置了 VPC 及相关子网。
  • 您在 AWS 中创建并配置了 DNS、负载均衡器和监听程序。
  • 您在 AWS 中创建了集群所需的安全组和角色。

流程

  1. 提供一个位置,以便向集群提供 bootstrap.ign Ignition 配置文件。此文件位于您的安装目录中。达成此目标的一种方式是在集群区域中创建一个 S3 存储桶,并将 Ignition 配置文件上传到其中。

    重要

    提供的 CloudFormation 模板假定集群的 Ignition 配置文件由 S3 存储桶提供。如果选择从其他位置提供文件,您必须修改模板。

    重要

    如果您部署到具有与 AWS SDK 不同的端点,或者您提供自己的自定义端点的区域,则必须为 S3 存储桶使用预签名 URL 而不是 s3:// 模式。

    注意

    bootstrap Ignition 配置文件包含 secret,如 X.509 密钥。以下步骤为 S3 存储桶提供基本安全性。若要提供额外的安全性,您可以启用 S3 存储桶策略,仅允许某些用户(如 OpenShift IAM 用户)访问存储桶中包含的对象。您可以完全避开 S3,并从 bootstrap 可访问的任意地址提供 bootstrap Ignition 配置文件。

    1. 创建存储桶:

      $ aws s3 mb s3://<cluster-name>-infra 1
      1
      <cluster-name>-infra 是存储桶名称。在创建 install-config.yaml 文件时,将 <cluster-name> 替换为为集群指定的名称。
    2. bootstrap.ign Ignition 配置文件上传到存储桶:

      $ aws s3 cp <installation_directory>/bootstrap.ign s3://<cluster-name>-infra/bootstrap.ign 1
      1
      对于 <installation_directory>,请指定安装文件保存到的目录的路径。
    3. 验证文件已经上传:

      $ aws s3 ls s3://<cluster-name>-infra/

      输出示例

      2019-04-03 16:15:16     314878 bootstrap.ign

  2. 创建一个 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:<region>:<account_number>:function:<dns_stack_name>-RegisterNlbIpTargets-<random_string>" 18
      },
      {
        "ParameterKey": "ExternalApiTargetGroupArn", 19
        "ParameterValue": "arn:aws:elasticloadbalancing:<region>:<account_number>:targetgroup/<dns_stack_name>-Exter-<random_string>" 20
      },
      {
        "ParameterKey": "InternalApiTargetGroupArn", 21
        "ParameterValue": "arn:aws:elasticloadbalancing:<region>:<account_number>:targetgroup/<dns_stack_name>-Inter-<random_string>" 22
      },
      {
        "ParameterKey": "InternalServiceTargetGroupArn", 23
        "ParameterValue": "arn:aws:elasticloadbalancing:<region>:<account_number>:targetgroup/<dns_stack_name>-Inter-<random_string>" 24
      }
    ]
    1
    您的 Ignition 配置文件中为集群编码的集群基础架构名称。
    2
    指定从 Ignition 配置文件元数据中提取的基础架构名称,其格式为 <cluster-name>-<random-string>
    3
    用于 bootstrap 节点的当前 Red Hat Enterprise Linux CoreOS (RHCOS) AMI。
    4
    指定有效的 AWS::EC2::Image::Id 值。
    5
    允许通过 SSH 访问 bootstrap 节点的 CIDR 块。
    6
    x.x.x.x/16-24 格式指定 CIDR 块。
    7
    与 VPC 关联的公共子网,将 bootstrap 节点启动到其中。
    8
    指定 VPC 的 CloudFormation 模板输出的 PublicSubnetIds 值。
    9
    master 安全组 ID(用于注册临时规则)
    10
    指定安全组和角色的 CloudFormation 模板输出的 MasterSecurityGroupId 值。
    11
    创建的资源将从属于的 VPC。
    12
    指定 VPC 的 CloudFormation 模板输出的 VpcId 值。
    13
    从中获取 bootstrap Ignition 配置文件的位置。
    14
    指定 S3 存储桶和文件名,格式为 s3://<bucket_name>/bootstrap.ign
    15
    是否要注册网络负载均衡器 (NLB) 。
    16
    指定 yesno。如果指定 yes,您必须提供一个 Lambda Amazon Resource Name (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
  3. 复制本主题的 Bootstrap 机器的 CloudFormation 模板部分中的模板,并将它以 YAML 文件形式保存到计算机上。此模板描述了集群所需的 bootstrap 机器。
  4. 启动 CloudFormation 模板,以创建代表 bootstrap 节点的 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
    <template> 是您保存的 CloudFormation 模板 YAML 文件的相对路径和名称。
    3
    <parameters> 是 CloudFormation 参数 JSON 文件的相对路径和名称。
    4
    您必须明确声明 CAPABILITY_NAMED_IAM 功能,因为提供的模板会创建一些 AWS::IAM::RoleAWS::IAM::InstanceProfile 资源。

    输出示例

    arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-bootstrap/12944486-2add-11eb-9dee-12dace8e3a83

  5. 确认模板组件已存在:

    $ aws cloudformation describe-stacks --stack-name <name>

    StackStatus 显示 CREATE_COMPLETE 后,输出会显示以下参数的值。您必须将这些参数值提供给您在创建集群时要运行的其他 CloudFormation 模板:

    BootstrapInstanceId

    bootstrap 实例 ID。

    BootstrapPublicIp

    bootstrap 节点公共 IP 地址。

    BootstrapPrivateIp

    bootstrap 节点专用 IP 地址。

4.11.12.1. bootstrap 机器的 CloudFormation 模板

您可以使用以下 CloudFormation 模板来部署 OpenShift Container Platform 集群所需的 bootstrap 机器。

例 4.34. bootstrap 机器的 CloudFormation 模板

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

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: "i3.large"
      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

其他资源