BIRD로 BGP 실행하기
BIRD로 BGP 실행하기 (deprecated) (Using BIRD to run BGP)
BIRD는 Unix 계열 운영체제에서 IP 패킷을 라우팅하는 오픈소스 구현이에요. 이 가이드는 전통적인 네트워킹 프로토콜로 경로를 광고해 Cilium이 관리하는 엔드포인트를 클러스터 밖에서 접근 가능하게 만드는 방법을, CentOS 7.x 기준으로 안내합니다.
본문
BIRD는 Unix 계열 운영체제에서 인터넷 프로토콜 패킷을 라우팅하는 오픈소스 구현입니다. 익숙하지 않다면 먼저 User's Guide를 한 번 훑어보는 것이 좋아요.
BIRD는 전통적인 네트워킹 프로토콜로 경로를 광고하는 방법을 제공해 Cilium이 관리하는 엔드포인트가 클러스터 밖에서 접근 가능하게 해 줍니다. 이 가이드는 Cilium이 이미 클러스터에 배포되어 있고, 남은 것은 pod CIDR 범위를 외부에서 라우팅 가능하게 만드는 방법이라고 가정해요.
BIRD는 현재 1.x 와 2.x 두 개의 릴리스 계열을 유지하고 있으며, 구성 형식이 둘 사이에 크게 다릅니다. 이미 1.x 를 배포하지 않았다면 2.x 를 바로 사용하는 것을 권장하는데, 2.x 가 더 오래 살아남을 것이기 때문이에요. 다음 예시는 bird 를 bird2 소프트웨어로 표기하고 bird2 가 이해하는 형식의 구성을 사용합니다.
이 가이드는 CentOS 7.x에서 bird를 설치하고 구성해 Cilium과 협력하도록 만드는 방법을 보여 줘요. 다른 플랫폼에서의 설치와 구성도 매우 유사할 것입니다.
bird 설치
$ yum install -y bird2
$ systemctl enable bird
$ systemctl restart bird
설치를 테스트해 보세요:
$ birdc show route
BIRD 2.0.6 ready.
$ birdc # interactive shell
BIRD 2.0.6 ready.
bird> show bfd sessions
There is no BFD protocol running
bird>
bird> show protocols all
Name Proto Table State Since Info
device1 Device --- up 10:53:40.147
direct1 Direct --- down 10:53:40.147
Channel ipv4
State: DOWN
Input filter: ACCEPT
Output filter: REJECT
...
기본 구성
특정 BGP 스킴을 고려하지 않고 bird 구성을 논의하기는 어렵습니다. 하지만 BGP 스킴 설계는 이 가이드의 범위를 벗어나요. 이 주제에 관심이 있다면 BGP in the Data Center (O'Reilly, 2017)를 참고해 빠르게 시작하세요.
아래에서는 BGP 시나리오를 다음과 같이 제한할게요:
- 물리 네트워크: 간단한 3계층 계층 구조
- 노드는 레이어 2 스위치를 통해 물리 네트워크에 연결
bird를 통해 각 노드의 PodCIDR을 물리 네트워크에 광고- 각 노드에 대해, 물리 네트워크에서의 경로 광고를 가져오지 않음
이 설계에서 BGP 연결은 다음과 같습니다:
- 코어 라우터는
bird에서 PodCIDR을 학습해 Pod IP 주소가 전체 네트워크에서 라우팅 가능해집니다. bird는 코어 라우터와 다른 노드에서 경로를 학습하지 않아, 각 노드의 커널 라우팅 테이블을 깨끗하고 작게 유지하며 성능 문제가 없습니다.
이 스킴에서 각 노드는 pod egress 트래픽을 노드의 기본 게이트웨이(코어 라우터)로 보내고, 라우팅은 후자가 담당하게 해요.
위 목적을 달성하기 위한 참조 구성은 다음과 같습니다:
$ cat /etc/bird.conf
log syslog all;
router id {{ NODE_IP }};
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
# Disable automatically generating direct routes to all network interfaces.
protocol direct {
disabled; # Disable by default
}
# Forbid synchronizing BIRD routing tables with the OS kernel.
protocol kernel {
ipv4 { # Connect protocol to IPv4 table by channel
import none; # Import to table, default is import all
export none; # Export to protocol. default is export none
};
}
# Static IPv4 routes.
protocol static {
ipv4;
route {{ POD_CIDR }} via "cilium_host";
}
# BGP peers
protocol bgp uplink0 {
description "BGP uplink 0";
local {{ NODE_IP }} as {{ NODE_ASN }};
neighbor {{ NEIGHBOR_0_IP }} as {{ NEIGHBOR_0_ASN }};
password {{ NEIGHBOR_PWD }};
ipv4 {
import filter {reject;};
export filter {accept;};
};
}
protocol bgp uplink1 {
description "BGP uplink 1";
local {{ NODE_IP }} as {{ NODE_ASN }};
neighbor {{ NEIGHBOR_1_IP }} as {{ NEIGHBOR_1_ASN }};
password {{ NEIGHBOR_PWD }};
ipv4 {
import filter {reject;};
export filter {accept;};
};
}
위 파일을 /etc/bird.conf 로 저장하고, 플레이스홀더를 자신의 값으로 바꾸세요:
sed -i 's/{{ NODE_IP }}/<your node ip>/g' /etc/bird.conf
sed -i 's/{{ POD_CIDR }}/<your pod cidr>/g' /etc/bird.conf
sed -i 's/{{ NODE_ASN }}/<your node asn>/g' /etc/bird.conf
sed -i 's/{{ NEIGHBOR_0_IP }}/<your neighbor 0 ip>/g' /etc/bird.conf
sed -i 's/{{ NEIGHBOR_1_IP }}/<your neighbor 1 ip>/g' /etc/bird.conf
sed -i 's/{{ NEIGHBOR_0_ASN }}/<your neighbor 0 asn>/g' /etc/bird.conf
sed -i 's/{{ NEIGHBOR_1_ASN }}/<your neighbor 1 asn>/g' /etc/bird.conf
sed -i 's/{{ NEIGHBOR_PWD }}/<your neighbor password>/g' /etc/bird.conf
bird 를 재시작하고 로그를 확인하세요:
$ systemctl restart bird
# check logs
$ journalctl -u bird
-- Logs begin at Sat 2020-02-22 16:11:44 CST, end at Mon 2020-02-24 18:58:35 CST. --
Feb 24 18:58:24 node systemd[1]: Started BIRD Internet Routing Daemon.
Feb 24 18:58:24 node systemd[1]: Starting BIRD Internet Routing Daemon...
Feb 24 18:58:24 node bird[137410]: Started
변경 사항을 검증하면 다음과 같은 결과를 볼 수 있어요:
$ birdc show route
BIRD 2.0.6 ready.
Table master4:
10.5.48.0/24 unicast [static1 20:14:51.478] * (200)
dev cilium_host
이것은 이 노드의 PodCIDR 10.5.48.0/24 가 BIRD로 성공적으로 가져와졌음을 나타냅니다.
$ birdc show protocols all uplink0 | grep -A 3 -e "Description" -e "stats"
Description: BGP uplink 0
BGP state: Established
Neighbor address: 10.4.1.7
Neighbor AS: 65418
--
Route change stats: received rejected filtered ignored accepted
Import updates: 0 0 0 0 0
Import withdraws: 10 0 --- 10 0
Export updates: 1 0 0 --- 1
여기서 uplink0 BGP 세션이 성립되었고 위의 PodCIDR이 내보내져 BGP 피어가 받아들였음을 볼 수 있어요.
모니터링
bird_exporter는 bird 데몬 상태를 수집해 Prometheus 스타일 메트릭으로 내보낼 수 있어요.
또한 간단한 Grafana 대시보드를 제공하지만, 직접 만들 수도 있습니다. 예를 들어 Trip.com의 것은 이런 모습이에요.
고급 구성
BGP 스킴을 프로덕션에 적합하게 만들기 위해 몇 가지 고급 구성이 필요할 수 있어요. 이 섹션은 이러한 매개변수 중 일부를 나열하지만 세부 사항까지 파고들지는 않을게요. 그것은 BIRD User's Guide의 몫입니다.
BFD
Bidirectional Forwarding Detection (BFD)는 경로 실패 감지를 가속화하도록 설계된 감지 프로토콜입니다.
이 기능은 피어 측 구성에도 의존합니다.
protocol bfd {
interface "{{ grains['node_mgnt_device'] }}" {
min rx interval 100 ms;
min tx interval 100 ms;
idle tx interval 300 ms;
multiplier 10;
password {{ NEIGHBOR_PWD }};
};
neighbor {{ NEIGHBOR_0_IP] }};
neighbor {{ NEIGHBOR_1_IP] }};
}
protocol bgp uplink0 {
...
bfd on;
}
검증하면 다음과 같은 결과를 볼 수 있어요:
$ birdc show bfd sessions
BIRD 2.0.6 ready.
bfd1:
IP address Interface State Since Interval Timeout
10.5.40.2 bond0 Up 20:14:51.479 0.300 0.000
10.5.40.3 bond0 Up 20:14:51.479 0.300 0.000
ECMP
특별한 목적(예: L4LB)을 위해 여러 노드에 같은 CIDR을 구성할 수 있어요. 이 경우 Equal-Cost Multi-Path (ECMP) 라우팅을 구성해야 합니다.
이 기능도 피어 측 구성에 의존합니다.
protocol kernel {
ipv4 { # Connect protocol to IPv4 table by channel
import none; # Import to table, default is import all
export none; # Export to protocol. default is export none
};
# Configure ECMP
merge paths yes limit {{ N }} ;
}
더 자세한 정보는 사용자 매뉴얼을 참고하세요.
물리 네트워크(위 시나리오의 코어 라우터)에서 ECMP 정확성을 확인해야 합니다:
CORE01# show ip route 10.5.2.0
IP Route Table for VRF "default"
'*' denotes best ucast next-hop
'**' denotes best mcast next-hop
'[x/y]' denotes [preference/metric]
'%<string>' in via output denotes VRF <string>
10.5.2.0/24, ubest/mbest: 2/0
*via 10.4.1.7, [200/0], 13w6d, bgp-65418, internal, tag 65418
*via 10.4.1.8, [200/0], 12w4d, bgp-65418, internal, tag 65418
Graceful restart
이 기능도 피어 측 구성에 의존합니다.
각 bgp 섹션에 graceful restart 를 추가하세요:
protocol bgp uplink0 {
...
graceful restart;
}
더 알아보기 (Learn more)
- Cilium BGP 컨트롤 플레인 — 최신 BGP 지원 방식
- BGP 문서 목차