influxdb 是kubernetes中使用的一个时序性数据库,试用过程中发现了一个奇怪的问题:
influxdb没有监听ipv4的地址,但可以通过ipv4的地址正常访问,很神奇,于是有了本文:
复现步骤(ubuntu环境)
#添加必要的证书
curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
#添加apt源
source /etc/lsb-release
echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
#安装
sudo apt-get update && sudo apt-get install influxdb
#启动
service influxdb start
#监听地址查看
sudo netstat -ltnp|grep influx
tcp 0 0 127.0.0.1:8088 0.0.0.0:* LISTEN 6667/influxd
tcp6 0 0 :::8086 :::* LISTEN 6667/influxd
可以看到,influxdb的api接口只监听在了tcp6的8086端口上了,对应的v4端口并没有监听,
但使用influx cli连接本机,可以看到,连接没有任何问题:
$ influx
Connected to http://localhost:8086 version 1.7.6
InfluxDB shell version: 1.7.6
Enter an InfluxQL query
>
网上找了一圈,终于晓得原因了。
linux服务端在新建ipv6 socket的时候,有一个选项:
IPV6_V6ONLY (since Linux 2.4.21 and 2.6)
If this flag is set to true (nonzero), then the socket is re‐
stricted to sending and receiving IPv6 packets only. In this
case, an IPv4 and an IPv6 application can bind to a single
port at the same time.
If this flag is set to false (zero), then the socket can be
used to send and receive packets to and from an IPv6 address
or an IPv4-mapped IPv6 address.
The argument is a pointer to a boolean value in an integer.
The default value for this flag is defined by the contents of
the file /proc/sys/net/ipv6/bindv6only. The default value for
that file is 0 (false).
该选项在设置为0(false)的时候,IPV6的套接字可以同时去访问IPV4和IPV6的协议栈,所以server端只需要创建一个IPV6的socket就可以了。IPV4的连接会通过IPV4-mapped转换为IPV6的地址结构,来进行处理,也即所谓的 双栈绑定
实际编码中,不太建议这种双栈绑定,不同系统的缺省值不同,会带来一些兼容性上的问题。因此,建议分别创建v4和v6的socket进行数据的处理。