2012년 7월 13일 금요일

여러개의 네트워크 인터페이스를 하나로! Bonding 하기

오늘은 bonding 기술에 대해서 다뤄보고자 한다. 이것은 여러개의 네트워크 인터페이스를 하나로 만들어 이더넷 카드 장애 또는 링크 Fail 에 대해 대비를 할 수 있다. 또한 로드발랜스를 구현할 수 있으며, 자연스럽게 Fault tolerance 를 보장해주어 고장 허용한계를 최소화 할 수도 있겠다.  스위치 장비 같은것에서 보면 "채널본딩", "트렁킹" 같은 기술들이 이와 이론적으로는 유사하다고 할 수 있다.

여기서는 리눅스를 기반으로 설정하는 방법을 다뤄볼 것이다. 대부분의 배포용 리눅스에는 이미 본딩 드라이버를 이용할 수 있다. 가장 쉽게 설치해 볼 수 있는 방법은 각 배포판에서 제공해주는 패키지 도구를 이용하면 된다. 데비안, 우분투의 경우는 apt-get 를 이용해 설치할 수 있다.


# apt-cache search ifenslave
ifenslave-2.6 - Attach and detach slave interfaces to a bonding device
# apt-get install ifenslave-2.6

설치가 되었으면, bonding 모듈이 올라가 있는 것을 확인할 수 있다.

# lsmod | grep bon
bonding                73991  0

Bonding 인터페이스 설정 


이제 사용할 준비는 되었으니 설정만 해 주면 된다. 수동으로 명령어를 통해 다음과 같은 형태로 잡아줄 수도 있으나,

# modprobe bonding
# ifconfig bond0 192.168.0.1 netmask 255.255.0.0
# ifenslave bond0 eth0 eth1

아래와 같은 방법을 통해 설정파일에 내용을 기록해 두고 사용하는 편이 훨씬 수월하다. bond0 라는 이름이 이제 우리가 설정할 bonding 인터페이스이다.



# cat /etc/network/interface
auto bond0
iface bond0 inet static
 address 192.168.0.1
 netmask 255.255.255.0
 gateway 192.168.0.254
 bond_mode balance-tlb
 bond_miimon 100
 bond_downdelay 200
 bond_updelay 200
 slaves eth0 eth1


위 내용중에서 아래 5라인 정도가 실제 bonding 과 관련된 내용이다. 인터페이스 bond0 에 192.168.0.1 IP 를 설정하고 동작모드로 balance-tlb 를 설정하였다. 이 모드는 Active slave 모드로 슬레이브로 설정된 인터페이스에서 들어오는 트래픽을 받는다.
bond-miimon 은 링크 모니터링 주기를 설정하는 것으로 100 밀리세컨드로 지정하였다.
bond-downdelay 는 링크 Fail 이 감지된 후 Slave 를 중지시키기전 대기할 시간을 정의한 것이다. bond-updelay 는 downdelay 와 반대로 링크가 복구된 후 slave 를 재 동작하기까지 대기할 시간이다.  그리고 마지막으로 slaves 를 통해 실제 본딩에 사용될 인터페이스 eth0 과 eth1 을 지정했다.

커널상에서는 가상의 bond0 를 통해 통신되며 실제 모든 통신은 slave 를 통해서 이뤄진다는 점이다.

bond-mode 는 다양하게 존재하는데 몇 가지를 알아보면 다음과 같다.

  •  balance-rr 
전달되는 패킷에 대해 sequential 하게 라운드로빈 형태로 동작하게 된다. 설정된 인터페이스로 나눠 전달되므로 로드 발랜싱 역할을 하게 된다.
  • active-backup
본딩 인터페이스중 오직 한개 슬레이브만 엑티브로 동작한다. Active 로 동작하는 슬레이브가 Fail 되면 다른 슬레이브가 대체하게 된다. Fault Tolerance 형태로 보면 된다.
  • balance-xor
선택된 해쉬 정책에 따라 트래픽이 전달된다. (기본 정책은 출발지 맥 주소와 목적지 맥 주소를 XOR 한다)

  • broadcast

모든 슬레이브 인터페이스로 전송한다

  •  balance-tlb

적절하게 로드 발랜싱 역할을 수행한다. Outbound 트래픽은 각 슬래이브의 로드를 고려해 분산되며, Incoming 트래픽은 현재 설정된 슬레이브로 받게 된다. 만약 트래픽을 받고 있는 슬레이브가 Fail 되면 다른 슬레이브가 MAC 주소를 이어받아 계속 트래픽을 전달 받을 수 있다.

  • balance-alb

적절하게 로드 발랜싱 역할을 수행한다는 측면에서 balance-tlb 와 같다. 그런데 여기에 추가로 트래픽을 받는 부분에 있어서도 로드발랜싱을 수행한다. 이것은 ARP negotiation 을 통해서 동작하게 된다.


Bonding 이 잘 동작하고 있는지의 확인은 ?



내가 설정한 Bonding 이 잘 동작하고 있는지 확인하려면 간단하게는 /proc/net/bonding/bond0 를 살펴보면 된다. 그러면 현재 설정된 정보를 볼 수 있는데, Bonding mode 는 transmit load balancing 으로 되어 있고 Up Delay 나 Down Delay 등이 위 설정파일에 설정한 것과 동일하게 정의되어 있다.


# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008)


Bonding Mode: transmit load balancing
Primary Slave: None
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200


Slave Interface: eth0
MII Status: up
Link Failure Count: 1
Permanent HW addr: 84:XX:XX:XX:10:1c


Slave Interface: eth1
MII Status: up
Link Failure Count: 1
Permanent HW addr: 84:XX:XX:XX:10:1e

또는 ifconfig 를 통해 설정한 bonding 인터페이스인 bond0 가 있는지 확인해 볼 수도 있다.


bond0     Link encap:Ethernet  HWaddr 84:XX:XX:XX:10:1c
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::862b:2bff:fefa:101c/64 Scope:Link
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:64861 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2542 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:4984737 (4.7 MiB)  TX bytes:176928 (172.7 KiB)

eth0      Link encap:Ethernet  HWaddr 84:XX:XX:XX:10:1c
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:32694 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1278 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2510260 (2.3 MiB)  TX bytes:90488 (88.3 KiB)
          Interrupt:36 Memory:d6000000-d6012800

eth1      Link encap:Ethernet  HWaddr 84:XX:XX:XX:10:1e
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:32167 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1264 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2474477 (2.3 MiB)  TX bytes:86440 (84.4 KiB)
          Interrupt:48 Memory:d8000000-d8012800


여기 인터페이스 정보를 보면 우선 설정한 bond0 가 보이고 그 아래 eth0, eth1 은 RUNNING SLAVE 로 동작하는 것이 보인다. eth0 은 맥 뒷자리가 10:1c 이고 eth1 은 10:1e 이다. bond0 를 보면 10:1c 로 되어 있다. 즉 현 시점에서 Active Slave 는 eth0 이 되는 것이다.

만약 eth0 인터페이스의 링크가 Fail 되면 eth1 이 맥 주소를 넘겨받아 10:1e 가 아닌 10:1c 상태가 되어 버린다. 이것은 bonding 을 구성후 랜 케이블을 뽑아보면 쉽게 살펴볼 수 있다.

링크 Fail 을 감지한다면?


링크 Fail 을 감지하면 앞서 설명한 것과 맥 주소를 넘겨받는 다고 하였는데, 이런 동작 과정이 /var/log/message 에 상세히 기록되어 있다.


Jul  6 00:18:36 test kernel: [    4.227038] bonding: bond0: Setting down delay to 200.
Jul  6 00:18:36 test kernel: [    4.233007] bonding: bond0: doing slave updates when interface is down.
Jul  6 00:18:36 test kernel: [    4.233012] bonding: bond0: Adding slave eth0.
Jul  6 00:18:36 test kernel: [    4.233014] bonding bond0: master_dev is not up in bond_enslave
Jul  6 00:18:36 test kernel: [    4.335328] bnx2: eth0: using MSIX
Jul  6 00:18:36 test kernel: [    4.337600] bonding: bond0: enslaving eth0 as an active interface with a down link.
Jul  6 00:18:36 test kernel: [    4.380870] bonding: bond0: doing slave updates when interface is down.
Jul  6 00:18:36 test kernel: [    4.380875] bonding: bond0: Adding slave eth1.
Jul  6 00:18:36 test kernel: [    4.380878] bonding bond0: master_dev is not up in bond_enslave
Jul  6 00:18:36 test kernel: [    4.463151] bnx2: eth1: using MSIX
Jul  6 00:18:36 test kernel: [    4.465304] bonding: bond0: enslaving eth1 as an active interface with a down link.
Jul  6 00:18:36 test kernel: [    4.470976] ADDRCONF(NETDEV_UP): bond0: link is not ready
Jul  6 00:18:38 test kernel: [    7.540376] bnx2: eth0 NIC Copper Link is Up, 1000 Mbps full duplex
Jul  6 00:18:38 test kernel: [    7.560033] bonding: bond0: link status up for interface eth0, enabling it in 0 ms.
Jul  6 00:18:38 test kernel: [    7.560037] bonding: bond0: link status definitely up for interface eth0.
Jul  6 00:18:38 test kernel: [    7.560041] bonding: bond0: making interface eth0 the new active one.
Jul  6 00:18:38 test kernel: [    7.560065] bonding: bond0: first active interface up!
Jul  6 00:18:38 test kernel: [    7.562122] ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
Jul  6 00:18:39 test kernel: [    7.668144] bnx2: eth1 NIC Copper Link is Up, 1000 Mbps full duplex
Jul  6 00:18:39 test kernel: [    7.759691] bonding: bond0: link status up for interface eth1, enabling it in 200 ms.
Jul  6 00:18:39 test kernel: [    7.959351] bonding: bond0: link status definitely up for interface eth1.


위 로그를 보면 알 수 있듯이 eth0 링크가 문제 생기면서 eth1 으로 slave 가 변경되는 과정을 알 수 있다.

Bonding 구성을 완료후에는, 정상적으로 잘 동작하는지 랜 케이블 선을 제거해 보는 것과 같이 테스트 과정을 거치는 것이 필요하다. 최근의 서버급 장비들은 하나의 랜 카드에 4개의 이더넷 포트가 달려 있는 경우도 많이 있다. 시스템의 사용용도에 따라 이와 같이 설정해 사용해 보는 것은 어떨까 한다.

실제로 사용해 보면 아주 간단하고도 쉽게 구성할 수가 있다.

[참고]
1. 리눅스 파운데이션 : bonding
http://www.linuxfoundation.org/collaborate/workgroups/networking/bonding

댓글 2개:

  1. 이렇게 하면 보안이나 관리또한 편하겠네요 :) ㅎㅎ

    또 하나 배워갑니다 ㅋ

    답글삭제
    답글
    1. 오랜만이시네요. ㅋㅋ 여유 인터페이스 있으시면 본딩이 효율적일 수 있습니다.물론 환경에 따라 다르지만요.

      삭제