本文档采用自动化机器翻译技术翻译。 尽管我们力求提供准确的译文,但不对翻译内容的完整性、准确性或可靠性作出任何保证。 若出现任何内容不一致情况,请以原始 英文 版本为准,且原始英文版本为权威文本。

设置亚马逊云提供商

重要说明:

在 Kubernetes 1.27 及更高版本中,您必须使用外部 AWS 云提供商。内部云提供商已被弃用。亚马逊云提供商已被完全移除,升级到 Kubernetes 1.27 后将无法使用。下面列出的步骤仍然需要设置亚马逊云提供商。您可以在创建 IAM 角色并配置 ClusterID 后设置外部云提供商

您还可以在 Kubernetes 1.26 及更早版本上从内部迁移到外部 AWS 云提供商。所有现有集群必须在升级到 v1.27 之前进行迁移,以保持功能正常。

从 Kubernetes 1.23 开始,您必须停用 CSIMigrationAWS 功能门控才能使用内部 AWS 云提供商。您可以通过在高级集群配置中将 feature-gates=CSIMigrationAWS=false 设置为集群的 Kubelet、控制器管理器、API 服务器和调度程序的附加参数来实现。

当您使用亚马逊作为云提供商时,您可以利用以下功能:

  • 负载均衡器:*当您在 *端口映射 中选择 Layer-4 Load Balancer 或者在启动带有 type: LoadBalancerService 时,启动 AWS 弹性负载均衡器 (ELB)。

  • 持久卷:使用 AWS 弹性块存储 (EBS) 作为持久卷。

有关亚马逊云提供商的更多信息,请参见 cloud-provider-aws README

要设置亚马逊云提供商,

1.创建 IAM 角色并附加到实例

所有添加到集群的节点必须能够与 EC2 交互,以便它们可以创建和删除资源。您可以通过使用附加到实例的 IAM 角色来启用此交互。请参阅 亚马逊文档:创建 IAM 角色 了解如何创建 IAM 角色。有两个示例策略:

  • 第一个策略适用于具有 controlplane 角色的节点。这些节点必须能够创建/删除 EC2 资源。以下 IAM 策略是一个示例,请根据您的用例删除任何不需要的权限。

  • 第二个策略适用于具有 etcdworker 角色的节点。这些节点只需能够从 EC2 检索信息。

在创建 亚马逊 EC2 集群 时,您必须在创建 节点模板 时填写所创建 IAM 角色的 IAM 实例配置文件名称(不是 ARN)。

在创建 自定义集群 时,您必须手动将 IAM 角色附加到实例。

具有 controlplane 角色的节点的 IAM 策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "autoscaling:DescribeAutoScalingGroups",
        "autoscaling:DescribeLaunchConfigurations",
        "autoscaling:DescribeTags",
        "ec2:DescribeInstances",
        "ec2:DescribeRegions",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeRouteTables",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets",
        "ec2:DescribeVolumes",
        "ec2:CreateSecurityGroup",
        "ec2:CreateTags",
        "ec2:CreateVolume",
        "ec2:ModifyInstanceAttribute",
        "ec2:ModifyVolume",
        "ec2:AttachVolume",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:CreateRoute",
        "ec2:DeleteRoute",
        "ec2:DeleteSecurityGroup",
        "ec2:DeleteVolume",
        "ec2:DetachVolume",
        "ec2:RevokeSecurityGroupIngress",
        "ec2:DescribeVpcs",
        "elasticloadbalancing:AddTags",
        "elasticloadbalancing:AttachLoadBalancerToSubnets",
        "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
        "elasticloadbalancing:CreateLoadBalancer",
        "elasticloadbalancing:CreateLoadBalancerPolicy",
        "elasticloadbalancing:CreateLoadBalancerListeners",
        "elasticloadbalancing:ConfigureHealthCheck",
        "elasticloadbalancing:DeleteLoadBalancer",
        "elasticloadbalancing:DeleteLoadBalancerListeners",
        "elasticloadbalancing:DescribeLoadBalancers",
        "elasticloadbalancing:DescribeLoadBalancerAttributes",
        "elasticloadbalancing:DetachLoadBalancerFromSubnets",
        "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
        "elasticloadbalancing:ModifyLoadBalancerAttributes",
        "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
        "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",
        "elasticloadbalancing:AddTags",
        "elasticloadbalancing:CreateListener",
        "elasticloadbalancing:CreateTargetGroup",
        "elasticloadbalancing:DeleteListener",
        "elasticloadbalancing:DeleteTargetGroup",
        "elasticloadbalancing:DescribeListeners",
        "elasticloadbalancing:DescribeLoadBalancerPolicies",
        "elasticloadbalancing:DescribeTargetGroups",
        "elasticloadbalancing:DescribeTargetHealth",
        "elasticloadbalancing:ModifyListener",
        "elasticloadbalancing:ModifyTargetGroup",
        "elasticloadbalancing:RegisterTargets",
        "elasticloadbalancing:SetLoadBalancerPoliciesOfListener",
        "iam:CreateServiceLinkedRole",
        "kms:DescribeKey"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

具有 etcdworker 角色的节点的 IAM 策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:DescribeRegions",
        "ec2:DescribeAvailabilityZones",
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:GetRepositoryPolicy",
        "ecr:DescribeRepositories",
        "ecr:ListImages",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    }
  ]
}

2.配置 ClusterID

以下资源需要标记为 ClusterID

  • 节点:在Rancher中添加的所有主机。

  • 子网:用于您的集群的子网。

  • 安全组:用于您的集群的安全组。

请勿标记多个安全组。标记多个组在创建弹性负载均衡器(ELB)时会导致错误。

当您创建 亚马逊 EC2 集群 时,ClusterID 会自动为所创建的节点配置。其他资源仍需手动标记。

请使用以下标签:

= kubernetes.io/cluster/<cluster-id> = owned

将标签的值设置为 owned 告诉集群所有带有此标签的资源由该集群拥有和管理。

如果您在集群之间共享资源,可以将标签更改为:

= kubernetes.io/cluster/<cluster-id> = shared

字符串值 <cluster-id> 是 Kubernetes 集群的 ID。

不要给资源标记多个拥有或共享的标签。

使用亚马逊弹性容器注册表 (ECR)

当在 创建 IAM 角色并附加到实例 中提到的 IAM 控制文件被附加到实例时,kubelet 组件能够自动获取 ECR 凭证。在使用 Kubernetes 版本低于 v1.15.0 时,需要在集群中配置亚马逊云提供商。从 Kubernetes 版本 v1.15.0 开始,kubelet 可以在未配置亚马逊云提供商的情况下获取 ECR 凭证。

使用外部 AWS 云提供商

  • RKE2

  • RKE

  1. 必须遵循 节点名称约定和其他先决条件,以便云提供商能够正确找到实例。

  2. Rancher 管理的 RKE2/K3s 集群不支持配置 providerID。但是,如果在配置集群对象上设置以下配置,引擎将正确设置节点名称:

    spec:
      rkeConfig:
        machineGlobalConfig:
          cloud-provider-name: aws

    此选项将传递给在节点上运行的各种 Kubernetes 组件的配置,并且必须逐个组件覆盖,以防止内部云提供商意外运行:

    在 Etcd 上覆盖:

    spec:
      rkeConfig:
        machineSelectorConfig:
          - config:
              kubelet-arg:
                - cloud-provider=external
            machineLabelSelector:
              matchExpressions:
                - key: rke.cattle.io/etcd-role
                  operator: In
                  values:
                    - 'true'

    在控制平面上覆盖:

    spec:
      rkeConfig:
        machineSelectorConfig:
          - config:
            disable-cloud-controller: true
            kube-apiserver-arg:
              - cloud-provider=external
            kube-controller-manager-arg:
              - cloud-provider=external
            kubelet-arg:
              - cloud-provider=external
            machineLabelSelector:
              matchExpressions:
                - key: rke.cattle.io/control-plane-role
                  operator: In
                  values:
                    - 'true'

    在工作节点上覆盖:

    spec:
      rkeConfig:
        machineSelectorConfig:
          - config:
              kubelet-arg:
                - cloud-provider=external
            machineLabelSelector:
              matchExpressions:
                - key: rke.cattle.io/worker-role
                  operator: In
                  values:
                    - 'true'
  3. 如果依赖上述机制设置提供商 ID,请选择 Amazon。否则,选择 外部云提供商 云提供商,该提供商为 Kubernetes 组件设置 --cloud-provider=external

  4. 指定 aws-cloud-controller-manager Helm 图表作为要安装的附加清单:

    spec:
      rkeConfig:
        additionalManifest: |-
          apiVersion: helm.cattle.io/v1
          kind: HelmChart
          metadata:
            name: aws-cloud-controller-manager
            namespace: kube-system
          spec:
            chart: aws-cloud-controller-manager
            repo: https://kubernetes.github.io/cloud-provider-aws
            targetNamespace: kube-system
            bootstrap: true
            valuesContent: |-
              hostNetworking: true
              nodeSelector:
                node-role.kubernetes.io/control-plane: "true"
              args:
                - --configure-cloud-routes=false
                - --v=5
                - --cloud-provider=aws
  1. 必须遵循 节点名称约定和其他先决条件,以便云提供商能够找到实例。Rancher 配置的集群不支持配置 providerID

    如果您使用基于 IP 的命名,节点必须以实例名称命名,后面跟着区域域名 (ip-xxx-xxx-xxx-xxx.ec2.<region>.internal)。如果您在 DHCP 选项中设置了自定义域名,则必须在 kube-proxykubelet 上设置 --hostname-override 以匹配此命名约定。

    为了满足节点命名约定,当选择 External Amazon 云提供商时,Rancher 允许设置 useInstanceMetadataHostname。启用 useInstanceMetadataHostname 将查询 EC2 元数据服务,并将 /hostname 设置为 hostname-override,适用于 kubeletkube-proxy

    rancher_kubernetes_engine_config:
      cloud_provider:
        name: external-aws
        useInstanceMetadataHostname: true

    在为自定义集群设置 hostname-override 的自定义值时,您不得启用 useInstanceMetadataHostname。当您创建一个 自定义集群 时,向 docker run 节点注册命令添加 --node-name 以设置 hostname-override --,例如 "$(hostname -f)"。这可以手动完成,或通过在 Rancher UI 中使用 显示高级选项 来添加 节点名称

  2. 选择云提供商。

    选择 外部 Amazon(树外) 将设置 --cloud-provider=external 并启用 useInstanceMetadataHostname。如步骤 1 中所述,启用 useInstanceMetadataHostname 将查询 EC2 元数据服务,并将 http://169.254.169.254/latest/meta-data/hostname 设置为 hostname-override,适用于 kubeletkube-proxy

    在通过 node-name 为自定义集群设置自定义节点名称时,您必须禁用 useInstanceMetadataHostname

    rancher_kubernetes_engine_config:
      cloud_provider:
        name: external-aws
        useInstanceMetadataHostname: true/false

    使用 外部 云提供商的现有集群将为 Kubernetes 组件设置 --cloud-provider=external,但不会设置节点名称。

  3. 在集群完成配置后安装 AWS 云控制器管理器。请注意,在部署云控制器管理器之前,集群尚未成功配置,节点仍处于 uninitialized 状态。这可以手动完成,或通过 UI 中的 Helm 图表 完成。

    请参考官方 AWS 上游文档,了解 云控制器管理器

通过 CLI 安装 Helm 图表

  • RKE2

  • RKE

关于 Helm 图表安装 的官方上游文档可以在 GitHub 上找到。

  1. 添加 Helm 储存库:

    helm repo add aws-cloud-controller-manager https://kubernetes.github.io/cloud-provider-aws
    helm repo update
  2. 创建一个包含以下内容的 values.yaml 文件以覆盖默认 values.yaml

    # values.yaml
    hostNetworking: true
    tolerations:
      - effect: NoSchedule
        key: node.cloudprovider.kubernetes.io/uninitialized
        value: 'true'
      - effect: NoSchedule
        value: 'true'
        key: node-role.kubernetes.io/control-plane
    nodeSelector:
      node-role.kubernetes.io/control-plane: 'true'
    args:
      - --configure-cloud-routes=false
      - --use-service-account-credentials=true
      - --v=2
      - --cloud-provider=aws
    clusterRoleRules:
      - apiGroups:
          - ""
        resources:
          - events
        verbs:
          - create
          - patch
          - update
      - apiGroups:
          - ""
        resources:
          - nodes
        verbs:
          - '*'
      - apiGroups:
          - ""
        resources:
          - nodes/status
        verbs:
          - patch
      - apiGroups:
          - ""
        resources:
          - services
        verbs:
          - list
          - patch
          - update
          - watch
      - apiGroups:
          - ""
        resources:
          - services/status
        verbs:
          - list
          - patch
          - update
          - watch
      - apiGroups:
         - ''
        resources:
          - serviceaccounts
        verbs:
        - create
        - get
      - apiGroups:
          - ""
        resources:
          - persistentvolumes
        verbs:
          - get
          - list
          - update
          - watch
      - apiGroups:
          - ""
        resources:
          - endpoints
        verbs:
          - create
          - get
          - list
          - watch
          - update
      - apiGroups:
          - coordination.k8s.io
        resources:
          - leases
        verbs:
          - create
          - get
          - list
          - watch
          - update
      - apiGroups:
          - ""
        resources:
          - serviceaccounts/token
        verbs:
          - create
  3. 安装 Helm 图表:

    helm upgrade --install aws-cloud-controller-manager aws-cloud-controller-manager/aws-cloud-controller-manager --values values.yaml

    验证 Helm 图表是否成功安装:

    helm status -n kube-system aws-cloud-controller-manager
  4. (可选)验证云控制器管理器更新是否成功:

    kubectl rollout status daemonset -n kube-system aws-cloud-controller-manager

关于 Helm 图表安装 的官方上游文档可以在 GitHub 上找到。

  1. 添加 Helm 储存库:

    helm repo add aws-cloud-controller-manager https://kubernetes.github.io/cloud-provider-aws
    helm repo update
  2. 创建一个包含以下内容的 values.yaml 文件以覆盖默认 values.yaml

    # values.yaml
    hostNetworking: true
    tolerations:
      - effect: NoSchedule
        key: node.cloudprovider.kubernetes.io/uninitialized
        value: 'true'
      - effect: NoSchedule
        value: 'true'
        key: node-role.kubernetes.io/controlplane
    nodeSelector:
      node-role.kubernetes.io/controlplane: 'true'
    args:
      - --configure-cloud-routes=false
      - --use-service-account-credentials=true
      - --v=2
      - --cloud-provider=aws
    clusterRoleRules:
      - apiGroups:
          - ""
        resources:
          - events
        verbs:
          - create
          - patch
          - update
      - apiGroups:
          - ""
        resources:
          - nodes
        verbs:
          - '*'
      - apiGroups:
          - ""
        resources:
          - nodes/status
        verbs:
          - patch
      - apiGroups:
          - ""
        resources:
          - services
        verbs:
          - list
          - patch
          - update
          - watch
      - apiGroups:
          - ""
        resources:
          - services/status
        verbs:
          - list
          - patch
          - update
          - watch
      - apiGroups:
         - ''
        resources:
          - serviceaccounts
        verbs:
        - create
        - get
      - apiGroups:
          - ""
        resources:
          - persistentvolumes
        verbs:
          - get
          - list
          - update
          - watch
      - apiGroups:
          - ""
        resources:
          - endpoints
        verbs:
          - create
          - get
          - list
          - watch
          - update
      - apiGroups:
          - coordination.k8s.io
        resources:
          - leases
        verbs:
          - create
          - get
          - list
          - watch
          - update
      - apiGroups:
          - ""
        resources:
          - serviceaccounts/token
        verbs:
          - create
  3. 安装 Helm 图表:

    helm upgrade --install aws-cloud-controller-manager -n kube-system aws-cloud-controller-manager/aws-cloud-controller-manager --values values.yaml

    验证 Helm 图表是否成功安装:

    helm status -n kube-system aws-cloud-controller-manager
  4. 如果存在,请编辑 Daemonset 以去除默认节点选择器 node-role.kubernetes.io/control-plane: ""

    kubectl edit daemonset aws-cloud-controller-manager -n kube-system
  5. (可选)验证云控制器管理器更新是否成功:

    kubectl rollout status daemonset -n kube-system aws-cloud-controller-manager

通过 UI 安装 Helm 图表

  • RKE2

  • RKE

  1. 点击 ,然后从左侧导航中选择集群的名称。

  2. 选择 应用 > 储存库

  3. 点击 创建 按钮。

  4. 索引 URL 字段中输入 https://kubernetes.github.io/cloud-provider-aws

  5. 从左侧导航中选择 应用 > 图表 并安装 aws-cloud-controller-manager

  6. 选择名称空间 kube-system, 并启用 安装前自定义 Helm 选项

  7. 添加以下容器参数:

      - '--use-service-account-credentials=true'
      - '--configure-cloud-routes=false'
  8. get 添加到 verbs,以便在 clusterRoleRules 中获取 serviceaccounts 资源。这允许云控制器管理器在启动时获取服务账户。

      - apiGroups:
          - ''
        resources:
          - serviceaccounts
        verbs:
          - create
          - get
  9. Rancher 提供的 RKE2 节点被标记为 node-role.kubernetes.io/control-plane。更新容忍度和节点选择器:

    tolerations:
      - effect: NoSchedule
        key: node.cloudprovider.kubernetes.io/uninitialized
        value: 'true'
      - effect: NoSchedule
        value: 'true'
        key: node-role.kubernetes.io/control-plane
    nodeSelector:
      node-role.kubernetes.io/control-plane: 'true'

    目前存在一个 已知问题,节点选择器无法从 Rancher UI 更新。 继续安装图表,然后手动编辑 Daemonset 以设置 nodeSelector

    +

    nodeSelector:
      node-role.kubernetes.io/control-plane: 'true'
  10. 安装图表并确认 Daemonset aws-cloud-controller-manager 正在运行。验证 aws-cloud-controller-manager pods 在目标名称空间中运行(kube-system,除非在第 6 步中修改)。

  1. 点击 ,然后从左侧导航中选择集群的名称。

  2. 选择 应用 > 储存库

  3. 点击 创建 按钮。

  4. https://kubernetes.github.io/cloud-provider-aws 索引 URL 字段中输入。

  5. 从左侧导航中选择 APP > 图表 并安装 aws-cloud-controller-manager

  6. 选择名称空间 kube-system, 并启用 安装前自定义 Helm 选项

  7. 添加以下容器参数:

      - '--use-service-account-credentials=true'
      - '--configure-cloud-routes=false'
  8. get 添加到 verbs,用于 serviceaccounts 中的 clusterRoleRules 资源。这允许云控制器管理器在启动时获取服务账户:

      - apiGroups:
          - ''
        resources:
          - serviceaccounts
        verbs:
          - create
          - get
  9. Rancher 提供的 RKE 节点被标记为 node-role.kubernetes.io/controlplane。更新容忍度和节点选择器:

    tolerations:
      - effect: NoSchedule
        key: node.cloudprovider.kubernetes.io/uninitialized
        value: 'true'
      - effect: NoSchedule
        value: 'true'
        key: node-role.kubernetes.io/controlplane
    nodeSelector:
      node-role.kubernetes.io/controlplane: 'true'

    目前存在一个 已知问题nodeSelector 无法从 Rancher UI 更新。 继续安装图表,然后手动部署守护程序集以设置 nodeSelector

    +

    nodeSelector:
      node-role.kubernetes.io/controlplane: 'true'
  10. 安装图表并确认守护程序集 aws-cloud-controller-manager 成功部署:

    kubectl rollout status deployment -n kube-system aws-cloud-controller-manager