使用附加网络的Pod在服务器重启后启动异常,报错信息如下:,我来为大家科普一下关于k8s节点重启后变成notready?下面希望有你要的答案,我们一起来看看吧!

k8s节点重启后变成notready(K8S问题排查-附加网络Pod无法启动)

k8s节点重启后变成notready

问题背景

使用附加网络的Pod在服务器重启后启动异常,报错信息如下:

Events: Type Reason Age From Message Normal Scheduled 53m default-scheduler Successfully assigned xxx/xxx1-64784c458b-q67tx to node001 Warning FailedCreatePodSandBox 53m kubelet, node001 Failed to create pod sandbox: rpc er or: code = Unknown desc = failed to set up sandbox container "xxx" network for pod "xxxl-64784c458b-q67tx": NetworkPlugin cni failed to set up pod "xxx1-64784c458b-q67tx_xxx" network: Multus: Err adding pod to network "net-netl-nodeOOl": Multus: error in invoke Delegate add - "macvlan": failed to create macvlan: device or resource busy Warning FailedCreatePodSandBox 53m kubelet, node001 Failed to create pod sandbox: rpc er or: code = Unknown desc = failed to set up sandbox container "xxx" network for pod "xxxl-64784c458b-q67tx": NetworkPlugin cni failed to set up pod "xxx1-64784c458b-q67tx_xxx" network: Multus: Err adding pod to network "net-netl-nodeOOl": Multus: error in invoke Delegate add - "macvlan": failed to create macvlan: device or resource busy ...

分析过程

从日志初步看,创建Pod的sandbox异常,具体是Multus无法将Pod添加到net-netl-nodeOOl网络命名空间内,再具体点是Multus无法创建macvlan网络,原因是device or resource busy;

最后的这个错误信息还是比较常见的,从字面理解,就是设备或资源忙,常见于共享存储的卸载场景。那这里也应该类似,有什么设备或资源处于被占用状态,所以执行macvlan的创建失败,既然是附加网络的问题,那优先查看了下附加网络相关的CRD资源,没什么异常;

网上根据日志搜索一番,也没有什么比较相关的问题,那就看代码吧,首先找到Multus的源码,根据上述日志找相关处理逻辑,没有找到。再一想,Multus实现macvlan网络使用的是macvlan插件,再下载插件代码,找到了相关处理逻辑:

plugins/main/macvlan/macvlan.go:169 if err := netlink.LinkAdd(mv); err != nil { return nil, fmt.Errorf("failed to create macvlan: %v", err) } // LinkAdd adds a new link device. The type and features of the device // are taken from the parameters in the link object. // Equivalent to: `ip link add $link` func LinkAdd(link Link) error { return pkgHandle.LinkAdd(link) } // LinkAdd adds a new link device. The type and features of the device // are taken from the parameters in the link object. // Equivalent to: `ip link add $link` func (h *Handle) LinkAdd(link Link) error { return h.linkModify(link, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) } ...

根据上述代码和注释简单的看,是在执行ip link add $link命令时报错,实际验证看看:

[root@node001 ~] ip link add link bond1 name macvlan1 type macvlan mode bridge RTNETLINK answers: Device or resource busy

确实如此,在bond1接口上无法配置macvlan,那换一个接口试试:

[root@node001 ~] ip link add link bond0 name macvlan1 type macvlan mode bridge [root@node001 ~] ip link show ... 110: macvlan1@bond0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether ea:31:c9:7f:d9:a4 brd ff:ff:ff:ff:ff:ff ...

配置成功,说明bond1接口有什么问题,看看这俩接口有没有差异:

[root@node001 ~] ip addr show ... 2: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 0c:da:41:1d:6f:ca brd ff:ff:ff:ff:ff:ff inet x.x.x.x/16 brd x.x.255.255 scope global bond0 valid_lft forever preferred_lft forever inet6 fe80::eda:41ff:fe1d:6fca/64 scope link valid_lft forever preferred_lft forever ... 17: bond1: <BROADCAST,MULTICAST,MASTER,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 0c:da:41:1d:a8:62 brd ff:ff:ff:ff:ff:ff ...

对比两个接口可以发现两个差异点:

  1. bond0配置了IP地址,而bond1没有配置;

  2. bond0是MASTER角色,bond1既是MASTER,又是SLAVE角色;

考虑到bond0接口是用来建集群的,bond1接口是给Multus创建macvlan网络用的,所以第一个差异点属于正常现象。第二个是什么情况呢?一般来说,配置bond的目的是把几个物理接口作为SLAVE角色聚合成bond接口,这样既能增加服务器的可靠性,又增加了可用网络宽带,为用户提供不间断的网络服务。配置后,实际的物理接口应该是SLAVE角色,而聚合后的bond接口应该是MASTER角色,所以正常来说,不会同时出现两个角色才对;

查看两个bond的相关配置,没有发现什么异常,反过来讲,如果配置的有问题,那初次部署就应该报错了,而不是重启节点才发现。所以,问题的关键是重启导致的。也就是说,可能是在重启后的启动脚本里加了什么配置影响的;

搜索相关资料[1],发现在配置过程中可能有这么一个操作:

4、在/etc/rc.d/rc.local文件中加入如下语句,使系统启动自动运行 ifenslave bond0 eth0 eth1

查看问题环境上怎么配置的:

[root@node001 ~] cat /etc/rc.local ... touch /var/lock/subsys/local ifenslave bond0 bond1 enp661s0f0 enp661s0f1 ens1f0 ens1f1

发现有类似的配置,但不同的是,问题环境上配置了两个bond,并且配置在了一个命令里。感觉不是太对,个人理解这么配置应该会把bond1也认为是bond0的SLAVE,修改一下试试:

[root@node001 ~] cat /etc/rc.local ... touch /var/lock/subsys/local ifenslave bond0 enp661s0f0 enp661s0f1 ifenslave bond1 ens1f0 ens1f1 [root@node001 ~] systemctl restart network

再观察两个bond接口的角色,发现恢复正常,再看看异常Pod,也都起来了。

[root@node001 ~] kubectl get pod -A |grep -v Running NAMESPACE NAME READY STATUS RESTARTS AGE

解决方案

将rc.local里的两个bond的命令拆开分别配置即可。

参考资料
  1. http://www.cnblogs.com/geaozhang/p/6763876.html