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
版权声明:本文为博主原创文章,转载请附上博文链接!

kubernetes集群pod使用tc进行网络资源限额的更多相关文章

  1. kubernetes集群之Pod说能不能让我体面的消亡呀?

    kubernetes集群之Pod说能不能让我体面的消亡呀? 由于 Pod 所代表的是在集群中节点上运行的进程,当不再需要这些进程时允许其体面地终止. 1.如果 preStop 回调所需要的时间长于默认 ...

  2. [云原生]Kubernetes - 集群搭建(第2章)

    目录 一.前置知识点 二.kubeadm部署方式介绍 三.安装要求 四.最终目标 五.准备环境 六.环境初始化 6.1 设置系统主机名以及Hosts文件的相互解析 6.2 安装依赖文件(所有节点) 6 ...

  3. Kubernetes集群搭建过程中遇到的问题

    1. 创建Nginx Pod过程中报如下错误: #kubectlcreate -f nginx-pod.yaml Error from server: error when creating &quo ...

  4. Kubernetes集群初探

    上文我们在一台虚机上演示了Kubernetes基于redis和docker的guestbook留言簿案例,本文我们将通过配置Kubernetes集群的方式继续深入研究.集群组件安装如下配置. IP N ...

  5. kubernetes集群部署

    鉴于Docker如此火爆,Google推出kubernetes管理docker集群,不少人估计会进行尝试.kubernetes得到了很多大公司的支持,kubernetes集群部署工具也集成了gce,c ...

  6. Centos7上安装Kubernetes集群部署docker

    一.安装前准备1.操作系统详情需要三台主机,都最小化安装 centos7.3,并update到最新 [root@master ~]# (Core) 角色 主机名 IPMaster master 192 ...

  7. 在Kubernetes集群中使用calico做网络驱动的配置方法

    参考calico官网:http://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/kubeadm ...

  8. 使用acs-engine在Azure中国区部署kubernetes集群详解

    转载请注明出处:http://www.cnblogs.com/wayneiscoming/p/7649642.html 1. acs-engine简介 ACS是微软在2015年12月推出的一项基于容器 ...

  9. Traefik实现Kubernetes集群服务外部https访问

    转载请注明出处:http://www.cnblogs.com/wayneiscoming/p/7707942.html traefik 是一个前端http反向代理服务器以及负载均衡器,支持多种微服务后 ...

随机推荐

  1. __x__(20)0907第四天__列表ul,ol,dl

    列表分为: 有序列表 ul: <ul type="disc"> <li>张三</li> <li>李四</li> < ...

  2. (65)Wangdao.com第十天_JavaScript 垃圾回收机制 GC

    垃圾积累过多,致使程序运行缓慢,什么是垃圾? 当堆中某个内容,再也没有指针指向它,我们将再也用不了它,此时就是一个垃圾. 出现这种情况是因为 obj = null; 此时,js 中的垃圾回收机制会自动 ...

  3. (81)Wangdao.com第十六天_JavaScript 严格模式

    严格模式 除了正常的运行模式,JavaScript 还有第二种运行模式:严格模式(strict mode).顾名思义,这种模式采用更加严格的 JavaScript 语法 同样的代码,在正常模式和严格模 ...

  4. Oracle 用户权限 Grant

    用户的权限来自系统权限和对象权限 一.系统权限 3个索引权限 Grant CREATE ANY INDEX to User_Name://创建索引 Grant ALTER ANY INDEX to U ...

  5. AVL树的Java实现

    AVL树:平衡的二叉搜索树,其子树也是AVL树. 以下是我实现AVL树的源码(使用了泛型): import java.util.Comparator; public class AVLTree< ...

  6. LDAP与实现

    LDAP是什么? LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP.它是基于X.500标准的,但是简单多了并且可以 ...

  7. Windows bat批处理使用

    mkdir commonmkdir datamkdir savemkdir data\tsushima_m_mapmkdir save\tsushima_m_map msxsl ..\common\r ...

  8. Python title()、upper()、lower()方法--string

    描述 title()方法: 将字符串中的单词“标题化”,即首字母大写,其余字母转化为小写. upper()方法:将字符串中的小写字母转化为大写字母. lower()方法:将字符串中的大写字母转化为小写 ...

  9. gitlab自动备份和定时删除

    GitLab数据手动备份1.GitLab默认备份目录为/var/opt/gitlab/backups,可以修改/etc/gitlab/gitlab.rb里面的默认存放备份文件目录,这里使用默认备份目录 ...

  10. windows共享文件夹至centos系统文件夹下

    1. window 共享文件夹 https://jingyan.baidu.com/article/358570f6633ba4ce4624fc48.html 2. 在访问Windows共享资料之前, ...