返回博客

如何排查和检查 Kubernetes 网络

如何排查和检查 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 开头并以唯一标识符结尾的设备,例如 veth742f721veth90。而在 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.

或者,您也可以直接从节点本身使用 dignsenter 命令来查询 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 教程.

祝您使用愉快!

author

Pranay Kapgate

作者 · CloudSigma

Preslav Dobrev 是 CloudSigma 的创意设计师,专注于通过传统和创新营销渠道打造一致的企业形象。他擅长将艺术愿景与战略营销相融合,创造具有影响力的品牌叙事。

评论

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