zoukankan      html  css  js  c++  java
  • kubernetes集群pod使用tc进行网络资源限额

    kubernetes集群pod使用tc进行网络资源限额

     Docker容器可以实现CPU,内存,磁盘的IO限额,但是没有实现网络IO的限额。主要原因是在实际使用中,构建的网络环境是往超级复杂的大型网络。这样的网络机构,如何管理每一个容器的带宽本身就是一个挑战,对一台主机来说,你已经限制了带宽,然后你想更细颗粒度的管理里面的容器带宽,而且容器的种类特别多,而且不能一刀切解决的,所以这是非常大的挑战。所以Docker没有实现网络资源的限制,把这部分工作交给第三方工具实现。

           但是在实际的使用过程中,对网络带宽要求不一样的容器进行网络带宽的限额是非常由必要的。本文就是根据此目标进行的一些调研和实践的总结。
    一. kubernetes集群docker容器cpu,内存资源限额介绍
          因docker容器中用cgroup实现了cpu,内存等资源的限额,所以最开始考虑能不能通过cgroup对容器的网络资源进行限额。

            Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。这个项目最早是由Google的工程师在2006年发起(主要是Paul Menage和Rohit Seth),最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器这个名词太过广泛,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核中去。然后,其它开始了他的发展。

    cgroup主要提供了如下功能:

    Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制。
    Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐。
    Accounting: 一些审计或一些统计,主要目的是为了计费。
    Control: 挂起进程,恢复执行进程。

    cgroup实现成了一个file system,你可以mount。在我的Ubuntu 14.04下,你输入以下命令你就可以看到cgroup已为你mount好了

    wade@wade-ThinkCentre-E73:~$ mount -t cgroup
    cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,relatime,cpuset)
    cgroup on /sys/fs/cgroup/cpu type cgroup (rw,relatime,cpu)
    cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,relatime,cpuacct)
    cgroup on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory)
    cgroup on /sys/fs/cgroup/devices type cgroup (rw,relatime,devices)
    cgroup on /sys/fs/cgroup/freezer type cgroup (rw,relatime,freezer)
    cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,relatime,net_cls)
    cgroup on /sys/fs/cgroup/blkio type cgroup (rw,relatime,blkio)
    cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,relatime,perf_event)
    cgroup on /sys/fs/cgroup/net_prio type cgroup (rw,relatime,net_prio)
    cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,relatime,hugetlb)
    systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd)

    你可以到/sys/fs/cgroup的各个子目录下去make个dir,你会发现,一旦你创建了一个子目录,这个子目录里又有很多文件了。

    先来看看control group有哪些子系统:
    blkio — 这​​​个​​​子​​​系​​​统​​​为​​​块​​​设​​​备​​​设​​​定​​​输​​​入​​​/输​​​出​​​限​​​制​​​,比​​​如​​​物​​​理​​​设​​​备​​​(磁​​​盘​​​,固​​​态​​​硬​​​盘​​​,USB 等​​​等​​​)。
    cpu — 这​​​个​​​子​​​系​​​统​​​使​​​用​​​调​​​度​​​程​​​序​​​提​​​供​​​对​​​ CPU 的​​​ cgroup 任​​​务​​​访​​​问​​​。​​​
    cpuacct — 这​​​个​​​子​​​系​​​统​​​自​​​动​​​生​​​成​​​ cgroup 中​​​任​​​务​​​所​​​使​​​用​​​的​​​ CPU 报​​​告​​​。​​​
    cpuset — 这​​​个​​​子​​​系​​​统​​​为​​​ cgroup 中​​​的​​​任​​​务​​​分​​​配​​​独​​​立​​​ CPU(在​​​多​​​核​​​系​​​统​​​)和​​​内​​​存​​​节​​​点​​​。​​​
    devices — 这​​​个​​​子​​​系​​​统​​​可​​​允​​​许​​​或​​​者​​​拒​​​绝​​​ cgroup 中​​​的​​​任​​​务​​​访​​​问​​​设​​​备​​​。​​​
    freezer — 这​​​个​​​子​​​系​​​统​​​挂​​​起​​​或​​​者​​​恢​​​复​​​ cgroup 中​​​的​​​任​​​务​​​。​​​
    memory — 这​​​个​​​子​​​系​​​统​​​设​​​定​​​ cgroup 中​​​任​​​务​​​使​​​用​​​的​​​内​​​存​​​限​​​制​​​,并​​​自​​​动​​​生​​​成​​​​​内​​​存​​​资​​​源使用​​​报​​​告​​​。​​​
    net_cls — 这​​​个​​​子​​​系​​​统​​​使​​​用​​​等​​​级​​​识​​​别​​​符​​​(classid)标​​​记​​​网​​​络​​​数​​​据​​​包​​​,可​​​允​​​许​​​ Linux 流​​​量​​​控​​​制​​​程​​​序​​​(tc)识​​​别​​​从​​​具​​​体​​​ cgroup 中​​​生​​​成​​​的​​​数​​​据​​​包​​​。​​​
    net_prio — 这个子系统用来设计网络流量的优先级
    hugetlb — 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统。

    二.  cgroup+tc对网络带宽限额尝试
    可以查看到net_cls子系统包含了docker目录,并且docker目录下面是个容器的id,各个容器目录下面task文件已经包含了该docker容器的所有进程ID。

    wade@wade-ThinkCentre-E73:/sys/fs/cgroup/net_cls$ ll
    总用量 0
    dr-xr-xr-x 4 root root 0 8月 30 10:25 ./
    drwxr-xr-x 14 root root 280 8月 30 10:25 ../
    -rw-r--r-- 1 root root 0 8月 30 14:24 cgroup.clone_children
    -rw-r--r-- 1 root root 0 8月 30 14:24 cgroup.procs
    -r--r--r-- 1 root root 0 8月 30 14:24 cgroup.sane_behavior
    drwxr-xr-x 22 root root 0 8月 30 10:34 docker/
    -rw-r--r-- 1 root root 0 8月 30 14:24 net_cls.classid
    -rw-r--r-- 1 root root 0 8月 30 14:24 notify_on_release
    -rw-r--r-- 1 root root 0 8月 30 14:24 release_agent
    -rw-r--r-- 1 root root 0 8月 30 14:24 tasks
    drwxr-xr-x 3 root root 0 8月 30 10:25 user/

    所以首先想到是是否可以通过cgroup+tc实现容器网络的限额。
    首先用tc工具对eth0进行htb算法的限额,并用cgroup进行流量的分类

    tc qdisc del dev eth0 root
    tc qdisc add dev eth0 root handle 1: htb
    tc class add dev eth0 parent 1: classid 1: htb rate 1000mbit ceil 1000mbit
    tc class add dev eth0 parent 1: classid 1:3 htb rate 10mbit
    tc class add dev eth0 parent 1: classid 1:4 htb rate 10kbit
    tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 1: cgroup


    把相应分类写入要限额容器的net_cls.classid中
    echo '0x10004' > /cgroup/net_cls/docker/id/net_cls.classid


    最后进行实验的时候发现完全没有达到网络限额的效果。


    然后同理对docker0进行限额。最后实验发现对所有的容器的网络进行了限额。不能对单个容器实现限额。

    而容器默认使用veth方式创建虚拟机网络的,veth就是要把从一个网络用户空间(network namespace )发出的数据包转发到另一个用户空间。veth 设备是成对的(veth pair),一个是容器之中,另一个在容器之外,即在真实机器上能看到的。在容器内部看到的是eth0,容器外部就是一个veth device绑定到docker0虚拟网桥上. 因此设置在eth0上的限制,以及对于包的标记是都不管用的。

    三.  tc对veth限额实现kubernetes中pod级别的网络限额
    ​​​kubernetes中每个pod对应一个veth
    1.首先需要找到kubernetes中pod对应的vethname。

    #!/bin/bash
    #filename:getveth.sh
    #author:wade
    container_name=$1
    if [ -z $1 ] ; then
    echo "Usage: ./getveth.sh container_name"
    exit 1
    fi

    if [ `docker inspect -f "{{.State.Pid}}" ${container_name} &>>/dev/null && echo 0 || echo 1` -eq 1 ];then
    echo "no this container:${container_name}"
    exit 1
    fi
    pid=`docker inspect -f "{{.State.Pid}}" ${container_name}`
    mkdir -p /var/run/netns
    ln -sf /proc/$pid/ns/net "/var/run/netns/${container_name}"
    index=`ip netns exec "${container_name}" ip link show eth0 | head -n1 | sed s/:.*//`
    let index=index+1
    vethname=`ip link show | grep "^${index}:" | sed "s/${index}: (.*):.*/1/"`
    echo $vethname
    rm -f "/var/run/netns/${container_name}"


    docker容器下载流量限额
    在node节点上用tc设置对应veth的流量带宽

    tc qdisc add dev vethname root tbf rate 10mbit latency 50ms burst 10000 mpu 64 mtu 15000

    docker容器上传流量限额
    在容器内使用tc设置eth0设备的流量带宽
    (注意:因为要配置容器的网络设备eth0,所以kubelet,kube-apiserver的启动时候需要添加--allow-privileged=true 参数,或者pod的yaml文件中spec.containers[0].securityContext.privileged:true)

    tc qdisc add dev eth0 root tbf rate 10mbit latency 50ms burst 10000 mpu 64 mtu 15000

    通过测试发现实现了kubernetes中pod的网络带宽限额。


    四.  若有朋友的docker网络没有使用默认bridge,而是绑定了openvswitch的bridge,并使用pipework提供网络,可以通过openvswitch基于port来进行网络资源的限制。
    详细请移步以下链接
    http://dl528888.blog.51cto.com/2382721/1641569
    ---------------------
    作者:ptmozhu
    来源:CSDN
    原文:https://blog.csdn.net/ptmozhu/article/details/52368681
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    S2-020 Struts ClassLoader Manipulation安全限制绕过(CVE-2014-0094)
    几本关于PHP安全的书
    招聘软件开发实习生
    招聘安全测试工程师
    Fortify对移动应用安全的支持
    安全测试服务方案
    对比AppScan Source和Fortify扫描AltoroJ的结果
    JAVA白盒安全测试需要关注的API
    Java安全防御学习笔记V1.0
    appscan 安全漏洞修复办法
  • 原文地址:https://www.cnblogs.com/xuchenCN/p/10782856.html
Copyright © 2011-2022 走看看