### Written by Arang ###
1. 목적 : 리눅스의 Kernel에서 세션별 Bandwidth를 제어 가능하도록 한다.
2. 테스트환경
l Kernel : Linux 2.6.15-1.2054_FC5 (Fedora core 5)
l Package : iproute-2.6.15-1.2 (Fedora core 5의 경우 기본 포함)
3. 구현
3-1. 토큰 버킷 필터(TBF)
- 기본개념 : 설정된 전송률을 초과하는 패킷을 보내지 않도록 하는 큐구조이다. 그러나,
순간적으로 이 전송률을 초과하는 짧은 burst(패킷이 빨리 연속되는 경우)의 경우에는
패킷을 전달한다.
- 기본동작 : bucket(token으로 채워지는 바구니), token rate(토큰 발생률)
l 데이터가 TBF에 도착하는 속도 = 토큰 발생률 : 각각 도착하는 패킷은 토큰과
일치하여 지연없이 바로 큐로 통과된다.
l 데이터가 TBF에 도착하는 속도 < 토큰 발생률 : 패킷이 도착하는 것보다 토큰이
더 많이 생성되므로, 토큰은 bucket 크기 만큼 쌓이게 되고, 그후에는 데이터가
도착하는 것보다 더 빨리 만들어지는 토큰은 지워진다. bucket에 쌓인 토큰은
데이터가 연속으로 빨리 도착하는 burst의 경우에 사용된다.
l 데이터가 TBF에 도착하는 속도 > 토큰 발생률 : 이 경우 bucket에 쌓였던 토큰이
당분간 사용된다. 이것을 overlimit situation이라고 한다. 만약 계속 패킷이 빠르게
도착하면, 패킷 손실이 시작된다.
- 파라미터
l limit or latency
limit : 토큰이 사용가능하게 되기를 기다리는 바이트 수
latency : TBF 내에 패킷이 기다리는 최대 시간(bucket, token rate, peakrate 고려)
l burst /buffer /maxburst : bucket의 크기. 한번에 사용가능한 토큰의 최대 총 바이트 수
l mpu : 최소 패킷 크기
l rate : 속도
l peakrate : bucket을 비우는 속도 설정
- 실행 예제
à tc 명령어를 이용하여 eth0 디바이스에 TBF로 전체 bandwidth 설정
à 설정 삭제(원상태로 복귀)
<그림 1.1> Linux Server에서 FTP를 이용한 다운로드 속도(outgoing) 비교
<그림 1.1>의 경우 위의 행은 원래 상태에서의 속도이며, 아래의 행은 TBF로 bandwidth를
위 예제와 같이 설정한 후의 속도이다.
- 결론 : 여러 파라미터를 조절하여 bandwidth를 조절할 수 있다.
3-2. 확률적으로 공정한 큐잉(Stochastic Fairness Queuing)
- 기본개념 : 트래픽을 FIFO큐로 나누어서 FIFO큐 하나가 conversation 하나를 담당하게 한다. 트래픽은 한턴에 한번씩 전송될 기회를 얻는 라운드 로빈(round robin) 방식으로 보내진다.
SFQ는 해싱알고리즘을 사용하여 트래픽들을 제한된 수의 큐로 분류를 하는 알고리즘을
사용한다. 해쉬를 사용하기 때문에 여러 개의 세션들이 동일한 큐로 들어갈 수 있게한다.
각 세션의 패킷을 보내는 기회가 공정하게 나누어지므로, 결국 실제 속도도 나뉘어지게 된다.
- Outgoing 인터페이스가 실제로 full이 날 경우에 유효하며, 그렇지 않은 경우에는 패킷이
큐가 되지 않으므로 SFQ의 효과를 확인할 수는 없다.
- 파라미터
l perturb : hashing을 다시할 주기를 초단위로 설정
l quantum : 다음 큐로 넘어가기 전에 큐에서 꺼내는 바이트 수 (기본값: MTU 바이트 값)
l limit : SFQ에 의해 큐되는 패킷의 최대 개수. 이 수를 넘어갈 경우 패킷은 폐기된다.
- 실행 예제
à SFQ를 사용하여 perturb값을 10초로 설정à 설정 상태 확인. 기본적으로 set되는 limit, quantum 등을 확인할 수 있다.
- 결론
실제 동작 상태를 검증 해보기 위해서는 다른 추가적인 방법으로 shaping 이 필요하다.
3-3. PRIO qdisc
- 기본개념 : shaping 기능은 없고, class를 분류하고 우선순위에 따라 트래픽 처리
- 파라미터
l bands : band의 개수. class를 의미
l priomap : tc 필터로 우선순위를 지정하지 않을경우 TC_PRIO에 따라 트래픽 처리
- 실행예제 : 1행 : root 아래에 class 1:1, 1:2, 1:3을 만든다
2행 : class 1:1 에 우선순위 10으로 설정하고 SFQ 규칙을 적용한다.
3행 : class 1:2 에 우선순위 20으로 설정하고 TBF 규칙을 적용한다.
4행 : class 1:3 에 우선순위 30으로 설정하고 SFQ 규칙을 적용한다. <초기 설정 상태 확인>
우선순위가 높은 class 1:1을 이용하여 패킷이 지나가고 있는 것을 확인할 수 있다.
FTP를 이용하여 File download와 같은 대용량 트래픽을 발생시킬 경우, 우선순위가 낮은
class 1:3으로 보내진다.File download를 중지하고 interactive 트래픽을 발생시킬 경우, 우선순위가 낮은 class 1:3의
사용을 중지하고 우선순위가 높은 class를 사용하는 것을 알 수 있다.
3-4. CBQ(Class Based Queuing)를 이용하여 class별 트래픽 처리
- 간단한 구성 예제
: Webserver의 트래픽을 5Mbit로 SMTP의 트래픽을 3Mbit로 제한하고, 둘이 합쳐 6Mbit를
넘지 않도록 한다. 100Mbit NIC을 기준으로 구성 한 예이다.
step 1>class 1:1이 전체 bandwidth 6Mbit를 넘지 않도록 제한한다.
step 2>두 class 를 각각 5Mbit, 3Mbit로 제한한다. 전체 bandwidth는 제한하지 않았지만, 이 두
class는 class 1:1에 연결되므로 6Mbit를 넘지 못한다.
step 3>기본적으로 FIFO 규칙을 따르고 있는 두 class를 SFQ 규칙에 따라 트래픽을 공평하게
걸리게 한다.
step 4>각 class를 각 Source Port(sport)에 연결한다.
『위의 4단계에 따라 구성을 하게되면 webserver와 SMTP가 많은 트래픽을 발생할 경우webserver는 5/8 * 6mbit 즉, 3.75mbit의 bandwidth를 최소한으로 가지게 된다.』
- 파라미터
l avpkt : 패킷의 평균 크기를 byte 단위로 지정.
l bandwidth : 장치의 물리적인 대역폭 지정.
l cell : 패킷이 네트웍 장치로 전송되는데 걸리는 시간. 패킷의 크기에 따라 2의
멱승으로 증가하며 일반적으로 8을 사용한다.
l maxburst : maxidle 값을 계산하는데 사용할 패킷의 수 지정. 이 값을 크게
하면 burst 보다 잘 통과하게 된다.
l minburst : overlimit 상황에서 패킷을 차단할 때, minburst 만큼의 패킷을
통과시키고 minburst 배수의 시간만큼 다시 패킷을 차단한다.
l mpu : 패킷의 최소크기. CBQ가 idle time을 정확하게 계산하기 위해 필요.
l rate : qdisc 를 빠져나가는 트래픽의 rate 지정.
l allot : 각 class가 패킷을 보낼 기회를 가질 때, 제한된 데이터 크기만큼 보낸다. allot는 이 크기의 기본 단위이다.
l prio : 우선순위
l weight : class를 분류하고 각 class가 패킷을 보낼 기회를 가질 때, weight 값을
이용하여 특정 class 가 더 많은 패킷을 보낼 수 있도록 허락한다.
l isolated/ sharing : 고립/ 공유 à class에서 bandwidth를 공유할지 아니면
고립시킬지를 결정한다.
l bounded/ borrow : 제한 / 차용 결정.
3-5. cbq.init 스크립트 활용하기
step 1>
패키지 확인 : rpm 명령어로 iproute 패키지 설치시 생성되는 파일 및 경로를 확인한다.
‘/usr/share/doc/iproute-2.6.15/examples/cbq.init-v0.7.3’ 와 같이 스크립트 파일의 경로
를 확인할 수 있다.
step 2>
이 파일을 /etc/init.d/ 로 복사한 후 실행 퍼미션을 준다.
step 3>
/etc/sysconfig/cbq/ 디렉토리를 확인해보면 cbq-0000.example 파일이 있다.
cbq-0000.example를 copy하여 cbq-0100.ftptest 파일을 생성한다.
파일의 생성 규칙 : cbq-<classid>.<name>
파일은 cbq- 로 시작해야 하며 일반적으로 class id 와 임의의 name으로 결정한다.
step 4>
cbq-0100.ftptest 파일을 다음과 같이 설정한다.
l DEVICE=<ifname>,<bandwidth>,<weight>
<ifname> : 제어할 인터페이스의 이름
<bandwidth> : device의 물리적 bandwidth
<weight> : 가변 bandwidth. 일반적으로 <bandwidth> / 10 으로 할당.
l RATE=<speed> : 제어할 속도 지정
l WEIGHT=<speed> : RATE / 10
l PRIO=<1-8> default 5 : 숫자가 높을수록 우선순위가 낮다.
l RULE=[[saddr[/prefix]][:sport[/mask]],][daddr[/prefix]][:dport[/mask]]
: 소스/목적지 주소와 포트를 지정한다.
l MARK=<mark> : 10진수의 숫자로 지정하며, 업스트림에 필수적으로
사용한다.
ex> ipchains -I input -p tcp -s xxx.xxx.xxx.xxx/mask sport -d yyy.yyy.yyy.yyy/mask
dport -m marknumber
참고> ‘마스커레이딩’ 때문에 다운스트림과 달리 내부 네트워크의 사설주소가 공식IP로
번역되면서 어떤 패킷에 속도제한을 가해야 할지 모른다. 특정 패킷에 mark 를
해줌으로써 외부로 나가는 패킷 중 그 패킷만을 골라내 업스트림 속도제어를 할 수 있다
step 5>앞에서 만들어 놓은 cbq.init 스크립트를 실행한다.
warning 메시지가 나오지만 정상적으로 동작한다.
l start : 스크립트 실행
l stop : 스크립트 중지
l restart : 스크립트 재시작
l compile : 실행은 하지 않고, 설정파일대로 만들어낸 구문을 보여준다.
스크립트를 시작하고 다운스트림을 실행하면 아래행에서와 같이 속도의 변화를 확인할 수
있다.
- 설정파일에 대한 몇가지 사항
l 다수의 설정파일을 가질 수 있다.
l 하나의 설정파일에 여러가지 RULE을 적용할 수 있다.
RULE=10.1.1.0/24:80 : 네트워크 10.1.1.0 내 포트 80으로 가는 트래픽 선택
RULE=10.2.2.5 : 호스트 10.2.2.5상의 모든 포트로 가는 트래픽 선택
RULE=10.2.2.5:20/0xfffe : 호스트 10.2.2.5의 20,21포트로 가는 트래픽 선택.(ftp)
RULE=:25,10.2.2.128/26:5000 : 포트 25에서 네트워크 10.2.2.128 네트워크내 포트 5000으로
가는 트래픽을 선택
RULE=10.5.5.5:80, : 호스트 10.5.5.5의 포트 80에서 나가는 트래픽을 선택
< 주 의 >
Queueing은 데이터를 보내는 방법만을 정의 한다. 즉, 속도제어는 인터페이스에서 나가는
트래픽만 가능하다는 것이다. 그럼 Incomming 트래픽의 제어는 어떻게 할 수 있을까?
위 그림에서 처럼 두개의 NIC를 사용하여 제어할 수 있다. 즉, 업스트림은 eth0 를 사용하고
다운스트림은 eth1을 사용하면 된다. 두 경우 모두 인터페이스에서는 Outgoing의 트래픽만
제어를 하지만 리눅스 박스의 입장에서 보면 업/다운 스트림을 모두 제어한다.
cbq.init 스크립트의 내용을 확인해보면 이와 같은 설명들을 확인해 볼 수 있는데, 이렇게
두개의 NIC를 사용할 경우 설정파일의 setting 방법을 예시해 두었다.각각의 파일에 DEVICE=<ifname>을 다르게 설정하면 해당 인터페이스가 트래픽을 제어하게
된다.
4. 향후과제
- filter의 정확한 사용법에 대해 더 알아 보아야 한다.
- IP Address, Port 별 제어는 가능하나 사용자별 제어는 확인해 보지 못 하였다.
5. 참고자료
http://lartc.org/lartc.pdf
http://kldp.org/KoreanDoc/html/Kernel-KLDP/index.html