1. 简介
Kubernetes 将容器组织为称为 Pod 的单元,每个 Pod 负责其中容器的存储分配、资源调度和网络配置。因此,要获取某个容器的 IP 地址等信息,通常我们会查看其所在 Pod 的定义。
然而,有时我们希望从 Pod 内部获取这些网络配置信息。本文将探讨几种方式,帮助你从容器内部或通过 Kubernetes 工具获取 Pod 或容器的 IP 地址。
我们假设使用的是 Docker 作为容器运行时,测试环境为 Debian 12(Bookworm)+ GNU Bash 5.2.15。
2. 创建 Pod
Kubernetes 中,Pod 通常通过配置文件定义并创建。
以下是一个简单的 Pod 定义文件:
$ cat compod.yaml
apiVersion: v1
kind: Pod
metadata:
name: compod
spec:
containers:
- name: deb1
image: debian:latest
command: ["sh"]
tty: true
- name: deb2
image: debian:latest
command: ["sh"]
tty: true
使用 kubectl
创建该 Pod:
$ kubectl apply --filename=compod.yaml
或者直接通过命令行输入定义内容:
$ kubectl apply --filename=- <<< '
apiVersion: v1
kind: Pod
metadata:
name: compod
spec:
containers:
- name: deb1
image: debian:latest
command: ["sh"]
tty: true
- name: deb2
image: debian:latest
command: ["sh"]
tty: true
'
pod/compod created
接下来,我们来看看 Kubernetes 是如何为 Pod 分配网络地址的。
3. Pod 网络基础
Kubernetes 的网络模型通常由底层容器运行时(如 Docker)支持,也可以通过插件(如 Flannel、Calico)进行扩展。
关键组件包括:
- 网络插件:为 Pod 分配 IP
- kube-apiserver:为 Service 分配 IP
- kubelet / cloud-controller-manager:为节点分配 IP
每个 Pod 内的容器通过一个 veth 接口连接到主机上的一个 bridge 网络接口。例如:
+------------+ +------------+
| container1 | | container2 |
|(10.244.0.#)| |(10.244.0.#)|
| veth0 | | veth1 |
+------------+ +------------+
^ ^
v v
+-----------------------------+
| host |
| (10.244.0.1) |
| bridge |
+-----------------------------+
这种结构使得 Pod 内容器拥有独立 IP,并可通过 bridge 与外部通信。
4. Pod IP 地址分配机制
4.1. 获取节点 CIDR 地址
Kubernetes 每个节点会被分配一个 CIDR 子网。查看当前节点的子网:
$ kubectl get node minikube --output=jsonpath={..podCIDR}
10.244.0.0/24
这个子网用于为该节点上的 Pod 分配 IP。
4.2. 查看 Kubernetes 网桥
查看主机上的网络接口:
$ ip address show
3: bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ce:e9:1c:47:3f:16 brd ff:ff:ff:ff:ff:ff
inet 10.244.0.1/16 brd 10.244.255.255 scope global bridge
可以看到 Kubernetes 使用的网桥 bridge
,IP 为 10.244.0.1
。
4.3. 容器虚拟以太网接口
每个容器都有一个对应的 veth*
接口连接到这个网桥:
$ ip address show
4: veth24d8dc94@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge state UP group default
35: veth28f88740@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge state UP group default
这些接口与容器内的 eth0
对应,实现网络通信。
5. 在容器内部获取 IP 地址
5.1. 列出容器
使用 docker ps
查看容器信息:
$ docker ps
CONTAINER ID IMAGE NAMES
ff9f22b59b1d debian k8s_deb2_compod_default_855cfd1d-5aec-4240-b750-1283af2c1a26_0
6cc96be009e3 debian k8s_deb1_compod_default_855cfd1d-5aec-4240-b750-1283af2c1a26_0
5.2. 进入容器
使用 kubectl exec
或 docker exec
进入容器:
$ kubectl exec --stdin --tty pod/compod --container deb1 -- bash
5.3. 使用 ip
或 /proc
获取 IP
在容器中运行:
root@compod:/# ip address show
2: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether c2:98:17:b5:04:e2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.244.0.33/16 brd 10.244.255.255 scope global eth0
如果容器没有 ip
命令,可以查看 /proc/net/fib_trie
:
$ cat /proc/net/fib_trie
Main:
+-- 10.244.0.0/16 2 0 2
+-- 10.244.0.0/26 2 0 2
|-- 10.244.0.33
/32 host LOCAL
5.4. 无 Shell 容器的处理
如果容器没有 shell,可以使用 kubectl exec
直接读取文件:
$ kubectl exec --stdin --tty pod/compod --container deb1 -- cat /proc/net/fib_trie
5.5. 极简容器的调试方式
使用 kubectl debug
创建调试容器:
$ kubectl debug --tty --stdin pod/compod --image=debian:latest --target=deb1 -- bash
该调试容器与目标容器共享命名空间,可使用完整工具链。
⚠️ 注意:同一个 Pod 中的所有容器共享 IP。
6. 从 Pod 定义中获取 IP 地址
使用 kubectl get
查看 Pod 的 IP:
$ kubectl get pod/compod --output wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
compod 2/2 Running 0 25h 10.244.0.33 minikube <none> <none>
使用 kubectl describe
也能看到:
$ kubectl describe pod/compod
Name: compod
IP: 10.244.0.33
使用 jsonpath
提取 IP:
$ kubectl get pod/compod --output=jsonpath='{..podIP}'
10.244.0.33
若存在多个 IP:
$ kubectl get pod/compod --output=jsonpath='{..podIPs}'
[{"ip":"10.244.0.33"}]
⚠️ 注意:使用 docker inspect
不会显示 Kubernetes 的 IP,因为 Docker 网络不参与 Kubernetes 的 IP 分配。
7. 总结
✅ 本文总结了从容器内部及外部获取 Kubernetes Pod 和容器 IP 的多种方式:
方法 | 说明 |
---|---|
ip address |
最直接,但容器可能无此命令 |
/proc/net/fib_trie |
无需安装工具,适用于极简容器 |
kubectl exec |
可直接执行命令或读取文件 |
kubectl debug |
创建调试容器,适合无工具容器 |
kubectl get / describe |
从外部快速获取 Pod IP |
⚠️ 踩坑提示:
- Docker 网络接口不参与 Kubernetes IP 分配,
docker inspect
无法获取有效信息。 - 极简容器可能连
/proc
都不挂载,需提前规划好调试方式。
熟练掌握这些方法,有助于在实际部署中快速定位网络问题,提升调试效率。