Ssoon
[8주차] Cilium CNI : Cilium 기본 정보 본문
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기
🧿 변수와 alias 를 설정합니다.
- CILIUMPOD0, CILIUMPOD1, CILIUMPOD2: 각각의 Cilium Pod의 이름을 저장하여 해당 Pod에서 실행되는 Cilium 및 bpftool 명령어에 쉽게 접근할 수 있도록 합니다.
- alias: 특정 명령어에 짧은 이름(별칭)을 할당하여, 명령어를 보다 간편하게 사용할 수 있도록 합니다.
- c0, c1, c2: Cilium CLI 명령어를 실행하는 데 사용.
- c0bpf, c1bpf, c2bpf: bpftool 명령어를 실행하는 데 사용.
bpftool은 Linux의 eBPF 기능과 관련된 여러 작업을 수행할 수 있게 도와줍니다. eBPF 프로그램과 맵을 조작하고, 상태를 확인하는 데 유용한 명령줄 도구입니다.
export CILIUMPOD0=... | Cilium Pod의 이름을 CILIUMPOD0 환경 변수에 저장합니다. |
export CILIUMPOD1=... | Cilium Pod의 이름을 CILIUMPOD1 환경 변수에 저장합니다. |
export CILIUMPOD2=... | Cilium Pod의 이름을 CILIUMPOD2 환경 변수에 저장합니다. |
alias c0=... | c0라는 별칭을 만들어 CILIUMPOD0의 Cilium CLI 명령어에 접근합니다. |
alias c1=... | c1라는 별칭을 만들어 CILIUMPOD1의 Cilium CLI 명령어에 접근합니다. |
alias c2=... | c2라는 별칭을 만들어 CILIUMPOD2의 Cilium CLI 명령어에 접근합니다. |
alias c0bpf=... | c0bpf라는 별칭을 만들어 CILIUMPOD0의 bpftool 명령어에 접근합니다. |
alias c1bpf=... | c1bpf라는 별칭을 만들어 CILIUMPOD1의 bpftool 명령어에 접근합니다. |
alias c2bpf=... | c2bpf라는 별칭을 만들어 CILIUMPOD2의 bpftool 명령어에 접근합니다. |
(⎈|CiliumLab:N/A) root@k8s-s:~# export CILIUMPOD0=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-s -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD1=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w1 -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD2=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w2 -o jsonpath='{.items[0].metadata.name}')
(⎈|CiliumLab:N/A) root@k8s-s:~# alias c0="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- cilium"
alias c1="kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- cilium"
alias c2="kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- cilium"
(⎈|CiliumLab:N/A) root@k8s-s:~# alias c0bpf="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- bpftool"
alias c1bpf="kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- bpftool"
alias c2bpf="kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- bpftool"
- Hubble UI 서비스를 Kubernetes 클러스터 내에서 NodePort 타입으로 설정하고, 이를 통해 Hubble UI에 접근할 수 있는 URL을 생성합니다.
kubectl patch -n kube-system svc hubble-ui -p '{"spec": {"type": "NodePort"}}' | Hubble UI 서비스의 타입을 NodePort로 변경합니다. |
HubbleUiNodePort=$(kubectl get svc -n kube-system hubble-ui -o jsonpath={.spec.ports[0].nodePort}) | Hubble UI 서비스의 NodePort를 변수 HubbleUiNodePort에 저장합니다. |
echo -e "Hubble UI URL = http://$(curl -s ipinfo.io/ip):$HubbleUiNodePort" | Hubble UI에 접근할 수 있는 URL을 출력합니다. |
(⎈|CiliumLab:N/A) root@k8s-s:~# kubectl patch -n kube-system svc hubble-ui -p '{"spec": {"type": "NodePort"}}'
service/hubble-ui patched
(⎈|CiliumLab:N/A) root@k8s-s:~# HubbleUiNodePort=$(kubectl get svc -n kube-system hubble-ui -o jsonpath={.spec.ports[0].nodePort})
(⎈|CiliumLab:N/A) root@k8s-s:~# echo -e "Hubble UI URL = http://$(curl -s ipinfo.io/ip):$HubbleUiNodePort"
Hubble UI URL = http://3.35.54.219:31274
- Kubernetes 클러스터 내의 모든 네임스페이스에서 Cilium Endpoint의 상태를 조회합니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# kubectl get ciliumendpoints -A
NAMESPACE NAME SECURITY IDENTITY ENDPOINT STATE IPV4 IPV6
kube-system coredns-55cb58b774-2xvk2 39166 ready 172.16.1.210
kube-system coredns-55cb58b774-7v788 39166 ready 172.16.1.221
kube-system hubble-relay-88f7f89d4-jgwk2 44886 ready 172.16.1.78
kube-system hubble-ui-59bb4cb67b-vr67b 42840 ready 172.16.1.79
✅Cilium의 IP 주소 할당
- IP 주소 할당:
- Cilium은 애플리케이션 컨테이너에 IP 주소를 할당하여 네트워크에서 접근할 수 있도록 합니다.
- 여러 개의 애플리케이션 컨테이너가 동일한 IP 주소를 공유할 수 있습니다.
- 여러 컨테이너가 같은 IP 주소를 사용할 때, Cilium에서는 이를 엔드포인트(endpoint) 라고 부릅니다. 엔드포인트는 같은 IP 주소를 가진 컨테이너 그룹을 나타냅니다.
- 포트 범위 사용:
- 각 엔드포인트에 개별 IP 주소를 할당하면, 각 포드가 Layer 4 포트 범위의 모든 포트를 사용할 수 있습니다.
- 즉, 동일한 클러스터 노드에서 실행 중인 여러 애플리케이션 컨테이너가 80번 포트와 같은 잘 알려진 포트에 동시에 바인딩(연결)할 수 있으며, 이는 충돌을 피하는 데 도움을 줍니다.
- IP 주소 관리(IPAM)
- Cilium은 IP 주소 할당 및 관리를 위해 IP 주소 관리(IPAM) 기능을 제공합니다.
🧿 Cilium 네트워크의 엔드포인트 목록
- 엔드포인트 905:
- POLICY : 인그레스 및 이그레스 정책 모두 비활성화 (Disabled).
- IDENTITY : 4로 설정되어 있으며, 레이블은 reserved:health로 나타나 건강 체크 엔드포인트를 나타냄.
- IPv4: 172.16.0.236 할당됨.
- 엔드포인트 1541:
- POLICY : 인그레스 및 이그레스 정책 모두 비활성화 (Disabled).
- IDENTITY : 1로 설정되어 있으며, 레이블은 k8s:node-role.kubernetes.io/control-plane, k8s:node.kubernetes.io/exclude-from-external-load-balancers, reserved:host를 포함하여 Kubernetes 제어 평면 노드임을 나타냄.
ENDPOINT | Cilium이 관리하는 엔드포인트의 고유 ID |
POLICY (ingress) | 인그레스(수신) 트래픽에 대한 정책 적용 상태 (Enabled/Disabled) |
POLICY (egress) | 이그레스(발신) 트래픽에 대한 정책 적용 상태 (Enabled/Disabled) |
IDENTITY | 엔드포인트의 보안 식별자 (Security Identity), 보안 정책에 사용 |
LABELS | 엔드포인트에 적용된 레이블, 키-값 쌍 형식으로 표시 |
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 endpoint list
ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS
ENFORCEMENT ENFORCEMENT
905 Disabled Disabled 4 reserved:health 172.16.0.236 ready
1541 Disabled Disabled 1 k8s:node-role.kubernetes.io/control-plane ready
k8s:node.kubernetes.io/exclude-from-external-load-balancers
reserved:host
🧿 Cilium BPF 에서 관리하는 엔드포인트의 목록
- 172.16.0.12:0와 192.168.10.10:0는 로컬 호스트의 IP 주소이며, 각각 포트 번호는 0입니다.
- 172.16.0.236:0:
- id: 905로 설정되어 있으며, Cilium 엔드포인트 ID입니다.
- sec_id: 4로 설정되어 있으며, 보안 식별자입니다.
- flags: 0x0000, 추가적인 플래그가 설정되어 있지 않음을 나타냅니다.
- ifindex: 8, 이 엔드포인트와 연결된 네트워크 인터페이스 인덱스입니다. 커널의 네트워크 인터페이스를 나타냄
- mac: 22:1F:BD:B2:24:65, 이 엔드포인트의 MAC 주소입니다.
- nodemac: BE:40:78:DD:72:24, 이 엔드포인트가 속한 노드의 MAC 주소입니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf endpoint list
IP ADDRESS LOCAL ENDPOINT INFO
172.16.0.12:0 (localhost)
172.16.0.236:0 id=905 sec_id=4 flags=0x0000 ifindex=8 mac=22:1F:BD:B2:24:65 nodemac=BE:40:78:DD:72:24
192.168.10.10:0 (localhost)
🧿 Cilium의 LXC(Linux Containers) 맵에서 특정 엔드포인트의 세부 정보
- Key: 172.16.0.236:0는 LXC 엔드포인트의 IP 주소 및 포트입니다. 포트 0은 LXC가 이 IP를 통해 동작함을 나타냅니다.
- Value:
- id=905: 엔드포인트의 고유 ID입니다.
- sec_id=4: 보안 식별자(Security Identity)로, 이 엔드포인트에 적용된 보안 정책을 정의합니다.
- flags=0x0000: 엔드포인트의 상태를 나타내는 플래그로, 0x0000은 특별한 설정이 없음을 의미합니다.
- ifindex=8: 네트워크 인터페이스 인덱스로, 이 엔드포인트와 연결된 인터페이스를 나타냅니다.
- mac=22:1F:BD:B2:24:65: 엔드포인트의 MAC 주소입니다.
- nodemac=BE:40:78:DD:72:24: 노드의 MAC 주소입니다.
- State: sync는 이 엔드포인트가 Cilium의 동기화 상태에 있으며 정상적으로 운영되고 있음을 나타냅니다.
- Error: 현재 오류가 없음을 나타냅니다.
✅cilium_lxc 맵의 주요 기능
- 엔드포인트 정보 저장:
- cilium_lxc 맵은 각 LXC 엔드포인트에 대한 정보를 저장합니다. 여기에는 IP 주소, 보안 식별자(security identity), MAC 주소 및 인터페이스 인덱스와 같은 속성이 포함됩니다.
- BPF와의 통합:
- Cilium은 BPF를 사용하여 고급 네트워킹 기능을 제공합니다. BPF 프로그램은 네트워크 패킷을 필터링하고 수정하는 데 사용되며, cilium_lxc 맵은 이러한 프로그램에서 참조됩니다.
- 동기화 및 상태 관리:
- Cilium은 클러스터의 각 엔드포인트 상태를 실시간으로 관리하고 동기화합니다. cilium_lxc 맵은 각 엔드포인트의 상태를 추적하여, 네트워크 정책을 적용하고 트래픽을 적절히 처리할 수 있도록 합니다.
- 보안 및 정책 적용:
- 보안 정책이 적용될 때, cilium_lxc 맵의 정보를 기반으로 해당 엔드포인트에 대한 패킷 필터링 및 트래픽 제어가 수행됩니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 map get cilium_lxc
Key Value State Error
172.16.0.236:0 id=905 sec_id=4 flags=0x0000 ifindex=8 mac=22:1F:BD:B2:24:65 nodemac=BE:40:78:DD:72:24 sync
✅ Cilium Identity
- 모든 엔드포인트에 정체성이 부여됨:
- Cilium에서는 네트워크의 모든 엔드포인트(예: Pod)에 고유한 정체성이 주어집니다. 이 정체성은 엔드포인트 간의 기본적인 연결성을 보장하는 데 사용됩니다.
- 전통적인 네트워킹 용어와의 비교:
- 전통적인 네트워크 용어로는 이 정체성 개념이 Layer 3 enforcement 과 비슷합니다. 즉, 네트워크에서 데이터가 어떻게 전송되는지를 결정하는 것입니다.
- 정체성의 구성:
- 각 정체성은 레이블에 의해 정의됩니다. 이 레이블은 클러스터 전체에서 유일한 식별자를 부여받습니다.
- 각 엔드포인트는 보안 관련 레이블(Security Relevant Labels) 에 따라 정체성이 부여됩니다. 예를 들어, 같은 보안 레이블을 가진 모든 엔드포인트는 같은 정체성을 공유하게 됩니다.
- 정책 집행의 확장성:
- 이 개념 덕분에 수많은 엔드포인트에 대해 정책을 쉽게 적용할 수 있습니다. 예를 들어, 많은 엔드포인트가 같은 보안 레이블을 공유하는 경우, 각각의 엔드포인트에 개별적으로 정책을 적용할 필요 없이, 동일한 정책을 적용할 수 있습니다.
- reserved: 접두어가 붙은 정체성은 Cilium 외부의 엔드포인트를 나타내는 데 사용됩니다.
Cilium은 Pod이나 컨테이너의 레이블에 따라 엔드포인트의 정체성을 정하고, 이 엔드포인트가 생성되면 정체성을 확인합니다. 레이블이 변경되면 정체성을 자동으로 업데이트하여 항상 최신 상태를 유지합니다.
🧿 Cilium이 관리하는 IP 주소와 해당 IP에 대한 보안 정체성 및 소스 정보
- IDENTITY:
- Cilium이 각 IP에 부여하는 보안 정체성을 나타냅니다. 이 정체성은 네트워크 보안 정책을 적용하는 데 사용
- SOURCE:
- 해당 IP 주소가 생성된 리소스의 종류를 설명합니다.
- 예를 들어, custom-resource는 Kubernetes 리소스에 의해 생성된 IP임을 나타냅니다.
- reserved:host는 해당 IP가 호스트에 속함을 의미합니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 ip list
IP IDENTITY SOURCE
0.0.0.0/0 reserved:world
172.16.0.12/32 reserved:host
reserved:kube-apiserver
172.16.0.236/32 reserved:health
172.16.1.78/32 k8s:app.kubernetes.io/name=hubble-relay custom-resource
k8s:app.kubernetes.io/part-of=cilium
k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system
k8s:io.cilium.k8s.policy.cluster=default
k8s:io.cilium.k8s.policy.serviceaccount=hubble-relay
k8s:io.kubernetes.pod.namespace=kube-system
k8s:k8s-app=hubble-relay
172.16.1.79/32 k8s:app.kubernetes.io/name=hubble-ui custom-resource
k8s:app.kubernetes.io/part-of=cilium
k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system
k8s:io.cilium.k8s.policy.cluster=default
k8s:io.cilium.k8s.policy.serviceaccount=hubble-ui
k8s:io.kubernetes.pod.namespace=kube-system
k8s:k8s-app=hubble-ui
172.16.1.159/32 reserved:health
172.16.1.198/32 reserved:remote-node
172.16.1.210/32 k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system custom-resource
k8s:io.cilium.k8s.policy.cluster=default
k8s:io.cilium.k8s.policy.serviceaccount=coredns
k8s:io.kubernetes.pod.namespace=kube-system
k8s:k8s-app=kube-dns
172.16.1.221/32 k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system custom-resource
k8s:io.cilium.k8s.policy.cluster=default
k8s:io.cilium.k8s.policy.serviceaccount=coredns
k8s:io.kubernetes.pod.namespace=kube-system
k8s:k8s-app=kube-dns
172.16.2.73/32 reserved:health
172.16.2.116/32 reserved:remote-node
192.168.10.10/32 reserved:host
reserved:kube-apiserver
192.168.10.101/32 reserved:remote-node
192.168.10.102/32 reserved:remote-node
✅ Cilium IP Cache
- IP 주소 및 엔드포인트 정보 저장:
- 네트워크에서 사용되는 IP 주소와 그 주소에 연결된 엔드포인트(endpoint)에 대한 정보를 저장합니다.
- 빠른 조회:
- 특정 IP 주소에 대한 엔드포인트 정보를 빠르게 조회할 수 있습니다. 이는 네트워크 패킷이 들어오거나 나갈 때, 패킷을 처리하는 속도를 높이는 데 기여합니다.
- 즉, IP 주소에 대한 정보가 캐시에 이미 있다면, Cilium은 매번 데이터베이스나 API 서버에 요청하지 않고도 빠르게 해당 정보를 가져올 수 있습니다.
- 정책 적용:
- Cilium은 IP Cache를 사용하여 네트워크 정책을 신속하게 적용할 수 있습니다. 예를 들어, 특정 IP 주소에 대해 설정된 보안 규칙이나 트래픽 흐름 규칙을 캐시에서 바로 조회할 수 있습니다.
- 이를 통해 네트워크 보안을 강화하고, 패킷 필터링이나 로드 밸런싱 등의 작업을 효율적으로 수행할 수 있습니다.
- 정기적인 업데이트:
- IP Cache는 동적 환경에서 IP 주소가 변경되거나 새로운 엔드포인트가 추가될 때 자동으로 업데이트됩니다.
- Cilium 에이전트는 Kubernetes API로부터 변경 사항을 감지하고 캐시를 갱신하여 최신 정보를 유지합니다.
- TTL(Time to Live):
- IP Cache의 항목은 TTL(유효 시간)을 설정할 수 있어, 일정 시간 동안 사용되지 않은 캐시 항목은 자동으로 삭제됩니다.
- 이는 메모리 사용을 최적화하고, 오래된 정보로 인해 발생할 수 있는 문제를 방지합니다.
🧿 Cilium에서 IP 캐시(IP Cache)에 저장된 IP 주소와 해당 IDENTITY 정보
- IP PREFIX/ADDRESS:
- IP 주소 및 서브넷 마스크를 포함합니다. /32는 단일 호스트를 나타내며, /24는 클래스 C 네트워크를 나타냅니다.
- IDENTITY:
- Cilium에서 정의된 보안 정체성을 나타냅니다. 각 IP 주소에 대해 Cilium은 고유한 정체성을 부여하여 보안 정책을 적용합니다.
- ENCRYPTKEY:
- 이 필드는 IP 패킷 암호화에 사용되는 키를 나타내지만, 현재 값이 0이면 암호화가 활성화되어 있지 않음을 의미합니다.
- TUNNELENDPOINT:
- IP 패킷이 터널을 통해 전송되는 경우, 이 필드는 터널의 종단점 IP 주소를 나타냅니다. 0.0.0.0은 해당 IP가 터널링되지 않음을 나타냅니다.
- FLAGS:
- 추가적인 플래그 정보로, 현재는 <none>으로 설정되어 있습니다. 이는 특별한 플래그가 없음을 의미합니다.
Cilium이 IP 주소에 대한 상태 정보를 저장하고 있으며, 이를 통해 각 IP에 대한 보안 정책 및 엔드포인트 상태를 관리함을 보여줍니다. Cilium은 이 정보를 사용하여 네트워크 보안을 강화하고, 정책 집행을 수행합니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf ipcache list
IP PREFIX/ADDRESS IDENTITY
172.16.2.73/32 identity=4 encryptkey=0 tunnelendpoint=192.168.10.102, flags=<none>
192.168.10.10/32 identity=1 encryptkey=0 tunnelendpoint=0.0.0.0, flags=<none>
192.168.10.102/32 identity=6 encryptkey=0 tunnelendpoint=0.0.0.0, flags=<none>
172.16.1.78/32 identity=44886 encryptkey=0 tunnelendpoint=192.168.10.101, flags=<none>
172.16.1.198/32 identity=6 encryptkey=0 tunnelendpoint=192.168.10.101, flags=<none>
172.16.2.116/32 identity=6 encryptkey=0 tunnelendpoint=192.168.10.102, flags=<none>
172.16.1.79/32 identity=42840 encryptkey=0 tunnelendpoint=192.168.10.101, flags=<none>
172.16.1.159/32 identity=4 encryptkey=0 tunnelendpoint=192.168.10.101, flags=<none>
172.16.0.12/32 identity=1 encryptkey=0 tunnelendpoint=0.0.0.0, flags=<none>
172.16.1.221/32 identity=39166 encryptkey=0 tunnelendpoint=192.168.10.101, flags=<none>
192.168.10.101/32 identity=6 encryptkey=0 tunnelendpoint=0.0.0.0, flags=<none>
0.0.0.0/0 identity=2 encryptkey=0 tunnelendpoint=0.0.0.0, flags=<none>
172.16.0.236/32 identity=4 encryptkey=0 tunnelendpoint=0.0.0.0, flags=<none>
172.16.1.210/32 identity=39166 encryptkey=0 tunnelendpoint=192.168.10.101, flags=<none>
🧿 Cilium에서 관리하는 서비스 목록
- Frontend:
- 클라이언트가 요청을 보내는 서비스의 IP 주소 및 포트입니다.
- ClusterIP 서비스는 클러스터 내부에서만 접근 가능하고, NodePort 서비스는 외부에서도 접근할 수 있습니다.
- Service Type:
- 서비스의 종류를 나타냅니다.
- ClusterIP: 클러스터 내부에서만 접근 가능한 서비스입니다.
- NodePort: 클러스터의 모든 노드에서 접근 가능한 포트를 엽니다.
- 서비스의 종류를 나타냅니다.
- Backend:
- 각 서비스에 연결된 백엔드 엔드포인트를 나타냅니다.
- 1 => 192.168.10.10:6443 (active)와 같은 형식으로 나타나며, 이는 프론트엔드 서비스가 백엔드로 포워딩되는 IP 주소와 포트를 의미합니다.
- (active)는 해당 백엔드가 활성 상태임을 나타냅니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 service list
ID Frontend Service Type Backend
1 10.10.0.1:443 ClusterIP 1 => 192.168.10.10:6443 (active)
2 10.10.92.90:443 ClusterIP 1 => 192.168.10.10:4244 (active)
3 10.10.203.229:80 ClusterIP 1 => 172.16.1.78:4245 (active)
4 10.10.201.143:80 ClusterIP 1 => 172.16.1.79:8081 (active)
5 10.10.0.10:53 ClusterIP 1 => 172.16.1.221:53 (active)
2 => 172.16.1.210:53 (active)
6 10.10.0.10:9153 ClusterIP 1 => 172.16.1.221:9153 (active)
2 => 172.16.1.210:9153 (active)
7 192.168.10.10:31274 NodePort 1 => 172.16.1.79:8081 (active)
8 0.0.0.0:31274 NodePort 1 => 172.16.1.79:8081 (active)
🧿 Cilium의 로드 밸런싱 정보
- SERVICE ADDRESS:
- 클라이언트가 접근하는 서비스의 IP 주소와 포트입니다.
- (0) 또는 (1)과 같은 숫자는 로드 밸런싱 슬롯을 나타냅니다.
- BACKEND ADDRESS (REVNAT_ID) (SLOT):
- 실제 트래픽이 전달되는 백엔드 IP 주소와 포트입니다.
- REVNAT_ID는 해당 주소의 고유 식별자입니다.
- (SLOT)은 이 백엔드가 연결된 슬롯 번호입니다.
- 서비스 유형:
- [ClusterIP, non-routable]: 클러스터 내부에서만 접근 가능한 서비스로, 외부에서는 접근할 수 없습니다.
- [NodePort]: 클러스터 외부에서도 접근할 수 있는 서비스입니다.
- [InternalLocal, non-routable]: 클러스터 내부에서만 접근 가능하며, 다른 클러스터와는 통신할 수 없습니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf lb list
SERVICE ADDRESS BACKEND ADDRESS (REVNAT_ID) (SLOT)
10.10.0.10:53 (0) 0.0.0.0:0 (5) (0) [ClusterIP, non-routable]
0.0.0.0:31274 (1) 172.16.1.79:8081 (8) (1)
10.10.0.1:443 (1) 192.168.10.10:6443 (1) (1)
10.10.203.229:80 (0) 0.0.0.0:0 (3) (0) [ClusterIP, non-routable]
10.10.92.90:443 (1) 192.168.10.10:4244 (2) (1)
10.10.203.229:80 (1) 172.16.1.78:4245 (3) (1)
10.10.0.1:443 (0) 0.0.0.0:0 (1) (0) [ClusterIP, non-routable]
10.10.0.10:9153 (0) 0.0.0.0:0 (6) (0) [ClusterIP, non-routable]
10.10.92.90:443 (0) 0.0.0.0:0 (2) (0) [ClusterIP, InternalLocal, non-routable]
10.10.201.143:80 (0) 0.0.0.0:0 (4) (0) [ClusterIP, non-routable]
192.168.10.10:31274 (0) 0.0.0.0:0 (7) (0) [NodePort]
10.10.0.10:53 (2) 172.16.1.210:53 (5) (2)
192.168.10.10:31274 (1) 172.16.1.79:8081 (7) (1)
10.10.201.143:80 (1) 172.16.1.79:8081 (4) (1)
10.10.0.10:9153 (2) 172.16.1.210:9153 (6) (2)
10.10.0.10:53 (1) 172.16.1.221:53 (5) (1)
0.0.0.0:31274 (0) 0.0.0.0:0 (8) (0) [NodePort, non-routable]
10.10.0.10:9153 (1) 172.16.1.221:9153 (6) (1)
✅ Cilium Reverse NAT
- 서비스에 대한 접근:
- Cilium은 클러스터 내에서 실행 중인 서비스에 대한 접근을 관리합니다. 외부에서 클러스터 내의 서비스로 요청이 들어올 때 Reverse NAT를 사용하여 요청을 적절한 Pod로 전달합니다.
- 서비스의 가시성:
- Reverse NAT를 통해 외부 요청은 클러스터 내부의 특정 Pod로 전송됩니다. 이를 통해 클러스터의 서비스가 외부에서 접근 가능하게 됩니다.
- IP 주소 관리:
- Cilium은 각 Pod의 IP 주소를 관리하며, Reverse NAT를 통해 외부 IP와 내부 IP 간의 변환을 수행합니다. 이로 인해 클러스터 내의 Pod는 외부 트래픽을 효과적으로 처리할 수 있습니다.
Cilium Reverse NAT는 외 외부에서 들어오는 요청을 클러스터 내의 특정 Pod로 전달하는 기능입니다. 이를 통해 클러스터 내의 서비스가 외부에서 접근 가능하게 되고, IP 주소를 효율적으로 관리할 수 있습니다.
🧿 Cilium의 리버스 NAT (Reverse NAT) 정보
- BACKEND ADDRESS (REVNAT_ID) (SLOT):
- 실제 백엔드 IP 주소와 포트입니다.
- 이 주소는 클라이언트 요청이 도착할 때 해당 서비스로 라우팅됩니다.
- (SLOT)은 특정 백엔드가 연결된 로드 밸런싱 슬롯 번호입니다.
- 리버스 NAT:
- 리버스 NAT는 외부 트래픽이 내부 서비스로 올 때, 클러스터 내의 실제 백엔드 IP 주소로 트래픽을 전달하는 데 사용됩니다.
- 이 기능은 Cilium이 로드 밸런싱을 수행하고, 서비스가 외부 요청을 처리하는 데 필요한 정보를 제공합니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf lb list --revnat
ID BACKEND ADDRESS (REVNAT_ID) (SLOT)
6 10.10.0.10:9153
8 0.0.0.0:31274
4 10.10.201.143:80
2 10.10.92.90:443
3 10.10.203.229:80
7 192.168.10.10:31274
1 10.10.0.1:443
5 10.10.0.10:53
🧿 Cilium에서 네트워크 주소 변환(NAT) 정보
프로토콜 | 방향 | 원본 주소:포트 | 목적지 주소:포트 | 변환 유형 | 변환 결과 주소:포트 |
UDP | IN | 169.254.169.123:123 | 192.168.10.10:37218 | XLATE_DST | 192.168.10.10:37218 |
TCP | OUT | 112.152.82.177:61916 | 172.16.1.79:8081 | XLATE_SRC | 192.168.10.10:61916 |
ICMP | OUT | 192.168.10.10:36167 | 192.168.10.101:0 | XLATE_SRC | 192.168.10.10:36167 |
UDP | IN | 169.254.169.123:123 | 192.168.10.10:57771 | XLATE_DST | 192.168.10.10:57771 |
TCP | OUT | 112.152.82.177:61924 | 172.16.1.79:8081 | XLATE_SRC | 192.168.10.10:61924 |
UDP | OUT | 192.168.10.10:57771 | 169.254.169.123:123 | XLATE_SRC | 192.168.10.10:57771 |
UDP | OUT | 192.168.10.10:35096 | 192.168.0.2:53 | XLATE_SRC | 192.168.10.10:35096 |
UDP | IN | 192.168.0.2:53 | 192.168.10.10:35096 | XLATE_DST | 192.168.10.10:35096 |
ICMP | OUT | 192.168.10.10:35577 | 172.16.2.73:0 | XLATE_SRC | 192.168.10.10:35577 |
UDP | OUT | 192.168.10.10:60997 | 169.254.169.123:123 | XLATE_SRC | 192.168.10.10:60997 |
ICMP | OUT | 192.168.10.10:35577 | 172.16.1.159:0 | XLATE_SRC | 192.168.10.10:35577 |
UDP | IN | 169.254.169.123:123 | 192.168.10.10:44380 | XLATE_DST | 192.168.10.10:44380 |
UDP | IN | 169.254.169.123:123 | 192.168.10.10:33729 | XLATE_DST | 192.168.10.10:33729 |
UDP | OUT | 192.168.10.10:42289 | 169.254.169.123:123 | XLATE_SRC | 192.168.10.10:42289 |
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf nat list
UDP IN 169.254.169.123:123 -> 192.168.10.10:37218 XLATE_DST 192.168.10.10:37218 Created=183sec ago NeedsCT=1
TCP OUT 112.152.82.177:61916 -> 172.16.1.79:8081 XLATE_SRC 192.168.10.10:61916 Created=222sec ago NeedsCT=0
ICMP OUT 192.168.10.10:36167 -> 192.168.10.101:0 XLATE_SRC 192.168.10.10:36167 Created=166sec ago NeedsCT=1
UDP IN 169.254.169.123:123 -> 192.168.10.10:57771 XLATE_DST 192.168.10.10:57771 Created=491sec ago NeedsCT=1
TCP OUT 112.152.82.177:61924 -> 172.16.1.79:8081 XLATE_SRC 192.168.10.10:61924 Created=219sec ago NeedsCT=0
UDP OUT 192.168.10.10:57771 -> 169.254.169.123:123 XLATE_SRC 192.168.10.10:57771 Created=491sec ago NeedsCT=1
UDP OUT 192.168.10.10:35096 -> 192.168.0.2:53 XLATE_SRC 192.168.10.10:35096 Created=237sec ago NeedsCT=1
UDP IN 192.168.0.2:53 -> 192.168.10.10:35096 XLATE_DST 192.168.10.10:35096 Created=237sec ago NeedsCT=1
ICMP OUT 192.168.10.10:35577 -> 172.16.2.73:0 XLATE_SRC 192.168.10.10:35577 Created=106sec ago NeedsCT=1
UDP OUT 192.168.10.10:60997 -> 169.254.169.123:123 XLATE_SRC 192.168.10.10:60997 Created=200sec ago NeedsCT=1
ICMP OUT 192.168.10.10:35577 -> 172.16.1.159:0 XLATE_SRC 192.168.10.10:35577 Created=106sec ago NeedsCT=1
UDP IN 169.254.169.123:123 -> 192.168.10.10:44380 XLATE_DST 192.168.10.10:44380 Created=329sec ago NeedsCT=1
UDP IN 169.254.169.123:123 -> 192.168.10.10:33729 XLATE_DST 192.168.10.10:33729 Created=6sec ago NeedsCT=1
UDP OUT 192.168.10.10:42289 -> 169.254.169.123:123 XLATE_SRC 192.168.10.10:42289 Created=410sec ago NeedsCT=1
...
✅ BPF maps
- 데이터 저장소:
- BPF 맵은 key-value 형태로 데이터를 저장하는 구조입니다. 여기서 key는 고유한 식별자이며, value는 해당 key에 연결된 데이터입니다. 예를 들어, IP 주소를 key로 사용하고, 그에 대한 통계 정보를 value로 저장할 수 있습니다.
- 다양한 유형:
- BPF 맵은 여러 가지 유형이 있으며, 각 유형은 특정 용도에 맞게 설계되었습니다. 주요 유형은 다음과 같습니다:
- Hash Map: 키를 해시하여 저장하는 일반적인 형태의 맵.
- Array Map: 정수 인덱스를 사용하여 값을 저장하는 배열 형태.
- Per-CPU Map: 각 CPU마다 별도의 데이터를 저장하여 성능을 향상시키는 맵.
- LRU(Least Recently Used) Map: 메모리가 부족할 때 가장 오랫동안 사용되지 않은 데이터를 삭제하는 형태.
- BPF 맵은 여러 가지 유형이 있으며, 각 유형은 특정 용도에 맞게 설계되었습니다. 주요 유형은 다음과 같습니다:
- 성능 및 확장성:
- BPF 맵은 커널 내에서 실행되기 때문에 매우 빠르고 효율적입니다. 그러나 각 맵에는 저장할 수 있는 데이터의 양에 제한이 있으며, 이로 인해 성능에 영향을 줄 수 있습니다.
- 데이터 접근:
- eBPF 프로그램은 BPF 맵에 데이터를 읽고 쓰는 작업을 수행할 수 있습니다. 이를 통해 패킷 통계, 트래픽 필터링, 성능 모니터링 등 다양한 작업을 수행할 수 있습니다.
eBPF(Extended Berkeley Packet Filter)에서 데이터를 저장하고 관리하기 위해 사용되는 자료 구조입니다.
BPF 맵은 저장할 수 있는 데이터의 양에 제한이 있으며, 이 한계를 초과하면 데이터 삽입이 실패합니다. 기본적으로 설정된 용량은 소스 코드에서 조정할 수 있고, 필요에 따라 추가적인 설정 옵션이 제공될 수 있습니다. 이로 인해 데이터 경로의 확장성에 제약이 발생할 수 있습니다.
🧿 Cilium이 네트워킹 기능을 처리하기 위해 유지하는 다양한 내부 맵 정보
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 map list
Name Num entries Num errors Cache enabled
cilium_lb4_source_range 0 0 true
cilium_runtime_config 256 0 true
cilium_lb4_reverse_nat 8 0 true
cilium_lb4_affinity 0 0 true
cilium_lb4_reverse_sk 0 0 true
cilium_lb4_backends_v3 2 0 true
cilium_policy_01541 2 0 true
cilium_lxc 1 0 true
cilium_ipmasq_v4 12 0 true
cilium_policy_00905 3 0 true
cilium_ipcache 14 0 true
cilium_lb4_services_v2 18 0 true
cilium_lb_affinity_match 0 0 true
cilium_metrics 0 0 false
cilium_skip_lb4 0 0 false
cilium_l2_responder_v4 0 0 false
cilium_node_map 0 0 false
cilium_auth_map 0 0 false
cilium_node_map_v2 0 0 false
🧿 Cilium과 관련된 BPF 정책 정보
- 엔드포인트 ID: 905
- Ingress에서 reserved:unknown과 reserved:host가 각각 31,868 바이트와 22,485 바이트의 트래픽을 허용하고 있습니다.
- reserved:kube-apiserver는 라벨이 있지만 트래픽이 나타나지 않습니다.
- Egress에서 reserved:unknown은 허용되지만 트래픽은 없습니다.
- 엔드포인트 ID: 1541
- Ingress와 Egress 모두 트래픽이 없습니다. 즉, 이 엔드포인트는 현재 어떤 트래픽도 처리하지 않고 있습니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf policy get --all
Endpoint ID: 905
Path: /sys/fs/bpf/tc/globals/cilium_policy_00905
POLICY DIRECTION LABELS (source:key[=value]) PORT/PROTO PROXY PORT AUTH TYPE BYTES PACKETS PREFIX
Allow Ingress reserved:unknown ANY NONE disabled 31868 399 0
Allow Ingress reserved:host ANY NONE disabled 22485 255 0
reserved:kube-apiserver
Allow Egress reserved:unknown ANY NONE disabled 0 0 0
Endpoint ID: 1541
Path: /sys/fs/bpf/tc/globals/cilium_policy_01541
POLICY DIRECTION LABELS (source:key[=value]) PORT/PROTO PROXY PORT AUTH TYPE BYTES PACKETS PREFIX
Allow Ingress reserved:unknown ANY NONE disabled 0 0 0
Allow Egress reserved:unknown ANY NONE disabled 0 0 0
(⎈|CiliumLab:N/A) root@k8s-s:~# c0 bpf policy get --all -n
Endpoint ID: 905
Path: /sys/fs/bpf/tc/globals/cilium_policy_00905
POLICY DIRECTION IDENTITY PORT/PROTO PROXY PORT AUTH TYPE BYTES PACKETS PREFIX
Allow Ingress 0 ANY NONE disabled 32000 401 0
Allow Ingress 1 ANY NONE disabled 22551 256 0
Allow Egress 0 ANY NONE disabled 0 0 0
Endpoint ID: 1541
Path: /sys/fs/bpf/tc/globals/cilium_policy_01541
POLICY DIRECTION IDENTITY PORT/PROTO PROXY PORT AUTH TYPE BYTES PACKETS PREFIX
Allow Ingress 0 ANY NONE disabled 0 0 0
Allow Egress 0 ANY NONE disabled 0 0 0
✅ cilium_net과 cilium_host
cilium_net
- 정의:
- cilium_net는 Cilium이 관리하는 가상 네트워크 인터페이스입니다. 이 인터페이스는 Cilium의 eBPF 프로그램을 통해 네트워크 트래픽을 처리하고 제어합니다.
- 기능:
- Cilium은 Pod 간의 통신을 관리하기 위해 cilium_net 인터페이스를 사용합니다. 이를 통해 Cilium은 보안 정책을 적용하고, 패킷을 필터링하며, 네트워크 성능을 최적화할 수 있습니다.
- cilium_net 인터페이스는 각 Pod에 대해 생성되며, Pod의 IP 주소와 연결됩니다.
- 패킷 처리:
- 이 인터페이스는 eBPF 프로그램이 패킷을 검사하고 처리할 수 있도록 해줍니다. 따라서 Cilium은 커널 레벨에서 패킷을 효율적으로 처리할 수 있습니다.
cilium_host
- 정의:
- cilium_host는 Cilium이 관리하는 호스트 네트워크 인터페이스입니다. 이 인터페이스는 클러스터 내의 Pod와 외부 네트워크 간의 연결을 처리합니다.
- 기능:
- cilium_host는 Cilium이 Pod에서 나가는 트래픽과 외부에서 들어오는 트래픽을 처리하는 데 사용됩니다. 즉, Pod가 외부 네트워크와 통신할 때 이 인터페이스를 통해 이루어집니다.
- 이 인터페이스는 외부에서 들어오는 요청을 적절한 Pod로 전달하는 Reverse NAT 기능을 포함합니다.
- 네트워크 연결:
- cilium_host는 Cilium이 클러스터 내의 Pod와 외부 네트워크 간의 통신을 관리하기 위해 필수적인 역할을 합니다. 이를 통해 Cilium은 네트워크 정책을 적용하고, 외부와의 안전한 연결을 유지할 수 있습니다.
🧿 시스템의 네트워크 인터페이스 정보
- cilium_net와 cilium_host: Cilium이 사용하는 가상 네트워크 인터페이스입니다. Cilium은 Kubernetes 클러스터에서 컨테이너 간의 네트워크 통신을 관리합니다.
- lxc_health@if7: LXC(리눅스 컨테이너) 환경에서 사용하는 인터페이스입니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# ip -br -c link
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
ens5 UP 02:ca:b4:99:6a:93 <BROADCAST,MULTICAST,UP,LOWER_UP>
cilium_net@cilium_host UP 9e:49:6a:bb:a4:d7 <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP>
cilium_host@cilium_net UP 4a:69:bb:d6:61:c6 <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP>
lxc_health@if7 UP be:40:78:dd:72:24 <BROADCAST,MULTICAST,UP,LOWER_UP>
(⎈|CiliumLab:N/A) root@k8s-s:~# ip -br -c addr
lo UNKNOWN 127.0.0.1/8 ::1/128
ens5 UP 192.168.10.10/24 metric 100 fe80::ca:b4ff:fe99:6a93/64
cilium_net@cilium_host UP fe80::9c49:6aff:febb:a4d7/64
cilium_host@cilium_net UP 172.16.0.12/32 fe80::4869:bbff:fed6:61c6/64
lxc_health@if7 UP fe80::bc40:78ff:fedd:7224/64
🧿 Cilium의 가상 네트워크 인터페이스인 cilium_net과 cilium_host에 대한 IP 주소 및 기타 네트워크 정보
- cilium_net 은 가상 네트워크를 나타내며, IPv6 주소를 가지고 있습니다.
- cilium_host 는 Cilium에서 호스트 네트워크와 통신하기 위해 사용되며, IPv4 주소를 할당받고 있습니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# ip -c addr show cilium_net ; ip -c addr show cilium_host
3: cilium_net@cilium_host: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default qlen 1000
link/ether 9e:49:6a:bb:a4:d7 brd ff:ff:ff:ff:ff:ff
inet6 fe80::9c49:6aff:febb:a4d7/64 scope link
valid_lft forever preferred_lft forever
4: cilium_host@cilium_net: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default qlen 1000
link/ether 4a:69:bb:d6:61:c6 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.12/32 scope global cilium_host
valid_lft forever preferred_lft forever
inet6 fe80::4869:bbff:fed6:61c6/64 scope link
valid_lft forever preferred_lft forever
✅ cilium_net과 cilium_host의 Proxy ARP
- Proxy ARP란? Proxy ARP는 특정 장치가 네트워크 내에서 다른 장치를 대신해 ARP 요청을 처리하는 기능입니다
- cilium_net의 Proxy ARP:
- cilium_net 인터페이스에서 proxy ARP 기능이 활성화되면, Cilium은 Pod의 IP 주소에 대한 ARP 요청을 처리할 수 있습니다. 즉, Pod가 아닌 Cilium 자체가 다른 장치에게 Pod의 MAC 주소를 응답합니다.
- 이를 통해 Pod가 같은 서브넷에 있지 않은 다른 장치와 통신할 수 있게 됩니다. 예를 들어, cilium_net은 특정 IP 주소에 대해 ARP 응답을 보내어 다른 장치가 올바른 MAC 주소로 패킷을 전송할 수 있도록 돕습니다.
- cilium_host의 Proxy ARP:
- cilium_host 인터페이스에서도 proxy ARP 기능이 사용됩니다. 이 경우, 외부 네트워크에서 들어오는 요청이 Cilium을 통해 Pod로 라우팅될 수 있도록 도와줍니다.
- Cilium은 외부에서 들어오는 트래픽에 대한 ARP 요청을 처리하여, 요청을 Pod로 전달할 때 필요한 MAC 주소를 제공합니다. 이를 통해 외부 네트워크에서 Pod와의 통신이 가능해집니다.
🧿 cilium_net과 cilium_host의 proxy_arp 설정
- 두 인터페이스 모두 proxy ARP가 비활성화됨 (값: 0). 이는 외부 네트워크의 호스트가 이 인터페이스들로의 직접적인 통신이 불가능함을 의미합니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# cat /proc/sys/net/ipv4/conf/cilium_net/proxy_arp
0
(⎈|CiliumLab:N/A) root@k8s-s:~# cat /proc/sys/net/ipv4/conf/cilium_host/proxy_arp
0
🧿 현재 시스템의 네트워크 네임스페이스에 대한 정보
- cilium-health-responder는 Cilium의 건강 상태를 확인하기 위한 프로세스입니다. 이 프로세스는 특정 포트(4240)에서 요청을 수신하도록 설정되어 있습니다.
- cilium-health-responder 프로세스는 Cilium이 정상적으로 작동하는지 확인하기 위한 모니터링 역할을 하며, 기본 네임스페이스에서 실행되고 있습니다.
(⎈|CiliumLab:N/A) root@k8s-s:~# lsns -t net
NS TYPE NPROCS PID USER NETNSID NSFS COMMAND
4026531840 net 143 1 root unassigned /sbin/init
4026532328 net 1 10315 root 0 cilium-health-responder --listen 4240 --pidfile /var/run/cilium/state/health-endpoint.pid
'쿠버네티스 네트워크 스터디 3기' 카테고리의 다른 글
[8주차] Cilium CNI : 노드 간 파드 통신 확인 (0) | 2024.10.21 |
---|---|
[8주차] Cilium CNI : Hubble UI & CLI (0) | 2024.10.21 |
[8주차] Cilium CNI : Cilium 이란? (0) | 2024.10.21 |
[7주차] Service Mesh : Traffic Management : TCP Traffic Shifting (0) | 2024.10.15 |
[7주차] Service Mesh : Traffic Management : Request Timeouts (0) | 2024.10.15 |