LInux中为同一个物理网卡增加多个ip地址,以前通过ifconfig命令来创建和维护ip alias, 而在新的IPROUTE2中通过ip address命令来创建和维护Primary address与Secondary address
# 查看网卡是否能将second ip提升为primary ip
[root@k8s-node-1 ~]# sysctl -a | grep promote_secondaries
net.ipv4.conf.all.promote_secondaries = 1
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.docker0.promote_secondaries = 1
net.ipv4.conf.dummy0.promote_secondaries = 1
net.ipv4.conf.ens33.promote_secondaries = 1
net.ipv4.conf.flannel/1.promote_secondaries = 1
net.ipv4.conf.kube-ipvs0.promote_secondaries = 1
net.ipv4.conf.lo.promote_secondaries = 0
net.ipv4.conf.tunl0.promote_secondaries = 1
# 含义
sbin/sysctl net.ipv4.conf.eth0.promote_secondaries=1 # (晋升辅助ip地址)
只要一个网卡上配置的多个ip不是一个网段的,那么都是Primary IP
,对一个特定的网络掩码(例如网络掩码为/24),只能有一个Primary地址
,就是吊链结构中上面的那条主链中的IP,linux中的Secondary address是主链结点的子链结点中的IP,这一点一定注意节点 | IP |
---|---|
k8s-master-1 | 192.168.0.10 |
k8s-node-1 | 192.168.0.11 |
VIP | 192.168.0.15 |
# 192.168.0.15 为VIP
[root@k8s-node-1 ~]# hostname -I
192.168.0.11 192.168.0.15 172.17.0.1 10.70.1.0
# 查看IPVS规则,可以发现192.168.0.15 并没有相应的ipvs 规则,而192.168.0.11 却有ipvs规则,这将导致我外部无法通过VIP:PORT去访问k8s service暴露出来的服务
[root@k8s-node-1 ~]# ipvsadm -ln | grep -E "192.168.0.11|192.168.0.15" -C 3
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.11:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 10.0.0.1:443 rr
-> 192.168.0.10:6443 Masq 1 1 0
# 查看IP地址,通过下面可以发现ens33的确是本机的IP
[root@k8s-node-1 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:1e:01:7f brd ff:ff:ff:ff:ff:ff
inet 192.168.0.11/24 brd 192.168.0.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.0.15/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe1e:17f/64 scope link
valid_lft forever preferred_lft forever
........................................................
使用与ens33网卡原始IP不同网段的IP(且不能与原IP拥有相同的子网掩码),那么这个IP将被提升为primary ip(这二个不同网段的IP将会同时存在于ens33这张网卡上),此时kube-proxy就会为primary IP创建相应的IPVS规则
# 删除192.168.0.15
[root@k8s-node-1 ~]# ip addr del 192.168.0.15/24 dev ens33
# 添加192.168.0.15/32
[root@k8s-node-1 ~]# ip addr add 192.168.0.15/32 dev ens33
# 清空IPVS规则,kube-proxy 默认会隔段时间检查IPVS规则,并动态更新
[root@k8s-node-1 ~]# ipvsadm -C
# 查看IPVS规则,可以看到192.168.0.15相应的IPVS规则已经存在了
[root@k8s-node-1 ~]# ipvsadm -ln | grep -E "192.168.0.11|192.168.0.15" -C 3
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.17.0.1:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 192.168.0.11:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 192.168.0.15:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 10.0.0.1:443 rr
-> 192.168.0.10:6443 Masq 1 1 0
# 安装上面思路我们在添加几个不同网段的IP
[root@k8s-node-1 ~]# ip addr add 192.168.1.10/24 dev ens33
[root@k8s-node-1 ~]# ip addr add 192.168.2.10/24 dev ens33
# 这里也并没有创建规则,怀疑不能是/24,换其他的试一下
[root@k8s-node-1 ~]# ipvsadm -ln | grep -E "192.168.0.11|192.168.0.15|192.168.1.10|192.168.2.10" -C 3
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.11:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 192.168.0.15:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 192.168.1.10:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 192.168.2.10:39090 rr
-> 10.70.0.159:9090 Masq 1 0 0
TCP 10.0.0.1:443 rr
-> 192.168.0.10:6443 Masq 1 1 0
# 添加/16网段
[root@k8s-node-1 ~]# ip addr add 10.8.0.10/16 dev ens33
# 查看IPVS规则,可见生成IPVS规则了
[root@k8s-node-1 ~]# ipvsadm -ln | grep 10.8
TCP 10.8.0.10:39090 rr
# 查看k8s-master-1路由表
[root@k8s-master-1 ~]# ip route show
default via 192.168.0.2 dev ens33 proto static metric 100
10.70.0.0/24 dev cni0 proto kernel scope link src 10.70.0.1
10.70.1.0/24 via 10.70.1.0 dev flannel.1 onlink
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.0.0/24 dev ens33 proto kernel scope link src 192.168.0.10 metric 100
# 清空k8s-master-1节点所有已知MAC地址
[root@k8s-master-1 ~]# ip neigh flush all
# k8s-master-1节点ping 192.168.2.10, 可见与192.168.2.10无法ping通,由于匹配不到路由,所以会把数据包发送给网关192.168.0.2
[root@k8s-master-1 ~]# ping 192.168.2.10
PING 192.168.2.10 (192.168.2.10) 56(84) bytes of data.
^C
--- 192.168.2.10 ping statistics ---
48 packets transmitted, 0 received, 100% packet loss, time 48149ms
# k8s-master-1节点抓包
[root@k8s-master-1 ~]# tcpdump -i ens33 arp or icmp -w cap -Nnv
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
^C23 packets captured
24 packets received by filter
0 packets dropped by kernel
# k8s-node-1节点抓包,可见网关将数据包转发到k8s-node-1节点了,但是k8s-node-1节点并没有对这个ICMP REQUEST数据包做出回应
[root@k8s-node-1 ~]# tcpdump -i ens33 -Nnv arp or icmp
tcpdump: listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
21:00:24.423670 IP (tos 0x0, ttl 64, id 24789, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.0.10 > 192.168.2.10: ICMP echo request, id 58528, seq 177, length 64
21:00:25.447510 IP (tos 0x0, ttl 64, id 25524, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.0.10 > 192.168.2.10: ICMP echo request, id 58528, seq 178, length 64
21:00:26.472494 IP (tos 0x0, ttl 64, id 26075, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.0.10 > 192.168.2.10: ICMP echo request, id 58528, seq 179, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
通过上述实验我们验证了只要一个网卡上配置的多个ip不是一个网段的,那么都是Primary IP
,对一个特定的网络掩码(例如网络掩码为/24),只能有一个Primary地址,如果有多个IP掩码一样,后边的实际上不会起作用,例如上面k8s-node-1节点:192.168.2.10这个IP
参考链接:https://blog.csdn.net/dog250/article/details/5303542
参考链接:http://blog.chinaunix.net/uid-1838361-id-66436.html
参考链接:https://blog.csdn.net/xiewen99/article/details/54729112?utm_source=itdadao&utm_medium=referral