用户指南

最佳实践

API 文档

网络无法访问

最近更新时间:2020-11-03 17:41:56

本文档介绍 TKE 集群中多场景下可能发生的常见网络问题,并给出对应的排查思路。当遇到此类问题时,建议您首先按照下文中的检查建议进行排查,若确认检查项无误后仍不能正常访问,请您及时 提交工单 与我们联系。

现象描述及排查步骤

集群中不同节点上的容器(Pod)无法互访

同一集群中不同节点上的 Pod 可以直接互访,当出现一个节点上 Pod 无法访问其他节点上 Pod 时,建议您进行如下检查:

  1. 检查上述不同节点间是否可以互访。
  2. 检查节点安全组是否正确放通容器网段和对端节点所在的 VPC 网段或 VPC 子网网段。

同一个 VPC 内的节点与容器(Pod)无法互访

同一个 VPC 内的节点和 Pod 可以直接互访,当出现无法互访的情况时,建议您进行如下检查:

  1. 检查对端节点和 Pod 所在节点是否可以互访。
  2. Pod 所在节点的安全组是否正确放通对端节点所在的 VPC 子网网段。
  3. 对端节点的安全组是否正确放通容器网段。

不同 VPC 内的节点与容器(Pod)或容器(Pod)与容器(Pod)间无法互访

不同 VPC 间的互访需要先通过 云联网对等连接 完成打通。如果打通之后仍出现无法互访的情况,建议您进行如下检查:

  1. 检查节点与节点是否可以互访。
  2. 检查对端节点的安全组是否正确放通 VPC 网段和容器网段。
  3. 检查 Pod 所在节点的安全组是否正确放通对端节点所在的 VPC 网段或 VPC 子网网段。

如果容器(Pod)与容器(Pod)间无法互访,需进一步执行如下检查:

  1. 检查 Pod 所在节点的安全组是否正确放通对端 VPC 网段(或者节点所在的 VPC 子网网段)和容器网段。
  2. 如需查看 Pod 的源 IP ,可执行以下命令,进一步修改 ip_masq_agent 的配置,彼此增加对方容器网段。
    kubectl -n kube-system edit configmap ip-masq-agent-config

开启内网访问后无法访问

您可以直接在 TKE 控制台上 开启内网访问。如果开启内网访问之后仍出现无法访问的情况,建议您对应集群类型进行如下检查:

托管集群

参考 查看节点安全组配置 检查集群中节点的安全组是否正确放通30000 - 32768端口区间。

独立集群

  1. 参考 查看节点安全组配置 检查集群中节点的安全组是否正确放通30000 - 32768端口区间。
  2. 开启内网访问时,您已通过控制台设置了 VPC 子网网段,请检查集群中 Master 节点是否正确放通该 VPC 子网网段。
  3. 检查集群中 Master 节点的安全组是否正确放通 Master 节点所在的 VPC 网段或 VPC 子网网段。

开启公网访问后无法访问

您可以直接在 TKE 控制台上 开启公网访问。如果开启公网访问之后仍出现无法访问的情况,建议您对应集群类型进行如下检查:

托管集群

检查安全组来源 CIDR 是否正确设置,或将来源 0.0.0.0/0 设置为全放通之后,再进行公网访问测试。

独立集群

独立集群开启公网访问之后,会在集群中自动创建 default/kubelb-internet Service 对象。该 Service 会自动绑定一个公网类型的 CLB,默认不会为该 CLB 绑定安全组(即全放通),且 EXTERNAL-IP 字段显示即为此 CLB 的 VIP。如下所示:

$ kubectl get service kubelb-internet
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)         AGE
kubelb-internet   LoadBalancer   172.16.252.94   152.136.8.98   443:32750/TCP   3m4s
  1. 检查 default/kubelb-internet Service 对象已绑定的 CLB 是否设置了安全组,并且安全组是否正确配置。
  2. 参考 查看节点安全组配置 检查集群中 Master 节点的安全组是否正确放通30000 - 32768端口区间。
  3. 检查集群中 Master 节点的安全组是否正确放通 Master 节点所在的 VPC 网段或 VPC 子网网段。

IDC 与容器(Pod)无法访问

IDC 与 Pod 互访需要先通过 云联网专线网关 完成打通。如果打通之后仍出现无法互访的情况,建议您进行如下检查:

  1. IDC 防火墙是否放通容器网段和 CVM 网段。
  2. CVM 安全组是否放通 IDC 网段。
  3. 检查 IDC 是否使用 BGP 协议:
    • 若未使用 BGP 协议,则需在 IDC 内配置访问容器网段下一跳路由到专线网关。
    • 若使用 BGP 协议,则会自动同步,通常不需要任何配置。除非 IDC 有特殊的静态配置,可联系运维人员配访问容器网段下一跳到专线网关。
说明:

  • 如需在 IDC 中查看 Pod 的 IP,则需要放通 IDC 网段。
  • 默认情况下,除 VPC 之外的包会经过 SNAT 处理转换为 NodeIP。放通 IDC 网段时需配置为不经过 SNAT 处理。
  • 放通 IDC 网段的方法为:执行命令 kubectl -n kube-system edit configmap ip-masq-agent-config,修改 ip-masq-agent 配置,并将 IDC 网段添加到 NonMasqueradeCIDRs 列表中。

Service 提供公网或者内网服务无法访问

提供公网服务或者内网服务的 Service,如果出现无法访问或者 CLB 端口状态异常的情况,建议您进行如下检查:

  1. 参考 查看节点安全组配置 检查集群中节点的安全组是否正确放通30000 - 32768端口区间。
  2. 如果是公网服务,则进一步检查节点是否有公网带宽(仅针对 传统账户类型)。
  3. 如果 Service 的 type 为 loadbalancer 类型,可忽略 CLB,直接检查 NodeIP + NodePort 是否可以访问。
  4. 检查 Service 是否可以在集群中正常访问。

Ingress 提供公网服务无法访问

提供公网服务的 Ingress 如果出现无法访问的情况,建议您进行如下检查:

  1. 若请求返回504,请参考 查看节点安全组配置 检查集群中节点的安全组是否正确放通30000 - 32768端口区间。
  2. 检查 Ingress 绑定的 CLB 是否设置了未放通443端口的安全组。
  3. 检查 Ingress 后端服务 Service 是否可以在集群中正常访问。
  4. 若请求返回404,请检查 Ingress 转发规则是否正确设置。

集群内 DNS 解析错误

在 TKE 集群内,主要是通过集群中的 kube-dns 或者 CoreDNS 服务来提供域名解析功能,如果在 Pod 内发生域名无法解析的情况,建议您进行如下检查:

  1. 执行以下命令,测试 kube-dns 服务的53端口是否开通。
    telnet <kube-dns service ip> 53
  2. 测试 kube-dns 服务 Endpoint 的53端口是否开通,若端口不通,可参考 集群中不同节点上的容器(Pod)无法互访 进一步检查。
  3. 检查当前 Pod 所在节点上的 iptables 或者 ipvs 转发规则是否完整。

集群内 Service 无法访问

在 TKE 集群内,Pod 之间一般是通过 Service 的 DNS 名称 my-svc.my-namespace.svc.cluster.local 来进行互访,如果在 Pod 内发生 Service 无法访问的情况,建议您进行如下检查:

  1. 检查 Service 的 spec.ports 字段是否正确。
  2. 测试 Service 的 ClusterIP 是否可通。若可通,则说明集群内 DNS 解析存在问题,可参考 集群内 DNS 解析错误 进一步检查。
  3. 测试 Service 的 Endpoint 是否可通。若不通,可参考 集群中不同节点上的容器(Pod)无法互访 进一步检查。
  4. 检查当前 Pod 所在节点上的 iptables 或者 ipvs 转发规则是否完整。

相关操作

查看节点上的 iptables 或 ipvs 转发规则

您可以通过执行以下命令,查看节点上的 iptables 或者 ipvs 转发规则。

  • 执行以下命令,检查 iptables 转发规则。
    iptables-save
  • 执行以下命令,检查 ipvs 转发规则。
    ipvsadm -Ln -t/-u ip:port

抓包命令

以下抓包命令可用于分析集群内不同节点上的容器(Pod)互访不通的情况。

  • 执行以下命令,在源 Pod 的节点上抓网卡 eth0 的包。
    tcpdump -nn -vv -i eth0 host <对端pod-ip>
  • 执行以下命令,在对端 Pod 的节点上抓网卡 eth0 的包。
    tcpdump -nn -vv -i eth0 host <源pod-ip>
  • 执行以下命令,在对端 Pod 的 netns 中抓网卡 eth0 的包。
    tcpdump -nn -vv -i eth0 port <请求的端口号>

容器内抓包定位网络问题

在使用 Kubernetes 运行应用的时候,可能会遇到一些网络问题,其中比较常见的是服务端无响应(超时)及回包内容不正常。如果您无法在相关配置上定位到问题点,则需要确认数据包最终是否被路由到容器里,或者报文到达容器的内容和出容器的内容是否符合预期,并通过分析报文进一步缩小问题范围。
本文提供脚本,可一键进入容器网络命名空间(netns),并使用宿主机上的 tcpdump 进行抓包。

使用脚本一键进入 Pod netns 抓包

当发现某个服务不通时,建议将其副本数调为1,并按照以下步骤进行抓包。

  1. 执行以下命令,获取该 Pod 副本所在的节点和 Pod 名称。
    kubectl get pod -o wide
  2. 登录 Pod 所在节点,将如下脚本粘贴到 Shell ,注册函数到当前登录的 Shell 。
    function e() {
     set -eu
     ns=${2-"default"}
     pod=`kubectl -n $ns describe pod $1 | grep -A10 "^Containers:" | grep -Eo 'docker://.*$' | head -n 1 | sed 's/docker:\/\/\(.*\)$/\1/'`
     pid=`docker inspect -f {{.State.Pid}} $pod`
     echo "entering pod netns for $ns/$1"
     cmd="nsenter -n --target $pid"
     echo $cmd
     $cmd
    }
    您可前往 脚本原理 了解并开始使用脚本。
  3. 执行以下命令,一键进入 Pod 所在的 netns。
    e POD_NAME NAMESPACE
    具体示例如下:
    e istio-galley-58c7c7c646-m6568 istio-system 
    e proxy-5546768954-9rxg6 # 省略 NAMESPACE 默认为 default
    说明:

    进入 Pod 所在的 netns 之后,可在宿主机上执行 ip aifconfig 命令来查看容器的网卡,执行 netstat -tunlp 命令查看当前容器的监听端口。

  4. 执行以下命令,使用 tcpdump 进行抓包。
    tcpdump -i eth0 -w test.pcap port 80

使用 wireshark 分析报文

您可以执行 Ctrl+C 操作停止抓包,使用 scpsz 命令将抓取的包下载到本地使用 wireshark 分析。分析过程中,您可能会用到以下常见的 wireshark 过滤语法:

  • 使用 telnet 连接并发送测试文本,例如 "lbtest"
    执行以下命令,查看已发送的测试报文是否传递到容器。
    tcp contains "lbtest"
  • 如果容器提供 HTTP 服务,则可使用 curl 发送测试路径请求。
    执行以下命令过滤 uri,查看报文是否传递到容器。
    http.request.uri=="/mytest"

脚本原理

  • 查看指定 Pod 运行的容器 ID。
    kubectl describe pod <pod> -n mservice
  • 获得容器进程的 Pid。
    docker inspect -f {{.State.Pid}} <container>
  • 进入该容器的 network namespace。`
    nsenter -n --target <PID>
    上述脚本依赖的宿主机命名包含有:kubectl、docker、nsenter、grep、head、sed。

查看节点安全组配置

  1. 登录 TKE 控制台,选择左侧导航栏中的【集群】。
  2. 选择集群 ID,进入集群 “Deployment” 列表页面。
  3. 选择左侧导航栏中的【节点管理】>【节点】。
  4. 在“节点列表”页面,选择需查看安全组的节点 ID。
  5. 在节点管理页面,选择【详情】页签,并单击“主机信息”中的节点 ID。如下图所示:
  6. 在节点“基本信息”页面中,选择【安全组】页签,并在页面中查看该节点的安全组是否正确放通30000 - 32768端口区间。如下图所示:
目录