Kubernetes中Debian系Pod执行apt update报NOSPLIT错误排查
问题根因
该报错的本质是apt拉取软件源InRelease签名文件时,收到的响应内容不符合合法GPG Clearsigned格式要求。结合集群环境信息(宿主机apt更新正常、仅Pod内访问异常、v1.24版本Kubernetes+Docker+Calico架构),触发原因按出现概率从高到低排序:
- Calico VXLAN模式MTU配置与物理网卡不匹配:Calico VXLAN封装会占用50字节额外报文头,如果部署时Calico的MTU参数没有对应调小,超过物理网卡MTU的TCP报文会被直接丢弃,导致apt拉取的签名文件内容截断,触发NOSPLIT报错;宿主机直接走物理网卡不存在封装开销,因此访问正常。
- 出方向流量被未认证的透明代理劫持:如果节点所在网络存在强制认证的上网网关/透明代理,Pod流量被重定向到代理后,代理返回的是认证要求的HTML页面而非签名文件,apt解析非预期内容就会抛出该错误;宿主机因为配置了代理认证参数或者绕过规则,所以可以正常访问。
- Docker iptables规则配置异常:如果Docker daemon配置中关闭了iptables自动管理,Pod出方向的SNAT、报文分片规则不会自动生成,大体积HTTP响应会出现截断。
排查步骤
按顺序执行以下操作定位具体原因:
- 验证MTU匹配性:进入故障Pod执行
ping -M do -s 1472 deb.debian.org,该命令指定ICMP报文不分片,载荷大小对应标准1500 MTU的最大上限。如果ping不通,逐步调低-s参数值直到通信正常,计算得到实际可传输的最大报文尺寸,如果和当前Calico配置的veth MTU差值大于等于50,即可确认是MTU问题。 - 验证流量劫持:在故障Pod内执行
curl -v http://deb.debian.org/debian/dists/bullseye/InRelease,正常响应开头必须是-----BEGIN PGP SIGNED MESSAGE-----格式的GPG签名内容,如果返回HTML格式的认证页、拦截提示,即可确认是流量被中间设备劫持。 - 验证Docker配置:查看节点上
/etc/docker/daemon.json配置文件,确认iptables字段是否被设置为false。
修复方案
对应排查到的根因选择对应修复操作:
- 针对MTU不匹配问题:
- 先在宿主机执行
ip link show <物理网卡名,如eth0>确认物理网卡实际MTU值 - 执行
kubectl edit ippool default-ipv4-ippool修改Calico IPPool配置,将spec.mtu字段值设置为「物理网卡MTU - 50」,保存后Calico会自动更新所有veth网卡的MTU配置,无需重建Pod - 临时验证可先在Pod内写入apt配置关闭管线:
echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99fixmtu,再执行apt update验证,该配置仅作临时验证使用,根因修复后可删除
- 先在宿主机执行
- 针对透明代理劫持问题:
- 如果是企业内网强制认证代理,在Pod部署时注入正确的
HTTP_PROXY/HTTPS_PROXY环境变量,同时将集群Service网段、Pod网段、软件源域名加入NO_PROXY列表绕过代理 - 如果是节点残留的错误iptables规则导致流量误转发,清理nat表中非Kubernetes、Docker、Calico生成的自定义规则,重启kubelet、Docker服务重新加载正确规则
- 如果是企业内网强制认证代理,在Pod部署时注入正确的
- 针对Docker iptables配置异常问题:
修改/etc/docker/daemon.json添加"iptables": true配置,执行systemctl daemon-reload && systemctl restart docker重启Docker服务生效,注意重启前先驱逐节点上的运行Pod避免业务中断。
内容的提问来源于stack exchange,提问作者devops-admin
相关产品推荐
相关产品推荐

