部署 Amazon EKS IPv6
集群和 Amazon Linux 托管节点
在本教程中,您将部署 IPv6
Amazon VPC、具有 IPv6
系列的 Amazon EKS 集群以及具有 Amazon EC2 Amazon Linux 节点的托管节点组。您无法在 IPv6
集群中部署 Amazon EC2 Windows 节点。您还可以将 Fargate 节点部署到集群,但为了简单起见,本主题中没有提供这些说明。
先决条件
开始教程前,请完成以下任务:
安装并配置创建和管理 Amazon EKS 集群所需的以下工具和资源。
-
我们建议您熟悉所有设置,并使用符合您要求的设置部署集群。有关更多信息,请参阅创建 Amazon EKS 集群。、使用托管式节点组简化节点生命周期和本主题中的注意事项。一些设置仅在创建集群时才能启用。
-
您的设备或 AWS CloudShell 上安装了
kubectl
命令行工具。该版本可以与集群的 Kubernetes 版本相同,或者最多早于或晚于该版本一个次要版本。例如,如果您的集群版本为1.29
,则可以将kubectl
的1.28
、1.29
或1.30
版本与之配合使用。要安装或升级kubectl
,请参阅 设置 kubectl 和 eksctl。 -
您正在使用的 IAM 安全主体必须具有使用 Amazon EKS IAM 角色、服务相关角色、AWS CloudFormation、VPC 和相关资源的权限。有关更多信息,请参阅《IAM 用户指南》中的操作和编辑服务相关角色。
-
如果您使用 eksctl,请在计算机上安装
0.194.0
或更高版本。要安装或更新该工具,请参阅eksctl
文档中的安装。 -
在您的设备或 AWS CloudShell 上安装和配置 AWS 命令行界面(AWS CLI)的版本
2.12.3
或更高版本,或版本1.27.160
或更高版本。要查看当前版本,请使用aws --version | cut -d / -f2 | cut -d ' ' -f1
。软件包管理器(如yum
、apt-get
或适用于 macOS 的 Homebrew)通常比 AWS CLI 的最新版本落后几个版本。要安装最新版本,请参阅《AWS 命令行界面用户指南》中的安装和使用 aws configure 快速配置。AWS CloudShell 中安装的 AWS CLI 版本也可能比最新版本落后几个版本。要对其进行更新,请参阅《AWS CloudShell 用户指南》中的将 AWS CLI 安装到您的主目录。如果您使用 AWS CloudShell,则可能需要安装版本 2.12.3 或更高版本或者 1.27.160 版或更高版本的 AWS CLI,因为 AWS CloudShell 中安装的默认 AWS CLI 版本可能是较早的版本。
您可以使用 eksctl 或 CLI 来部署 IPv6
集群。
使用 eksctl 部署 IPv6 集群
-
创建
ipv6-cluster.yaml
文件。将以下命令复制到您的设备。根据需要对该命令进行以下修改,然后运行修改后的命令:-
将
my-cluster
替换为您的集群名称。名称只能包含字母数字字符(区分大小写)和连字符。该名称必须以字母数字字符开头,且不得超过 100 个字符。对于您在其中创建集群的 AWS 区域和 AWS 账户,该名称必须在其内具有唯一性。 -
请将
region-code
替换为 Amazon EKS 支持的任何 AWS 区域。有关 AWS 区域列表,请参阅《AWS 一般参考》指南中的 Amazon EKS 服务端点和配额。 -
version
的值与您的集群版本有关。有关更多信息,请参阅 了解 EKS 上的 Kubernetes 版本生命周期。 -
将
my-nodegroup
替换为您的节点组的名称。节点组名称的长度不能超过 63 个字符。它必须以字母或数字开头,但也可以包括其余字符的连字符和下划线。 -
将
t3.medium
替换为任何 AWS Nitro 系统实例类型。cat >ipv6-cluster.yaml <<EOF --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster region: region-code version: "X.XX" kubernetesNetworkConfig: ipFamily: IPv6 addons: - name: vpc-cni version: latest - name: coredns version: latest - name: kube-proxy version: latest iam: withOIDC: true managedNodeGroups: - name: my-nodegroup instanceType: t3.medium EOF
-
-
创建您的集群。
eksctl create cluster -f ipv6-cluster.yaml
创建集群需要几分钟时间。在看到输出的最后一行(与以下输出类似)之前,不要继续操作。
[...] [✓] EKS cluster "my-cluster" in "region-code" region is ready
-
确认默认 Pods 已分配
IPv6
地址。kubectl get pods -n kube-system -o wide
示例输出如下。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES aws-node-rslts 1/1 Running 1 5m36s 2600:1f13:b66:8200:11a5:ade0:c590:6ac8 ip-192-168-34-75.region-code.compute.internal <none> <none> aws-node-t74jh 1/1 Running 0 5m32s 2600:1f13:b66:8203:4516:2080:8ced:1ca9 ip-192-168-253-70.region-code.compute.internal <none> <none> coredns-85d5b4454c-cw7w2 1/1 Running 0 56m 2600:1f13:b66:8203:34e5:: ip-192-168-253-70.region-code.compute.internal <none> <none> coredns-85d5b4454c-tx6n8 1/1 Running 0 56m 2600:1f13:b66:8203:34e5::1 ip-192-168-253-70.region-code.compute.internal <none> <none> kube-proxy-btpbk 1/1 Running 0 5m36s 2600:1f13:b66:8200:11a5:ade0:c590:6ac8 ip-192-168-34-75.region-code.compute.internal <none> <none> kube-proxy-jjk2g 1/1 Running 0 5m33s 2600:1f13:b66:8203:4516:2080:8ced:1ca9 ip-192-168-253-70.region-code.compute.internal <none> <none>
-
确认默认服务已分配
IPv6
地址。kubectl get services -n kube-system -o wide
示例输出如下。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kube-dns ClusterIP fd30:3087:b6c2::a <none> 53/UDP,53/TCP 57m k8s-app=kube-dns
-
(可选)部署示例应用程序或部署AWS 负载均衡器控制器和示例应用程序,对 HTTP 应用程序(通过 使用应用程序负载均衡器路由应用程序和 HTTP 流量)或流向
IPv6
Pods 的网络流量(通过使用网络负载均衡器路由 TCP 和 UDP 流量)进行负载均衡。 -
在使用完成针对本教程而创建的集群和节点后,应使用以下命令清理创建的资源。
eksctl delete cluster my-cluster
使用 AWS CLI 部署 IPv6 集群
重要
-
您必须以同一用户身份完成此程序中的所有步骤。要查看当前用户,请运行以下命令:
aws sts get-caller-identity
-
您必须在同一 shell 中完成此程序中的所有步骤。有几个步骤使用了之前步骤中设置的变量。如果在不同的 shell 中设置变量值,则使用这些变量的步骤将无法正常运行。如果使用 AWS CloudShell 完成以下程序,请记住,如果您在大约 20–30 分钟内没有使用键盘或指针与其交互,则 shell 会话将结束。正在运行的进程不算作交互。
-
这些说明是针对 Bash shell 编写的,在其他 shell 中可能需要调整。
将此程序步骤中的所有示例值
替换为您自己的值。
-
运行以下命令以设置在后面的步骤中使用的一些变量。将
region-code
替换为您想要在其中部署资源的 AWS 区域。该值可以是 Amazon EKS 支持的任何 AWS 区域。有关 AWS 区域列表,请参阅《AWS 一般参考》指南中的 Amazon EKS 服务端点和配额。将my-cluster
替换为您的集群名称。名称只能包含字母数字字符(区分大小写)和连字符。该名称必须以字母数字字符开头,且不得超过 100 个字符。对于您在其中创建集群的 AWS 区域和 AWS 账户,该名称必须在其内具有唯一性。将my-nodegroup
替换为您的节点组的名称。节点组名称的长度不能超过 63 个字符。它必须以字母或数字开头,但也可以包括其余字符的连字符和下划线。请将111122223333
替换为您的账户 ID。export region_code=region-code export cluster_name=my-cluster export nodegroup_name=my-nodegroup export account_id=111122223333
-
创建具有公有和私有子网且符合 Amazon EKS 和
IPv6
要求的 Amazon VPC。-
运行以下命令设置 AWS CloudFormation 堆栈名称的变量。您可以将
my-eks-ipv6-vpc
替换为选择的任何名称。export vpc_stack_name=my-eks-ipv6-vpc
-
使用 AWS CloudFormation 模板创建
IPv6
VPC。aws cloudformation create-stack --region $region_code --stack-name $vpc_stack_name \ --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-ipv6-vpc-public-private-subnets.yaml
堆栈需要几分钟的时间来创建。运行以下命令。在命令的输出变成
CREATE_COMPLETE
之前,请勿继续执行下一步。aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name --query Stacks[].StackStatus --output text
-
检索创建的公有子网的 ID。
aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \ --query='Stacks[].Outputs[?OutputKey==`SubnetsPublic`].OutputValue' --output text
示例输出如下。
subnet-0a1a56c486EXAMPLE,subnet-099e6ca77aEXAMPLE
-
为创建的公有子网启用自动分配
IPv6
地址选项。aws ec2 modify-subnet-attribute --region $region_code --subnet-id subnet-0a1a56c486EXAMPLE --assign-ipv6-address-on-creation aws ec2 modify-subnet-attribute --region $region_code --subnet-id subnet-099e6ca77aEXAMPLE --assign-ipv6-address-on-creation
-
从部署的 AWS CloudFormation 堆栈中检索模板创建的子网和安全组的名称,将其存储在变量中,以供后续步骤使用。
security_groups=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \ --query='Stacks[].Outputs[?OutputKey==`SecurityGroups`].OutputValue' --output text) public_subnets=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \ --query='Stacks[].Outputs[?OutputKey==`SubnetsPublic`].OutputValue' --output text) private_subnets=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \ --query='Stacks[].Outputs[?OutputKey==`SubnetsPrivate`].OutputValue' --output text) subnets=${public_subnets},${private_subnets}
-
-
创建集群 IAM 角色并向其附加所需的 Amazon EKS IAM 托管策略。Amazon EKS 托管的 Kubernetes 集群会代表您调用其他 AWS 服务,以管理您用于该服务的资源。
-
运行以下命令以创建
eks-cluster-role-trust-policy.json
文件。cat >eks-cluster-role-trust-policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF
-
运行以下命令设置角色名称的变量。您可以将
myAmazonEKSClusterRole
替换为选择的任何名称。export cluster_role_name=myAmazonEKSClusterRole
-
创建角色。
aws iam create-role --role-name $cluster_role_name --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
-
检索 IAM 角色的 ARN 并将其存储在变量中以供后续步骤使用。
CLUSTER_IAM_ROLE=$(aws iam get-role --role-name $cluster_role_name --query="Role.Arn" --output text)
-
将所需的 Amazon EKS 托管 IAM 策略附加到角色。
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name $cluster_role_name
-
-
创建您的集群。
aws eks create-cluster --region $region_code --name $cluster_name --kubernetes-version 1.XX \ --role-arn $CLUSTER_IAM_ROLE --resources-vpc-config subnetIds=$subnets,securityGroupIds=$security_groups \ --kubernetes-network-config ipFamily=ipv6
-
注意:您可能会收到一个错误,指示请求中的可用区之一没有足够容量来创建 Amazon EKS 集群。如果发生这种情况,错误输出将包含可支持新集群的可用区。再次尝试使用至少两个位于您账户中支持的可用区的子网创建集群。有关更多信息,请参阅 容量不足。
创建集群需要几分钟时间。运行以下命令。在命令的输出变成
ACTIVE
之前,请勿继续执行下一步。aws eks describe-cluster --region $region_code --name $cluster_name --query cluster.status
-
-
为集群创建或更新
kubeconfig
文件,以便您可以与集群通信。aws eks update-kubeconfig --region $region_code --name $cluster_name
默认情况下,
config
文件创建在~/.kube
中或者新集群的配置已添加到~/.kube
的现有config
文件中。 -
创建节点 IAM 角色。
-
运行以下命令以创建
vpc-cni-ipv6-policy.json
文件。cat >vpc-cni-ipv6-policy <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:AssignIpv6Addresses", "ec2:DescribeInstances", "ec2:DescribeTags", "ec2:DescribeNetworkInterfaces", "ec2:DescribeInstanceTypes" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ec2:CreateTags" ], "Resource": [ "arn:aws:ec2:*:*:network-interface/*" ] } ] } EOF
-
创建 IAM 策略。
aws iam create-policy --policy-name AmazonEKS_CNI_IPv6_Policy --policy-document file://vpc-cni-ipv6-policy.json
-
运行以下命令以创建
node-role-trust-relationship.json
文件。cat >node-role-trust-relationship.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF
-
运行以下命令设置角色名称的变量。您可以将
AmazonEKSNodeRole
替换为选择的任何名称。export node_role_name=AmazonEKSNodeRole
-
创建 IAM 角色。
aws iam create-role --role-name $node_role_name --assume-role-policy-document file://"node-role-trust-relationship.json"
-
将 IAM 策略附加到 IAM 角色。
aws iam attach-role-policy --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy \ --role-name $node_role_name
重要
为简单起见,在本教程中,该策略附加到此 IAM 角色。但是,在生产集群中,我们建议将该策略附加到单独的 IAM 角色。有关更多信息,请参阅 配置 Amazon VPC CNI 插件以使用 IRSA。
-
将两个所需的 IAM 托管策略附加到 IAM 角色。
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \ --role-name $node_role_name aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \ --role-name $node_role_name
-
检索 IAM 角色的 ARN 并将其存储在变量中以供后续步骤使用。
node_iam_role=$(aws iam get-role --role-name $node_role_name --query="Role.Arn" --output text)
-
-
创建托管节点组。
-
查看在上一步中创建的子网的 ID。
echo $subnets
示例输出如下。
subnet-0a1a56c486EXAMPLE,subnet-099e6ca77aEXAMPLE,subnet-0377963d69EXAMPLE,subnet-0c05f819d5EXAMPLE
-
创建节点组。将
0a1a56c486EXAMPLE
、099e6ca77aEXAMPLE
、0377963d69EXAMPLE
和0c05f819d5EXAMPLE
替换为上一步输出中返回的值。请务必在以下命令之前的输出中删除子网 ID 之间的逗号。您可以将t3.medium
替换为任何 AWS Nitro 系统实例类型。aws eks create-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name \ --subnets subnet-0a1a56c486EXAMPLE subnet-099e6ca77aEXAMPLE subnet-0377963d69EXAMPLE subnet-0c05f819d5EXAMPLE \ --instance-types t3.medium --node-role $node_iam_role
创建节点组需要几分钟的时间。运行以下命令。在返回的输出为
ACTIVE
之前,请勿继续执行下一步。aws eks describe-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name \ --query nodegroup.status --output text
-
-
确认默认 Pods 已分配
IP
列中的IPv6
地址。kubectl get pods -n kube-system -o wide
示例输出如下。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES aws-node-rslts 1/1 Running 1 5m36s 2600:1f13:b66:8200:11a5:ade0:c590:6ac8 ip-192-168-34-75.region-code.compute.internal <none> <none> aws-node-t74jh 1/1 Running 0 5m32s 2600:1f13:b66:8203:4516:2080:8ced:1ca9 ip-192-168-253-70.region-code.compute.internal <none> <none> coredns-85d5b4454c-cw7w2 1/1 Running 0 56m 2600:1f13:b66:8203:34e5:: ip-192-168-253-70.region-code.compute.internal <none> <none> coredns-85d5b4454c-tx6n8 1/1 Running 0 56m 2600:1f13:b66:8203:34e5::1 ip-192-168-253-70.region-code.compute.internal <none> <none> kube-proxy-btpbk 1/1 Running 0 5m36s 2600:1f13:b66:8200:11a5:ade0:c590:6ac8 ip-192-168-34-75.region-code.compute.internal <none> <none> kube-proxy-jjk2g 1/1 Running 0 5m33s 2600:1f13:b66:8203:4516:2080:8ced:1ca9 ip-192-168-253-70.region-code.compute.internal <none> <none>
-
确认默认服务已分配
IP
列中的IPv6
地址。kubectl get services -n kube-system -o wide
示例输出如下。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kube-dns ClusterIP fd30:3087:b6c2::a <none> 53/UDP,53/TCP 57m k8s-app=kube-dns
-
(可选)部署示例应用程序或部署AWS 负载均衡器控制器和示例应用程序,对 HTTP 应用程序(通过 使用应用程序负载均衡器路由应用程序和 HTTP 流量)或流向
IPv6
Pods 的网络流量(通过使用网络负载均衡器路由 TCP 和 UDP 流量)进行负载均衡。 -
在使用完成针对本教程而创建的集群和节点后,应使用以下命令清理创建的资源。删除之前,确保您没有使用本教程之外的任何资源。
-
如果您在与之前步骤不同的 shell 中完成此步骤,请设置之前步骤中使用的所有变量的值,然后将
example values
替换为完成之前步骤时指定的值。如果在完成之前步骤的同一 shell 中完成此步骤,请跳至下一步。export region_code=region-code export vpc_stack_name=my-eks-ipv6-vpc export cluster_name=my-cluster export nodegroup_name=my-nodegroup export account_id=111122223333 export node_role_name=AmazonEKSNodeRole export cluster_role_name=myAmazonEKSClusterRole
-
删除您的节点组。
aws eks delete-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name
删除需要花费几分钟的时间。运行以下命令。如果返回任何输出,请勿继续执行下一步。
aws eks list-nodegroups --region $region_code --cluster-name $cluster_name --query nodegroups --output text
-
请删除集群。
aws eks delete-cluster --region $region_code --name $cluster_name
删除集群需要几分钟时间。在继续之前,请确保使用以下命令删除集群。
aws eks describe-cluster --region $region_code --name $cluster_name
在输出与以下输出类似之前,请勿继续执行下一步。
An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-cluster.
-
删除您创建的 IAM 资源。如果您选择的名称与与之前步骤中使用的名称不同,则将
AmazonEKS_CNI_IPv6_Policy
替换为您选择的名称。aws iam detach-role-policy --role-name $cluster_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy aws iam delete-policy --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy aws iam delete-role --role-name $cluster_role_name aws iam delete-role --role-name $node_role_name
-
删除创建 VPC 的 AWS CloudFormation 堆栈。
aws cloudformation delete-stack --region $region_code --stack-name $vpc_stack_name
-