在虚拟化环境中,VM 与主机间的通信往往受限于 TCP/IP 栈的开销,包括协议处理、上下文切换和内存拷贝,导致延迟升高、吞吐受限。Linux VSOCK(AF_VSOCK 地址族)通过 virtio-vsock 传输机制,直接利用共享内存和 virtqueue 实现零拷贝通信,完全绕过网络栈,提供微秒级延迟和 Gbps 级吞吐,适用于 KVM/QEMU 场景下的 guest-agent、日志传输或实时控制平面。
VSOCK 的核心是标准 socket API,但寻址使用 32 位 CID(Context ID)和端口:主机 CID 固定为 2,VM CID 由 hypervisor 分配(如 QEMU 的 guest-cid=3)。支持 SOCK_STREAM(可靠流)和 SOCK_DGRAM(数据报)。创建 socket:socket(AF_VSOCK, SOCK_STREAM, 0)。地址结构struct sockaddr_vm { sa_family_t svm_family; unsigned short svm_reserved1; unsigned int svm_port; unsigned int svm_cid; ... },端口 < 1024 需 CAP_NET_BIND_SERVICE 权限。
工程化使用从配置开始。宿主机加载modprobe vhost_vsock,生成/dev/vhost-vsock和/dev/vsock。QEMU 启动 VM 添加-device vhost-vsock-pci,guest-cid=3,或 libvirt XML 中<vsock model='virtio'><cid auto='yes'/></vsock>自动分配 CID。客机内核需 CONFIG_VIRTIO_VSOCKETS=m。CID 查询:ioctl(fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid)。
主机监听示例(C):
#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <stdio.h>
#include <string.h>
int main() {
int s = socket(AF_VSOCK, SOCK_STREAM, 0);
struct sockaddr_vm addr = { .svm_family = AF_VSOCK, .svm_port = 9999, .svm_cid = VMADDR_CID_ANY };
bind(s, (struct sockaddr*)&addr, sizeof(addr));
listen(s, 0);
struct sockaddr_vm peer;
socklen_t len = sizeof(peer);
int fd = accept(s, (struct sockaddr*)&peer, &len);
char buf[1024];
recv(fd, buf, sizeof(buf), 0);
printf("Received from CID %u\n", peer.svm_cid);
close(fd); close(s);
return 0;
}
VM 客户端连接主机:addr.svm_cid = VMADDR_CID_HOST (2),connect()发送数据。Python 示例类似,使用socket.AF_VSOCK。
性能测试显示,VSOCK 在 iperf-vsock 基准下客到主方向达 10Gbps,延迟微秒级,远超 TCP 桥接(受 NAT / 桥接开销影响)。“vsock 提供了一种 socket family:AF_VSOCK,提供 connect/bind/send 等标准操作,但依赖 virtio-vsock 设备绕过协议栈。” 相比 virtio-serial(串口模拟,中断多、单队列),VSOCK 支持多队列、零拷贝。
调优参数清单:
- 队列深度:QEMU
-device vhost-vsock-pci,guest-cid=3,queues=8,匹配 vCPU 数,提升并发(默认 1)。 - 缓冲区:sysctl
net.core.rmem_max=16777216 net.core.wmem_max=16777216,增大 socket 缓冲(默认 212992B)。 - 中断合并:ethtool-like,但 VSOCK 用
irqbalance或 CPU 亲和:taskset -c 0-7 qemu-kvm,绑定中断核心。 - 零拷贝启用:内核 vhost_vsock 默认支持,监控
/proc/net/vsock统计丢包。 - 监控点:
ss -l -n -p | grep vsock查看连接;perf stat -e cycles,instructions iperf-vsock测 CPU;阈值:丢包 > 1% 调大缓冲,延迟 > 10us 查队列。 - 回滚策略:测试负载下 fallback TCP,参数
net.ipv4.tcp_rmem="4096 87380 16777216"。
风险:实时迁移断开 STREAM 连接,应用需重连逻辑;CID 冲突用 auto 分配;嵌套 VM 需 multi-transport(Linux 5.5+)。安全:CID 隔离防扫描,但勿暴露特权端口。
落地清单:
- 内核检查:
grep -i vsock /boot/config-$(uname -r) - 基准脚本:用 nc-vsock(github.com/stefanha/nc-vsock)测吞吐。
- 高负载:多线程 send/recv,调
SO_SNDBUF/RECVBUF至 64MB。
VSOCK 工程化显著降低 VM - 主机通信开销,适用于云原生控制平面或 Kata Containers 嵌套场景。通过上述参数,生产环境可稳定 10Gbps + 吞吐、<5us 延迟。
资料来源:
- man vsock(7): man7.org/linux/man-pages/man7/vsock.7.html
- QEMU virtio-vsock: wiki.qemu.org/Features/VirtioVsock
- Benchmarks: stefano-garzarella.github.io/posts/2019-11-08-kvmforum-2019-vsock/
- Kernel docs: git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vm_sockets.h
(正文约 1250 字)