前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯云容器网络 vpc 对比 vxlan 性能测试

腾讯云容器网络 vpc 对比 vxlan 性能测试

原创
作者头像
真的志国
发布2017-12-05 14:52:23
5.8K0
发布2017-12-05 14:52:23
举报
文章被收录于专栏:腾讯云容器服务团队的专栏

前言

在腾讯云基于VPC(虚拟私有网络)的CVM上使用k8s集群,有两种方式:

  • 使用腾讯云官方容器服务CCS
  • 自己搭建k8s集群

使用腾讯云官方容器服务CCS时, 会使用专有的VPC容器网络, 节点上会给容器分配一个跟VPC CIDR不重叠的容器网段(用户可配置),由CCS负责向VPC网络注册容器网段的路由,容器之间,容器跟节点之间,在用户看来都是直接路由的。

自己搭建k8s集群的话, 常用的容器网络方案是vxlan。

为了弄清楚这两种网络方案下, 容器网络的性能情况,笔者设计并执行了一个简单的对比测试, 对比了吞吐量和时延。

本文不介绍vxlan和vpc网络原理,只呈现一个可复现的详细测试流程,并附上典型测试结果。 只关心测试结果的话,直接看最后一节。

测试流程简介

通过腾讯云容器服务(CCS)创建一个两节点的集群。

通过CCS(或kubectl)创建两个POD, 分布在两个节点上。这两个POD使用的是VPC容器网络。后面简称这两个POD为VPC POD。

通过flannel给两个节点分配另一个虚拟网段,并创建vxlan设备。通过本地docker run命令在两个节点个运行一个docker container, 这两个docker container使用的是flannel管理的vxlan虚拟网络,后面简称这两个容器为vxlan容器

测试容器到容器(c2c)的网络性能对比

在两个VPC POD间运行qperf测试(走的是VPC容器网络), 在两个vxlan 容器之间运行qperf测试(走的是vxlan网络), 然后进行对比。

测试容器到其他节点(c2n)的网络性能对比

从节点二的VPC POD和vxlan容器分别访问节点一, 通过qperf测试性能对比。

关于测试流程的问题

如何屏蔽母机网络负载的影响?

测试使用的节点是CVM, 不可避免收到母机上其他CVM的影响。 为了尽量排除这一影响, 让两个网络下的qperf测试,在同样两台CVM节点上,先后进行(间隔在一分钟之内)。

为了排除两次测试收到母机网络负载的波动影响,每间隔半小时,重复执行一遍对比测试,测试多次。最后取平均值来对比。

为什么不分别创建一个CCS 集群和一个使用flannel网络插件的k8s集群来对比?

参考上一问题的答案。

第一步 申请一个包含两个节点的容器集群

首先创建一个VPC(虚拟私有网络)

https://console.cloud.tencent.com/vpc

CIDR选择 172.31.0.0/16

创建一个k8s集群

https://console.cloud.tencent.com/ccs/cluster

容器网络CIDR选择 10.0.0.0/14

节点配置选择1核CPU, 1G内存

操作系统选择Ubuntu 16.04 64位

等几分钟,两个节点的状态为“健康”以后,说明节点和集群都已经初始化完成了。

两个节点分配到的IP分别为(后面分别记为节点一和节点二):

  • 节点一 172.31.0.5
  • 节点二 172.31.0.16

检查集群的状态

查看节点的内网IP和状态

代码语言:javascript
复制
root@VM-0-5-ubuntu:~# kubectl get nodes
NAME          STATUS    AGE       VERSION
172.31.0.16   Ready     14d       v1.7.8-qcloud
172.31.0.5    Ready     12d       v1.7.8-qcloud

查看CCS(腾讯云容器服务)给每个节点分配的容器网段

代码语言:javascript
复制
# kubectl get node/172.31.0.5  -o jsonpath={.spec.podCIDR}
10.0.1.0/24

kubectl get node/172.31.0.16  -o jsonpath={.spec.podCIDR}
10.0.0.0/24

第二步 安装和配置flannel

在节点上下载flannel

代码语言:javascript
复制
wget https://github.com/coreos/flannel/releases/download/v0.9.1/flannel-v0.9.1-linux-amd64.tar.gz
tar -xzf flannel-v0.9.1-linux-amd64.tar.gz

搭建etcd集群

为了简单,只在节点172.31.0.5上安装和运行etcd:

代码语言:javascript
复制
apt install etcd
systemctl start etcd

这样两个节点上都可以通过 http://172.31.0.5:4001 来访问这个只有一个实例的etcd集群

往etcd配置flannel网络

代码语言:javascript
复制
etcdctl --endpoint http://172.31.0.5:4001 set /flannel/net/config '{"NetWork":"192.168.0.0/16","SubnetLen": 24, "Backend": {"Type": "vxlan"}}'

在两个节点上启动flanneld

./flanneld -etcd-endpoints=http://172.31.0.5:4001 -etcd-prefix=/flannel/net -iface=eth0 &

查看etcd数据可以看到两个节点上的flanneld各自分配到的网段:

代码语言:javascript
复制
# etcdctl --endpoint http://172.31.0.5:4001 ls /flannel/net/subnets          
/flannel/net/subnets/192.168.24.0-24
/flannel/net/subnets/192.168.81.0-24

# etcdctl --endpoint http://172.31.0.5:4001 get /flannel/net/subnets/192.168.24.0-24
{"PublicIP":"172.31.0.5","BackendType":"vxlan","BackendData":{"VtepMAC":"6a:7d:68:63:b4:d1"}}

# etcdctl --endpoint http://172.31.0.5:4001 get /flannel/net/subnets/192.168.81.0-24
{"PublicIP":"172.31.0.16","BackendType":"vxlan","BackendData":{"VtepMAC":"7e:f8:6a:92:eb:a8"}}

flanneld还会在本地生成一个文件/run/flannel/subnet.env。例如在节点172.31.0.5上:

代码语言:javascript
复制
# cat /run/flannel/subnet.env
FLANNEL_NETWORK=192.168.0.0/16
FLANNEL_SUBNET=192.168.24.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

修改dockerd启动参数

停止dockerd

代码语言:javascript
复制
systemctl stop dockerd

修改/usr/lib/systemd/system/dockerd.service, 如下所示,增加"EnvironmentFile=-/run/flannel/subnet.env", 并修改ExecStart定义

代码语言:javascript
复制
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/dockerd ${LOG_LEVEL} --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} ${STORAGE_DRIVER} ${REGISTRY_MIRROR}

重新启动dockerd

代码语言:javascript
复制
systemctl start dockerd

第三步 运行两个使用VPC容器网络的POD

通过kubectl create -f命令创建一个deployment。 所用yaml文件内容如下:

代码语言:javascript
复制
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    qcloud-app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      qcloud-app: nginx
  template:
    metadata:
      labels:
        qcloud-app: nginx
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "qcloud-app"
                    operator: In
                    values: 
                    - nginx
              topologyKey: "kubernetes.io/hostname"
      containers:
      - image: nginx:alpine
        imagePullPolicy: Always
        name: nginx
      imagePullSecrets:
      - name: qcloudregistrykey
      restartPolicy: Always

这个yaml文件中通过podAntiAffinity来确保两个POD被调度到两个不同的节点。

(这一步也可以通过控制台来完成: https://console.cloud.tencent.com/ccs/service)

然后检查pod状态

代码语言:javascript
复制
# kubectl get pod -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP          NODE
nginx-2438677318-d9jv7   1/1       Running   0          3m        10.0.1.10   172.31.0.5
nginx-2438677318-jc4b1   1/1       Running   0          3m        10.0.0.26   172.31.0.16

可以看到,两个POD分布在两个节点, IP分别为10.0.1.10 和 10.0.1.26, 属于之前配置的VPC容器网络10.0.0.0/14。

第四步 运行两个使用flannel网络的容器(后面简称flannel容器)

代码语言:javascript
复制
docker run -d nginx:alpine

第五步 获取四个POD/容器的pid和IP

获取POD和vxlan容器的IP。 以节点一上的VPC POD为例:

代码语言:javascript
复制
# kubectl get pod/nginx-2438677318-d9jv7 -o jsonpath={.status.containerStatuses[0].containerID}
docker://a1173da42e8b395a1b72e9ffe9dad43a135826e32dedc9202acc717d63b21967

# docker inspect --format '{{.State.Pid}}' a1173da42e8b395a1
17694

最终两个VPC POD和vxlan容器的IP, pid如下表所示:

节点

POD

容器

容器IP

pid

172.31.0.5

nginx-2438677318-d9jv7

a1173da42e8b

10.0.1.11

17694

172.31.0.5

---

8b610711dc45

192.168.24.2

28611

172.31.0.16

nginx-2438677318-jc4b1

461b98c72697

10.0.1.30

6512

172.31.0.16

---

5a56b09429b

192.168.81.2

18172

第六步 运行qperf测试

安装qperf

ubuntu下安装qperf:

代码语言:javascript
复制
wget https://www.openfabrics.org/downloads/qperf/qperf-0.4.9.tar.gz
tar -xzvf qperf-0.4.9.tar.gz
cd qperf-0.4.9
/config
make

centos下直接yum install qperf 即可

在节点一上启动三个qperf server

在host, VPC POD, vxlan容器三个不同的网络namespace中启动qperf server。

1) host网络

代码语言:javascript
复制
qperf &

2) VPC POD

代码语言:javascript
复制
# 其中17694是节点一上VPC POD的pid
nsenter -t 17694 -n qperf &

3) vxlan容器

代码语言:javascript
复制
# 其中28611是节点一上vxlan容器的pid
nsenter -t 28611 -n qperf &

测试两个VPC POD之间的网络性能

在172.31.0.16上,运行

代码语言:javascript
复制
# 其中10.0.1.11是远端POD的IP
nsenter -t 6512 -n qperf 10.0.1.11 -oo msg_size:64:64K:*2 -vu -vvc tcp_bw tcp_lat > vpc-c2c.raw

测试两个vxlan容器之间的网络性能

在172.31.0.16上,运行

代码语言:javascript
复制
# 其中192.168.24.2是远端vxlan容器的IP
nsenter -t 18172 -n qperf 192.168.24.2 -oo msg_size:64:64K:*2 -vu -vvc tcp_bw tcp_lat > vxlan-c2c.raw

测试VPC POD访问另一个节点

在172.31.0.16上,运行

代码语言:javascript
复制
nsenter -t 6512 -n qperf 172.31.0.5 -oo msg_size:64:64K:*2 -vu -vvc tcp_bw tcp_lat > vpc-c2n.raw

测试vxlan容器访问另一个节点

在172.31.0.16上,运行

代码语言:javascript
复制
nsenter -t 18172 -n qperf 172.31.0.5 -oo msg_size:64:64K:*2 -vu -vvc tcp_bw tcp_lat > vxlan-c2n.raw

测试节点二访问节点一

代码语言:javascript
复制
qperf 172.31.0.5 -oo msg_size:64:64K:*2 -vu -vvc tcp_bw tcp_lat > n2n.raw

处理原始数据生成对比图表

下载qperf-plot工具: https://github.com/honkiko/qperf-plot

把原始qperf报告转换为plot数据文件

代码语言:javascript
复制
cat vxlan-c2c.raw | ./qperf-parse.py > vxlan-c2c
cat vpc-c2c.raw | ./qperf-parse.py > vpc-c2c
cat vxlan-c2n.raw | ./qperf-parse.py > vxlan-c2n
cat vpc-c2n.raw | ./qperf-parse.py > vpc-c2n
cat n2n.raw | ./qperf-parse.py > n2n

生成对比图表

代码语言:javascript
复制
gnuplot -c qperf-plot.plt vpc-c2c vxlan-c2c

会在当前目录生成bw-[vpc-c2c]-vs-[vxlan-c2c].png和lat-[vpc-c2c]-vs-[vxlan-c2c].png

代码语言:javascript
复制
gnuplot -c qperf-plot.plt vpc-c2n vxlan-c2n

会在当前目录生成bw-[vpc-c2n]-vs-[vxlan-c2n].png和lat-[vpc-c2n]-vs-[vxlan-c2n].png

测试环境和结果

节点配置: 腾讯云北京一区 标准型S1 1核1G

节点操作系统: Ubuntu 16.04.1 LTS

节点内核版本: 4.10.0-32-generic

qperf版本: qperf 0.4.9

flannel版本: v0.9.1

容器到容器(c2c)

以上5个qperf测试(vpc-c2c, vxlan-c2c, vpc-c2n, vxlan-c2n, n2n),重复5轮, 每轮之间间隔两分钟。5轮测试结果取平均值。结果如下。

容器到容器的对比

加入节点到节点(n2n)的曲线(图中紫色曲线)作为参照

容器到其他节点的对比

加入节点到节点(n2n)的曲线(图中紫色曲线)作为参照

CPU占用率的对比

吞吐率方面,VPC容器网络要比vxlan高40%, 是不是消耗了特别多的CPU资源换来的呢。为此笔者专门做了一个对比测试。

两种网络模式下,使用固定msg_size=1440, 执行qperf tcp_bw测试, 时长60秒, 同时通过mpstat每秒采集一次CPU利用率指标。 重复执行10轮测试,取平均值。结果如下:

同样的msg_size, 吞吐率大40%, 也意味着同样时间的发包数量多40%, 从而send系统调用次数也多40%。 因此mpstat统计出来的VPC容器网络下sys要高。 vxlan的封包解包是在软中断中执行的,所以即使多发送了40%的报文, VPC容器网络模式下, mpstat统计出来的softirq CPU占用反而还比vxlan要低。

进行吞吐率测试时, usr和sys这两个CPU消耗,肯定是随着每秒发包数量(pps, PacketPerSecond)增加而增加的。但是softirq的消耗对比, 则体现出了vxlan模式下额外的封包解包带来的额外CPU开销。

结论

容器到容器,VPC容器网络是直接路由,无论是吞吐率还是时延,都很接近节点到节点通信的性能;

而vxlan需要多一层隧道封装,因此带来了很大的开销。

吞吐率方面,VPC容器网络要比vxlan高40%,时延要小5%~10%。

容器到其他节点, VPC容器网络仍然是直接路由,而vxlan容器则是通过iptables规则实现的NAT来完成通信,因此性能损耗不算大。但是不得不面对NAT带来的各种复杂性。

因此,想要在腾讯云上使用k8s, 建议还是选择官方CCS。官方CCS由专业团队来提供保障和服务,在网络性能上也有巨大的优势。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 测试流程简介
    • 测试容器到容器(c2c)的网络性能对比
      • 测试容器到其他节点(c2n)的网络性能对比
      • 关于测试流程的问题
        • 如何屏蔽母机网络负载的影响?
          • 为什么不分别创建一个CCS 集群和一个使用flannel网络插件的k8s集群来对比?
          • 第一步 申请一个包含两个节点的容器集群
            • 首先创建一个VPC(虚拟私有网络)
              • 创建一个k8s集群
                • 检查集群的状态
                  • 在节点上下载flannel
                  • 搭建etcd集群
                  • 往etcd配置flannel网络
                  • 在两个节点上启动flanneld
                  • 修改dockerd启动参数
                  • 安装qperf
                  • 在节点一上启动三个qperf server
                  • 测试两个VPC POD之间的网络性能
                  • 测试两个vxlan容器之间的网络性能
                  • 测试VPC POD访问另一个节点
                  • 测试vxlan容器访问另一个节点
                  • 测试节点二访问节点一
                  • 处理原始数据生成对比图表
                  • 容器到容器的对比
                  • 容器到其他节点的对比
              • 第二步 安装和配置flannel
              • 第三步 运行两个使用VPC容器网络的POD
              • 第四步 运行两个使用flannel网络的容器(后面简称flannel容器)
              • 第五步 获取四个POD/容器的pid和IP
              • 第六步 运行qperf测试
              • 测试环境和结果
              • CPU占用率的对比
              • 结论
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档