← Back to blog

如何排查和检查 Kubernetes 网络

Category
如何排查和检查 Kubernetes 网络

Kubernetes 是一个开源工具,在 容器编排 中至关重要。Kubernetes 有助于在各种云环境甚至本地服务器上大规模编排和管理集群。集群是一组用于运行容器化应用程序和服务的宿主机。一个集群至少需要两个节点才能工作 – 一个主节点和一个工作节点。您可以通过添加更多工作节点来扩展您的 Kubernetes 基础设施。主节点及其工作节点必须能够通过网络进行通信,基础设施才能正常工作。有关 Kubernetes 最重要功能的概述,请参考我们的教程:了解 Kubernetes.

在本教程中,我们将向您展示 几种有助于检查和排查 Kubernetes 网络故障的工具和技术。

前提条件

  • 您还应该在本地安装 kubectl。根据您的本地环境,请遵循官方文档关于 安装 Kubernetes 工具 的说明。 kubectl 应该配置为连接到您的集群。我们将在下面的章节中进一步解释。

我们将在本地和 Kubernetes 节点上运行几个命令。让我们开始吧!

配置本地 kubectl 以连接到远程 Kubernetes 集群

让我们首先安装 kubectl。我们的本地环境运行的是 Ubuntu,如果您运行的是其他本地环境,请访问 此链接。要在使用 kubectl 工具的 Ubuntu/Debian 本地环境上,使用 apt 包管理器进行安装,请运行以下命令来更新 apt 软件源并安装必要的软件包:

接下来,运行以下命令下载 Google 云端公开签名密钥:

然后,添加 Kubernetes apt 软件源:

之后,使用以下命令更新 apt 索引并安装 kubectl:

然后,通过使用以下命令检查版本来验证 kubectl 是否已安装:

如果您刚刚在本地安装了 kubectl,输出如下:

kubectl version

在上面的截图中, kubectl 正在尝试连接 to 本地 Kubernetes 集群。但是,连接失败了,因为我们的本地机器上还没有运行 Kubernetes 集群。

要连接到远程 Kubernetes 集群,您首先需要从远程集群下载 Kubernetes 凭据。以下是从主节点复制凭据的命令:

将突出显示的部分替换为您的 ssh 用户名和主节点的公网 IP。凭据下载完成后,将凭据复制到您的家目录:

就这么简单。您的本地 kubectl 应该能够连接到您的远程 Kubernetes 集群并向其发出命令。要确认您的本地 kubectl 已连接到远程集群,请再次使用 version 命令进行检查:

以下是输出,显示连接成功:

kubectl version json

(可选)您可以执行 get nodes 命令,如下所示:

kubectl get nodes

获取 Pod 的 Cluster IP

您可以通过在本地计算机上运行 kubectl get pod 命令来获取 Pod 的 Cluster IP。要列出更多信息(例如托管 Pod 的节点以及 Pod 的 Cluster IP),请将标志 -o wide 添加到命令中:

以下是我们的 Kubernetes 集群的输出。如您所见,在前提条件教程中,我们已经创建了一个 Nginx Web 服务器部署:

kubectl get pod -o wide

IP 列显示了单个 Pod 的内部 IP 地址。如果您寻找的 Pod 没有出现在列表中,您可能处于不同的命名空间中。您可以发出以下命令来列出所有 namespaces:

获取 Service 的 IP 地址

您还可以获取集群上 Service 的 IP 地址。通过添加 --all-namespaces 标志,您可以获取集群上运行的所有服务:

上述命令的输出如下。Service IP 位于 cluster-ip 列中:

kubectl get svc

获取和访问 Pod 网络命名空间

每个 Kubernetes Pod 都分配有一个网络命名空间。网络命名空间(也称为 netns)是 Linux 中的原生网络库,用于提供网络设备之间的隔离。

要检查 DNS 解析或常规网络连接,您可以在 Pod 的网络命名空间内运行命令。为此,您首先需要查找 Pod 中某个容器的进程 ID。您可以在 Docker 中使用 Docker 特定的命令轻松完成此操作。第一个命令列出了节点上运行的容器。登录到您的一个工作节点并运行以下命令:

docker ps

在输出中,我们关注的是容器 ID 或 Names(名称)列。请注意我们在前提条件教程中部署的 Nginx Nginx 容器 如何在 Ubuntu 20.04 上安装和使用 Kubernetes.

接下来,复制容器 ID 或名称,因为我们将在下一个命令中使用它来查找进程 ID:

将突出显示的部分替换为您从上一个命令中复制的值。以下是我们得到的输出,即进程 ID:

docker inspect

现在我们有了进程 ID,可以使用它在进程的网络命名空间内运行 nsenter 命令:

将突出显示的部分替换为您在上一个命令中获取的进程 ID。然后,在 ip addr 的位置,您可以输入任何您想在 Pod 的网络命名空间内运行的命令。如果遇到权限被拒绝的错误,您也可以使用 sudo 来运行它。

使用 nsenter 命令允许您运行节点上可用的更广泛的命令,相比之下,使用 docker exec 命令仅限制您使用容器内安装的命令。

检索 Pod 的虚拟以太网接口

Pod 上的网络命名空间通过虚拟以太网管道与节点的根 netns 进行通信。在节点端,此管道显示为一个名称以 veth 开头并以唯一标识符结尾的设备,例如 veth742f721 或 veth90。而在 Pod 内部,该管道标识为 eth0.

您可能想知道哪个 veth 设备与哪个 Pod 配对。您可以先列出节点上的所有网络设备,然后列出 Pod 网络中的所有设备。要识别哪个 veth 设备与特定 Pod 配对,您可以关联这两个列表之间的设备编号。

使用 nsenter 命令在 Pod 的网络命名空间中运行 ip addr 命令。您需要知道其中一个容器的进程 ID。为此,请参阅上一节关于 获取和访问 Pod 网络命名空间.

接下来,在工作节点的终端上执行以下命令,并相应地替换突出显示的部分:

该命令输出 Pod 的接口列表:

nsenter ip addr

注意 if7 字符,在 之后eth0@ (在上述输出中)。这意味着 Pod 的 eth0 与节点的第 7 个接口配对。接下来,通过运行 ip addr 命令列出节点默认命名空间内的接口:

该命令列出的接口如下所示:

Kubernetes Networking ip addr

在输出中,第 7 个接口是 veth254b50e6@if3  – 与我们正在测试的 Pod 配对的虚拟以太网管道。

审查 Iptables 规则

您可以执行命令 iptables-save 来列出节点上的所有 iptables:

该命令的输出可能会很长,因此您可以将其保存到文件中以便稍后检查:

您也可以使用 less 对输出进行分页:

由于我们只对 Kubernetes NAT 规则感兴趣,请添加 -L 标志来指定正确的目标:

以下是输出:

Kubernetes Networking iptables

检查 IPVS 详情

Kube-proxy 是运行在 Kubernetes 集群中每个节点上的网络代理。它可用于配置 IPVS,以处理虚拟 Service IP 到 Pod IP 的转换。要列出 IP 转换表,您可以使用 ipvsadm 命令。首先,您需要在节点上安装它:

现在您可以执行以下命令:

要显示单个 Service IP,请添加 -t 标志,并指定所需的 IP 地址:

查询集群 DNS

有几种方法可以用来调试集群 DNS 解析。官方文档 描述的一种方法是部署一个包含所有必要工具的调试容器,然后使用 kubectl 来执行 nslookup.

或者,您也可以直接从节点本身使用 dig 和 nsenter 命令来查询 DNS。首先,您必须在主节点上安装 dig。对于 Ubuntu,请使用 apt 命令进行安装:

Kubernetes Networking install dnsutils

返回本地机器上的终端,运行以下命令以查找 kube-dns 服务的集群 IP:

该命令输出:

get kube dns service

The cluster-ip 列包含我们需要的值。现在我们可以使用 nsenter 来在容器命名空间中运行 dig 。但是,您需要一个容器进程 ID 才能访问其命名空间。请参阅上面的 获取和访问 Pod 网络命名空间 部分以获取指导。

一旦您获得了 container-id,请在主节点上执行以下命令:

The dig 命令接收集群 DNS 服务的 IP( @10.96.0.10)并查找服务的完整域名 service-name.namespace.svc.cluster.local:

Kubernetes Networking nsenter dig

有关查找服务名称 and 命名空间的信息,请参阅 获取服务的 IP 地址.

审查 Conntrack 连接跟踪

您可以使用 conntrack 命令来查看当前正在跟踪的所有连接:

它的输出类似于屏幕截图:

Kubernetes Networking conntrac -l

添加 -E 标志以持续监视传入的连接:

要查看跟踪到特定目标地址的连接,请添加 -d 标志并指定目标地址:

有时连接跟踪表会被填满,导致新连接被丢弃。这会导致一些问题,阻止您的节点建立可靠的连接。如果发生这种情况,您将在系统日志的以下位置看到类似以下的信息: /var/log/syslog:

存在一个用于跟踪最大连接数的系统设置。使用以下命令列出您的当前值:

它输出:

conntrack max

您可以通过使用 -w 标志:

您可能需要修改您的 /etc/sysctl.conf 文件以使该值永久生效,并确保其在重启后依然存在。使用 nano 打开该文件:

接下来,如果该行存在则修改其值,或者在文件末尾添加该行,并指定新值:

结论

在部署多个容器化服务时,您将从 Kubernetes 中获益匪浅,因为它为您提供了一个集中管理点。为了确保各个 Kubernetes Pod 之间的连通性,我们向您展示了一些网络检查命令,您可以使用这些命令来排查 Kubernetes 基础设施中的任何问题。

要了解更多关于 Kubernetes 及其优势、在 Kubernetes 上设置和部署应用程序的信息,请查看我们的各种 Kubernetes 教程.

祝您使用愉快!

Pranay Kapgate

作者 · CloudSigma

评论

暂无评论。发表第一条评论吧。