记一次kubernetes获取internal Ip错误流程
本文分享自华为云社区《记一次kubernetes获取internal Ip错误流程》,作者:张俭。
偶尔也回首一下处理的棘手问题吧。问题的现象是,通过kubernetes get node输出的ip不是期望的ip地址。大概如下所示
ip addr eth0 ip1 eth0:xxx ip2
最终输出的不是预期的ip1地址,而是ip2地址。
按藤摸瓜,kubernetes把节点信息保存在/registry/minions/$node-name
中的InternalIp 字段。
InternalIp是如何确定的呢,这段代码位于pkg/kubelet/nodestatus/setters.go
中
// 1) Use nodeIP if set (and not "0.0.0.0"/"::") // 2) If the user has specified an IP to HostnameOverride, use it // 3) Lookup the IP from node name by DNS // 4) Try to get the IP from the network interface used as default gateway // // For steps 3 and 4, IPv4 addresses are preferred to IPv6 addresses // unless nodeIP is "::", in which case it is reversed.
我们的场景下没有手动设置nodeIp,如需设置通过kubelet命令行即可设置 –node-ip=localhost,最终通过如下的go函数获取ip地址
addrs, _ = net.LookupIP(node.Name)
对这行go函数进行strace追溯,最终调用了c函数,getaddrinfo函数。getaddrinfo底层是发起了netlink请求,开启netlink的抓包
modprobe nlmon ip link add nlmon0 type nlmon ip link set dev nlmon0 up tcpdump -i nlmon0 -w netlinik.pcap # 使用nlmon 驱动模块,这个nlmon 驱动模块会注册一个 netlink tap 口,用户态向内核发送 netlink 消息、内核向用户态发送 netlink 消息,报文都会经过这个 tap 口。
通过抓包我看到通过netlink报文请求返回的ip地址顺序都是合乎预期的,只能是getaddrinfo函数修改了返回的顺序
Google了一下发现是getaddrinfo支持了rfc3484导致了ip的重新排序,代码地址glibc/sysdeps/posix/getaddrinfo.c
RFC3484 总共有十个规则,比较关键的有
Rule9
Rule 9: Use longest matching prefix. When DA and DB belong to the same address family (both are IPv6 or both are IPv4): If CommonPrefixLen(DA, Source(DA)) > CommonPrefixLen(DB, Source(DB)), then prefer DA. Similarly, if CommonPrefixLen(DA, Source(DA)) < CommonPrefixLen(DB, Source(DB)), then prefer DB.
举个例子,假如机器的ip地址是 172.18.45.2/24
,它会更青睐于172.18.45.6
而不是172.31.80.8
。这个RFC存在较大的争议,它与dns轮询策略不兼容,如:dns服务器轮询返回多个ip地址,客户端总是选择第一个ip连接。与这个策略存在很大的冲突。并且社区内也有投票试图停止对RFC3484 rule9的适配, 但是最终被拒绝了。
根据分析,认为是ip2的地址小于ip1的地址,最终glibc排序的时候把ip2放在了前面。最终我们给kubelet配置了eth0地址的–node-ip,解决了这个问题。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
GaussDB(DWS)中的分布式死锁问题实践
本文分享自华为云社区《GaussDB(DWS)中的分布式死锁问题实践》,作者: 他强由他强 。 1、什么是分布式死锁 分布式死锁是相对于单机死锁而言,一个事务块中的语句,可能会分散在集群里多个节点(CN/DN)执行,在不同节点上可能都会持有锁,当并发事务进行时可能会导致分布式(全局)死锁,如下图所示,会话SESSION1持有了DN1上的lock1资源后再去请求DN2上的lock2,会话SESSION2持有了DN2上的lock2资源后再去请求DN1上的lock1,两个会话形成互相等待。出现分布式死锁现象后,如果没有外部干预,通常是一方等待锁超时报错后,事务回滚清理持有锁资源,另一方可继续执行。 2、常见的分布式死锁场景 一般来说,分布式死锁的产生与在不同节点上的并发时序或持锁顺序有关,所以现网实际发生概率较低,分布式死锁通常都是RegularLock类型,下面是几种常见的分布式死锁场景,举例说明两个并发事务产生的分布式死锁: 1)锁升级 # 集群两个CN,两个DN create table mytable(a int, b int); insert into mytable valu...
- 下一篇
Mysql tls 会话:再一次抓包之后,我认识到…
本文分享自华为云社区《有些事你只有抓包才知道之mysql tls会话》,作者:张俭。 你的mysql客户端和服务端之间开启tls了吗?你的回答可能是No,我根本没开启mysql的tls。 可是当你抓取了3306 mysql的端口之后,你会发现,抓出来的包里居然有Client Hello、Server Hello这样的典型TLS报文。 Mysql返回的Server Greeting中有一个flag的集合字段,名为Capabilities Flag,顾名思义,这就是用来做兼容性的位flag。其中的2048位、也就是第12位,代表着CLIENT_SSL,如果设置为1,则会在后面的会话中切换到TLS。可以看到里面还有一些其他的flag,事务、长密码等等相关的兼容性开关。 那么该如何关闭这个TLS呢,只需要在my.cnf中添加 echo "ssl=0" >> /etc/my.cnf 重启mysql。再度进行抓包,就发现没有tls的报文了,都是在使用明文进行通信了。 点击关注,第一时间了解华为云新鲜技术~
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7