Kubernetes集群部署

    前置要求与约定

    • 约定:Master(s)节点为Kubernetes主节点、Worker(s)节点为Kubernetes普通节点、Etcd节点为将部署Etcd的节点,按本教程安装Master(s)节点与Etcd节点必须一致,Etcd官方建议Etcd集群节点个数为奇数个(比如1、3、5)以防止脑裂。

    • 按本教程安装Kubernetes集群只会在Master(s)节点上安装kubectl命令。

    请检测防火墙状态,如果防火墙已开启请仔细阅读端口要求并按下面方式开放指定的端口;若未开启防火墙请跳过本节操作。

    • 检测firewall-cmd状态

    表示防火墙未启动,如果出现running则为启动状态。

    • 检测iptables状态
    1. service iptables status

    当状态为inactive或者提示Unit iptables.service could not be found.均表示iptables未启动。

    开放指定端口

    如果防火墙已启用,则需要开放指定端口,下面分别列举使用firewalld和iptables设置开放端口命令(不同发行版可能存在差异)。

    • firewalld
    1. firewall-cmd --add-port=6443/tcp --permanent # 永久开放6443端口
    2. firewall-cmd --reload # 重新加载firewall
    • iptables
    1. $ iptables -A INPUT -p tcp --dport 6443 -j ACCEPT # 开放6443端口
    2. $ iptables -A INPUT -p tcp --dport 2379:2380 -j ACCEPT # 开放2379到2380端口
    3. $ iptables-save > /etc/sysconfig/iptables && service iptables restart # 保存并重启iptables

    同步服务器时区

    时区和时间的同步性对于服务器很重要(例如您在更新数据库时,时间的准确性对业务的影响会非常大),为避免实例上运行的业务逻辑混乱和避免网络请求错误,您需要将一台或多台服务器设置在同一时区下,比如 Asia/Shanghai 或 America/Los Angeles。您可以根据自己的业务需求并参照本文为服务器设置或者修改时区。此外,NTP(Network Time Protocol)服务能保证您的服务器的时间与标准时间同步,您可以根据本文配置 NTP 服务。详细过程可以参考此处

    • 本地虚拟机安装指的是在个人电脑上模拟安装。一般情况下个人电脑无法满足安装choerodon的要求,如果你需要在个人电脑上安装choerodon请确认CPU8核以上,内存48G以上。

    • 安装

    • 使用k3s创建一个本地集群(https://github.com/rancher/k3s)

    私有云安装示例

    私有云安装模式指的是在已有的虚拟机中安装,绝大部分centos 7.3+的虚拟机可以通过执行下述命令进行安装,如果你需要安装choerodno请确认集群总内存在48G以上,CPU总核心数大于8核。

    环境准备

    • 在要执行ansible脚本的机器上部署ansible运行需要的环境:
    1. sudo yum install epel-release -y
    2. sudo yum install git python3-pip sshpass -y
    3. pip3 install --no-cache-dir ansible==2.7.5 netaddr -i https://mirrors.aliyun.com/pypi/simple/
    • 克隆项目:
    1. git clone https://github.com/choerodon/kubeadm-ansible.git

    修改hosts文件

    • 注意Etcd节点和Master节点需要在相同的机器。
    • 示例中的node1为主机的hostname
    • ansible_host为目标主机的连接地址,比如您可以通过192.168.56.11这个ip连接到node1的ssh服务,则此处填写192.168.56.11
    • ip为目标主机的内网网卡对应的ip及内网ip
    • 请勿将外网ip配置到ip字段中,否则极有可能部署失败

    • 编辑项目下的kubeadm-ansible/inventory/hosts文件,修改各机器的访问地址、用户名、密码,并维护好各节点与角色的关系,node1为机器的hostname。该用户必须是具有root权限的用户。但并非要求一定是root用户,其他具有root权限的用户也可以。比如,想要部署单节点集群,只需要这样配置(参考):

    1. [all]
    2. node1 ansible_host=192.168.56.11 ip=192.168.56.11 ansible_user=root ansible_ssh_pass=change_it ansible_become=true
    3. [kube-master]
    4. node1
    5. # 请与kube-master节点一致
    6. [etcd]
    7. node1
    8. [kube-node]
    9. node1
    • 如果所有机器以代理的方式访问外网,请配置以下几个变量,否则请不要配置:
    1. http_proxy: http://1.2.3.4:3128
    2. https_proxy: http://1.2.3.4:3128
    3. no_proxy: localhost,127.0.0.0/8
    4. docker_proxy_enable: true
    • 执行:
    1. export ANSIBLE_HOST_KEY_CHECKING=False
    2. #在kubeadm-ansible/目录下执行
    3. ansible-playbook -i inventory/hosts -e @inventory/vars cluster.yml -K
    如果你配置的是root用户则无需添加-K参数
    • 查看等待pod的状态为runnning:
    1. kubectl get po -n kube-system
    • 如果部署失败,想要重置集群(所有数据),执行:
    1. #在kubeadm-ansible/目录下执行
    2. ansible-playbook -i inventory/hosts reset.yml -K

    添加节点

    • 若集群搭建完毕后还想再添加节点,请按以下方式进行添加:

      • 修改kubeadm-ansible/inventory/hosts文件,在[all]分区按照原有格式添加新增节点信息,在[kube-node]分区添加新增节点名,其他分区请一定不要改动。比如原有信息如下,我们添加一个ip为192.168.56.12的node2节点:
    1. [all]
    2. node1 ansible_host=192.168.56.11 ip=192.168.56.11 ansible_user=root ansible_ssh_pass=vagrant ansible_become=true
    3. [kube-master]
    4. node1
    5. # 请与kube-master节点一致
    6. [etcd]
    7. node1
    8. [kube-node]
    9. node1
    • 修改后信息如下:
    1. [all]
    2. node1 ansible_host=192.168.56.11 ip=192.168.56.11 ansible_user=root ansible_ssh_pass=vagrant ansible_become=true
    3. node2 ansible_host=192.168.56.12 ip=192.168.56.12 ansible_user=root ansible_ssh_pass=vagrant ansible_become=true
    4. [kube-master]
    5. node1
    6. # 请与kube-master节点一致
    7. [etcd]
    8. node1
    9. [kube-node]
    10. node1
    11. node2
    • 执行添加节点命令
    1. #在kubeadm-ansible/目录下执行
    2. ansible-playbook -i inventory/hosts -e @inventory/vars scale.yml -K

    公有云安装以阿里云ECS为例进行讲解,其它公有云可参考本教程,但具体安装方式请咨相应云提供商。目前只支持Centos 7.2及以上版本。

    环境准备

    • 在要执行ansible脚本的机器上部署ansible运行需要的环境:
    1. sudo yum install epel-release -y
    2. sudo yum install git python3-pip sshpass -y
    3. pip3 install --no-cache-dir ansible==2.7.5 netaddr -i https://mirrors.aliyun.com/pypi/simple/
    • 克隆项目:

      修改hosts文件

      在阿里云的ECS的控制面板上修改ECS实例的hostname,名称最好只包含小写字母、数字和中划线。并保持与inventory/hosts中的名称与ECS控制台上的名称保持一致,重启生效。

      执行下一步前请注意以下几点:

      • 注意Etcd节点和Master节点需要在相同的机器。
      • 示例中的node1为主机的hostname
      • ansible_host为目标主机的连接地址,比如您可以通过192.168.56.11这个ip连接到node1的ssh服务,则此处填写192.168.56.11
      • ip为目标主机的内网网卡对应的ip及内网ip
      • 请勿将外网ip配置到ip字段中,否则极有可能部署失败开始安装

      • 编辑项目下的kubeadm-ansible/inventory/hosts文件,修改各机器的访问地址、用户名、密码,并维护好各节点与角色的关系。该用户必须是具有root权限的用户。但并非要求一定是root用户,其他具有root权限的用户也可以。比如,想要部署单节点集群,只需要这样配置(参考):

      本文档部署的网络类型为flannel类型
      • 在使用VPC网络的ECS上部署k8s时,flannel网络的Backend类型需要是ali-vpc。在本脚本中默认使用的是vxlan类型,虽然在vpc环境下网络能通,但是不稳定波动较大。所以推荐使用ali-vpc的类型。

      • 因此,首先需要设置默认的flannel网络不部署,通过在kubeadm-ansible/inventory/vars文件中添加变量:

      1. flannel_enable: false
      • 网段选择,如果ECS服务器用的是专有网络,pod和service的网段不能与vpc网段重叠,若有重叠请配置kube_pods_subnet和kube_service_addresses变量设置pod和service的网段,示例参考:
      1. # 如果vpc网段为`192.168.*`
      2. kube_pods_subnet: 172.16.0.0/20
      3. kube_service_addresses: 172.16.16.0/20
      • 如果所有机器以代理的方式访问外网,配置以下几个变量,否则请不要配置:
      1. http_proxy: http://1.2.3.4:3128
      2. https_proxy: http://1.2.3.4:3128
      3. no_proxy: localhost,127.0.0.0/8
      4. docker_proxy_enable: true

      部署

      • 下面开始部署集群:
      1. export ANSIBLE_HOST_KEY_CHECKING=False
      2. #在kubeadm-ansible/目录下执行
      • 获取阿里云ACCESS_KEY,该ACCESS_KEY需要拥有以下权限:

        • 只读访问云服务器(ECS)的权限
        • 管理专有网络(VPC)的权限
      • 手动部署flannel网络插件,在任意一个Master节点创建配置文件kube-flannel-aliyun.yml
      1. kind: ClusterRole
        apiVersion: rbac.authorization.k8s.io/v1beta1
        metadata:
        name: flannel
        rules:
        - apiGroups:
        - ""
        resources:
        - pods
        verbs:
        - get
        - apiGroups:
        - ""
        resources:
        - nodes
        verbs:
        - list
        - watch
        - apiGroups:
        - ""
        resources:
        - nodes/status
        verbs:
        - patch
        ---
        kind: ClusterRoleBinding
        apiVersion: rbac.authorization.k8s.io/v1beta1
        metadata:
        name: flannel
        roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: flannel
        subjects:
        - kind: ServiceAccount
        name: flannel
        namespace: kube-system
        ---
        apiVersion: v1
        kind: ServiceAccount
        metadata:
        name: flannel
        namespace: kube-system
        ---
        kind: ConfigMap
        apiVersion: v1
        metadata:
        name: kube-flannel-cfg
        namespace: kube-system
        labels:
        tier: node
        app: flannel
        data:
        cni-conf.json: |
        {
        "name": "cbr0",
        "type": "flannel",
        "delegate": {
        "isDefaultGateway": true
        }
        }
        net-conf.json: |
        {
      2. "Network": "172.16.0.0/20",
      1. "Backend": {
        "Type": "ali-vpc"
        }
        }
        ---
        apiVersion: extensions/v1beta1
        kind: DaemonSet
        metadata:
        name: kube-flannel-ds
        namespace: kube-system
        labels:
        tier: node
        app: flannel
        spec:
        template:
        metadata:
        labels:
        tier: node
        app: flannel
        spec:
        hostNetwork: true
        nodeSelector:
        beta.kubernetes.io/arch: amd64
        tolerations:
        - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
        serviceAccountName: flannel
        initContainers:
        - name: install-cni
        image: registry.cn-hangzhou.aliyuncs.com/google-containers/flannel:v0.9.0
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conf
        volumeMounts:
        - name: cni
        mountPath: /etc/cni/net.d
        - name: flannel-cfg
        mountPath: /etc/kube-flannel/
        containers:
        - name: kube-flannel
        image: registry.cn-hangzhou.aliyuncs.com/google-containers/flannel:v0.9.0
        command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr" ]
        securityContext:
        privileged: true
        env:
        - name: POD_NAME
        valueFrom:
        fieldRef:
        fieldPath: metadata.name
        - name: POD_NAMESPACE
        valueFrom:
        fieldRef:
        fieldPath: metadata.namespace
        - name: ACCESS_KEY_ID
      2. value: YOUR_ACCESS_KEY_ID
      1. - name: ACCESS_KEY_SECRET
      2. value: YOUR_ACCESS_KEY_SECRET
      1. volumeMounts:
      2. - name: run
      3. mountPath: /run
      4. - name: flannel-cfg
      5. mountPath: /etc/kube-flannel/
      6. volumes:
      7. - name: run
      8. hostPath:
      9. path: /run
      10. - name: cni
      11. hostPath:
      12. path: /etc/cni/net.d
      13. - name: flannel-cfg
      14. configMap:
      15. name: kube-flannel-cfg

      配置的pod网段,即变量文件kubeadm-ansible/inventory/vars中的kube_pods_subnet值

      阿里云中创建的 ACCESS_KEY_ID

      • 然后使用kubectl命令部署,部署成功后在vpc的路由表中会添加多条路由条目,下一跳分别为每个节点的pod ip段:
      1. kubectl apply -f kube-flannel-aliyun.yml
      • 接下来需要在ECS安全组,在入方向规则中加上pod网段的地址。否则在pod容器中无法访问别的节点的pod的端口,比如:

      授权策略协议类型端口范围授权类型授权对象允许全部-1/-1地址段访问172.16.0.0/20允许TCP443⁄443地址段访问0.0.0.0/0允许TCP80⁄80地址段访问0.0.0.0/0

      • 查看等待pod的状态为runnning:
      1. kubectl get po -n kube-system
      • 如果部署失败,想要重置集群(所有数据),执行:
      1. #在kubeadm-ansible/目录下执行
      2. ansible-playbook -i inventory/hosts reset.yml -K

      添加节点

      通过本小节教程添加的节点不能是Master或Etcd节点,只能是普通的Work节点。若你使用的是NFS作为存储,建议你先安装nfs-utils
      • 若集群搭建完毕后还想再添加节点,请按以下方式进行添加:

        • 修改kubeadm-ansible/inventory/hosts文件,在[all]分区按照原有格式添加新增节点信息,在[kube-node]分区添加新增节点名,其他分区请一定不要改动。比如原有信息如下,我们添加一个ip为192.168.56.12的node2节点:
      1. [all]
      2. node1 ansible_host=192.168.56.11 ip=192.168.56.11 ansible_user=root ansible_ssh_pass=vagrant ansible_become=true
      3. [kube-master]
      4. node1
      5. # 请与kube-master节点一致
      6. [etcd]
      7. node1
      8. [kube-node]
      9. node1
      • 修改后信息如下:
      1. [all]
      2. node1 ansible_host=192.168.56.11 ip=192.168.56.11 ansible_user=root ansible_ssh_pass=vagrant ansible_become=true
      3. node2 ansible_host=192.168.56.12 ip=192.168.56.12 ansible_user=root ansible_ssh_pass=vagrant ansible_become=true
      4. [kube-master]
      5. node1
      6. # 请与kube-master节点一致
      7. [etcd]
      8. node1
      9. [kube-node]
      10. node1
      11. node2
      • 执行添加节点命令
      1. #在kubeadm-ansible/目录下执行
      2. ansible-playbook -i inventory/hosts -e @inventory/vars scale.yml -K

      Kubernetes网络测试

      集群搭建完成后请一定进行以下测试步骤进行测试。

      集群访问公网测试

      测试说明

      • 镜像中将以下核心代码进行封装成为curls命令,使用方式curls url [times],例如curls choerodon.io 20则为访问choerodon.io20次并打印测试出的时间指标,命令默认访问10次。
      1. curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "choerodon.io"
      • 时间指标说明

        • 单位:秒
        • time_connect:建立到服务器的 TCP 连接所用的时间
        • time_starttransfer:在发出请求之后,Web 服务器返回数据的第一个字节所用的时间
        • time_total:完成请求所用的时间

      场景一、 Kubernetes集群node节点访问公网

      • 测试命令
      • 测试结果
      1. No time_connect time_starttransfer time_total
      2. 1 0.015071 0.027448 0.027570
      3. 2 0.010049 0.024527 0.024612
      4. 3 0.010025 0.022209 0.022311
      5. 4 0.012600 0.025269 0.025369
      6. 5 0.012847 0.025849 0.025932
      7. 6 0.009973 0.023102 0.023220
      8. 7 0.013074 0.029310 0.029411
      9. 8 0.015137 0.029992 0.030103
      10. 9 0.010994 0.029040 0.029173
      11. 10 0.010554 0.022011 0.022130
      • 平均响应时间:26ms

      场景二、Kubernetes集群Pod访问公网

      • 测试命令
      1. -it --quiet --rm --restart=Never \
      2. --image='registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0' \
      3. -- bash -c "sleep 3; curls choerodon.io"
      • 测试结果
      1. No time_connect time_starttransfer time_total
      2. 1 0.014916 0.027232 0.027418
      3. 2 0.020213 0.034626 0.034762
      4. 3 0.014945 0.028014 0.028165
      5. 4 0.016916 0.030483 0.032091
      6. 5 0.020519 0.033075 0.033281
      7. 6 0.015398 0.027727 0.028003
      8. 7 0.015260 0.027099 0.027247
      9. 9 0.020941 0.032935 0.035226
      10. 10 0.014298 0.026570 0.026983
      • 平均响应时间:29ms

      测试说明

      • 测试数据

      Service Name: default-http-backend.kube-system.svc

      Service Cluster IP: 172.16.17.173 (可通过kubectl get svc default-http-backend -n kube-system进行查看)

      Service Port: 80

      • 通过向default-http-backendhealthzapi执行curl命令进行网络延迟测试
      1. $ curl "http://172.16.17.173/healthz"
      2. ok

      场景一、 Kubernetes集群node节点上通过Service Cluster IP访问

      • 测试命令
      1. docker run -it --rm --net=host \
      2. registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0 \
      3. curls http://172.16.17.173/healthz
      • 测试结果
      1. No time_connect time_starttransfer time_total
      2. 1 0.000491 0.000983 0.001038
      3. 2 0.000347 0.002051 0.002122
      4. 3 0.000298 0.000894 0.000975
      5. 4 0.000263 0.082559 0.082665
      6. 5 0.000351 0.000732 0.000785
      7. 6 0.000234 0.084351 0.084445
      8. 7 0.000245 0.000550 0.000592
      9. 8 0.000436 0.086836 0.086947
      10. 9 0.000215 0.000536 0.000573
      11. 10 0.000369 0.089528 0.089635
      • 平均响应时间:34ms

      场景二、Kubernetes集群内部通过service访问

      • 测试命令
      1. kubectl run curl-test \
      2. -it --quiet --rm --restart=Never \
      3. --image='registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0' \
      4. -- bash -c "sleep 3; curls http://default-http-backend.kube-system.svc/healthz"
      • 测试结果
      1. No time_connect time_starttransfer time_total
      2. 1 0.040173 0.080107 0.080205
      3. 2 0.047826 0.065836 0.065932
      4. 3 0.064808 0.091835 0.091938
      5. 4 0.075448 0.087315 0.087410
      6. 5 0.112765 0.195511 0.195640
      7. 6 0.104970 0.199655 0.199777
      8. 7 0.127144 0.139747 0.139834
      9. 8 0.056066 0.063325 0.063456
      10. 9 0.021773 0.028471 0.028578
      11. 10 0.017777 0.023236 0.023330
      • 平均响应时间:112ms

      注意: 执行测试的node节点/Pod与Serivce所在的Pod的距离(是否在同一台主机上),对这两个场景可以能会有一定影响。

      集群内部网络性能测试

      测试说明

      • 使用iperf进行测试.

      场景一、主机之间

      • 服务端命令:
      1. docker run -it --rm --net=host \
      2. registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0 \
      3. iperf -s -p 12345 -i 1 -M

      注意: 此时该服务端命令会前台运行,一直等待客户端请求,请另起一个终端窗口进行执行客户端命令。

      • 客户端命令:
      1. docker run -it --rm --net=host \
      2. registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0 \
      3. iperf -c 服务端主机IP -p 12345 -i 1 -t 10 -w 20K
      • 测试结果
      1. [ ID] Interval Transfer Bandwidth
      2. [ 3] 0.0- 1.0 sec 225 MBytes 1.89 Gbits/sec
      3. [ 3] 1.0- 2.0 sec 223 MBytes 1.87 Gbits/sec
      4. [ 3] 2.0- 3.0 sec 237 MBytes 1.98 Gbits/sec
      5. [ 3] 3.0- 4.0 sec 223 MBytes 1.87 Gbits/sec
      6. [ 3] 4.0- 5.0 sec 273 MBytes 2.29 Gbits/sec
      7. [ 3] 5.0- 6.0 sec 259 MBytes 2.17 Gbits/sec
      8. [ 3] 6.0- 7.0 sec 308 MBytes 2.59 Gbits/sec
      9. [ 3] 7.0- 8.0 sec 257 MBytes 2.16 Gbits/sec
      10. [ 3] 8.0- 9.0 sec 261 MBytes 2.19 Gbits/sec
      11. [ 3] 9.0-10.0 sec 234 MBytes 1.96 Gbits/sec
      12. [ 3] 0.0-10.0 sec 2.44 GBytes 2.10 Gbits/sec

      场景二、不同主机的Pod之间

      • 服务端命令:
      1. kubectl run iperf-server \
      2. -it --quiet --rm --restart=Never \
      3. --overrides='{"spec":{"template":{"spec":{"nodeName":"指定服务端运行的节点"}}}}' \
      4. --image='registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0' \
      5. -- bash -c "sleep 3; ifconfig eth0; iperf -s -p 12345 -i 1 -M"
      • 客户端命令:
      1. kubectl run iperf-client \
      2. -it --quiet --rm --restart=Never \
      3. --overrides='{"spec":{"nodeName":"指定客户端运行的节点"}}' \
      4. --image='registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0' \
      5. -- iperf -c 服务端PODIP -p 12345 -i 1 -t 10 -w 20K
      • 测试结果
      1. [ ID] Interval Transfer Bandwidth
      2. [ 3] 0.0- 1.0 sec 1.42 GBytes 12.2 Gbits/sec
      3. [ 3] 1.0- 2.0 sec 1.39 GBytes 11.9 Gbits/sec
      4. [ 3] 2.0- 3.0 sec 1.22 GBytes 10.5 Gbits/sec
      5. [ 3] 3.0- 4.0 sec 1.27 GBytes 10.9 Gbits/sec
      6. [ 3] 4.0- 5.0 sec 1.04 GBytes 8.91 Gbits/sec
      7. [ 3] 5.0- 6.0 sec 1.36 GBytes 11.7 Gbits/sec
      8. [ 3] 6.0- 7.0 sec 1.42 GBytes 12.2 Gbits/sec
      9. [ 3] 7.0- 8.0 sec 1.57 GBytes 13.5 Gbits/sec
      10. [ 3] 8.0- 9.0 sec 1.25 GBytes 10.8 Gbits/sec
      11. [ 3] 9.0-10.0 sec 1.56 GBytes 13.4 Gbits/sec
      12. [ 3] 0.0-10.0 sec 13.5 GBytes 11.6 Gbits/sec

      场景三、Node与非同主机的Pod之间

      • 服务端命令:
      1. docker run -it --rm --net=host \
      2. registry.cn-hangzhou.aliyuncs.com/choerodon-tools/network-and-cluster-perfermance-test:0.1.0 \
      3. iperf -s -p 12345 -i 1 -M

      注意: 此时该服务端命令会前台运行,一直等待客户端请求,请另起一个终端窗口进行执行客户端命令。

      • 客户端命令:
      • 测试结果
      1. [ ID] Interval Transfer Bandwidth
      2. [ 3] 0.0- 1.0 sec 289 MBytes 2.43 Gbits/sec
      3. [ 3] 1.0- 2.0 sec 290 MBytes 2.43 Gbits/sec
      4. [ 3] 2.0- 3.0 sec 226 MBytes 1.89 Gbits/sec
      5. [ 3] 3.0- 4.0 sec 209 MBytes 1.75 Gbits/sec
      6. [ 3] 4.0- 5.0 sec 254 MBytes 2.13 Gbits/sec
      7. [ 3] 5.0- 6.0 sec 257 MBytes 2.15 Gbits/sec
      8. [ 3] 6.0- 7.0 sec 265 MBytes 2.23 Gbits/sec
      9. [ 3] 7.0- 8.0 sec 184 MBytes 1.55 Gbits/sec
      10. [ 3] 8.0- 9.0 sec 217 MBytes 1.82 Gbits/sec
      11. [ 3] 9.0-10.0 sec 236 MBytes 1.98 Gbits/sec