为什么我的容器组无法连接到 Amazon EKS 中的其他容器组?

3 分钟阅读
0

我的容器组无法连接到 Amazon Elastic Kubernetes Service (Amazon EKS) 中的其他容器组。

概述

**注意:**如果在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请确保您使用的是 AWS CLI 最新版本

如果您的容器组无法与其他容器连接,根据具体的应用,可能会收到以下错误。

如果 Worker 节点的安全组不允许节点间通信,您会收到以下错误信息:

curl: (7) Failed to connect to XXX.XXX.XX.XXX port XX: Connection timed out

如果 DNS 不起作用,您会收到以下错误信息:

curl nginx  
curl: (6) Could not resolve host: nginx

如果 DNS 正常运行但容器组存在连接问题,您会收到以下错误信息:

Error: RequestError: send request failed caused by: Post  dial tcp 1.2.3.4.5:443: i/o timeout

如果您尝试解析未通过服务公开的容器组 DNS,则会收到以下错误:

kubectl exec -it busybox -- nslookup nginx
Server:   10.100.0.10
Address:  10.100.0.10:53
** server can't find nginx.default.svc.cluster.local: NXDOMAIN
*** Can't find nginx.svc.cluster.local: No answer
*** Can't find nginx.cluster.local: No answer
*** Can't find nginx.ap-southeast-2.compute.internal: No answer
*** Can't find nginx.default.svc.cluster.local: No answer
*** Can't find nginx.svc.cluster.local: No answer
*** Can't find nginx.cluster.local: No answer
*** Can't find nginx.ap-southeast-2.compute.internal: No answer

要解决这些错误,请检查您的环境设置是否正确:

  • 您的安全组符合 Amazon EKS 准则。
  • 网络访问控制列表(网络 ACL)不拒绝连接。
  • 您的子网有一条用于在 Amazon Virtual Private Cloud (Amazon VPC) 内进行通信的本地路由。
  • 子网中有足够的 IP 地址可用。
  • 容器组的安全组允许容器组之间相互通信。
  • 您的 Worker 节点已启用 IP 转发。
  • 您符合 Kubernetes 的网络要求(不包括任何有意的 NetworkPolicy)。
  • 您的容器组正在正确使用 DNS 相互通信。
  • 您的容器组已调度并处于 RUNNING 状态。
  • 您有适用于 Kubernetes 的 Amazon VPC 容器网络接口 (CNI) 插件的推荐版本。

解决方法

您的安全组符合 Amazon EKS 准则

要限制 Worker 节点安全组上允许的流量,请创建入站规则。为您的 Worker 节点用于节点间通信的任何协议或任何端口创建这些规则。

最佳做法是允许 Worker 节点的安全组的所有流量。每次创建带有新端口的新容器组时,您无需更改安全组规则。

有关详细信息,请参阅 Amazon EKS 安全组要求和注意事项

网络 ACL 不拒绝连接

1.    确认您的 Amazon EKS 集群和 VPC CIDR 之间的流量在您的网络 ACL 上自由流动。

2.    (可选)要为您的 VPC 添加额外的安全层,请考虑使用与您的安全组相似的规则设置网络 ACL。

您的子网有一条本地路由用于在您的 VPC 内进行通信

确认您的子网具有用于在 VPC 内通信的默认路由。

子网中有足够的 IP 地址可用

确认您指定的子网有足够的 IP 地址可用于跨账户弹性网络接口和您的容器组。

有关详细信息,请参阅 Amazon EKS VPC 和子网要求和注意事项

要检查是否有可用的 IP 地址,请运行以下 AWS CLI 命令:

$ aws ec2 describe-subnets --subnet-id YOUR-SUBNET-ID --query 'Subnets[0].AvailableIpAddressCount'

您的容器组的安全组允许容器组相互通信

如果您使用容器组的安全组CNI 自定义网络,则可以将任何安全组分配给容器组。在这种情况下,请确认安全组允许容器组之间正确通信。

您的 Worker 节点已启用 IP 转发

如果您使用自定义 AMI,则必须确保 net.ipv4.ip_forward kernel 变量已启用。要在 Worker 节点上验证此设置,请运行以下任一命令:

# sysctl net.ipv4.ip_forward

# cat /proc/sys/net/ipv4/ip_forward

如果输出为 0,请使用以下任一命令激活 net.ipv4.ip_forward kernel 变量。

# sysctl -w net.ipv4.ip_forward=1

# echo 1 > /proc/sys/net/ipv4/ip_forward

有关 containerd 运行时系统中的 Amazon EKS AMI,请参阅 install-worker.sh 脚本的第 184-188 行(在 GitHub 上)了解设置的激活情况。由于 containerd 是 Amazon EKS 版本 1.24 及更高版本中的默认运行时系统,需要执行此步骤才能对容器组到容器组的网络连接进行故障排除。

您符合 Kubernetes 的网络要求(不包括任何有意的 NetworkPolicy)

确认您符合 Kubernetes 网络要求(来自 Kubernetes 网站)。

默认情况下,容器组不隔离。容器组接受来自任何来源的流量。可通过选择容器组 NetworkPolicy 来将这些容器组隔离。

**注意:**有关 NetworkPolicy 配置,请参阅安装 Calico 网络策略引擎插件

您的容器组正在正确使用 DNS 相互通信

您必须先通过服务公开容器组。如果不这样做,您的容器组将无法获取 DNS 名称,只能通过其特定 IP 地址访问。

以下示例输出显示了解析 nginx 服务的 DNS 名称的尝试。在这种情况下,将返回 ClusterIP 10.100.94.70

$ kubectl run nginx --image=nginx --replicas=5 -n web
deployment.apps/nginx created

$ kubectl expose deployment nginx --port=80 -n web
service/nginx exposed

$ kubectl get svc -n web
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.100.94.70   <none>        80/TCP    2s

# kubectl exec -ti busybox -n web -- nslookup nginx
Server:    10.100.0.10
Address 1: 10.100.0.10 ip-10-100-0-10.ap-southeast-2.compute.internal
Name:      nginx
Address 1: 10.100.94.70 ip-10-100-94-70.ap-southeast-2.compute.internal

如果您的容器组仍然无法解析 DNS,请参阅如何使用 Amazon EKS 排查 DNS 故障?

**注意:**有关详细信息,请参阅 Kubernetes 网站上的容器组服务Headless 服务

您的容器组已调度并处于 RUNNING 状态

确认您的容器组已完成调度且处于 RUNNING 状态。

要解决容器组状态问题,请参阅如何排查 Amazon EKS 中的容器组状态问题?

您有适用于 Kubernetes 的 Amazon VPC CNI 插件的推荐版本

如果没有适用于 Kubernetes 的 Amazon VPC CNI 插件推荐版本,请升级到最新版本。

如果有推荐版本但还是遇到了问题,请参阅如何解决 Amazon EKS 的 kubelet 或 CNI 插件问题?

AWS 官方
AWS 官方已更新 1 年前