由于授权失败,EKS 集群节点在大约 30 分钟后从“就绪”变为“未就绪”

由于授权失败,EKS 集群节点在大约 30 分钟后从“就绪”变为“未就绪”

我正在使用 eksctl 在 EKS/AWS 上设置集群。

按照 EKS 文档中的指南,我对几乎所有内容都使用默认值。

集群创建成功,我从集群更新了 Kubernetes 配置,并且可以成功运行各种 kubectl 命令 - 例如“kubectl get nodes”显示节点处于“就绪”状态。

我没有动任何其他东西,我有一个干净的开箱即用的集群,没有做任何其他更改,到目前为止,一切似乎都按预期运行。我没有向它部署任何应用程序,我只是让它保持原样。

问题是,在一段相对较短的时间内(大约在集群创建后 30 分钟),节点从“就绪”变为“未就绪”,并且永远无法恢复。

事件日志显示了这一点(我删除了IP):

LAST SEEN   TYPE     REASON                    OBJECT        MESSAGE
22m         Normal   Starting                  node/ip-[x]   Starting kubelet.
22m         Normal   NodeHasSufficientMemory   node/ip-[x]   Node ip-[x] status is now: NodeHasSufficientMemory
22m         Normal   NodeHasNoDiskPressure     node/ip-[x]   Node ip-[x] status is now: NodeHasNoDiskPressure
22m         Normal   NodeHasSufficientPID      node/ip-[x]   Node ip-[x] status is now: NodeHasSufficientPID
22m         Normal   NodeAllocatableEnforced   node/ip-[x]   Updated Node Allocatable limit across pods
22m         Normal   RegisteredNode            node/ip-[x]   Node ip-[x] event: Registered Node ip-[x] in Controller
22m         Normal   Starting                  node/ip-[x]   Starting kube-proxy.
21m         Normal   NodeReady                 node/ip-[x]   Node ip-[x] status is now: NodeReady
7m34s       Normal   NodeNotReady              node/ip-[x]   Node ip-[x] status is now: NodeNotReady

集群中其他节点也发生相同事件。

连接到实例并检查 /var/log/messages 时显示,同时节点进入 NotReady 状态:

Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.259207    3896 kubelet_node_status.go:385] Error updating node status, will retry: error getting node "ip-[x]": Unauthorized
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.385044    3896 kubelet_node_status.go:385] Error updating node status, will retry: error getting node "ip-[x]": Unauthorized
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.621271    3896 reflector.go:270] object-"kube-system"/"aws-node-token-bdxwv": Failed to watch *v1.Secret: the server has asked for the client to provide credentials (get secrets)
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.621320    3896 reflector.go:270] object-"kube-system"/"coredns": Failed to watch *v1.ConfigMap: the server has asked for the client to provide credentials (get configmaps)
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.638850    3896 reflector.go:270] k8s.io/client-go/informers/factory.go:133: Failed to watch *v1beta1.RuntimeClass: the server has asked for the client to provide credentials (get runtimeclasses.node.k8s.io)
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.707074    3896 reflector.go:270] k8s.io/kubernetes/pkg/kubelet/config/apiserver.go:47: Failed to watch *v1.Pod: the server has asked for the client to provide credentials (get pods)
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.711386    3896 reflector.go:270] object-"kube-system"/"coredns-token-67fzd": Failed to watch *v1.Secret: the server has asked for the client to provide credentials (get secrets)
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.714899    3896 reflector.go:270] object-"kube-system"/"kube-proxy-config": Failed to watch *v1.ConfigMap: the server has asked for the client to provide credentials (get configmaps)
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.720884    3896 kubelet_node_status.go:385] Error updating node status, will retry: error getting node "ip-[x]": Unauthorized
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.868003    3896 kubelet_node_status.go:385] Error updating node status, will retry: error getting node "ip-[x]": Unauthorized
Mar  7 10:40:37 ip-[X] kubelet: E0307 10:40:37.868067    3896 controller.go:125] failed to ensure node lease exists, will retry in 200ms, error: Get https://[X]/apis/coordination.k8s.io/v1beta1/namespaces/kube-node-lease/leases/ip-[x]?timeout=10s: write tcp 192.168.91.167:50866->34.249.27.158:443: use of closed network connection
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.017157    3896 kubelet_node_status.go:385] Error updating node status, will retry: error getting node "ip-[x]": Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.017182    3896 kubelet_node_status.go:372] Unable to update node status: update node status exceeds retry count
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.200053    3896 controller.go:125] failed to ensure node lease exists, will retry in 400ms, error: Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.517193    3896 reflector.go:270] object-"kube-system"/"kube-proxy": Failed to watch *v1.ConfigMap: the server has asked for the client to provide credentials (get configmaps)
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.729756    3896 controller.go:125] failed to ensure node lease exists, will retry in 800ms, error: Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.752267    3896 reflector.go:126] object-"kube-system"/"aws-node-token-bdxwv": Failed to list *v1.Secret: Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.824988    3896 reflector.go:126] object-"kube-system"/"coredns": Failed to list *v1.ConfigMap: Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.899566    3896 reflector.go:126] k8s.io/client-go/informers/factory.go:133: Failed to list *v1beta1.RuntimeClass: Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.963756    3896 reflector.go:126] k8s.io/client-go/informers/factory.go:133: Failed to list *v1beta1.CSIDriver: Unauthorized
Mar  7 10:40:38 ip-[X] kubelet: E0307 10:40:38.963822    3896 reflector.go:126] object-"kube-system"/"kube-proxy-config": Failed to list *v1.ConfigMap: Unauthorized

身份验证器组件的 CloudWatch 日志显示了许多以下消息:

time="2020-03-07T10:40:37Z" level=warning msg="access denied" arn="arn:aws:iam::[ACCOUNT_ID]]:role/AmazonSSMRoleForInstancesQuickSetup" client="127.0.0.1:50132" error="ARN is not mapped: arn:aws:iam::[ACCOUNT_ID]:role/amazonssmroleforinstancesquicksetup" method=POST path=/authenticate

我通过 IAM 控制台确认该角色确实存在。

显然,由于这些身份验证失败,该节点报告 NotReady。

这是大约 30 分钟后超时的身份验证令牌吗?如果是这样,难道不应该自动请求新令牌吗?还是我应该设置其他东西?

我很惊讶 eksctl 创建的新集群会出现这个问题。

我错过了什么?

答案1

这些是我解决此问题所遵循的步骤...

  1. 通过 SSH 连接到失败的实例。

  2. 执行“aws sts get-caller-identity”

  3. 记下用户的 ARN,它可能是这样的 arn:aws:sts::999999999999:assumed-role/AmazonSSMRoleForInstancesQuickSetup/i-00000000000ffffff

请注意,这里的角色是 AmazonSSMRoleForInstancesQuickSetup,这对我来说似乎是错误的 - 但据我所知,我在创建集群时严格遵循了指南。

目前存在的问题:

a) 为什么此角色用于 AWS 身份?

b) 如果这是正确的角色,为什么它一开始就成功,但在集群创建 30 分钟后才失败?

c) 如果这是正确的角色,缺少哪些访问权限?

就我个人而言,我觉得这对我来说是错误的角色,但我通过解决要点 (c) 解决了我的问题。

继续步骤...

  1. 如果通过 AWS 控制台中的 IAM 服务检查此角色,则可以看到它没有所有必需的权限,默认情况下它具有:
  • AmazonSSMManagedInstanceCore
  1. 假设此角色是正确的角色,那么它至少需要添加以下策略:
  • AmazonEC2ContainerRegistryPowerUser

以通常的方式附加该策略,我承认这可能会授予比需要更多的权限,但那是另一回事了。

至此,AWS 安全配置应该是正确的,但这并不是故事的结束。

  1. Kubernetes 通过 kubelet 进程有自己的安全角色映射需要考虑——即将 Kubernetes 用户映射到 IAM 用户或 AWS 上的角色。

通过编辑 Kubernetes 配置映射来维护此配置。

使用“kubectl edit -n kube-system configmap/aws-auth”编辑配置映射。

这是创建集群之后、进行任何更改之前的配置:

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::999999999999:role/eksctl-my-demo-nodegroup-my-demo-NodeInstanceRole-AAAAAAAAAAAAA
      username: system:node:{{EC2PrivateDNSName}}
kind: ConfigMap
metadata:
  [...whatever...]

这里映射的唯一角色是节点实例角色 —— 该角色是在通过配置集群期间自动创建的eksctl

  1. 更改配置图:
apiVersion: v1
data:
  mapRoles: |
    - rolearn: arn:aws:iam::999999999999:role/eksctl-my-demo-nodegroup-my-demo-NodeInstanceRole-AAAAAAAAAAAAA
      username: system:node:{{EC2PrivateDNSName}}
      groups:
      - system:bootstrappers
      - system:nodes
    - rolearn: arn:aws:iam::999999999999:role/AmazonSSMRoleForInstancesQuickSetup
      username: MyDemoEKSRole
      groups:
      - system:masters
    - rolearn: arn:aws:iam::999999999999:role/MyDemoEKSRole
      username: CodeBuild
      groups:
      - system:masters
      - system:bootstrappers
      - system:nodes
kind: ConfigMap
metadata:
  [...whatever...]

我已将 AmazonSSMRoleForInstancesQuickSetup 角色映射为 Kubernetes 主角色。

我还将MyDemoEKSRole先前为集群配置创建的集群安全角色映射到各种 Kubernetes 角色,以供 Kubernetes 被 CodeBuild 管道调用的情况。

  1. 保存此配置图,最终集群将自我修复并报告准备就绪。

结论:

执行完所有这些集群创建后步骤后,我的身份验证失败就消失了,集群再次开始报告成功状态,清除健康检查并将节点返回到状态Ready

我坦率地承认这可能不是解决我的问题的“正确”方法,并且确实感觉我开放的安全方式比我应该开放的要多,但它确实有效并解决了我的问题。

正如此后不久提到的,我们转换到了 Azure 而不是 AWS,所以我没有再采取任何进一步的行动 - 但我最终得到了一个完全正常运行的集群,并且不再有任何过期的凭据。

我天真地以为这些工具能帮我创建一个工作集群。我发现的任何指南中都没有提到这个问题或这些步骤。

答案2

您的角色似乎即将到期。

您可以从Amazon EKS 故障排除部分Unauthorized or Access Denied (kubectl)

如果在运行时收到以下错误之一 库布克 命令,然后你的 库布克 没有为 Amazon EKS 正确配置,或者您使用的 IAM 用户或角色凭证未映射到 Amazon EKS 集群中具有足够权限的 Kubernetes RBAC 用户。

  • could not get token: AccessDenied: Access denied

  • error: You must be logged in to the server (Unauthorized)

  • error: the server doesn't have a resource type "svc"

这可能是因为集群是使用一组 AWS 凭证(来自 IAM 用户或角色)创建的,并且 库布克 正在使用一组不同的凭证。

创建 Amazon EKS 集群时,创建集群的 IAM 实体(用户或角色)将作为管理员(具有 system:master 权限)添加到 Kubernetes RBAC 授权表中。最初,只有该 IAM 用户可以使用 库布克更多信息,请参阅 管理集群的用户或 IAM 角色。此外, 适用于 Kubernetes 的 AWS IAM 身份验证器 使用 AWS SDK for Go 针对您的 Amazon EKS 集群进行身份验证。如果您使用控制台创建集群,则必须确保在运行 库布克 命令。

如果您安装并配置了 AWS CLI,则可以为您的用户配置 IAM 凭证。如果为您的用户正确配置了 AWS CLI,则 适用于 Kubernetes 的 AWS IAM 身份验证器 也可以找到这些凭据。有关详细信息,请参阅 配置 AWS CLI 在里面 AWS 命令​​行界面用户指南

如果您承担创建 Amazon EKS 集群的角色,则必须确保 库布克 配置为承担相同的角色。使用以下命令更新 kubeconfig 文件以使用 IAM 角色。有关更多信息,请参阅 为 Amazon EKS 创建 kubeconfig

aws --region `region-code` eks update-kubeconfig --name `cluster_name` --role-arn arn:aws:iam::`aws_account_id`:role/`role_name

要将 IAM 用户映射到 Kubernetes RBAC 用户,请参阅 管理集群的用户或 IAM 角色 或者观看 视频 关于如何映射用户。

你应该阅读管理集群身份验证对于 AWS 和为 Amazon EKS 创建 kubeconfig

请记住,您应该使用aws-iam-authenticator可用的安装过程这里

答案3

部署节点组时,必须授予节点组角色,如下所述在文档中(aws-auth-cm.yaml)

尽管所有 pod 看起来都正常,但我的节点在启动后约 7 分钟内进入 NotReady 状态,并出现类似上述问题的错误。

原因:由于输入错误,nodegroup 的角色与该 yaml 中的角色不一样。

相关内容