🤔 "클러스터 내부는 CNI가 알아서 하는데, BGP는 왜 필요하죠?"
Kubernetes CNI와 BGP의 경계를 명확히 이해하고, 실전에서 BGP가 필요한 순간을 알아봅시다.
BGP는 인터넷의 백본을 구성하는 라우팅 프로토콜입니다. 서로 다른 네트워크(Autonomous System) 간에 "어떤 IP 주소가 어디에 있는지" 정보를 교환합니다.
우편 시스템:
- 서울 우체국: "06xxx 우편번호는 우리가 관리해요!"
- 부산 우체국: "48xxx 우편번호는 우리가 관리해요!"
BGP:
- 네이버 네트워크: "210.89.160.0/24 IP는 우리 네트워크예요!"
- 카카오 네트워크: "211.249.220.0/24 IP는 우리 네트워크예요!"
사용자가 www.google.com 접속 시:
1. 사용자 ISP: "142.250.x.x는 어디로 보내지?"
2. BGP 조회: "Google AS (15169)로 보내!"
3. 최적 경로 선택: SKT → 해외 회선 → Google
4. 페이지 로딩 완료
| 구분 | CNI | BGP |
|---|---|---|
| 범위 | 클러스터 내부 | 클러스터 외부 |
| 역할 | Pod 간 네트워킹 | 네트워크 간 라우팅 |
| 필요성 | 항상 필수 | 특수한 경우만 |
| 설정 주체 | DevOps | DevOps + 네트워크팀 |
┌─────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ Pod A (10.244.1.5) │
│ ↓ │
│ CNI가 자동 라우팅 │
│ ↓ │
│ Pod B (10.244.2.10) │
│ │
│ ✅ BGP 불필요! │
└─────────────────────────────────────┘
CNI가 자동으로 처리하는 것:
┌─────────────────────┐ ┌─────────────────────┐
│ K8s Cluster A │ │ K8s Cluster B │
│ (서울) │ │ (도쿄) │
│ 10.244.0.0/16 │ │ 10.245.0.0/16 │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
└────────┬───────────────────┘
│ BGP 필요!
┌────────▼────────┐
│ Global Router │
│ "경로 알려줘!" │
└─────────────────┘
BGP가 필요한 이유:
서울 클러스터:
- Pod CIDR: 10.244.0.0/16
- Service CIDR: 10.96.0.0/12
도쿄 클러스터:
- Pod CIDR: 10.245.0.0/16
- Service CIDR: 10.97.0.0/12
// 서울 클러스터의 Pod에서
const response = await axios.post(
'http://10.245.1.50:8080/api', // 도쿄 클러스터 Pod IP
data
);
// ❌ Error: Network unreachable
// 왜? 서울 클러스터는 10.245.x.x가 어디 있는지 몰라!
서울 클러스터:
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64512 # 서울 클러스터 AS
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: to-tokyo-cluster
spec:
peerIP: 203.0.113.1 # 도쿄 클러스터 게이트웨이
asNumber: 64513 # 도쿄 클러스터 AS
도쿄 클러스터:
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64513 # 도쿄 클러스터 AS
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: to-seoul-cluster
spec:
peerIP: 203.0.113.2 # 서울 클러스터 게이트웨이
asNumber: 64512 # 서울 클러스터 AS
1. 서울 Calico: "10.244.0.0/16은 우리 거야!" (BGP 광고)
2. 도쿄 Calico: "10.245.0.0/16은 우리 거야!" (BGP 광고)
3. 라우터들이 학습:
- "10.244.x.x → 서울로"
- "10.245.x.x → 도쿄로"
4. ✅ 서울 ↔ 도쿄 Pod 간 직접 통신 가능!
Kubernetes Cluster: 10.244.0.0/16 (AWS)
온프레미스 데이터센터: 192.168.0.0/16
- 레거시 ERP: 192.168.100.50
- 은행 연동 시스템: 192.168.200.30
- Oracle DB: 192.168.150.10
# Kubernetes Pod에서 온프레미스 DB 접근
import cx_Oracle
# ❌ 연결 실패!
connection = cx_Oracle.connect(
'user/password@192.168.150.10:1521/ORCL'
)
# 왜?
# 1. Pod → 192.168.150.10 경로를 몰라
# 2. 온프레미스 → 10.244.x.x 응답 경로를 몰라
AWS 측 설정:
# Terraform
resource "aws_vpn_gateway" "main" {
vpc_id = aws_vpc.main.id
amazon_side_asn = 64512 # AWS 측 AS
}
resource "aws_customer_gateway" "onprem" {
bgp_asn = 65000 # 온프레미스 AS
ip_address = "203.0.113.100" # 온프레미스 공인 IP
type = "ipsec.1"
}
resource "aws_vpn_connection" "main" {
vpn_gateway_id = aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.onprem.id
type = "ipsec.1"
static_routes_only = false # BGP 사용
}
Calico 설정:
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64513 # Kubernetes AS (AWS와 다름!)
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: aws-vpn-gateway
spec:
peerIP: 10.0.0.1 # VPN Gateway 내부 IP
asNumber: 64512 # AWS VGW AS
온프레미스 라우터 설정:
router bgp 65000
neighbor 203.0.113.100 remote-as 64512
network 192.168.0.0 mask 255.255.0.0
! Kubernetes Pod IP 학습
neighbor 203.0.113.100 route-map ACCEPT-K8S in
Pod (10.244.1.5) → Oracle DB (192.168.150.10)
1. Pod: "192.168.150.10으로 가고 싶어"
2. Calico: "BGP 테이블 확인... VPN Gateway로!"
3. VPN Gateway → Direct Connect
4. 온프레미스 라우터: "192.168.150.10은 내부 네트워크"
5. ✅ DB 도달
응답:
DB (192.168.150.10) → Pod (10.244.1.5)
1. 온프레미스 라우터: "10.244.1.5? BGP 테이블 확인..."
2. "아, AWS VPN으로 보내면 되겠네"
3. VPN → AWS VGW → Calico
4. ✅ Pod 도달
온프레미스 데이터센터 구조:
┌────────────────────────────────┐
│ Core Router (192.168.0.1) │
│ AS 65000 │
└────────┬───────────────────────┘
│
┌────┴────┬────────┐
│ │ │
┌───▼───┐ ┌──▼───┐ ┌──▼───┐
│ToR-1 │ │ToR-2 │ │ToR-3 │
│.1.1 │ │.1.2 │ │.1.3 │
│AS │ │AS │ │AS │
│65001 │ │65001 │ │65001 │
└───┬───┘ └──┬───┘ └──┬───┘
│ │ │
[노드] [노드] [노드]
BGP 없이 (VXLAN Overlay):
문제점:
1. 모든 트래픽이 캡슐화됨 (Overhead 증가)
2. ToR Switch가 Pod IP를 몰라 → 비효율적 라우팅
3. 물리 네트워크의 성능을 100% 활용 못 함
예시:
Pod A → Pod B (같은 랙)
실제 거리: 1 홉
VXLAN: 3 홉 (캡슐화/복호화 오버헤드)
BGP 사용 (Native Routing):
장점:
1. 캡슐화 없음 → 오버헤드 제거
2. ToR Switch가 Pod IP 인지 → 최적 경로
3. 물리 네트워크 성능 100% 활용
예시:
Pod A → Pod B (같은 랙)
실제 거리: 1 홉
BGP: 1 홉 (직접 전송)
ToR Switch 1:
router bgp 65001
neighbor 192.168.1.10 remote-as 64512 # K8s Node 1
neighbor 192.168.1.11 remote-as 64512 # K8s Node 2
! Pod IP 학습
address-family ipv4
neighbor 192.168.1.10 activate
neighbor 192.168.1.11 activate
Calico (모든 노드):
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64512
nodeToNodeMeshEnabled: false # Node Mesh 비활성화
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tor-switch-1
spec:
peerIP: 192.168.1.1
asNumber: 65001
벤치마크 (10Gbps 네트워크):
VXLAN Overlay:
처리량: 8.2 Gbps (18% 오버헤드)
레이턴시: 0.8ms
CPU 사용률: 25%
BGP Native Routing:
처리량: 9.7 Gbps (3% 오버헤드)
레이턴시: 0.3ms
CPU 사용률: 8%
결과: BGP가 3배 효율적!
요구사항:
- F5 하드웨어 로드밸런서 (물리 장비)
- Pod IP로 직접 트래픽 전송 (Service 거치지 않음)
- DSR (Direct Server Return) 구현
일반적인 방법 (NodePort/LoadBalancer):
사용자 → F5 → NodePort (30080)
→ kube-proxy NAT
→ Pod
문제:
1. kube-proxy 병목
2. NAT 오버헤드
3. Source IP 손실
4. 높은 레이턴시
BGP 방법:
사용자 → F5 → Pod IP 직접!
장점:
1. kube-proxy 우회
2. NAT 없음
3. Source IP 보존
4. 낮은 레이턴시
Calico:
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: f5-load-balancer
spec:
peerIP: 192.168.10.100 # F5 IP
asNumber: 65100
---
# 특정 Service의 Pod IP만 광고
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
serviceExternalIPs:
- cidr: 10.244.0.0/16 # Pod CIDR
F5 설정:
ltm pool k8s-payment-pool {
members {
10.244.1.50:8080 { } # Pod IP 직접 사용!
10.244.2.30:8080 { }
10.244.3.80:8080 { }
}
monitor tcp
}
1. Calico가 BGP로 광고:
"10.244.1.50은 192.168.1.10 (노드)에 있어요"
2. F5가 학습:
"10.244.1.50으로 가려면 192.168.1.10으로 보내면 되겠네"
3. 트래픽:
사용자 → F5 → 192.168.1.10 → Pod (10.244.1.50)
4. 응답 (DSR):
Pod → 사용자 (직접! F5 거치지 않음)
결과: 초고속 처리!
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: rack-tor-switch
spec:
peerIP: 192.168.1.1
asNumber: 64512
의미:
버전 히스토리:
의미:
Calico의 다른 kinds:
BGPPeer # 외부 BGP 라우터 연결
BGPConfiguration # BGP 전역 설정
NetworkPolicy # 네트워크 보안 정책
IPPool # IP 주소 풀
FelixConfiguration # Felix 데몬 설정
의미:
네이밍 컨벤션:
# 위치 기반
name: rack1-tor-switch
name: datacenter-seoul-tor1
# 기능 기반
name: production-bgp-peer
name: edge-router-primary
# 조합
name: seoul-dc-rack1-tor1
실제 데이터센터 용어:
데이터센터 구조:
┌─────────────────┐
│ Core Router │
└────────┬────────┘
│
┌────▼────┐
│ToR Switch│ ← 여기!
│(랙 상단) │
└────┬────┘
│
┌────┴────┐
│Server 1 │
│Server 2 │
│Server 3 │
└─────────┘
의미:
선택 기준:
✅ 모든 Kubernetes 노드에서 접근 가능한 IP
✅ 일반적으로 관리 네트워크의 IP
✅ 물리 라우터/스위치의 관리 인터페이스 IP
❌ NAT 뒤의 IP는 피할 것
❌ DHCP로 변경될 수 있는 IP 피할 것
실제 환경 예시:
# 온프레미스
peerIP: 192.168.1.1 # ToR Switch 관리 IP
# AWS
peerIP: 10.0.0.1 # Virtual Private Gateway
# GCP
peerIP: 10.1.0.1 # Cloud Router
의미:
AS Number 범위:
1 - 64511: 공인 AS (Public)
예: Google(15169), Amazon(16509)
64512 - 65534: 사설 AS (Private) ← 대부분 여기 사용
내부 네트워크용, 인터넷 광고 안 됨
4200000000 - 4294967294: 4바이트 사설 AS
대규모 조직용
왜 64512를 많이 사용하나?
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: payment-nodes-tor
spec:
peerIP: 192.168.1.1
asNumber: 64512
nodeSelector: "service == 'payment'" # 결제 노드만
# 노드 레이블 설정
kubectl label node worker-1 service=payment
kubectl label node worker-2 service=payment
# Primary
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tor-switch-primary
spec:
peerIP: 192.168.1.1
asNumber: 64512
---
# Backup
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tor-switch-backup
spec:
peerIP: 192.168.1.2
asNumber: 64512
동작:
정상: 모든 노드가 2개 스위치와 BGP 세션
Switch 1 장애: 자동으로 Switch 2만 사용
Switch 1 복구: 다시 2개 모두 사용
역할: 같은 네트워크 내 연결
계층: L2 (데이터 링크)
주소: MAC 주소 사용
범위: 로컬 네트워크
예시:
컴퓨터 A → 스위치 → 컴퓨터 B
(같은 사무실 내)
역할: 다른 네트워크 간 연결
계층: L3 (네트워크)
주소: IP 주소 사용
범위: 인터넷, WAN
예시:
회사 네트워크 → 라우터 → 인터넷
역할: 스위칭 + 라우팅
계층: L2 + L3
기능: 스위치처럼 빠르고, 라우터처럼 똑똑함
데이터센터의 ToR Switch는 보통 L3 스위치!
→ BGP 사용 가능
Kubernetes 클러스터
Node 1: 192.168.1.10
Node 2: 192.168.1.11
Node 3: 192.168.1.12
ToR Switch 1: 192.168.1.1 (AS 64512)
ToR Switch 2: 192.168.1.2 (AS 64512) ← 이중화
# 첫 번째 스위치
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tor-switch-1
spec:
peerIP: 192.168.1.1
asNumber: 64512
---
# 두 번째 스위치
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tor-switch-2
spec:
peerIP: 192.168.1.2
asNumber: 64512
[인터넷]
|
[Core Router]
|
┌─────┴─────┐
| |
[ToR Switch 1] [ToR Switch 2]
192.168.1.1 192.168.1.2
AS 64512 AS 64512
| |
| 이중 연결 |
└───────┬───────┘
|
┌────────┼────────┐
| | |
Node1 Node2 Node3
.1.10 .1.11 .1.12
각 Node는 Switch 1, 2 모두와 BGP 세션
# BGP Peer 확인
$ calicoctl get bgppeer
NAME PEERIP NODE ASN
tor-switch-1 192.168.1.1 (all) 64512
tor-switch-2 192.168.1.2 (all) 64512
# BGP 세션 상태
$ calicoctl node status
IPv4 BGP status
+--------------+-------+----------+-------------+
| PEER ADDRESS | STATE | SINCE | INFO |
+--------------+-------+----------+-------------+
| 192.168.1.1 | up | 10:52:33 | Established |
| 192.168.1.2 | up | 10:52:35 | Established |
+--------------+-------+----------+-------------+
# 2개 모두 "Established" = 정상!
1. 라우터/스위치 측 (네트워크팀)
# Cisco 라우터
router bgp 64512
bgp router-id 192.168.1.1
neighbor 192.168.1.10 remote-as 64513 # K8s 노드
neighbor 192.168.1.11 remote-as 64513
# "나는 AS 64512이고, 상대방은 AS 64513이야"
2. Kubernetes/Calico 측 (DevOps팀)
# 우리 클러스터 AS
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64513 # "우리는 AS 64513"
---
# Peer 정보
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tor-switch
spec:
peerIP: 192.168.1.1
asNumber: 64512 # "상대방은 AS 64512"
1단계: 네트워크 설계 회의
"온프레미스는 AS 65000"
"AWS 서울은 AS 64512"
"K8s 서울은 AS 64514"
2단계: 네트워크팀이 라우터 설정
router bgp 64512
neighbor x.x.x.x remote-as 64514
3단계: DevOps팀이 Calico 설정
asNumber: 64514 (우리)
peerIP: x.x.x.x
asNumber: 64512 (상대방)
라우터: AS 64512
Calico: AS 64512 ← 같으면 안 됨!
문제:
- iBGP (Internal BGP)로 동작
- 라우팅 루프 방지로 경로 광고 안 됨
- 연결은 되지만 라우팅 안 됨
라우터: AS 64512
Calico: AS 64513 ← 다른 AS
결과:
- eBGP (External BGP)로 동작
- 정상적으로 라우팅 정보 교환
65000: 온프레미스 데이터센터
65001: AWS 서울 VPC
65002: AWS 도쿄 VPC
65010: K8s 서울 프로덕션
65011: K8s 도쿄 DR
65020: K8s 개발 환경
64512: 코어 라우터
64520-64529: ToR Switch
64530-64539: Kubernetes 클러스터
64540-64549: 개발/테스트
65001: 서울 (SEL)
65001: 인프라
65011: K8s 프로덕션
65021: K8s 개발
65002: 도쿄 (TYO)
65002: 인프라
65012: K8s 프로덕션
65022: K8s 개발
# 이것만으로도 자동 장애 대응!
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: switch-1
spec:
peerIP: 192.168.1.1
asNumber: 64512
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: switch-2
spec:
peerIP: 192.168.1.2
asNumber: 64512
동작:
정상:
Node → Switch 1 (Active)
Node → Switch 2 (Standby)
Switch 1 장애:
10초 후 자동 감지
→ Switch 2로 전환
Switch 1 복구:
자동으로 원래대로
# Primary 라우터
router bgp 64512
neighbor 192.168.1.10 remote-as 64513
neighbor 192.168.1.10 weight 100 # 높은 우선순위
# Backup 라우터
router bgp 64512
neighbor 192.168.1.10 remote-as 64513
neighbor 192.168.1.10 weight 50 # 낮은 우선순위
# Primary: 짧은 경로
router bgp 64512
neighbor 192.168.1.10 route-map PRIMARY in
route-map PRIMARY permit 10
set as-path prepend 64512 # AS Path: 64512
# Backup: 긴 경로 (우선순위 낮음)
router bgp 64512
neighbor 192.168.1.10 route-map BACKUP in
route-map BACKUP permit 10
set as-path prepend 64512 64512 64512 # AS Path: 64512 64512 64512
기본 BGP: 30-90초 감지
# 기본 설정
keepAliveTime: 30s
holdTime: 90s
# → 최대 90초 후 장애 감지
BFD 사용: 1초 이내 감지
# 라우터 설정
interface GigabitEthernet0/0
bfd interval 200 min_rx 200 multiplier 3
# 200ms * 3 = 600ms 후 장애 감지
router bgp 64512
neighbor 192.168.1.10 remote-as 64513
neighbor 192.168.1.10 fall-over bfd
# 서울 리전 (Primary)
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64512
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: global-router
spec:
peerIP: 203.0.113.1
asNumber: 64500
---
# 도쿄 리전 (DR)
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64513
---
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: global-router
spec:
peerIP: 203.0.113.1
asNumber: 64500
정상 시:
사용자 → 서울 (AS Path 짧음)
서울 장애:
1. 서울 BGP 광고 중단 (30초)
2. 라우터가 서울 경로 제거
3. 도쿄 경로만 남음
4. 모든 트래픽 → 도쿄 (자동!)
서울 복구:
1. 서울 BGP 광고 재개
2. 라우터가 경로 추가
3. AS Path 비교 (서울이 짧음)
4. 다시 서울 우선 사용
상황:
- 시드 투자 직후, 팀 10명
- AWS 서울 단일 리전
- 10 노드 클러스터
선택: Flannel
이유: 빠른 구축, 운영 단순화
BGP: 불필요
상황:
- 시리즈 A, 팀 50명, MAU 10만
- 여전히 단일 리전
- 30 노드로 확장
선택: Flannel 계속 사용
이유: 충분한 성능, 안정적
BGP: 여전히 불필요
상황:
- 시리즈 B, 팀 200명, MAU 100만
- 멀티 리전 필요 (서울 + 도쿄)
- 리전당 100+ 노드
트리거:
✓ 엔터프라이즈 고객 요구 (네트워크 격리)
✓ SOC2 인증 필요
✓ 글로벌 확장
✓ 온프레미스 레거시 연동
선택: Calico + BGP
BGP 설정:
# 서울 클러스터
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64512
nodeToNodeMeshEnabled: false
---
# AWS 서울 VGW 연결
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: aws-seoul-vgw
spec:
peerIP: 10.0.0.1
asNumber: 64500
---
# 도쿄 클러스터 연결
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tokyo-dr
spec:
peerIP: 203.0.113.2
asNumber: 64513
---
# 온프레미스 연결
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: onprem-dc
spec:
peerIP: 192.168.1.1
asNumber: 65000
상황:
- 시리즈 C+, 팀 500명, MAU 500만+
- 글로벌 10개 리전
- 리전당 200+ 노드
BGP 사용:
✓ 멀티 리전 자동 장애 전환
✓ 온프레미스 통합 (레거시 시스템)
✓ 하이브리드 클라우드 (AWS + GCP + 온프레미스)
✓ 고성능 라우팅 (eBPF + BGP)
규제:
✓ 금융 데이터는 국내에만
✓ PCI-DSS 준수
✓ 모든 트래픽 암호화
✓ 네트워크 감사 추적
기술:
✓ 온프레미스 은행 연동
✓ 초저 레이턴시 (<5ms)
✓ 99.99% 가용성
✓ 멀티 리전 DR
# 1. 온프레미스 은행 연동
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: bank-mainframe
spec:
peerIP: 192.168.1.1 # 은행 연동 라우터
asNumber: 65000
nodeSelector: "service == 'payment'" # 결제 노드만
---
# 2. AWS 서울 (Primary)
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: aws-seoul-primary
spec:
peerIP: 10.0.0.1
asNumber: 64512
---
# 3. AWS 서울 (Backup)
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: aws-seoul-backup
spec:
peerIP: 10.0.0.2
asNumber: 64512
---
# 4. AWS 부산 DR
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: aws-busan-dr
spec:
peerIP: 10.1.0.1
asNumber: 64513
# BGP로 라우팅 + NetworkPolicy로 보안
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: payment-isolation
spec:
selector: app == 'payment'
ingress:
- action: Allow
protocol: TCP
source:
selector: app == 'api-gateway'
destination:
ports: [8080]
egress:
- action: Allow
protocol: TCP
destination:
nets:
- 192.168.100.0/24 # 은행 시스템만
ports: [3000]
성능:
✓ 초저 레이턴시 (<2ms)
✓ 초당 100만+ 패킷
✓ DDoS 방어
가용성:
✓ 99.99% 가동률
✓ 자동 리전 전환
✓ 글로벌 Anycast
# eBPF 활성화
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
name: default
spec:
bpfEnabled: true
bpfLogLevel: Info
---
# BGP Configuration
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: 64520
---
# 서울 리전
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: seoul-edge
spec:
peerIP: 203.0.113.1
asNumber: 64500
---
# 도쿄 리전
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: tokyo-edge
spec:
peerIP: 103.0.113.1
asNumber: 64501
---
# 싱가포르 리전
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: singapore-edge
spec:
peerIP: 123.0.113.1
asNumber: 64502
같은 Service IP를 모든 리전에서 광고:
서울: "1.2.3.4는 우리한테 있어요!" (BGP 광고)
도쿄: "1.2.3.4는 우리한테 있어요!" (BGP 광고)
싱가포르: "1.2.3.4는 우리한테 있어요!" (BGP 광고)
결과:
- 한국 플레이어 → 자동으로 서울 리전
- 일본 플레이어 → 자동으로 도쿄 리전
- 동남아 플레이어 → 자동으로 싱가포르 리전
서울 장애 시:
- 한국 플레이어도 자동으로 도쿄로 전환
A: 맞습니다! 대부분의 경우 BGP 불필요합니다.
BGP 불필요 (90%):
✓ 단일 클러스터
✓ Service를 통한 Pod 접근
✓ Ingress 사용
✓ 같은 클러스터 내 통신
BGP 필요 (10%):
✓ 멀티 클러스터
✓ 온프레미스 통합
✓ 물리 네트워크 직접 연동
✓ 외부에서 Pod IP 직접 접근
A: 방법에 따라 다릅니다.
단일 클러스터 교체:
- 다운타임: 10-30분
- Pod 전체 재시작 필요
Blue-Green 방식:
- 다운타임: 0분
- 새 클러스터 구축 후 전환
Rolling Update:
- 다운타임: 노드당 2-5분
- 노드를 하나씩 전환
A: 네트워크팀과 협의하여 결정합니다.
절차:
1. 네트워크팀과 회의
"우리 온프레미스는 AS 65000 사용 중"
2. 네트워크팀이 AS 할당
"K8s 서울은 AS 64512 써주세요"
3. DevOps팀이 Calico 설정
asNumber: 64512
주의: 임의로 변경하면 안 됨!
A: 체크리스트:
# 1. 핑 테스트
ping 192.168.1.1
# 2. BGP 포트 확인 (TCP 179)
telnet 192.168.1.1 179
# 3. 방화벽 확인
# AWS: Security Group에서 TCP 179 허용
# 온프레미스: 방화벽 규칙 확인
# 4. AS Number 확인
# 라우터와 Calico 설정이 서로 일치하는지
# 5. 라우터 설정 확인
# 네트워크팀에게 라우터 로그 요청
A: 아닙니다. 독립적입니다.
eBPF: 패킷 처리 성능 향상 (커널 레벨)
BGP: 네트워크 간 라우팅 정보 교환
조합:
✓ eBPF만: 가능 (고성능 단일 클러스터)
✓ BGP만: 가능 (멀티 클러스터)
✓ 둘 다: 가능 (고성능 멀티 클러스터) ← 최고!
✓ 둘 다 안 씀: 가능 (일반 Flannel)
A: 역할 분담:
네트워크팀:
- 물리/가상 라우터 설정
- AS Number 할당
- BGP 정책 설정
- 방화벽 규칙
DevOps팀:
- Calico BGP 설정
- Kubernetes 리소스 관리
- 모니터링 및 트러블슈팅
협업:
- AS Number 결정
- IP 대역 계획
- 장애 대응 절차
A: 여러 방법 사용:
# Calico 상태
calicoctl node status
# 상세 정보
sudo birdc show protocols all
# Prometheus 메트릭
felix_route_table_list_seconds
felix_int_dataplane_failures
bgp_peers_up
# 알림 설정
BGP 세션 Down → Slack 알림
경로 개수 급변 → 담당자 호출
A: 주로 운영 복잡도 차이:
Flannel:
- 설정 시간: 30분
- 학습 시간: 1일
- 운영 인력: 최소
Calico + BGP:
- 설정 시간: 2-4시간
- 학습 시간: 1주일
- 운영 인력: 네트워크 지식 필요
하드웨어 비용:
- 거의 차이 없음
- BGP 때문에 추가 장비 불필요
✅ 필요한 경우 (10%):
- 멀티 클러스터
- 온프레미스 통합
- 물리 네트워크 직접 연동
- 고성능 요구사항
❌ 불필요한 경우 (90%):
- 단일 클러스터
- Service/Ingress 사용
- 일반적인 마이크로서비스
# 3가지만 기억하세요
1. asNumber: 우리 클러스터 AS
2. peerIP: 상대방 라우터 IP
3. asNumber (peer): 상대방 AS
# 나머지는 자동!
BGP가 자동으로:
✓ 장애 감지 (10-30초)
✓ 대체 경로 선택
✓ 트래픽 우회
✓ 복구 시 원복
개발자는 신경 안 써도 됨!
// 코드는 항상 똑같음
await axios.post('http://service:8080/api', data);
// BGP가 있든 없든
// 멀티 클러스터든 단일 클러스터든
// 코드 변경 없음!
시작 단계:
→ Flannel (간단함)
성장 단계:
→ Flannel 유지 (충분함)
스케일업:
→ Calico (성능/보안)
멀티 클러스터:
→ Calico + BGP (필수)
엔터프라이즈:
→ Calico + BGP + eBPF (최고)
"BGP는 복잡하지만, 진짜 필요할 때까지는 쓰지 마세요.
하지만 필요한 순간이 오면, BGP만큼 강력한 게 없습니다."
BGP는 복잡해 보이지만, 핵심 개념만 이해하면 됩니다:
이 글이 BGP에 대한 두려움을 없애고, 실전에서 올바른 선택을 하는 데 도움이 되었기를 바랍니다!
Happy Networking!