关于Libvirtd端口16514的两个技术疑问求助
大家好,我有一台运行libvirtd的服务器,刚检查了16514端口的状态,输出如下:
root@prd-140:~# netstat -anpt |grep 16514 tcp6 0 0 :::16514 :::* LISTEN 1/systemd tcp6 0 0 10.1.6.140:16514 10.2.127.52:60556 ESTABLISHED 12289/libvirtd tcp6 0 0 10.1.6.140:16514 10.2.127.52:29463 ESTABLISHED 12289/libvirtd root@prd-140:~# lsof -i :16514 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root 59u IPv6 9761899 0t0 TCP *:16514 (LISTEN) libvirtd 12289 root 5u IPv6 9761899 0t0 TCP *:16514 (LISTEN) libvirtd 12289 root 30u IPv6 20539283 0t0 TCP prd-140:16514->10.2.127.52:60556 (ESTABLISHED) libvirtd 12289 root 35u IPv6 20549679 0t0 TCP prd-140:16514->10.2.127.52:29463 (ESTABLISHED)
现在有两个疑问想请教大家:
- 为什么处于LISTEN状态的16514端口,PID总是1(systemd)?
- 为什么tcp6条目会处理IPv4的连接?
针对疑问1的解答:
这是systemd套接字激活(Socket Activation)机制在工作。现在很多Linux发行版里,libvirtd是通过systemd的socket单元管理的:systemd会提前帮libvirtd监听指定端口(这里就是16514),当有客户端发起连接请求时,systemd才启动libvirtd进程,并把已经监听好的套接字传递给它。
从你的lsof输出也能佐证:libvirtd进程(PID 12289)同样持有这个LISTEN状态的套接字(FD 5u),说明它已经从systemd手里接管了监听工作。这种机制的好处很实在——没有连接请求时libvirtd可以不运行,节省系统资源;而且能在系统启动阶段更早抢占端口,避免被其他程序占用。
针对疑问2的解答:
这是Linux系统中IPv6套接字的默认行为:如果没有开启IPV6_V6ONLY选项,IPv6套接字会同时兼容处理IPv4连接。
默认情况下,net.ipv6.bindv6only这个sysctl参数的值是0,意味着创建的IPv6套接字不仅能处理IPv6流量,还能接受IPv4连接(此时IPv4地址会被映射成::ffff:x.x.x.x格式的IPv6地址)。所以你看到的tcp6条目其实是个“双栈”套接字,自然能处理那些10.1.6.140这类的IPv4连接。
如果想让IPv6套接字只处理纯IPv6流量,你可以把net.ipv6.bindv6only设置为1,不过需要修改系统配置并重启相关服务才会生效。
备注:内容来源于stack exchange,提问作者Rama

