Implementing Quality of Service

Not all network traffic is created equal nor are all services equally important. There are times when a network requires certain services to be treated with more urgency than others. Perhaps in a server environment, your web servers receive a high level of traffic from visitors and must prioritize MySQL, or perhaps your office uses VoIP (short for Voice over IP) and needs priority placed on the phone system. There are many reasons why your network may require a service to be treated with more urgency than others. Quality of Service (QoS) helps us achieve this.

While there are multiple ways of tweaking network adapters for QoS, the most typical is something known as queuing discipline (or more simply, qdisc). A queuing discipline is something an administrator can apply to a network adapter to use one of a multiple of schedulers, each with varying effects on how traffic is handled. To see which scheduler your network adapter is currently using, run the following command:

ip link list

Look for your default network card, which will likely either be eth0 (in Debian) or eno1 (in CentOS) or similar.

Implementing Quality of Service

Viewing the output of IP link list in Debian

Most likely, you'll see qdisc pfifo_fast in the output, which tells us that the queuing discipline currently in use is pfifo_fast. This is basically a first-come first-serve scheduler (first in, first out). But rather than contain a single band, pfifo_fast it contains three—each separating traffic into three priorities. The first band (band 0) contains the highest priority traffic. Each band is handled only after the previous one has been serviced. Unless your distribution has changed the default scheduler, pfifo_fast, is most likely what is currently in use on your system out of the box.

The pfifo_fast scheduler is known as a classless scheduler. In other words, what you see is what you get—there is no configuration to be done when it comes to how classless schedulers filter traffic. Other classless disciplines include Stochastic Fair Queuing (SFQ), Extended Stochastic Fair Queuing (ESFQ), and Token Bucket Filter (TBF).

The SFQ qdisc uses the concept of FIFO as we've mentioned before, but separates network traffic into more than one FIFO, handled in a round-robin fashion. This qdisc tries to be as fair as possible, using flows to schedule packet transmission. This gives each flow a turn to transmit, preventing any one of them from becoming saturated. ESFQ is very similar, but it gives the administrator more options in which to configure. Unlike SFQ, TBF does not actually manipulate packets nor does it do any scheduling. The main purpose of TBF is to set a rate at which transmission will occur, allowing you to set parameters, such as the rate, burst, peakrate, and more. For more in-depth information, on these qdiscs, see the main pages for sfq and tbf. Setting the preferred qdisc on a network adapter is done via the tc command. See the following example for setting sfq on Ethernet adapter eno1:

# tc qdisc add dev eno1 root sfq perturb 60

Here, we're calling the tc command with qdisc and clarifying that we would like to add (we can also del) a qdisc. We're going to execute this against interface eno1, and we're requesting this change to egress (root) while targeting the sfq qdisc for our interface. Finally, we're setting our qdisc specific parameters (in this case, pertub). The perturb parameter allows us to set the seconds in which the hashing algorithm for this qdisc will be reset. There are other sfq-specific values we can alter, such as the number of flows used, quantum, redflowlimit, and more. See man sfq for complete descriptions of the parameters that can be used with sfq or tbf.

Where the concept of classless qdiscs falls short is the fact that they don't allow you to classify traffic as granularly as one might like. While it is certainly useful to change how packets are scheduled, that concept doesn't allow you to pick and choose which type of traffic receives priority at any given time. Classful qdiscs solves this issue, and gives the administrator much more flexibility. With these, you're able to set parents and children, each with different rules. In fact, that is the primary difference between classful and classless qdiscs. It's not the case that classless qdiscs aren't configurable at all; they just don't have the options to support the flexibility of advanced use cases. Next, we'll explore the classful qdiscs and how they allow us this added flexibility.

By utilizing the power of classful qdiscs, you gain almost total control over how packets are handled on your network. I said almost because it's important to remember that the idea of queuing discipline affects only outbound traffic (egress) while little can be done to manage incoming traffic. However, on a production network, guaranteeing particular services a certain amount of bandwidth can be very beneficial. As we've discussed in the previous section, classless qdiscs allow us to manage the general way in which packets are handled, but classful qdiscs allow us more control by setting classes as well as filters.

A possible scenario you may run into is VoIP traffic becoming unstable, causing calls to sound fuzzy or drop altogether. In this case, you may want to guarantee more bandwidth to your VoIP server, even if that means sacrificing traffic from another source. In addition, SSH is also important on a Linux network. If your server is too inundated with packets to even respond to a request to connect to it via SSH, that could be a very bad problem since you wouldn't be able to log in and correct any issues that may come up. These are very real scenarios many face without prioritizing traffic. If there is a service your network or company depends on, it's a good measure to prioritize it.

The most popular qdisc to achieve this is Hierarchical Token Bucket (HTB), which is a classful qdisc. HTB allows you to control the egress bandwidth used on a device, and it is based on the TBF style we discussed earlier. HBT features a number of classes that can be used to control traffic, such as setting the parent, priority, rate, ceil, and the number of burst bytes. See man htb to view a complete list.

Just as we did with configuring a classless qdisc, the setting of a classful qdisc like HTB is also done via the tc command. On most systems, this command is stored in /sbin and is likely not to be in a regular user's path. Type which tc to locate where this binary is on your distribution. In most cases, your system should recognize this command if run while logged in root. What follows is an example of the process of setting up HTB as the qdisc for a network device named eth0.

# tc qdisc add dev eth0 root handle 1: htb default 10
# tc class add dev eth0 parent 1: classid 1:1 htb rate 2mbit
# tc class add dev eth0 parent 1:1 classid 1:10 htb rate 1mbit ceil 1.5mbit
# tc class add dev eth0 parent 1:1 classid 1:20 htb rate 100kbps ceil 100kbps

In the first command, we're changing the qdisc from the default pfifo_fast to htb. In this command, root pertains to the fact we're setting this against egress traffic. The handle of 1: is a name for this particular instance of htb. Setting a default of 10 means that any traffic that is not specifically classed elsewhere will be given a class ID of 1:10. With the second command, we're creating class ID 1:1 and adjusting it to use a rate of 2mbit. In the third, we're doing the same, except we're creating an ID of 1:10 with a ceiling, which will limit this class to 1.5mbit. Because we set the default as 10, this is the class that will be used if we don't specifically target traffic to use something else. Finally, I also threw in a third class, 1:20, which has a much lower limit of 100kbps. With both the rate and ceil values set to the same value, we can reasonably expect traffic under this class to consume 100kbps but also be limited to 100kbps. You can continue to add additional classes to the 1: parent using this method, as many as you need to split up your bandwidth accordingly.

Now that we have our classes identified, we should put them to use. With our previous example, you'll likely notice your bandwidth is now less than it was (assuming your bandwidth is above the 1.5mbit default that we set). But our other two classes are unused, so we can boost our limit our bandwidth for other services as we see fit. So, let's add a filter for SSH. Since SSH doesn't require a great deal of bandwidth, we can assign our 1:20 class to it. To do so, we'll again use the tc command:

# tc filter add dev eth0 parent 1: protocol ip prio 7 u32 match ip sport 22 0xfff classid 1:20

Note

It's possible to change the port that your server listens on for SSH connections, as we'll discuss in Chapter 9, Securing Your Network. If you changed your SSH port, adjust the tc command accordingly.

That leaves us with two classes, 1:1 and 1:10. We can assign filters to those as well, depending on which port we would like to classify for the traffic:

# tc filter add dev eth0 parent 1: u32 match ip sport 80 0xfff classid 1:1
# tc filter add dev eth0 parent 1: u32 match ip sport 5060 0xfff classid 1:10

Here, I used ports 80 and 5060 for HTTP and VoIP traffic, respectively. Your ports may differ, so feel free to adjust the command accordingly to fit the needs of your network. But in this hypothetical example, traffic on port 80 will be classified as 1:1 and granted a maximum rate of 2mbit (great for a web server), and traffic on port 5060 will be granted 1.5mbit.

In summary, classless qdiscs allow you to control the general consensus of how packets are managed on your system. Depending on your environment, you may find that changing to a classless qdisc increases performance. But the real benefit comes in the form of classful qdiscs, which allows you more granular control over how packets are handled, as well as the rates your server's resources are provided. Tuning network performance is a time-consuming task and requires trial and error to determine which values, classes, and filters will improve performance on your network.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset