【问题标题】:AWS EKS NodeGroup "Create failed": Instances failed to join the kubernetes clusterAWS EKS 节点组“创建失败”:实例未能加入 kubernetes 集群
【发布时间】:2020-10-24 16:27:11
【问题描述】:

我能够创建 EKS 集群,但是当我尝试添加节点组时,我收到“创建失败”错误,其中包含详细信息: “NodeCreationFailure”:实例加入kubernetes集群失败

我尝试了多种实例类型并增加了更大的卷大小 (60gb),但运气不佳。 查看 EC2 实例,我只看到以下问题。但是,由于我没有直接启动 EC2 实例(EKS NodeGroup UI 向导正在这样做),因此很难做任何事情。

如果在我可以跳入 ec2 机器并“修复”它们之前发生故障,人们将如何前进?

亚马逊 Linux 2

x86_64 上的内核 4.14.198-152.320.amzn2.x86_64

ip-187-187-187-175 登录:[54.474668] cloud-init[3182]:其中之一 配置的存储库失败(未知), [54.475887] cloud-init [3182]:yum 没有足够的缓存 数据继续。此时唯一 [ 54.478096] cloud-init [3182]:yum 可以做的安全事情是失败。那里 有几种方法可以“解决”这个问题: [54.480183] cloud-init[3182]:1.联系上游获取 存储库并让他们解决问题。 [54.483514] cloud-init[3182]:2.重新配置baseurl/etc。为了 存储库,指向一个工作 [54.485198]云初始化[3182]:上游。这通常很有用 如果您使用的是较新的 [54.486906] cloud-init [3182]:发行版比现在 由存储库(和 [54.488316] cloud-init [3182]:前一个包 发行版仍然有效)。 [54.489660] cloud-init [3182]:3.运行命令 存储库暂时禁用 [54.491045]云初始化[3182]:百胜--disablerepo = ... [54.491285] cloud-init [3182]:4.禁用存储库 永久,所以默认情况下 yum 不会使用它。百胜 [54.493407] cloud-init [3182]:然后将忽略存储库 直到您永久启用它 [54.495740] cloud-init [3182]:再次或使用--enablerepo for 临时使用: [54.495996] cloud-init [3182]:yum-config-manager --disable

【问题讨论】:

  • 您是否将实例部署到没有 NAT 网关的私有 VPC(无法访问互联网)?
  • 您是否尝试过使用 eksctl 添加节点?
  • @paltaa 好点。 eksctl 效果很好(表明权限不是问题),但是 eksctl 还不允许 v1.18,所以我不得不改用 UI 和/或 aws cli

标签: amazon-web-services kubernetes amazon-ec2 amazon-eks


【解决方案1】:

我将通过突出显示前线可能出错的一些事情来尝试使答案简短。

1. 将附加到 EKS 工作程序节点的 IAM 角色添加到 kube-system 命名空间中的 aws-auth 配置映射。 Ref

2. 登录创建的worker节点,加入集群失败。尝试使用 nc 从内部连接到 API 服务器。例如:nc -vz 9FCF4EA77D81408ED82517B9B7E60D52.yl4.eu-north-1.eks.amazonaws.com 443

3. 如果您没有使用 AWS 控制台下拉菜单中的 EKS 节点(这意味着您在 AWS EC2 中使用的是 LT 或 LC),请不要忘记添加 @987654327 @ 启动模板中的部分。 Ref

set -o xtrace
/etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArguments}

4. 检查 EKS 工作线程 IAM 节点策略并查看它是否添加了适当的权限。 AmazonEKS_CNI_Policy 是必须的。

5. 您的节点必须应用以下标签,其中 cluster-name 替换为您的集群名称。 kubernetes.io/cluster/cluster-name: owned

我希望您的问题在此列表中。

参考:https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting.html https://aws.amazon.com/premiumsupport/knowledge-center/resolve-eks-node-failures/

【讨论】:

    【解决方案2】:

    就我而言,问题在于我将节点组部署在私有子网中,但该私有子网没有关联的 NAT 网关,因此无法访问 Internet。我所做的是:

    1. 创建一个 NAT 网关

    2. 使用以下路由创建一个新的路由表(第二个是互联网访问路由,通过nat):

    • 目标:VPC-CIDR-block 目标:本地
    • 目标:0.0.0.0/0 目标:NAT-gateway-id
    1. 将私有子网与第二步中创建的路由表相关联。

    之后,节点组毫无问题地加入了集群。

    【讨论】:

    • 请注意,NAT 网关应在公共子网中创建。否则私有子网中的实例将无法连接到互联网,我们将收到同样的 NodeCreationFailure 错误。
    【解决方案3】:

    我注意到这里没有答案,但在过去的六个月里,这个问题大约有 2000 次访问。您可能会看到这些失败的原因似乎有很多。要反刍此处找到的 AWS 文档: https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting.html

    • aws-auth-cm.yaml 文件没有正确的 IAM 角色 ARN 你的节点。确保节点 IAM 角色 ARN(不是实例 profile ARN)在您的 aws-auth-cm.yaml 文件中指定。更多 信息,请参阅启动自我管理的 Amazon Linux 节点。

    • 您的节点 AWS CloudFormation 模板中的 ClusterName 没有 与您希望节点加入的集群的名称完全匹配。 向此字段传递不正确的值会导致不正确 节点的 /var/lib/kubelet/kubeconfig 文件的配置,以及 节点不会加入集群。

    • 节点未标记为由集群拥有。您的节点必须 将以下标签应用于它们,其中是 替换为您的集群名称。

        Key Value kubernetes.io/cluster/<cluster-name> 
        Value owned
    
    • 节点可能无法使用公共 IP 访问集群 地址。确保为公共子网中部署的节点分配了一个 公共 IP 地址。如果没有,您可以将弹性 IP 地址关联到 启动后的节点。有关详细信息,请参阅关联 具有正在运行的实例或网络接口的弹性 IP 地址。如果 公共子网未设置为自动分配公共 IP 地址到部署到它的实例,然后我们建议启用 环境。有关详细信息,请参阅修改公共 IPv4 子网的寻址属性。如果节点部署到 私有子网,则子网必须有到 NAT 网关的路由 有一个分配给它的公共 IP 地址。

    • 您将节点部署到的区域的 STS 端点是 未为您的帐户启用。要启用该区域,请参阅激活和 在 AWS 区域中停用 AWS STS。

    • 工作节点没有私有 DNS 条目,导致 包含节点“”未找到错误的 kubelet 日志。确保 VPC 创建工作节点的位置为 domain-name 和 domain-name-servers 作为 DHCP 选项集中的选项。默认 值为 domain-name:.compute.internal 和 域名服务器:AmazonProvidedDNS。有关详细信息,请参阅 DHCP Amazon VPC 用户指南中的选项集。

    我自己对需要大写字母的标记有疑问。实际上,如果您可以使用其他途径来部署您的 EKS 集群,我会推荐它(eksctl、aws cli、terraform 甚至)。

    【讨论】:

      【解决方案4】:

      在列表中添加另一个原因:

      在我的例子中,节点私有子网中运行并且我没有在API服务器下配置私有端点端点访问。

      更新后节点组没有自动更新,所以我不得不重新创建它们。

      【讨论】:

      • 我能够通过将私有子网转换为公共子网来让我的工作。我知道不是每个人都想这样做,但如果你这样做了,方法如下:只需添加到 Internet 网关的路由。如果您有任何公共子网,那么您将拥有一个互联网网关。转到 VPC > 子网 > 选择您的子网并查看详细信息。然后找到路由表并选择它。单击操作 > 编辑路由,然后单击添加路由。通过现有的 Internet 网关添加到 0.0.0.0/0 的路由。这会使子网公开,然后 EC2 实例可以访问您的集群的 API 服务器。
      • 嗨@Alejandro703,我想我宁愿避免将我的工作节点暴露在公共子网上——这会使它们面临不同类型的攻击向量。
      • 完全理解。在写完那个commebt之后,我想到你应该能够在路由表中直接从私有子网添加一个路由到公共API端点而不暴露整个子网。
      【解决方案5】:

      首先,我的私有子网中有 NAT 网关。然后我将 NAT 网关移回公共子网,它工作正常。

      Terraform代码如下:

      resource "aws_internet_gateway" "gw" {
        vpc_id = aws_vpc.dev-vpc.id
        tags = {
          Name = "dev-IG"
        }
      }
      
      resource "aws_eip" "lb" {
        depends_on    = [aws_internet_gateway.gw]
        vpc           = true
      }
      
      resource "aws_nat_gateway" "natgw" {
        allocation_id = aws_eip.lb.id
        subnet_id     = aws_subnet.dev-public-subnet.id
        depends_on = [aws_internet_gateway.gw]
        tags = {
          Name = "gw NAT"
        }
      }
      

      【讨论】:

        【解决方案6】:

        尝试向部署工作节点的私有子网添加标签。

        kubernetes.io/cluster/ = 共享

        【讨论】:

          【解决方案7】:

          我们需要检查我们配置的 nat 网关类型。它应该是公共的,但在我的情况下,我配置为私有。

          一旦我从私有更改为公开,问题就解决了。

          【讨论】:

            猜你喜欢
            • 2023-01-30
            • 1970-01-01
            • 2022-11-01
            • 2022-07-28
            • 2021-07-08
            • 2021-04-13
            • 2021-07-20
            • 1970-01-01
            • 2021-07-31
            相关资源
            最近更新 更多