ip —— 现代 Linux 网络配置工具(替代 ifconfig / route)
一句话定义
ip 是 Linux iproute2 套件的主命令,取代了老旧的 ifconfig / route / arp / iwconfig 等。一个命令统管:IP 地址 / 路由 / 网卡 / ARP / 网络命名空间 / 隧道。
典型场景
训练营文档里 ip 出场 53 次,主要在:
- 装机看网卡:
ip addr - 看路由:
ip route - 排查 K8s pod 网络:
ip link看 veth / cni 设备 - 看 ARP:
ip neigh - 进入 pod network namespace:
ip netns exec
Ubuntu / RHEL 现代版本默认没装
ifconfig(要装net-tools包)。学 ip、忘掉 ifconfig。
子命令架构
ip 是个分层命令:
ip <object> <command>
│ │
│ └─ add / del / show / flush / change ...
└─ addr / link / route / neigh / netns / rule / tunnel ...
最常用的对象:
| 对象 | 缩写 | 管啥 |
|---|---|---|
address | addr / a | IP 地址 |
link | l | 网卡(L2 层) |
route | r | 路由表 |
neighbor | neigh / n | ARP / NDP 邻居 |
netns | 网络命名空间 | |
rule | 路由策略(多路由表) |
可以缩写:ip a = ip addr、ip r = ip route、ip l = ip link。
ip addr —— 看 / 改 IP 地址
ip addr show # 看所有网卡和 IP
ip addr show eth0 # 看某网卡
ip a # 缩写
# 一行式(每个网卡显示一行)
ip -br addr
# lo UNKNOWN 127.0.0.1/8 ::1/128
# eth0 UP 10.0.24.28/24 fe80::.../64
# cni0 UP 10.244.0.1/24
-br 是 brief 模式,装机巡检最爱。
加 / 删 IP
ip addr add 10.0.0.5/24 dev eth0 # 加 IP
ip addr del 10.0.0.5/24 dev eth0 # 删
ip addr flush dev eth0 # 清空网卡所有 IP(小心)
注意 add 只在内存生效,重启就没了。永久要写 netplan / NetworkManager / systemd-networkd。
一个网卡多个 IP
ip addr add 10.0.24.28/24 dev eth0 # 主 IP
ip addr add 10.0.24.99/24 dev eth0 # 同网卡再加一个
ip addr show eth0
# inet 10.0.24.28/24 ...
# inet 10.0.24.99/24 ...
K8s ingress 节点可以这样绑多个 VIP。
ip link —— 网卡(L2 层)
ip link show # 看所有网卡
ip -br link # brief
# lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
# eth0 UP aa:bb:cc:dd:ee:ff <BROADCAST,MULTICAST,UP,LOWER_UP>
# cni0 UP aa:bb:cc:dd:ee:01 <BROADCAST,MULTICAST,UP,LOWER_UP>
# vethXXXX@if4 UP aa:bb:cc:dd:ee:02 <BROADCAST,MULTICAST,UP,LOWER_UP>
启用 / 禁用网卡
ip link set eth0 down
ip link set eth0 up
ip link set eth0 mtu 1450 # 改 MTU
ip link set eth0 address aa:bb:cc:dd:ee:ff # 改 MAC(小心)
看网卡详细
ip -s link show eth0 # -s = 含统计(收发包数 / 错误数)
# RX: bytes packets errors dropped overrun mcast
# TX: bytes packets errors dropped carrier collsns
排查丢包:errors / dropped 列突然涨 = 物理层或者 driver 问题。
K8s 的网卡:cni0 / flannel.1 / cilium_xxx / vethXXXX
K8s 节点跑起来后会多出一堆网卡:
| 网卡 | 来源 | 作用 |
|---|---|---|
cni0 / flannel.1 / weave | CNI 创建 | pod 网桥 / overlay |
cilium_host / cilium_net | Cilium | eBPF datapath |
vethXXXX@ifN | 每个 pod 启动时创建 | pod 的网卡在主机侧的一头(另一头在 pod netns 里) |
kube-ipvs0 | kube-proxy IPVS 模式 | 挂 service ClusterIP |
vethXXXX@if4 的 @if4 表示另一头对应 ifindex 是 4。在 pod 里跑 ip link 能看到 ifindex。
ip route —— 路由表
ip route show # 看主路由表
ip route # 等价
ip r # 缩写
# default via 10.0.24.1 dev eth0 proto dhcp src 10.0.24.28 metric 100
# 10.0.24.0/24 dev eth0 proto kernel scope link src 10.0.24.28
# 10.244.0.0/24 via 10.0.24.31 dev eth0 ← 到 worker 节点 pod cidr 的路由
# 10.244.1.0/24 via 10.0.24.32 dev eth0
读法:
default via X.X.X.X dev N—— 默认网关<cidr> dev N—— 直连路由<cidr> via X.X.X.X dev N—— 间接路由
看某个 IP 怎么走
ip route get 8.8.8.8
# 8.8.8.8 via 10.0.24.1 dev eth0 src 10.0.24.28 uid 0
ip route get 10.244.1.5 # 查 pod IP 怎么走
# 10.244.1.5 via 10.0.24.32 dev eth0 ... ← 经过 worker m5
ip route get 是 K8s 网络排错神器:你怀疑某个 IP 路由不对、跑一下立刻知道下一跳。
加 / 删路由(临时)
ip route add 10.10.10.0/24 via 192.168.1.1
ip route del 10.10.10.0/24
ip route flush table main # 清空(小心)
ip neigh —— ARP / NDP
ip neigh # 看 ARP 表
# 10.0.24.1 dev eth0 lladdr aa:bb:cc:dd:ee:00 REACHABLE
# 10.0.24.29 dev eth0 lladdr aa:bb:cc:dd:ee:11 STALE
# 10.0.24.30 dev eth0 lladdr aa:bb:cc:dd:ee:22 REACHABLE
状态:
REACHABLE—— 邻居在线STALE—— 信息陈旧、下次通信时验证FAILED—— 验证失败 / 不可达INCOMPLETE—— 发了 ARP 等回复中
排查"两台机器 ping 不通但路由对":看 ARP 是不是 INCOMPLETE / FAILED。
ip neigh flush all # 清 ARP 表(强制重新解析)
ip -4 / -6 / -c
ip -4 addr # 只看 IPv4
ip -6 addr # 只看 IPv6
ip -c addr # 加颜色(更易读)
ip -c -br addr # 颜色 + brief
ip -c -br a 是日常巡检最美观的写法。
ip netns —— 网络命名空间
K8s pod 的网络隔离本质就是 netns(network namespace)。每个 pod 一个 netns。
ip netns list # 列所有 netns
# (K8s 创建的 netns 默认不在这里显示,因为路径不一样)
找 pod 对应的 netns
# 1. 找 pod 在节点上的容器 ID
crictl ps | grep my-pod
# CONTAINER IMAGE ...
# abc123... nginx
# 2. 找容器的 PID
crictl inspect abc123 | jq '.info.pid'
# 12345
# 3. 进入这个 PID 的 netns
nsenter -t 12345 -n ip addr
# 看 pod 的网卡和 IP
或者更直接:
nsenter -t 12345 -n ip route
nsenter -t 12345 -n ss -lntp
nsenter -t 12345 -n curl http://localhost:8080
这是 K8s 网络排错神器:从节点上"进入"pod 的网络命名空间,跑任何网络工具,不需要
kubectl exec(容器没 shell 也能用)。
创建独立 netns
ip netns add ns1
ip netns exec ns1 ip addr # 在 ns1 里跑命令
ip netns delete ns1
主要用来学习 / 实验。
ip -s 看统计
ip -s link show eth0
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
# RX: bytes packets errors dropped missed mcast
# 1234567890 1234567 0 12 0 100
# TX: bytes packets errors dropped carrier collsns
# 987654321 876543 0 0 0 0
errors—— 物理 / driver 错误dropped—— 内核因 buffer 满 / 策略丢的mcast—— 收到的组播
K8s 节点上 dropped 持续涨可能是 conntrack 表满,或 buffer 不够。
训练营实战
1. 装机巡检三连
ip -c -br addr # IP 总览
ip -c -br link # 网卡总览
ip route # 路由总览
每台机器都跑一遍,确认网卡 UP / 主路由对。
2. K8s 节点之间 pod 网络通不通
# m1 上查 m2 的 pod CIDR 怎么走
ssh m1 'ip route get 10.244.1.5'
# 10.244.1.5 via 10.0.24.32 dev eth0 ...
# 经 m5 转发 ← 如果不是预期路径,CNI 有问题
# 看节点之间互通
ssh m1 'ping -c 3 10.0.24.32'
3. 进 pod 的 netns 排错
pod 报"连不上数据库"——但 kubectl exec 进容器没有 curl / ping:
# 找到 pod 在哪个节点
kubectl get pod my-pod -o wide
# Node: m4
ssh m4
# 找容器 PID
crictl inspect $(crictl ps -q --name my-pod) | jq '.info.pid'
# 12345
# 进 pod netns 跑你想跑的工具
nsenter -t 12345 -n curl -v http://db:5432
nsenter -t 12345 -n ss -lntp
nsenter -t 12345 -n ip route
nsenter -t 12345 -n cat /etc/resolv.conf
4. 给节点加个 VIP(kube-vip 之外的简单做法)
ip addr add 10.0.24.99/24 dev eth0
# 现在 m1 同时回应 10.0.24.28 和 10.0.24.99 上的请求
不持久。要永久要写 netplan / NetworkManager 配置。
常见踩坑
坑 1:习惯性敲 ifconfig
$ ifconfig
-bash: ifconfig: command not found
Ubuntu 20+ / RHEL 8+ 默认没有。装:apt install net-tools。或者改用 ip a。
坑 2:ip route add 不持久
ip route add 10.10.0.0/16 via 192.168.1.1 # 重启后没了
要持久写到:
- Ubuntu:netplan
/etc/netplan/*.yaml - RHEL:NetworkManager 或
/etc/sysconfig/network-scripts/route-eth0 - 通用:systemd-networkd
或者写到 K8s 集群的 startup script。
坑 3:ip link set eth0 down 把自己锁外面
ssh m1 'ip link set eth0 down' # 立刻断连
ssh 走的就是 eth0,关了就再连不上。要在 console / IPMI 里救。
避免:远程改网络配置前做好物理 console 备份。
坑 4:多网卡机器 default 路由错的
ip route
# default via 公网网关 ... ← 默认走公网
# default via 内网网关 ... ← 还有一条
多个 default 路由由 metric 决定优先级(数字越小越优先):
ip route show default
# default via 1.2.3.4 dev eth0 metric 100
# default via 10.0.0.1 dev eth1 metric 200 ← 不会走这个
K8s 节点应该让内网路由优先(更小 metric),否则 pod 间通信走公网 → 慢 + 计费 + 安全问题。
坑 5:对 vethXXXX 网卡做事
ip link set vethABCD down # 把 pod 的 host-side veth 关了
# pod 立刻失联(kubectl exec 进不去、健康检查失败)
K8s 创建的 veth 不要手动操作 —— 那是 CNI 的领地。
坑 6:ip route get 返回 RTNETLINK answers: Network is unreachable
ip route get 1.2.3.4
# RTNETLINK answers: Network is unreachable
通常是 default route 没了。看:
ip route show default
# 空
加回:ip route add default via <gw>。
坑 7:CIDR 写错把网卡的 IP 删了
ip addr del 10.0.24.28/16 dev eth0 # 实际 IP 是 /24,但写成 /16
# 删除失败
ip addr del 10.0.24.28/24 dev eth0 # 这样对
ip addr del 必须 IP 和 mask 都对得上才能删。看清楚再删。
坑 8:netns 名字 / PID 用混
nsenter --net=/proc/12345/ns/net <cmd> # 等价 nsenter -t 12345 -n <cmd>
ip netns exec my-ns <cmd> # 用 netns 名字(要先在 /var/run/netns/ 里有)
K8s 的 netns 默认不在 /var/run/netns/ 里(在 /var/run/netns-bind/ 或者直接以 PID 持有),所以 ip netns list 看不到 —— 用 nsenter -t PID -n 直接进。