容器限速和流量采集03-golang实现

1 docker-tc

实现上可参考github上的 lukaszlach/docker-tc。lukaszlach/docker-tc 提供了一个通过监听 docker event 来为对应容器做限速的方法,但是只支持 bridge 模式下的下行限速。
本方案采用 golang 来是实现容器限速和流量采集,支持对 bridge host模式下容器限速,支持上行和下行限速,支持多网口限速。用户只需要在需要限速的容器配置对应的 --label "com.docker-tc.enabled=1" 启动参数即可。支持 NetworkModehostbridge 两种网络模式;支持配置限速的基础速率 rate 和最高速率 ceil ;支持对于配置了限速的容器做流量采集。

2 技术方案

2.1 主要技术栈

  • 使用 docker golang sdk 来获取容器相关信息并且监听容器的事件(主要关注create 和 die 事件)
  • 使用 tc-traffic control 来进行限速,使用 tchtb 策略进行限速。对应到容器的不同网络模式采用不同的限速方法。对于 net=host, 需要借助 cgroup 来区别不同的容器,并且在 WAN 接口上进行限速,对于 net=bridge ,找出容器对应的 veth,对 veth 接口进行限速。
  • 使用 ifb-Intermediate Functional Block 来将某个端口的流量 ingressifb 接口,然后对 ifb 接口做限速,从而实现下行速率的限制
  • 使用 netlink 来实现各种网络相关的操作
  • 使用 prometheus 来暴露流量的 metric

2.2 数据流

在这里插入图片描述

  1. 程序启动后,首先检查所有 running 状态的容器,并且根据 --label "com.docker-tc.enabled=1"label 来确定是否要对这些容器配置限速策略。
  2. 启动一个循环,一直监听容器的事件,对于 create 事件,需要对容器应用限速策略;对于 die 事件,需要删除容器的限速策略。
  3. 对于容器的限速需要区分 net=hostnet=bridge,使用对应的限速方式来实现。
  4. 下行流量限速借助配置 ifb 接口来实现。

2.3 限速策略

bridge 模式下容器限速

# bridge 模式容器下行限速,veth6552aeb 是容器对应的 veth 接口
tc qdisc del dev veth6552aeb root
tc qdisc add dev veth6552aeb root handle 1: htb default 1
tc class add dev veth6552aeb parent 1: classid 1:1 htb rate 1000mbit ceil 1000mbit prio 2

tc class add dev veth6552aeb parent 1:1 classid 1:10 htb rate 4Mbit ceil 8Mbit prio 1 burst 96kbit
tc qdisc add dev veth6552aeb parent 1:10 handle 10: sfq perturb 10
tc filter add dev veth6552aeb protocol ip parent 1: prio 2 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 1:10

# bridge 模式容器上行限速,veth6552aeb 是容器对应的 veth 接口, ss是 container name,用 container name 起一个 ifb 接口
ip link add ss type ifb
ip link set ss up

tc qdisc add dev veth5d3d1d6 handle ffff: ingress
tc filter add dev veth5d3d1d6 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ss

tc qdisc add dev ss root handle 1: htb default 1
tc class add dev ss parent 1: classid 1:1 htb rate 1000mbit ceil 1000mbit prio 2

tc class add dev ss parent 1:1 classid 1:10 htb rate 8Mbit ceil 12Mbit prio 1 burst 96kbit
tc qdisc add dev ss parent 1:10 handle 10: sfq perturb 10
tc filter add dev ss protocol ip parent 1: prio 2 u32 match ip src 0.0.0.0/0 match ip dst 0.0.0.0/0 flowid 1:10

注意事项

  • 需要处理 docker-tc 容器异常关闭、重启等场景
  • 删除 tc 策略的顺序应该跟添加 tc 策略的顺序相反,应该先删除 filter,再删除 class,不然可能出现 RTNETLINK answers: Device or resource busy 的错误
  • 为了配置下行限速,给对应网口配置了 ingress mirror,比如 ppp4014 的流量 mirror 到了 ifbppp4014,如果直接删除 ifbppp4014,会导致 ppp4014 的网络不通,需要有一个协程定期清理 filternetlink.U32.RedirIndex == 0 的网口的 ingress 策略
  • 需要处理 WAN 口重启或删除导致 tc 策略丢失问题,所以需要监听网口up/down 等事件,并配置对应的 tc 策略。

3 使用说明

3.1 部署和启动该服务

在需要进行容器限速的每台服务器上部署该服务,可以使用 systemd 来启动服务,或者使用 docker 来部署该服务。如果使用 docker 来部署该服务,启动脚本如下:

docker run -d \
    --name docker-tc \
    --network host \
    --privileged \
    --pid=host \
    --restart always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /var/docker-tc:/var/docker-tc \
    -v /opt/docker-tc/config:/docker-tc/config \
    -v /sys/fs/cgroup/net_cls:/sys/fs/cgroup/net_cls \
    docker-tc

由于 docker-tc 需要操作网络接口,需要配置 --network host--cap-add NET_ADMIN 。另外 docker-tc 需要监听 docker 事件,所以需要配置 -v /var/run/docker.sock:/var/run/docker.sock

3.2 限速容器的配置

如果需要对某个容器做限速,需要配置对应的 label 参数, docker-tc 相关的 label 参数 如下:

  • com.docker-tc.enabled 配置该值=1时应用限速策略,其他值或者没有配置该 label 值将不应用限速策略。
  • com.docker-tc.down.rate 下行限速的基础速率,这个速率范围的的带宽不会拿来跟其他容器的限速共享,但是当某个接口上所有限速策略的技术速率总和超过接口的总速率时,无法保证容器能够达到这个速率。速率单位参考 tc 速率单位如下:
    • 以bit为单位:bit, kbit, mbit, gbit, tbit
    • 以btye为单位: bps, kbps, mbps, gbps, tbps
  • com.docker-tc.down.ceil 下行限速的最高速率。
  • com.docker-tc.up.rate 上行限速的基础速率,这个速率范围的的带宽不会拿来跟其他容器的限速共享,但是当某个接口上所有限速策略的技术速率总和超过接口的总速率时,无法保证容器能够达到这个速率。
  • com.docker-tc.up.ceil 上行限速的最高速率。
  • com.docker-tc.up.cgroup cgroup id,用于关联限速策略
  • com.docker-tc.biz 该容器的业务id,暴露流量采集 metric 时会用到该标签

3.3 测试

3.3.1 启动一个限速的容器

docker run -it --name xxxx \
  --label "com.docker-tc.enabled=1" \
  --label "com.docker-tc.cgroup=65552" \
  --label "com.docker-tc.down.rate=2mbps" \
  --label "com.docker-tc.down.ceil=10mbps" \
  --label "com.docker-tc.up.rate=20mbps" \
  --label "com.docker-tc.up.ceil=30mbps" \
  --label "com.docker-tc.biz=test" \
  nettool-centos7 bash

3.3.2 速率测试

docker exec 进入容器使用 wgetiperf 测试一下限速策略是否生效。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值