在我之前的面试中,有好几次都问到了这个问题,但是回答的不是很好。但是,后面还挺不错,面试官还帮我解释了下,我们就直接面对吧。
在 Kubernetes 集群中,某些容器镜像(如基于 scratch
或 distroless
的镜像)为了追求极简化和安全性,移除了交互式 Shell(如 /bin/bash
或 /bin/sh
)以及常见网络工具(如 curl
、ping
)。当这类 Pod 出现外网访问异常时,传统调试方法失效,需要更高级的技巧。
容器内预装了 curl
、wget
、nc
(netcat)等工具,但缺少交互式 Shell。
通过 kubectl exec
直接执行命令:
# 测试 HTTP 连通性(curl)
kubectl exec <pod-name> -- curl -Iv https://www.google.com
# 测试 TCP 端口连通性(netcat)
kubectl exec <pod-name> -- nc -zv www.google.com 443
# 下载内容验证(wget)
kubectl exec <pod-name> -- wget -qO- http://example.com
exec: command not found
。ncat
、telnet
)。容器无任何网络工具,且 Kubernetes 版本 ≥1.23
(支持临时容器功能)。
Step 1:注入临时容器
kubectl debug -it <pod-name> --image=nicolaka/netshoot --target=<container-name>
--image
:选择一个调试镜像(推荐 nicolaka/netshoot
,内置完整网络工具链)。--target
:指定共享网络命名空间的目标容器。Step 2:在临时容器中测试外网
# 测试 HTTP 访问
curl -I https://www.google.com
# 测试 DNS 解析
nslookup google.com
# 测试 ICMP(ping)
ping 8.8.8.8
临时容器会共享目标容器的 网络命名空间,因此两者的网络栈(IP、端口、路由等)完全一致。退出临时容器后,它会被自动销毁,不会影响原 Pod。
1.23
,需启用 EphemeralContainers
特性门控。临时容器功能不可用,但允许修改 Pod 配置(如测试环境)。
Step 1:编辑 Pod 定义,添加 Sidecar
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: main-app
image: my-minimal-image:latest
# 主容器无 Shell 和网络工具...
- name: network-debugger
image: nicolaka/netshoot
command: ["sleep", "infinity"] # 保持 Sidecar 运行
securityContext:
runAsUser: 0 # 以 root 用户运行(可选)
Step 2:进入 Sidecar 测试网络
kubectl exec -it my-pod -c network-debugger -- curl -v https://www.google.com
同一 Pod 内的所有容器共享同一个网络命名空间,因此 Sidecar 可以直接访问主容器的网络环境。
怀疑 DNS 配置错误导致外网访问失败。
方法 1:使用 nslookup
(需容器支持)
kubectl exec <pod-name> -- nslookup google.com
方法 2:查看 DNS 配置
kubectl exec <pod-name> -- cat /etc/resolv.conf
预期输出示例:
nameserver 10.96.0.10 # Kubernetes DNS Service IP
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
nslookup
失败,检查 CoreDNS 或 kube-dns 是否正常运行:kubectl get pods -n kube-system -l k8s-app=kube-dnsdnsPolicy
)是否为 ClusterFirst
。怀疑网络策略(NetworkPolicy)或云平台安全组阻止外网访问。
Step 1:检查 NetworkPolicy
kubectl describe networkpolicy -n <namespace>
重点关注是否有策略限制出站流量(egress
)。
Step 2:验证云平台安全组/防火墙规则
Step 3:检查节点 IPtables 规则
登录到 Pod 所在节点,查看 NAT 表和过滤规则:
iptables -t nat -L -n -v
iptables -L -n -v
无法修改目标 Pod,且需要模拟相同网络环境。
Step 1:启动跳板机 Pod
kubectl run jumpbox --image=nicolaka/netshoot --rm -it --restart=Never -- /bin/sh
Step 2:在跳板机中通过代理测试目标 Pod 网络
假设目标 Pod 的 IP 为 10.244.1.5
:
# 使用 curl 的 --proxy 参数
curl -x http://10.244.1.5:80 http://example.com
# 使用 nc 测试 TCP 连通性
nc -zv 10.244.1.5 80
镜像名称 | 特点 | 适用场景 |
---|---|---|
nicolaka/netshoot | 包含完整网络工具(curl, tcpdump, dig 等) | 通用网络调试 |
busybox:glibc | 轻量级,支持 nslookup、ping | 基础连通性测试 |
alpine:latest | 包含 Shell 和包管理器(apk) | 需临时安装工具的场合 |
编写脚本批量测试多个 Pod 的外网连通性:
#!/bin/bash
PODS=$(kubectl get pods -o name | grep target-pod-prefix)
for POD in $PODS; do
echo "Testing $POD..."
kubectl exec $POD -- curl -Is https://www.google.com | head -n 1
done
如果 Pod 使用自定义 ServiceAccount,检查其是否被授予访问外网的权限:
# 例:限制 Pod 仅可访问集群内资源
automountServiceAccountToken: false
方法 | 复杂度 | 侵入性 | 需重启 Pod | 适用阶段 |
---|---|---|---|---|
kubectl exec | 低 | 无 | 否 | 开发/测试 |
临时调试容器 | 中 | 低 | 否 | 生产/测试 |
Sidecar 注入 | 高 | 高 | 是 | 测试 |
DNS 检查 | 低 | 无 | 否 | 所有阶段 |
网络策略/防火墙检查 | 中 | 无 | 否 | 生产问题排查 |
跳板机代理 | 中 | 无 | 否 | 模拟生产环境 |
nslookup
,发现 DNS 服务器无响应。以上就是我们今天的内容,希望可以帮助到大家,在面试中游刃有余,主动出击。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。