BGP 피어
BGP 피어 (BGP peer)
BGPPeer 리소스는 Calico 클러스터의 하나 이상 노드가 라우트를 교환하는 원격 BGP 피어를 나타내요. BGP 피어를 구성하면 Calico 네트워크를 ToR(top-of-rack) 라우터 같은 데이터센터 패브릭과 피어링할 수 있어요. 클러스터 레이아웃에 대한 자세한 내용은 Calico의 Calico over IP fabrics 문서를 참고하세요.
출처: 문서
본문
Border Gateway Protocol(BGP) 피어 리소스(BGPPeer)는 Calico 클러스터의 하나 이상 노드가 라우트를 교환하는 원격 BGP 피어를 나타내요. BGP 피어를 구성하면 Calico 네트워크를 데이터센터 패브릭, 예를 들어 ToR(top-of-rack) 라우터와 피어링할 수 있어요. 클러스터 레이아웃에 대한 자세한 정보는 Calico의 Calico over IP fabrics 문서를 참고하세요.
샘플 YAML
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: some.name
spec:
node: rack1-host1
peerIP: 192.168.1.1
asNumber: 63400
BGP 피어 정의
메타데이터 (Metadata)
| 필드 | 설명 | 허용 값 | 스키마 |
|---|---|---|---|
| name | 이 리소스 인스턴스를 설명하는 고유 이름이에요. 반드시 지정해야 해요. | ., _, -를 선택적으로 포함하는 영숫자 문자열 |
string |
스펙 (Spec)
| 필드 | 설명 | 허용 값 | 스키마 | 기본값 |
|---|---|---|---|---|
| node | 지정하면 스코프가 노드 수준이 되고, 그렇지 않으면 스코프는 전역이에요. | 이 피어가 적용될 노드의 호스트네임 | string | |
| peerIP | 이 피어의 IP 주소이고, 포트 번호는 선택적으로 붙일 수 있어요. 포트 번호가 설정되지 않았고 피어가 listenPort가 설정된 Calico 노드라면 listenPort가 사용돼요. |
유효한 IPv4 또는 IPv6 주소. 포트 번호를 설정한다면 IPv4:port 또는 [IPv6]:port 형식을 사용해요. |
string | |
| asNumber | 피어의 원격 AS 번호예요. | 유효한 AS 번호. dotted 표기로 지정할 수도 있어요. | integer/string | |
| localASNumber | Calico가 이 피어에 대해 로컬 AS 번호로 사용할 AS 번호를 지정해요. 기본 BGPConfiguration에 설정된 전역 AS 번호를 재정의해요. | 유효한 AS 번호. dotted 표기로 지정할 수도 있어요. | integer/string | |
| nodeSelector | 이 피어링을 가져야 할 노드를 고르는 셀렉터예요. 이 값을 설정하면 node 필드는 비워 두어야 해요. |
selector | ||
| peerSelector | 피어링할 원격 노드를 고르는 셀렉터예요. 이 값을 설정하면 peerIP와 asNumber 필드는 비워 두어야 해요. |
selector | ||
| localWorkloadSelector | 노드가 피어링해야 할 로컬 워크로드를 고르는 셀렉터예요. 이 값을 설정하면 peerSelector와 peerIP 필드는 비워 두어야 하고, BGPConfiguration 리소스의 localWorkloadPeeringIPV4 및/또는 localWorkloadPeeringIPV6 필드가 구성되어 있어야 해요. 이 기능을 사용할 때는 적절한 import/export 필터를 구성하는 것도 중요해요. 자세한 내용은 가이드를 참고하세요. |
selector | ||
| keepOriginalNextHop | 원본 next hop BGP 라우트 속성을 유지하고 다른 AS의 특정 피어에게 전달해요. 참고: 이 필드는 폐기(deprecated)됐어요. BGP 피어의 next hop 속성은 nextHopMode 필드로 제어해야 해요. | boolean | ||
| password | 이 BGPPeer 리소스가 만드는 피어링에 사용할 BGP 비밀번호예요. | BGPPassword | nil (비밀번호 없음) |
|
| sourceAddress | 이 BGPPeer 리소스가 만드는 피어링에 소스 주소를 설정할지, 어떻게 설정할지 지정해요. 기본값인 "UseNodeIP"는 노드 IP를 소스 주소로 설정한다는 뜻이에요. "None"은 소스 주소를 설정하지 않는다는 뜻이에요. | "UseNodeIP", "None" | string | "UseNodeIP" |
| maxRestartTime | BGP graceful restart capability에서 BIRD가 알리는 재시작 시간으로, 재시작 후 오래된(stale) 라우트를 삭제하기 전에 이웃이 BGP 세션 재수립을 기다리는 시간을 지정해요. 참고: 이 구성을 바꿀 때는 각별히 주의해야 해요. 클러스터 네트워킹이 깨질 수 있거든요. 지정하지 않으면 BIRD는 기본값 120초를 사용해요. | 10s, 120s, 2m 등 |
Duration string | nil (빈 구성이면 BIRD가 기본값 120s를 사용해요) |
| numAllowedLocalASNumbers | 수신한 라우트의 AS path에서 허용할 로컬 AS 번호의 개수예요. BGP 루프 방지를 비활성화하므로 필요할 때만 사용해야 해요. | integer | nil (BIRD가 기본값 0을 사용하며, 루프 방지 동작은 변하지 않아요) |
|
| ttlSecurity | 기본화된 TTL 보안 메커니즘(GTSM)을 활성화해요. 예상보다 작은 TTL 값을 가진 수신 패킷을 무시해 스푸핑 패킷으로부터 보호하죠. 제공하는 값은 피어 간 홉(엣지) 수예요. | 0 - 255 | 8-bit 정수 | nil (BIRD 구성이 ttl security off가 돼요) |
| filters | 이 피어링에 적용할 BGPFilter 리소스 이름 목록이에요. | [ "my-calico-bgp-filter1","my-calico-bgp-filter2" ] | 문자열 목록 | |
| reachableBy | 피어에 연결할 때 필요할 수 있는 스태틱 라우트를 추가해요. 경우에 따라 BGP 피어링용 스태틱 라우트가 없으면 라우트 플래핑(route flapping)이 생겨요. 피어가 연결된 게이트웨이의 주소를 추가하면 라우트 플래핑을 막는 스태틱 라우트가 추가돼요. | 피어가 연결된 게이트웨이의 주소 | string | |
| nextHopMode | 수신한 라우트의 next hop 속성을 계산하는 방식을 지정해요. 폐기된 KeepOriginalNextHop 필드를 대체하고 확장하는 필드예요. BGP 피어의 next hop 속성은 이 설정으로 제어해야 해요. 이 값을 설정하면 keepOriginalNextHop 필드의 값은 무시돼요. keepOriginalNextHop과 nextHopMode 둘 다 지정하지 않으면 BGP의 기본 동작을 사용해요. 기본값인 "Auto"는 BGP의 기본 동작을 적용한다는 뜻이에요. "Self"는 "bird.cfg"에 "next hop self;"를 구성한다는 뜻이고, "Keep"은 "bird.cfg"에 "next hop keep;"를 구성한다는 뜻이에요. | "Auto", "Self", "Keep" | string | "Auto" |
| reversePeering | peerSelector가 고른 노드에 대해 Calico가 역방향 피어링(reverse peering)을 자동으로 생성할지 지정해요. Manual로 설정하면 역방향 피어링용 BGPPeer를 별도로 만들어야 해요. | "Auto", "Manual" | string | "Auto" |
성공 팁: 피어와 통신할 때 사용하는 클러스터 전역 기본 로컬 AS 번호는 BGPConfiguration 리소스로 제어해요. 이 값은 node 리소스의
bgp필드로 노드별로 재정의할 수 있어요.
보조 정보: 클러스터 내부 노드 간에 BGP 세션을 구성하려고
BGPPeer리소스를 사용하고 싶다면, 예를 들어 기본값이 아닌 BGPPeer 파라미터를 설정하려는 경우, BGPConfiguration 리소스에서nodeToNodeMeshEnabled파라미터를 false로 설정해 노드 간 메시(node-to-node mesh)를 비활성화해야 해요.
BGPPassword
보조 정보: BGP 비밀번호는 80자 이하여야 해요. 그보다 긴 비밀번호를 구성하면 그 비밀번호를 쓰는 BGP 세션은 수립에 실패해요.
| 필드 | 설명 | 스키마 |
|---|---|---|
| secretKeyRef | 시크릿에서 비밀번호를 가져와요. | KeyRef |
KeyRef
KeyRef는 Calico에게 BGP 비밀번호를 어디서 가져올지 알려줘요. 참조하는 Kubernetes 시크릿은 calico/node 파드와 같은 네임스페이스에 있어야 해요.
| 필드 | 설명 | 스키마 |
|---|---|---|
| name | 시크릿의 이름 | string |
| key | 시크릿 안의 키 | string |
경고: Calico는 참조하는 시크릿을 읽을 수 있어야 해요.
즉,
calico-nodeServiceAccount가 KeyRef에서 참조하는 시크릿을list, get, watch할 권한이 있어야 해요.실무에서는 시크릿에
list, get, watch를 허용하는 Role과, 그 Role의 권한을calico-nodeServiceAccount에 부여하는 RoleBinding을 만들면 돼요.예시:
--- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: bgp-passwords-reader namespace: calico-system # Or kube-system if installed using manifests. rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["bgp-passwords"] verbs: ["list", "watch", "get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: calico-read-bgp-passwords namespace: calico-system # Or kube-system if installed using manifests. roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: bgp-passwords-reader subjects: - kind: ServiceAccount name: calico-node --- apiVersion: v1 kind: Secret metadata: name: "bgp-passwords" namespace: calico-system # Or kube-system if installed using manifests. data: peer_a_pw: "base64-encoded Password for Peer A" peer_b_pw: "base64-encoded Password for Peer B" --- apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: "peer-a" spec: password: secretKeyRef: name: "bgp-passwords" key: "peer_a_pw" --- apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: "peer-b" spec: password: secretKeyRef: name: "bgp-passwords" key: "peer_b_pw"
피어 스코프 (Peer scopes)
BGP 피어는 전역 또는 노드별 스코프 중 하나로 존재할 수 있어요. 피어의 스코프가 어떤 calico/node가 그 피어와 BGP 세션 수립을 시도할지 결정하죠. calico/node의 BGPConfiguration에 listenPort가 설정되어 있으면 피어링에 그 값이 사용돼요.
전역 피어 (Global peer)
BGP 피어에게 전역 스코프를 부여하려면 node와 nodeSelector 필드를 생략해요. 클러스터의 모든 노드가 그 피어와 BGP 커넥션 수립을 시도해요.
노드별 피어 (Node-specific peer)
BGP 피어는 노드별로 존재할 수도 있어요. node 필드가 있으면 지정한 노드만 그 피어와 피어링해요. nodeSelector 필드가 있으면 그 셀렉터와 라벨이 일치하는 노드들이 피어링해요.
셀렉터 (Selectors)
라벨 셀렉터는 리소스의 라벨을 기준으로 매칭되거나 매칭되지 않는 표현식이에요.
Calico 라벨 셀렉터는 여러 연산자를 지원하고, 불리언 연산자와 괄호로 더 큰 표현식을 조합할 수 있어요.
| 표현식 | 의미 |
|---|---|
| 논리 연산자 | |
( <expression> ) |
<expression>이 매칭될 때 정확히 매칭돼요. (괄호는 표현식 묶기에 사용해요.) |
! <expression> |
<expression>이 매칭되지 않을 때 정확히 매칭돼요. 팁: !는 YAML 문자열의 시작 위치에서 특수 문자예요. YAML 문자열 시작에 !를 써야 한다면 문자열을 따옴표로 감싸세요. |
<expression 1> && <expression 2> |
"And": <expression 1>과 <expression 2>가 모두 매칭될 때 정확히 매칭돼요 |
<expression 1> || <expression 2> |
"Or": <expression 1> 또는 <expression 2> 중 하나가 매칭될 때 정확히 매칭돼요. |
| 매치 연산자 | |
all() |
스코프 안의 모든 리소스와 매칭돼요. 아무것도 매칭하지 않으려면 이 연산자를 !와 조합해 !all()을 만드세요. |
global() |
네임스페이스가 없는 모든 리소스와 매칭돼요. namespaceSelector에서 글로벌 네트워크 셋 같은 전역 리소스를 고를 때 유용해요. |
k == 'v' |
라벨 'k'와 값 'v'를 가진 리소스와 매칭돼요. |
k != 'v' |
라벨 'k'가 없거나, 라벨 'k'의 값이 v와 같지 않은 리소스와 매칭돼요 |
has(k) |
값과 무관하게 라벨 'k'를 가진 리소스와 매칭돼요. 라벨 k가 없는 파드를 매칭하려면 이 연산자를 !와 조합해 !has(k)를 만드세요 |
k in { 'v1', 'v2' } |
라벨 'k'를 가지고 값이 주어진 집합에 속하는 리소스와 매칭돼요 |
k not in { 'v1', 'v2' } |
라벨 'k'가 없거나, 라벨 'k'의 값이 주어진 집합에 속하지 않는 리소스와 매칭돼요 |
k contains 's' |
라벨 'k'를 가지고 값에 부분문자열 's'를 포함하는 리소스와 매칭돼요 |
k starts with 's' |
라벨 'k'를 가지고 값이 부분문자열 's'로 시작하는 리소스와 매칭돼요 |
k ends with 's' |
라벨 'k'를 가지고 값이 부분문자열 's'로 끝나는 리소스와 매칭돼요 |
연산자의 우선순위는 다음과 같아요.
- 가장 높음: 모든 매치 연산자
- 괄호
( ... ) !를 사용한 부정&&를 사용한 논리곱- 가장 낮음:
||를 사용한 논리합
예를 들어 다음 표현식은
! has(my-label) || my-label starts with 'prod' && role in {'frontend','business'}
이렇게 "괄호로 묶여" 있어요:
((!(has(my-label)) || ((my-label starts with 'prod') && (role in {'frontend','business'}))
이 표현식은 다음을 매칭해요:
- 라벨 "my-label"이 없는 모든 리소스.
- 다음 두 조건을 모두 만족하는 모든 리소스:
my-label의 값이 "prod"로 시작하고,- role 라벨의 값이 "frontend" 또는 "business" 중 하나인 경우.
더 알아보기 (Learn more)
BGPPeer는 데이터센터 패브릭이나 외부 라우터와 Calico를 피어링할 때 쓰는 핵심 리소스예요. 노드 간 BGP 세션을 직접 구성하려면 nodeToNodeMeshEnabled를 끄고 피어링을 명시적으로 정의해야 해요. 라벨 셀렉터 우선순위를 이해하면 nodeSelector·peerSelector를 정확히 짤 수 있어요.