如何检查 Kubernetes 网络配置

简介: 如何检查 Kubernetes 网络配置

简介

Kubernetes 是一个容器编排系统,可以管理集群中的容器化应用程序。在集群中保持所有容器之间的网络连接需要一些高级网络技术。在本文中,我们将简要介绍一些工具和技术,用于检查这种网络设置。

如果您正在调试连接问题,调查网络吞吐量问题,或者探索 Kubernetes 的运行方式,这些工具可能会很有用。

如果您想了解更多关于 Kubernetes 的一般信息,我们的指南《Kubernetes 简介》涵盖了基础知识。对于 Kubernetes 的网络概述,请阅读《深入了解 Kubernetes 网络》。

如果您正在寻找托管的 Kubernetes 服务,可以查看我们为增长而构建的简单、托管的 Kubernetes 服务。

入门指南

本教程将假定您已经有一个 Kubernetes 集群,并在本地安装并配置了 kubectl 以连接到该集群。

以下各节包含许多命令,这些命令旨在在 Kubernetes 节点上运行。它们看起来像这样:

echo '这是一个节点命令'

应在本地机器上运行的命令将具有以下外观:

[本地环境]
echo '这是一个本地命令'

查找 Pod 的集群 IP

要查找 Kubernetes Pod 的集群 IP 地址,请在本地机器上使用 kubectl get pod 命令,并带有 -o wide 选项。此选项将列出更多信息,包括 Pod 所在的节点以及 Pod 的集群 IP。

[本地环境]
kubectl get pod -o wide
[本地环境]
NAME                           READY     STATUS    RESTARTS   AGE       IP            NODE
hello-world-5b446dd74b-7c7pk   1/1       Running   0          22m       10.244.18.4   node-one
hello-world-5b446dd74b-pxtzt   1/1       Running   0          22m       10.244.3.4    node-two

IP 列将包含每个 Pod 的内部集群 IP 地址。

如果您没有看到您要查找的 Pod,请确保您在正确的命名空间中。您可以通过添加 --all-namespaces 标志来列出所有命名空间中的所有 Pod。

查找服务的 IP

我们也可以使用 kubectl 来查找服务 IP。在这种情况下,我们将列出所有命名空间中的所有服务:

[本地环境]
kubectl get service --all-namespaces
[本地环境]
NAMESPACE     NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
default       kubernetes                 ClusterIP   10.32.0.1       <none>        443/TCP         6d
kube-system   csi-attacher-doplugin      ClusterIP   10.32.159.128   <none>        12345/TCP       6d
kube-system   csi-provisioner-doplugin   ClusterIP   10.32.61.61     <none>        12345/TCP       6d
kube-system   kube-dns                   ClusterIP   10.32.0.10      <none>        53/UDP,53/TCP   6d
kube-system   kubernetes-dashboard       ClusterIP   10.32.226.209   <none>        443/TCP         6d

服务 IP 可以在 CLUSTER-IP 列中找到。

查找并进入 Pod 网络命名空间

每个 Kubernetes Pod 都被分配了自己的网络命名空间。网络命名空间(或 netns)是 Linux 的网络原语,提供了网络设备之间的隔离。

从 Pod 的 netns 中运行命令可能很有用,以检查 DNS 解析或一般网络连接。为此,我们首先需要查找一个 Pod 中容器的进程 ID。对于 Docker,我们可以使用两个命令来完成。首先,列出在节点上运行的容器:

docker ps
CONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS              PORTS               NAMES
173ee46a3926        gcr.io/google-samples/node-hello        "/bin/sh -c 'node se…"   9 days ago          Up 9 days                               k8s_hello-world_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0
11ad51cb72df        k8s.gcr.io/pause-amd64:3.1              "/pause"                 9 days ago          Up 9 days                               k8s_POD_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0
. . .

找到您感兴趣的 Pod 中的任何容器的 容器 ID名称。在上面的输出中,我们展示了两个容器:

  • 第一个容器是在 hello-world Pod 中运行的 hello-world 应用程序
  • 第二个是在 hello-world Pod 中运行的 pause 容器。此容器仅用于保存 Pod 的网络命名空间

要获取任一容器的进程 ID,请记下容器 ID 或名称,并将其用于以下 docker 命令:

docker inspect --format '{{ .State.Pid }}' container-id-or-name
14552

将输出一个进程 ID(或 PID)。现在我们可以使用 nsenter 程序在该进程的网络命名空间中运行命令:

nsenter -t your-container-pid -n ip addr

请确保使用您自己的 PID,并将 ip addr 替换为您想在 Pod 的网络命名空间中运行的命令。

查找 Pod 的虚拟以太网接口

每个 Pod 的网络命名空间通过虚拟以太网管道与节点的根 netns 进行通信。在节点端,这个管道会显示为一个设备,通常以 veth 开头并以唯一标识符结尾,比如 veth77f2275veth01。在 Pod 内部,这个管道会显示为 eth0

将特定的 veth 设备与相应的 Pod 相关联可能会很有用。为了做到这一点,我们将列出节点上的所有网络设备,然后列出 Pod 的网络命名空间中的设备。然后我们可以对比这两个列表中的设备编号,以建立它们之间的关联。

首先,在 Pod 的网络命名空间中使用 nsenter 运行 ip addr。有关如何执行此操作,请参考前面的章节 查找并进入 Pod 网络命名空间

nsenter -t your-container-pid -n ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    link/ether 02:42:0a:f4:03:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.244.3.4/24 brd 10.244.3.255 scope global eth0
       valid_lft forever preferred_lft forever

该命令将输出 Pod 的接口列表。请注意示例输出中 eth0@ 后面的 if11 编号。这意味着该 Pod 的 eth0 连接到节点的第 11 个接口。现在在节点的默认命名空间中运行 ip addr 以列出其接口:

ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
. . .
7: veth77f2275@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default
    link/ether 26:05:99:58:0d:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::2405:99ff:fe58:db9/64 scope link
       valid_lft forever preferred_lft forever
9: vethd36cef3@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default
    link/ether ae:05:21:a2:9a:2b brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::ac05:21ff:fea2:9a2b/64 scope link
       valid_lft forever preferred_lft forever
11: veth4f7342d@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default
    link/ether e6:4d:7b:6f:56:4c brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::e44d:7bff:fe6f:564c/64 scope link
       valid_lft forever preferred_lft forever

在这个示例输出中,第 11 个接口是 veth4f7342d。这是我们要调查的 Pod 的虚拟以太网管道。

检查 Conntrack 连接跟踪

在 1.11 版本之前,Kubernetes 使用 iptables NAT 和 conntrack 内核模块来跟踪连接。要列出当前正在被跟踪的所有连接,使用 conntrack 命令:

conntrack -L

要持续监视新连接,使用 -E 标志:

conntrack -E

要列出针对特定目标地址进行 conntrack 跟踪的连接,使用 -d 标志:

conntrack -L -d 10.32.0.1

如果您的节点在与服务建立可靠连接时出现问题,可能是您的连接跟踪表已满,新连接正在被丢弃。如果是这种情况,您可能会在系统日志中看到以下消息:

Jul 12 15:32:11 worker-528 kernel: nf_conntrack: table full, dropping packet.

有一个 sysctl 设置用于跟踪的最大连接数。您可以使用以下命令列出当前值:

sysctl net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_max = 131072

要设置新值,使用 -w 标志:

sysctl -w net.netfilter.nf_conntrack_max=198000

要使此设置永久生效,将其添加到 sysctl.conf 文件中:

. . .
net.ipv4.netfilter.ip_conntrack_max = 198000

检查 Iptables 规则

在版本 1.11 之前,Kubernetes 使用 iptables NAT 来实现服务 IP 的虚拟 IP 转换和负载均衡。

要在节点上转储所有 iptables 规则,请使用 iptables-save 命令:

iptables-save

由于输出可能很长,您可能希望将其重定向到文件(iptables-save > output.txt)或使用分页器(iptables-save | less)以便更轻松地查看规则。

要仅列出 Kubernetes 服务 NAT 规则,请使用 iptables 命令和 -L 标志来指定正确的链:

iptables -t nat -L KUBE-SERVICES
Chain KUBE-SERVICES (2 references)
target     prot opt source               destination
KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  anywhere             10.32.0.10           /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  anywhere             10.32.0.10           /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
KUBE-SVC-XGLOHA7QRQ3V22RZ  tcp  --  anywhere             10.32.226.209        /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:https
. . .

查询集群 DNS

调试集群 DNS 解析的一种方法是部署一个带有您需要的所有工具的调试容器,然后使用 kubectl 在其上执行 nslookup。这在官方 Kubernetes 文档中有描述。

另一种查询集群 DNS 的方法是在节点上使用 dignsenter。如果在基于 Debian 的 Linux 发行版上未安装 dig,可以使用 apt 进行安装:

apt install dnsutils

首先,找到 kube-dns 服务的集群 IP:

[environment local]
kubectl get service -n kube-system kube-dns
[environment local]
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.32.0.10   <none>        53/UDP,53/TCP   15d

上面突出显示了集群 IP。接下来,我们将使用 nsenter 在容器命名空间中运行 dig。有关此操作的更多信息,请参阅 查找并进入 Pod 网络命名空间 部分:

nsenter -t 14346 -n dig kubernetes.default.svc.cluster.local @10.32.0.10

dig 命令查找了服务的完整域名 service-name.namespace.svc.cluster.local,并指定了集群 DNS 服务 IP 的 IP(@10.32.0.10)。

查看 IPVS 详细信息

从 Kubernetes 1.11 开始,kube-proxy 可以配置 IPVS 来处理虚拟服务 IP 到 Pod IP 的转换。您可以使用 ipvsadm 列出 IP 的转换表:

ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  100.64.0.1:443 rr
  -> 178.128.226.86:443           Masq    1      0          0
TCP  100.64.0.10:53 rr
  -> 100.96.1.3:53                Masq    1      0          0
  -> 100.96.1.4:53                Masq    1      0          0
UDP  100.64.0.10:53 rr
  -> 100.96.1.3:53                Masq    1      0          0
  -> 100.96.1.4:53                Masq    1      0          0

要显示单个服务 IP,请使用 -t 选项并指定所需的 IP:

ipvsadm -Ln -t 100.64.0.10:53
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  100.64.0.10:53 rr
  -> 100.96.1.3:53                Masq    1      0          0
  -> 100.96.1.4:53                Masq    1      0          0

结论

在本文中,我们回顾了一些用于探索和检查 Kubernetes 集群网络细节的命令和技术。有关 Kubernetes 的更多信息,请查看我们的 Kubernetes 教程标签和官方 Kubernetes 文档。


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
12月前
|
运维 Kubernetes 前端开发
如何用 eBPF 实现 Kubernetes 网络可观测性?实战指南
本文深入探讨了Kubernetes网络观测的挑战与eBPF技术的应用。首先分析了传统工具在数据碎片化、上下文缺失和性能瓶颈上的局限性,接着阐述了eBPF通过零拷贝观测、全链路关联和动态过滤等特性带来的优势。文章进一步解析了eBPF观测架构的设计与实现,包括关键数据结构、内核探针部署及生产环境拓扑。实战部分展示了如何构建全栈观测系统,并结合NetworkPolicy验证、跨节点流量分析等高级场景,提供具体代码示例。最后,通过典型案例分析和性能数据对比,验证了eBPF方案的有效性,并展望了未来演进方向,如智能诊断系统与Wasm集成。
578 0
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
Kubernetes 负载均衡 网络安全
Kubernetes 网络模型与实践
【8月更文第29天】Kubernetes(K8s)是当今容器编排领域的佼佼者,它提供了一种高效的方式来管理容器化应用的部署、扩展和运行。Kubernetes 的网络模型是其成功的关键因素之一,它支持服务发现、负载均衡和集群内外通信等功能。本文将深入探讨 Kubernetes 的网络模型,并通过实际代码示例来展示服务发现和服务网格的基本概念及其实现。
705 3
|
Kubernetes Devops 持续交付
DevOps实践:使用Docker和Kubernetes实现持续集成和部署网络安全的守护盾:加密技术与安全意识的重要性
【8月更文挑战第27天】本文将引导读者理解并应用DevOps的核心理念,通过Docker和Kubernetes的实战案例,深入探讨如何在现代软件开发中实现自动化的持续集成和部署。文章不仅提供理论知识,还结合真实示例,旨在帮助开发者提升效率,优化工作流程。
|
Kubernetes Shell Windows
【Azure K8S | AKS】在AKS的节点中抓取目标POD的网络包方法分享
在AKS中遇到复杂网络问题时,可通过以下步骤进入特定POD抓取网络包进行分析:1. 使用`kubectl get pods`确认Pod所在Node;2. 通过`kubectl node-shell`登录Node;3. 使用`crictl ps`找到Pod的Container ID;4. 获取PID并使用`nsenter`进入Pod的网络空间;5. 在`/var/tmp`目录下使用`tcpdump`抓包。完成后按Ctrl+C停止抓包。
544 12
|
安全 网络协议 网络安全
当虚拟机出现网络连接问题时,应该先检查Hyper-V的网卡连接配置
当虚拟机出现网络连接问题时,应首先检查Hyper-V的网卡配置。具体步骤包括:确认虚拟机运行状态、检查虚拟交换机类型和物理网卡连接、确保虚拟机网络适配器正确连接到虚拟交换机,并验证网络配置(IP地址等)。常见问题如虚拟交换机配置错误、网络适配器未连接或防火墙阻止连接,可通过重新配置或调整设置解决。必要时重启虚拟机和宿主机,查看事件日志或联系技术支持以进一步排查问题。
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
1089 2
|
运维 监控 网络协议
|
Kubernetes 容器 Perl
Kubernetes网络插件体系及flannel基础
文章主要介绍了Kubernetes网络插件体系,特别是flannel网络模型的工作原理、配置和测试方法。
552 3
Kubernetes网络插件体系及flannel基础
|
Kubernetes 网络协议 网络安全
k8s中网络连接问题
【10月更文挑战第3天】
1297 7

推荐镜像

更多