L4 로드벨런서는 공인 IP가 하나 뿐이고, 추가 증설 이후 여러 IP를 가질 수 없는 경우에 필요한 장비입니다. 예를들면 어떤 앱이나 임베디드 서비스 엔드포인트 등에 IP가 하드코딩된 경우에 정말 유효한 방법이죠. 하드코딩되지 않았더라도, DNS에 등록된 호스트 테이블을 전부 참조하지 않고 한개만 잡아서 고정 서비스 되도록 개발되었다면 L4 로드벨런싱은 정말 강력한 유효타를 날릴 수 있습니다. (웹 서비스만 운영하는 경우는 DNS만을 이용해서 로드밸런싱을 할 수 있기 때문에 L4 로드벨런서가 그다지 필요성이 없습니다)
리눅스에서 iptables의 NAT 기능 만을 이용해서 로드벨런서를 만들 수가 있습니다. 리눅스로 로드벨런서를 만들게 되면, 전용 장비(Dedicated Device) 보다 훨씬 싼 비용으로 구축할 수 있을 겁니다. HP에서 만든 L4 Switch가 약 3천 파운드 정도 하네요. 원화로 약 4백 만원정도의 가격입니다. 좀 많이 비싸죠... 저가형 서버가 약 70만원 정도 하는 데, 이들 서버는 적어도 여유 포트 1개 이상을 가지고 있습니다.
"약 70만원"에 걸린 링크를 따라가보면 이 모델은 이더넷 포트가 2개인데 한쪽에 L2 허브나 스위치를 달아서 로드 벨런서를 구축하게 되면 70만원 + 1만 8천원 정도(이건 너무 저가형인가;;)로 떡을 치고도 남습니다. 자, 그러면 오픈소스 L4 로드벨런서를 만들어 보도록 하죠. (심지어 70만원이 들어갈 자리를 PC급 장비로 대체하고 PCI 이더넷 카드 몇장 달면 40만원 선에서 로드 밸런싱 셋팅이 마무리가 되기까지 합니다)
일단 기본적인 환경은 이렇게 될겁니다. 데비안 최소 환경은 당연히 Debian 그 자체랑 iptables 등 진짜 필수적인 것들만 셋팅된 상태(https://www.debian.org/CD/netinst/ <- 이걸로 기반 OS랑 네트워크 드라이버, apt만 설치하시면 됩니다)인 서버 장비(PC급 서버도 가능)를 의미합니다. 여기에다가 nat 설정만 돌려주고, TCP 트래픽 포워딩만 해주면 로드밸런서가 되지요. 당연하게도 서버 장비에다가 아이피를 먹여주시거나 DHCP를 돌리시거나...
jaehoon@jaehoon ~ $ sudo sysctl -w net.ipv4.ip_forward=1
jaehoon@jaehoon ~ $ sudo iptables -t nat -F
이렇게 실행하게 되면 그 리눅스 머신이 ip forwarding을 할 수 있게 됩니다. 이놈이 기본적으로 0 (disabled)가 되어 있는 이유는, RHEL 메뉴얼에 따르면, 그 시스템이 edge 라우터로 동작하는 것을 방지하기 위한 보안 정책(링크는 MIT 대학교에서 공개중인 가이드북)입니다.
그런데 sysctl로 활성화시킨 설정은 리부팅하면 초기화되어 버리기 때문에, rc.local이나 inittab, rcS 등 run level 스크립트에다가 집어 넣어주거나 셋팅 자체를 수정(어디서 했었는지 까먹음 =ㅅ= 죄송합니다...)하셔야 합니다. sysctl 명령이 여의치 않은 환경(특히 임베디드 리눅스나 가정용 공유기 자체에 포팅되어 들어가는 리눅스의 경우)에서는 아래처럼 셋팅합니다.
echo "1" > /proc/sys/net/ipv4/ip_forward
이것도 리부팅되면 다시 비활성화 상태로 변하기 때문에 이걸 초기화 스크립트에다가 넣어줘야 합니다. 그리고 네트워크 인터페이스가 리셋이 잦은 경우에는 이것도 만약을 대비해서 리셋될 때 수행될 수 있도록 만들어줘야 합니다.
sudo iptables -t nat -A PREROUTING -p tcp -i enp1s0 -m state --state NEW -m statistic \
--dport 80 --mode nth --every 2 --packet 0 -j DNAT --to-destination 192.168.0.2:80
sudo iptables -t nat -A PREROUTING -p tcp -i enp1s0 -m state --state NEW -m statistic \
--dport 80 --mode nth --every 2 --packet 1 -j DNAT --to-destination 192.168.0.3:80
이렇게 때려주기만 하면 라운드 로빈(돌아가면서 - 가중치나 그런 요소 없이) 형태의 로드밸런싱이 이뤄지게 됩니다. (every 옵션은 분산시켜줄 서버 댓수, packet 옵션은 몇번째 서버인지를 적으면 됩니다) 이걸 랜덤 파이어(아무렇게나 난사하는... 방식)으로 설정하는 것도 가능한데, 위에서 mode옵션에 random을 주고, packet옵션을 제거하신 후에 바로 뒤에다가 --probability .[ratio]로 주면 되는 것이죠. 아래처럼... (인터페이스 옵션에 들어간 인터페이스는 각자 환경에 맞게 바꾸시면 됩니다. 저는 포트 하나에다가 저가형 스위치 하나 물린다는 가정하에 저렇게 짜놓은 거에요)
sudo iptables -t nat -A PREROUTING -p tcp -i enp1s0 -m state --state NEW -m statistic \
--dport 80 --mode random --probability .50 -j DNAT --to-destination 192.168.0.2:80
sudo iptables -t nat -A PREROUTING -p tcp -i enp1s0 -m state --state NEW -m statistic \
--dport 80 --mode random --probability .50 -j DNAT --to-destination 192.168.0.3:80
이렇게 하면 랜덤 파이어, 임의 분산이 되는 거죠. 뭐, 여기다가 .50을 원하는 비율로 바꿔주면 분산율이 어느정도 조정이 되기는 합니다. 이렇게 구성하신 후에 이 룰들보다 더 앞에다가 방화벽을 구성하는 룰을 집어넣으면 로드 밸런서 겸 방화벽 장비가 되는 것이죠.
그리고 TP-Link WDR 모델중에 OpenWRT를 돌릴 수 있는 모델이 있는데 거기다가 로드벨런싱 셋팅해서 써도 정말 괜찮을 듯 한데, 그런 장비들은 iptables가 리셋되는 경우가 한번씩 있고, 그 상황에서 반복적으로 실행되는 스크립트가 있어요.
여기에다가 위 스크립트들을 독립적인 쉘 스크립트로 만들어서, rc.local이나 inittab, rcS 등 run level 스크립트에다가 그걸 실행하는 코드 넣고, iptables가 리셋되는 경우에 실행되는 스크립트에도 그걸 실행하는 코드를 넣어주면 완벽하게 동작할겁니다.
이렇게 오픈소스 솔루션으로 장비 구매 비용을 줄여서 임금을 늘려주는 사장님들이 많아졌으면 좋겠다는게 개인적인 바램입니다. ^^ 헣. 이걸 작게 자동화시켜주는 쉘 스크립트 뭉치를 한번 준비해 보겠습니다.
2017. 07. 22 --- L4 Load Ballancer 쉘 스크립트 뭉치를 준비했습니다.
구조는 아래와 같습니다.
psh 파일은 뭐냐구요? 예, 그거 php cli script 인데, php 코드를 shell script 형태로 사용하는 방식입니다. 쉘 스크립트 만으로 처리하기에는 제가 좀 딸려서 그냥 편하게 php로 밀었습니다.
1. addhost.psh : 로드 밸런싱을 당할 서버를 추가합니다.
2. delhost.psh : 로드 밸런싱을 당하던 서버를 제거합니다.
3. restartall.psh : iptables의 nat 테이블에 등록된 l4lb 데이터들을 전부 제거하고 새로 등록합니다.
4. startall.psh : iptables에 등록되지 않은 호스트를 전부 등록합니다.
5. stopall.psh : iptables에 등록된 모든 호스트를 전부 제거합니다.
6. startspec.psh : 특정 호스트만 iptables에 등록합니다.
7. stopspec.psh : 특정 호스트만 iptables에서 내립니다.
8. setifname.psh : 외부와 연결될 인터페이스를 선택합니다.
9. updstat.psh : 현재 iptables에 등록된 상태를 확인한 후 돌고있는지 아닌지를 확인합니다.
이렇게 9가지 유틸리티로 이뤄져 있습니다. 뭔가 정말 조잡한 스크립트이지만, 이런식으로 만들 수도 있다는 것을 보여드리기 위한 샘플이므로 양해를 부탁드립니다 ^^
이렇게 호스트 12개를 등록하고, startall.psh를 실행하면
이렇게 뜨고, iptables -t nat -L을 실행하면,
이렇게 됩니다. 다시 stopall.psh를 실행하면,
이렇게 됩니다. 결국에 이 스크립트 뭉치는 서비스 라기 보다는 iptables로 로드밸런싱을 쉽게 설정하고, 호스트를 관리하기 위한 도구 정도라고 생각해주시면 감사하겠습니다. ^^
잘 활용하시길 바랄게요.
'Anything' 카테고리의 다른 글
리눅스에 안드로이드 개발 환경 구축하기 (0) | 2017.07.22 |
---|---|
GTK 3와 Webkit2.0로 리눅스 웹앱 만들기! (0) | 2017.07.22 |
ufw + gufw 방화벽으로 조금 더 안전하게 (2) | 2017.07.21 |
휴대폰으로 찍은 사진을 편하게 옮기는 방법? vsftpd 돌리기 for Linux (0) | 2017.07.21 |
LightDM <-> MDM 전환하기 for Linux Mint (0) | 2017.07.20 |