使用 tcng 和 HTB 进行流量控制 HOWTO

版本 1.0.1

Martin A. Brown

2006 年 4 月

修订历史
修订版 1.0.12006-10-28修订者:MAB
更新联系信息
修订版 1.02003-04-16修订者:tab
初始版本,由 LDP 审核
修订版 0.52002-04-01修订者:MAB
提交到 tldp,使用 HOWTO 重命名/重定标题
修订版 0.42002-03-31修订者:MAB
新示例,Bucket 速成课程
修订版 0.32002-03-16修订者:MAB
来自 Jacob Teplitsky、raptor 和 Joshua Heling 的更正和注释
修订版 0.22002-03-15修订者:MAB
链接、清理、发布
修订版 0.12002-03-14修订者:MAB
初始修订

� 2006, Martin A. Brown

根据 GNU 自由文档许可证 1.1 版或自由软件基金会发布的任何更高版本的条款,允许复制、分发和/或修改本文档;没有任何不变部分,没有封面文本,没有封底文本。许可证副本位于 www.gnu.org/copyleft/fdl.html


目录
1. 简介
1.1. 什么是流量控制,它是如何工作的?
1.2. 什么是 htb?
1.3. 什么是 tcng
2. 要求
2.1. 内核要求
2.2. tc 要求
2.3. tcng 要求
3. 配置示例
3.1. 使用 tcng 仅对下载进行整形
3.2. 使用双速率三色计量器
4. 其他说明
5. 链接和进一步的文档

1. 简介

这是一个简短的教程,介绍如何将 tcng (流量控制下一代) 与 HTB (分层令牌桶) 结合使用,以便在 Linux 机器上执行流量整形。

本教程适用于具有以下条件的系统管理员:

Note

本文既不全面也不权威。作者征求积极和消极的反馈。 始终欢迎更正、补充和进一步的示例。


1.1. 什么是流量控制,它是如何工作的?

流量控制是指网络或网络设备中的整个数据包排队子系统。流量控制由几个不同的操作组成。分类是一种识别数据包并将它们放入单个流或类别的机制。策略是一种限制与特定分类匹配的流中的数据包或字节数量的机制。调度是决策过程,通过该过程对数据包进行排序和重新排序以进行传输。整形是通过延迟和传输数据包来产生均匀且可预测的流速的过程。

流量控制系统的这些许多特性可以以复杂的方式组合在一起,以为特定流(或应用程序)保留带宽,或限制特定流或应用程序可用的带宽量。

流量控制的关键概念之一是令牌的概念。策略或整形实现需要计算以什么速率传递了多少字节或数据包。每个数据包或字节(取决于实现)对应于一个令牌,并且策略或整形实现仅在其具有可用令牌时才传输或传递数据包。实现保持其令牌的常见隐喻容器是 Bucket。简而言之,Bucket 表示可以立即使用的令牌数量(Bucket 的大小)以及令牌补充的速率(Bucket 重新填充的速度)。

有关 linux 流量控制系统中的 Bucket 示例,请参见第 1.2 节

在 linux 下,流量控制在历史上一直是一项复杂的工作。 tc 命令行工具提供了一个接口,用于连接内核结构,这些内核结构执行整形、调度、策略和分类。但是,此命令的语法很神秘。 tcng 项目通过在强大的 tc 命令行工具之上分层一种语言,从而为人类提供了一种更加友好的界面。通过以 tcng 编写流量控制配置,它们变得易于维护,不那么神秘,并且重要的是也更具可移植性。


1.2. 什么是 htb?

分层令牌桶是由 Martin Devera 编写的一个有类别的 qdisc,它具有比 CBQ 更简单的一组配置参数。在作者的网站上以及在 Stef Coene 的网站上,都有大量关于 HTB 及其用途的文档。以下是 HTB 系统的简要概述。

从概念上讲,HTB 是以层次结构排列的任意数量的令牌桶(是的,你可能无需我说也能弄清楚)。让我们考虑最简单的情况。任何设备上的主要出口排队规则都称为rootqdisc。

rootqdisc 将包含一个类别(复杂情况可能会将多个类别附加到rootqdisc)。 此单个 HTB 类将使用两个参数设置,即rateceil。 对于顶级类,这些值应相同,并且将表示链路上的总可用带宽。

在 HTB 中,rate表示给定类别可用的保证带宽,并且ceil是 ceiling 的缩写,表示允许该类别消耗的最大带宽。 在rateceil之间使用的任何带宽都是从父类借用的,因此建议rateceil在顶级类中相同。

可以在此类下创建许多子类,每个子类都可以从父类分配一些可用带宽。 在这些子类中,rateceil参数值不必与建议的父类相同。 这使你可以为特定类别保留指定数量的带宽。 它还允许 HTB 计算可用带宽的分配比率与类别本身的比率。 这在下面的示例中应该更加明显。

分层令牌桶为 linux 流量控制系统实现了一个有类别的排队机制,并提供了rateceil允许用户控制特定流量类别的绝对带宽,并指示当额外带宽可用时带宽的分配比率(最多ceil).

在为顶级类选择带宽时,请记住,只有当你成为 LAN 和 Internet 之间的瓶颈时,流量整形才会有所帮助。 通常,这种情况发生在家庭和办公网络环境中,在这些环境中,整个 LAN 都由 DSL 或 T1 连接提供服务。

实际上,这意味着你应该将顶级类的带宽设置为可用带宽减去该带宽的一小部分。


1.3. 什么是 tcng

流量控制下一代 (tcng) 是 Werner Almesberger 的一个项目,旨在提供一种强大、抽象且统一的语言来描述流量控制结构。 tcng 发行版中的 tcc 解析器将 tcng 语言转换为多种输出格式。 默认情况下, tcc 将读取文件(指定为参数或 STDIN)并将创建内核中所需的流量控制结构所需的一系列 tc 命令(请参阅下面的 iproute2)打印到 STDOUT。

查阅 tcng 的参数参考以查看支持的排队规则。 Jacob Teplitsky, LARTC 邮件列表的活跃用户以及 tcng 项目的贡献者,为 tcng 编写了 htb 支持。

tcc 工具可以生成多种不同类型的输出,但是本文档仅考虑常规输出和默认输出。 有关使用 tcng 的更多详细信息,请查阅 TCNG 手册

tcsim 工具是一个流量控制模拟器,它接受 tcng 配置文件并读取一种控制语言,以模拟内核在发送和接收具有指定控制结构的数据包时的行为。 虽然 tcsimtcng 项目的重要组成部分,但本文将不涉及 tcsim


2. 要求

内核支持 HTB 和 DSMARKtc 支持 HTB 和 DSMARK 以及 tcng 本身,需要满足一些要求。

具体来说,绝对需要内核和 tc 中的 HTB 支持才能使本教程具有远程可用性(如果对此有任何疑问,请参考标题)。 严格来说,DSMARK 支持是可选的,尽管某些 示例(特别是类选择路径,但也许是其他示例)可能在没有 dsmark 支持的情况下无法运行。


2.1. 内核要求

内核要求很容易满足。 内核 2.4.20 和更高版本包含对 HTB 和 dsmark 的支持,因此只需确保在内核配置的 QoS/公平排队部分中启用了这些选项。 有关在内核配置中选择的选项的简要概述,请访问 DiffServ 项目内核配置说明

对于低于 2.4.20 的内核,应将以下 包含补丁的 tarball 应用于你的 2.4.17 或更高版本的内核树。


2.2. tc 要求

tc 命令是 iproute2 实用程序套件的一部分。 有关 iproute2 的常规文档,请参见 http://linux-ip.net/iproute2 手册。 该软件本身可直接从 Alexey Kuznetsov 的 FTP 存档获得,但通常也可以通过 linux 发行版提供的软件包获得。 如果你的发行版可以使用 RPMS,则可以下载此 SRPM 并在你自己的系统上编译它。

如果需要自己编译 iproute2 ,请使用 来自此 tarball 的 tc 补丁,网址为 Martin Devera 的 HTB 站点,以便在 tc 中提供对 HTB 的支持。

你的 tc 还需要支持 dsmark,即 diffserv 标记机制。 幸运的是,这是来自 iproute2 源代码包的Config文件的一个简单更改。 只需更改TC_CONFIG_DIFFSERV=nTC_CONFIG_DIFFSERV=y然后重新编译。

SRPM 创建了一个支持 dsmark 和 HTB 的 tc 二进制文件,这两个文件都是此示例所必需的。


2.3. tcng 要求

支持 tcng 是过程中最简单的部分。只需解压 tcng 源代码并运行./configure --no-tcsim然后再进行编译。

如果您使用的是基于 RPM 的系统,则可以使用以下文件中的 SPEC 文件tcng/build/tcng.spec为您的发行版构建,或者您可以下载并编译此 SRPM。该 SRPM 会生成两个软件包,tcc 和 tcc-devel。您只需要 tcc 即可创建配置。

为了运行 tcc 解析器,您还需要安装 cpp 包。tcc 使用 cpp。


3. 配置示例

此处显示的示例将是 此目录中可下载配置的修改版本。

这些示例可以用作独立的配置文件,馈入 tcc 解析器,或者可以与示例 SysV 启动脚本结合使用。该启动脚本是 raptor 在 LARTC 邮件列表中发布的脚本的修改版。

如果您要使用上面的启动脚本,请查看此示例/etc/sysconfig/tcng:

示例 1。/etc/sysconfig/tcng

# - tcng meta-configuration file
#   (I never meta-configuration file I didn't like)
#
# -- 2003-03-15 created; -MAB
# -- 2003-03-31 modified to allow ENVAR override; -MAB
#
# -- this directory will hold all of the tcng configurations
#    used on this host
#
TCCONFBASEDIR=${TCCONFBASEDIR:-/etc/sysconfig/tcng-configs}

# -- this is the active, desired tcng configuration
#    note, that, because tcng provides the #include construct,
#    the modularity of configuration can be built into the
#    configuration files in $TCCONFBASEDIR
#
TCCONF=${TCCONF:-$TCCONFBASEDIR/global.tcc}

tcstats=${tcstats:-no}   # -- will suppress statistical output
tcstats=${tcstats:-yes}  # -- will throw the "-s" option to tc

tcdebug=${tcdebug:-0}    # -- for typical startup script usage
tcdebug=${tcdebug:-1}    # -- for a bit of information about what's happening
tcdebug=${tcdebug:-2}    # -- for debugging information
#
#
# -- an additional measure to take, you can override the default tc and tcc
#    command line utilities by specifying their pathnames here, for example:
#
#  tc=/usr/local/bin/tc
#  tcc=/usr/local/tcng/bin/tcc
#
#
    

3.1. 使用 tcng 仅对下载进行整形

许多通用概念将在此示例中介绍。可以使用以下命令将此示例编译为 tc 输出tccclass-selection-path.tcc.

示例 2。/etc/sysconfig/tcng/class-selection-path.tcc

/*
 * Simply commented example of a tcng traffic control file.
 *
 *   Martin A. Brown 
 *
 * Example:  Using class selection path.
 *
 * (If you are reading the processed output in HTML, the callouts are
 *  clickable links to the description text.)
 *
 */

#include "fields.tc"     (1)
#include "ports.tc"

#define INTERFACE  eth0  (2)

dev INTERFACE {
    egress { (3)

        /* In class selection path, the filters come first!  DSmark */ (4)

        class ( <$ssh> )    if tcp_sport ==  22 && ip_tos_delay == 1 ;
        class ( <$audio> )  if tcp_sport == 554 || tcp_dport == 7070 ;
        class ( <$bulk> ) \
            if tcp_sport == PORT_SSH || tcp_dport == PORT_HTTP ; (5)
        class ( <$other> )  if 1 ; (6)

        /* section in which we configure the qdiscs and classes */ 

        htb () { (7)
            class ( rate 600kbps, ceil 600kbps ) { (8)
                $ssh   = class ( rate  64kbps, ceil 128kbps ) { sfq; } ; 
              (9) $audio = class ( rate 128kbps, ceil 128kbps ) { sfq; } ;
                $bulk  = class ( rate 256kbps, ceil 512kbps ) { sfq; } ;
                $other = class ( rate 128kbps, ceil 384kbps ) { sfq; } ; (10)
            }
        }
    }
}
      
(1)
tcng 语言提供对 C 风格 include 指令的支持,该指令可以包含任何文件。文件包含相对于当前目录或 tcng 库(通常是/usr/lib/tcng/include)。严格来说,没有必要#include ports.tcfields.tc,因为 tcc 默认会包含这些文件。

使用#include可以灵活地定义变量和包含常见的流量控制元素。

另请参阅 tcng 手册 关于包含

(2)
这些是 CPP 指令。#define可用于创建宏或常量。有关其使用的更多信息,您应该参阅 tcng 手册 关于变量
(3)
egress关键字与dsmark关键字同义。此处的示例使用 类选择路径。正是由于配置中使用了egress关键字,才需要在内核和 tc 中支持 dsmark。
(4)
类选择路径是流量整形的一种方法。在类选择路径中,数据包在进入路由器时会被标记(DiffServ 标记)。路由器可以采取任意数量的操作或应用任意数量的策略、调度或整形操作,这都取决于初始分类的结果。

有关更多详细信息,请参阅 tcng 手册 关于类选择路径

(5)
此示例显示了如何使用端口名称而不是数字。这是 tcng 提供的一个便利,这是由于自动包含了ports.tc。端口名称根据 IANA 端口名称命名。有关这些名称,请参阅 IANA 的注册端口或检查文件ports.tc.

名称和数字同样可以接受且有效。

(6)
请注意这种特殊的结构,它会对尚未分类的任何数据包进行分类。任何未被上述分类器分类的数据包都会被放入此处的 "$other" 类中。if 1结构可用于对剩余的未分类流量进行分类。
(7)
这是根 qdisc 的创建,它附加到设备eth0在这种情况下。有关每个 qdisc 的有效参数,请参阅 tcng 关于排队规则参数的附录中的参考资料。任何 qdisc 参数都可以以与示例中进一步下方的类参数相同的方式插入到括号中。如果不需要指定任何参数,则括号是可选的。
(8)
此示例中的顶级类设置允许通过此类的最大带宽。假设eth0是机器的内部网络接口。这会将传输到内部网络的总带宽限制为每秒 600 千比特。

参数rateceil对于任何使用过 HTB 的人都应该很熟悉。这些是 HTB 特定的参数,并由 tcc 实用程序正确翻译。请参阅关于 tcng 速率和速度规范的表格。

(9)
这是将类分配给变量。这通常作为类选择路径的一部分完成。
(10)
正如 Martin Devera 在 HTB 主页上建议的那样,嵌入式 SFQ 为每个类提供公平的排队算法,用于将资源分配给通过该类传递数据包的竞争者。请注意嵌入式排队规则没有任何参数。

如果未为叶类指定排队规则,则它们包含默认的 pfifo_fast qdisc。在叶类中包含随机公平排队 qdisc 会抑制单个连接在给定类中占主导地位的能力。


3.2. 使用双速率三色计量器

示例 3。/etc/sysconfig/tcng/two-rate-three-color-meter.tcc

/*
 * Simply commented example of a tcng traffic control file.
 *
 *   Martin A. Brown 
 *
 * Example:  Using a meter.
 *
 * (If you are reading the processed output in HTML, the callouts are
 *  clickable links to the description text.)
 *
 */

#define   EXCEPTION      192.168.137.50
#define   INTERFACE      eth0

$meter = trTCM( cir 128kbps, cbs 10kB, pir 256kbps, pbs 10kB );  (1)

dev eth0 {
    egress {
        class ( <$full> )     if ip_src == EXCEPTION      ; (2)
        class ( <$fast> )     if trTCM_green( $meter )    ; (3)
        class ( <$slow> )     if trTCM_yellow( $meter )   ; (4)
        drop                  if trTCM_red( $meter )      ; (5)
        htb {
            class ( rate 600kbps, ceil 600kbps ) {
                $fast = class ( rate 256kbps, ceil 256kbps ) { sfq; } ;
                $slow = class ( rate 128kbps, ceil 128kbps ) { sfq; } ;
                $full = class ( rate 600kbps, ceil 600kbps ) { sfq; } ;
            }
        }
    }
}
      
(1)
这是声明用于对流量进行分类的计量器。用于实现此计量器的底层技术是策略。有关不同类型的计量器,请参阅 tcng 手册关于计量器

此计量器是双速率三色计量器,它是 tcng 语言中最复杂的计量器。该计量器根据承诺和峰值存储桶中提供的速率返回颜色绿色、黄色和红色。如果计量速率超过承诺速率,则此计量器将变为黄色,如果计量速率超过峰值速率,则此计量器将变为红色。

变量$meter可以由适用于计量器类型的功能进行操作。在这种情况下,有三个功能可用于测试$meter的状态,trTCM_green, trTCM_yellow,以及trTCM_red。为了提高效率,还可以考虑 加速的对应项

(2)
在此示例中,IP 192.168.137.50 专门排除在应用于从 eth0 离开的流量的策略控制之外。
(3)
高达承诺信息速率 (cir),数据包将通过此类。令牌将从cir/cbs存储桶中删除。

计量器为绿色。

(4)
超过cir/cbs存储桶的流量将在此处进行分类。pir/pbs存储桶(pir是峰值信息速率,pbs是峰值突发大小)。这允许特定流量保证一种服务等级,直到给定的速率,然后以高于该速率重新分类。

计量器为黄色。

(5)
超过pir/pbs存储桶的流量将在此处进行分类。常见的配置导致流量在高于峰值速率时被丢弃,尽管流量可以从保证的类重新分类为尽力而为的类。

计量器为红色。


4. 其他说明

值得庆幸的是,tcng 消除了 tc 的一个小的烦恼。下表将这些工具的语法和约定与英语等效项进行了映射。

表 1. 速度/速率语法:tcng vs. tc

tcng英语tc
bps每秒比特数bit
Bps每秒字节数bps (啊!)
kbps每秒千比特数kbit
kBps每秒千字节数kbps
Mbps每秒兆比特数mbit 或 Mbit
MBps每秒兆字节数mbps 或 Mbps
pps每秒数据包数??

请注意,这意味着长期使用 tc 的用户需要进行一些调整,但对于英语使用者来说,这是更直观的选择。

例如,我们可以在 tcng 配置中使用传统的速率表达式100Mbps, 128kbps,甚至2Gpps。另请参阅 tcng 手册 关于单位

为了使流量控制有效,了解瓶颈所在非常重要。在大多数情况下,您需要在瓶颈处或附近执行流量控制。


5. 链接和更多文档