如何检查Kubernetes网络

介绍

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

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

如果您想了解更多关于Kubernetes的信息,我们的指南介绍Kubernetes涵盖了基础知识。 有关Kubernetes的网络特定概述,请阅读Kubernetes网络引擎

入门

本教程假设您有一个Kubernetes集群,其中kubectl在本地安装并配置为连接到集群。

以下部分包含许多要在Kubernetes节点上运行的命令。 它们看起来像这样:

echo 'this is a node command'

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

echo 'this is a local command'

注意:本教程中的大多数命令都需要以root用户身份运行。 如果您在Kubernetes节点上使用启用了sudo的用户,请在必要时添加sudo以运行命令。

查找Pod的群集IP

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

kubectl get pod -o wide
OutputNAME                           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
OutputNAMESPACE     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

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

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

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

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

docker ps
OutputCONTAINER 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
. . .

在您感兴趣的窗格中查找容器ID容器的 名称 。在上面的输出中,我们显示了两个容器:

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

要获取任一容器的进程ID,请记下容器ID或名称,并在以下docker命令中使用它:

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

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

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

请务必使用您自己的PID,并将ip addr替换为您要在pod的网络命名空间内运行的命令。

注意:使用nsenter在pod的命名空间中运行命令(与使用nsenter docker exec类的命令相比)的一个优点是,您可以访问节点上可用的所有命令,而不是容器中安装的通常有限的命令集。

寻找Pod的虚拟以太网接口

每个pod的网络命名空间通过虚拟以太网管道与节点的根网络通信。 在节点端,此管道显示为通常以veth并以唯一标识符结尾的设备,例如veth77f2275veth01 在pod中,此管道显示为eth0

关联哪个veth设备与特定pod配对可能是有用的。 为此,我们将列出节点上的所有网络设备,然后列出pod的网络命名空间中的设备。 然后,我们可以关联两个列表之间的设备编号以建立连接。

首先,使用nsenter在pod的网络命名空间中运行ip addr 请参阅上一节“ 查找和输入Pod网络命名空间”
有关如何执行此操作的详细信息:

nsenter -t your-container-pid -n ip addr
Output1: 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
Output1: 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

如果您的节点在与服务建立可靠连接时遇到问题,则可能是您的连接跟踪表已满并且正在删除新连接。 如果是这种情况,您可能会在系统日志中看到如下消息:

在/ var / log / syslog的
Jul 12 15:32:11 worker-528 kernel: nf_conntrack: table full, dropping packet.

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

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

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

sysctl -w net.netfilter.nf_conntrack_max=198000

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

/etc/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
OutputChain 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 如果没有安装dig ,可以在基于Debian的Linux发行版上安装apt

apt install dnsutils

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

kubectl get service -n kube-system kube-dns
OutputNAME       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的service-name的完整域名 命名空间 .svc.cluster.local并指定集群DNS服务IP的IP( @ 10.32.0.10 )。

查看IPVS详细信息

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

ipvsadm -Ln
OutputIP 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
OutputProt 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文档

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏