본문 바로가기
스터디 이야기/Kubernetes Advanced Networking Study

[KANS] Cilium CNI

by lakescript 2024. 10. 26.
728x90
더보기

이 스터디는 CloudNet@에서 진행하는 KANS 스터디를 참여하면서 공부하는 내용을 기록하는 블로그 포스팅입니다.

CloudNet@에서 제공해주는 자료들을 바탕으로 작성되었습니다.

 

Cilium CNI

 

Cilium이란?

https://isovalent.com/blog/post/migrating-from-metallb-to-cilium/

 

Cilium CNI는 Kubernetes와 같은 컨테이너 오케스트레이션 플랫폼에서 네트워킹을 관리하는 데 사용되는 오픈 소스 네트워킹 플러그인입니다. 특히, Cilium은 eBPF(extended Berkeley Packet Filter)를 사용하여 네트워크 패킷을 커널 수준에서 처리할 수 있는 고성능 네트워킹 기능을 제공합니다.

 

즉, Cilium은 eBPF (Berkeley Packet Filter)를 기반으로 Pod Network 환경과 보안 을 제공하는 CNI Plugin입니다.

 

 

 

Cilium은 Network Interface의 TC(Traffic Control)의 Ingress Hook에 eBPF 프로그램을 붙여, 들어오는 모든 패킷을 가로채서 처리합니다.

 

네트워크 모드

Cilium CNI는 터널 모드(VXLAN, GENEVE), 네이티브 라우팅 모드의 2가지 네트워크 모드를 제공합니다.

 

Turnel Mode

Tunnel Mode에서는 Cilium이 VXLAN 또는 Geneve이라는 터널링 프로토콜을 사용하여 트래픽을 전송합니다. 이때, VXLAN은 UDP 8472 포트, Geneve는 UDP 6081 포트를 사용하여 서로 다른 네트워크의 Pod들 간에 네트워크 트래픽을 전달할 수 있는 가상 터널을 설정합니다.

 

즉, Tunnel Mode는 Cilium이 각 네트워크의 Pod들이 서로 쉽게 통신할 수 있도록 가상의 터널을 만들어주는 방식입니다. 이 터널을 통해 다른 네트워크에 있는 Pod끼리 데이터를 주고받을 수 있습니다.

 

Native-Routing Mode

Native-Routing Mode는 터널링을 사용하지 않고, 네트워크의 기본 라우팅 기능을 그대로 활용하는 모드입니다. 이 모드에서는 Cilium이 네트워크 상의 연결성 설정을 직접 하지 않으며, 클러스터 외부)에서 Pod 간 통신을 위한 라우팅을 설정해야 합니다. 

 

즉, Cilium이 통신 연결을 관리하지 않고 네트워크 연결을 외부에서 알아서 처리해주는 모드입니다. Cilium은 기본 네트워크 라우팅을 이용하기만 할 뿐, 따로 통신 경로를 만드는 역할을 하지 않아서 네트워크 설정이 외부에 맡겨져 있는 설정입니다. 이 모드는 클라우드 환경에서 Pod 간 통신에 터널링을 사용하지 않도록 최적화할 때 유용하며, 트래픽 오버헤드를 줄일 수 있다는 장점이 있습니다.

 

100% Kube-proxy replacement

Cilium CNI는 iptables 거의 사용하지 않아도 동작합니다. 하지만 iptables 기능을 활용하는 일부 동작들은 이슈가 발생할 수 있어서 지속해서 해당 이슈를 해결하고 있습니다. 

기존의 IPtables 를 사용하지 않고, eBPF 로 Masqueading(SNAT) 처리

 

Cilium 아키텍처

https://docs.cilium.io/en/stable/overview/component-overview/

Cilium의 아키텍처는 여러 구성 요소로 이루어져 Kubernetes 클러스터의 네트워킹과 보안을 관리합니다. 

  • Cilium Agent : 데몬셋으로 각 노드에서 실행되며, K8s-API설정부터 네트워크 설정, 네트워크 정책 설정, 서비스 부하분산 설정, 모니터링 등을 수행하며, eBPF 프로그램을 관리하여 Pod간 트래픽을 제어합니다.
  • Cilium Client (CLI) : Cilium 커멘드툴로써 eBPF maps 에 직접 접속하여 상태를 확인할 수 있습니다.
  • Cilium Operator : K8s 클러스터 전반의 IP 할당을 담당하는데, 그외에  IP 주소 할당 초기화, 데이터베이스 정리, 노드 간 동기화 작업 등 클러스터 설정이나 리소스 구성에 영향을 주는 특정 작업을 관리하여 일관성을 유지하는 역할을 담당합니다. 
  • Hubble : 네트워크와 보안 모니터링 플랫폼 역할을 하여, 'Server, Relay, Client, Graphical UI' 로 구성되어 있습니다.
  • Data Store : Cilium Agent 간의 상태를 저장하고 전파하는 데이터 저장소로써 2가지 종류(K8S CRDs, Key-Value Store) 중 선택해서 설정합니다.

 

Hubble

 

Hubble은 클라우드 네이티브 워크로드를 위한 완전 분산형 네트워킹 및 보안 가시성 플랫폼입니다. Hubble은 오픈 소스 소프트웨어이며, Cilium과 eBPF 위에 구축되어 서비스 간의 통신과 동작뿐만 아니라 네트워킹 인프라에 대해 깊이 있는 가시성을 완전히 투명한 방식으로 제공합니다. 

 

Hubble의 주요 기능

https://cilium.io/blog/2019/11/19/announcing-hubble/

 

  • 네트워크/보안 모니터링: Hubble은 완전 분산형 네트워크 및 보안 모니터링 플랫폼입니다.
  • 추가 설정 없이 동작: Cilium과 eBPF 위에서 구축되어 애플리케이션의 코드 수정이나 추가 설정 없이 서비스 간 통신, 동작, 네트워크 인프라의 심층 가시성을 투명하게 제공합니다.
  • VM/서버도 모니터링 가능: 컨테이너화된 워크로드뿐만 아니라 가상 머신(VM)과 일반적인 리눅스 프로세스도 모니터링할 수 있습니다.
  • 서비스/파드/ID 기반 모니터링 및 통제: Linux eBPF를 활용하여 보안 가시성과 통제 기능을 투명하게 삽입할 수 있으며, 기존 IP 주소 기반 시스템과 달리 서비스/파드/컨테이너 ID를 기반으로 모니터링과 통제를 제공합니다. 또한 HTTP와 같은 애플리케이션 계층에서 필터링할 수 있습니다.
  • Hubble API 및 CLI: Hubble API는 기본적으로 Cilium 에이전트가 실행되는 개별 노드 범위 내에서 동작하며, 로컬 Cilium 에이전트가 관찰한 트래픽에 대한 네트워크 통찰력을 제공합니다. Hubble CLI(hubble)를 통해 로컬 Unix Domain Socket을 통해 제공된 Hubble API를 쿼리할 수 있으며, Hubble CLI 바이너리는 Cilium 에이전트 포드에 기본적으로 설치됩니다.
  • Hubble Relay와 UI: Hubble Relay를 배포하면 전체 클러스터 또는 ClusterMesh 시나리오에서 여러 클러스터에 대한 네트워크 가시성을 제공합니다. Hubble CLI(hubble)를 통해 Hubble Relay 서비스나 Hubble UI에 액세스할 수 있으며, Hubble UI는 L3/L4 및 L7 계층에서 서비스 종속성 그래프를 자동으로 탐지하여 시각화 및 필터링된 서비스 맵을 제공합니다.
  • Prometheus를 통한 메트릭스 내보내기: 주요 메트릭은 Prometheus를 통해 내보내져 기존 대시보드와 통합할 수 있습니다.

hubble ui의 화면

 

Socket-Based LoadBalancing

 

frontend pod가 client이고, clusterIP로 묶여있는 service를 통해 목적지 Pod가 있는 Worker Node로 통신할 때 Host에 있는 Iptables을 통해 DNAT이 일어나 서비스 IP를 백엔드 Pod IP로 변환하여 트래픽은 Kubernetes 서비스 IP에서 백엔드 Pod IP로 변환되는 과정이 일반적인 Network Based LoadBalancing입니다.

 

Cilium의 Socker-based load balancing을 사용하면 connect() system call을 이용하여 소켓을 연결할 때 Service IP를 직접 백엔드 Pod IP로 변환하여 이후 해당 소켓을 통해 보내는 모든 패킷의 목적지 주소는 이미 백엔드 주소로 설정되어 있기 때문에 중간에 DNAT 변환 및 역변환 과정이 필요없어집니다.

 

 

실습

실습 환경 구성

EC2 스펙

VPC 1개(퍼블릭 서브넷 2개), EC2 인스턴스 3대 (Ubuntu 22.04 LTS, t3.xlarge - vCPU 4 , Mem 16) , testpc 1대는 t3.small 를 배포해줍니다.

k8s-s EC2접근

ssh -i pem-key-path ubuntu@{k8s-s node ip}

control plane으로 사용할 k8s-s 노드에 접근합니다. 이때 pem-key 경로와 k8s-s node의 IP는 각자 다르니 자신의 환경에 맞게 넣어주세요.

Cilium 설치

Helm repo 추가

helm repo add cilium https://helm.cilium.io/
helm repo update

Cilium Helm 설치

helm install cilium cilium/cilium --version 1.16.3 --namespace kube-system \
--set k8sServiceHost=192.168.10.10 \
--set k8sServicePort=6443 \
--set debug.enabled=true \
--set rollOutCiliumPods=true \
--set routingMode=native \
--set autoDirectNodeRoutes=true \
--set bpf.masquerade=true \
--set bpf.hostRouting=true \
--set endpointRoutes.enabled=true \
--set ipam.mode=kubernetes \
--set k8s.requireIPv4PodCIDR=true \
--set kubeProxyReplacement=true \
--set ipv4NativeRoutingCIDR=192.168.0.0/16 \
--set installNoConntrackIptablesRules=true \
--set hubble.ui.enabled=true \
--set hubble.relay.enabled=true \
--set prometheus.enabled=true \
--set operator.prometheus.enabled=true \
--set hubble.metrics.enableOpenMetrics=true \
--set hubble.metrics.enabled="{dns:query;ignoreAAAA,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}" \
--set operator.replicas=1

 

각 설정값에 대한 설명은 아래와 같습니다.

 

  • debug.enabled :  cilium 파드에 로그 레벨을 debug 설정
  • autoDirectNodeRoutes: 동일 대역 내의 노드들 끼리는 상대 노드의 podCIDR 대역의 라우팅이 자동으로 설정
  • endpointRoutes.enabled: 호스트에 endpoint(파드)별 개별 라우팅 설정
  • hubble.relay.enabled, hubble.ui.enabled: hubble 활성화
  • ipam.mode=kubernetes, k8s.requireIPv4PodCIDR: k8s IPAM 활용
  • kubeProxyReplacement: kube-proxy 없이 (최대한) 대처할수 있수 있게
  • ipv4NativeRoutingCIDR=192.168.0.0/16 : 해당 대역과 통신 시 IP Masq 하지 않음, 보통 사내망 대역을 지정
  • installNoConntrackIptablesRules: iptables 규칙을 설정할 때 conntrack을 사용하지 않도록 하는 설정
  • operator.replicas=1 : cilium-operator 파드 기본 1개
  • enableIPv4Masquerade, bpf.masquerade: 파드를 위한 Masquerade , 추가로 Masquerade 을 BPF 로 처리 >> enableIPv4Masquerade=true 인 상태에서 추가로 bpf.masquerade=true 적용이 가능

설정 및 확인

ip -c addr

 

 

위의 명령어를 통해 네트워크 인터페이스를 먼저 확인해보겠습니다.

kubectl get node,pod,svc -A -owide

iptables -t nat -S

대망의 iptables 정보 중 Nat를 확인해보겠습니다!

svc가 배포된것이 적긴 하지만 상당히 말끔한 것을 확인하실 수 있습니다.

kubectl get crd

 

crd도 확인해보겠습니다.

kubectl get ciliumnodes

 

cilium agent가 설치된 node의 정보를 확인해보겠습니다.

 

여기서 CILIUMINTERNALIP와 INTERNALIP가 있는 것이 확인됩니다. 

CILIUMINTERNALIP는 위에서 살펴본 네트워크 인터페이스 정보 중 cilium host의 ip인 것을 확인하실 수 있습니다.

 

kubectl get ciliumendpoints -A

모든 네임스페이스에서 pod의 endpoint를 확인해보겠습니다. 

 

ethtool -i ens5

위 명령어를 통해 네트워크 인터페이스에서 사용되는 드라이버 이름, 버전, 펌웨어 정보등을 확인해보겠습니다.

 

iptables -t raw -S | grep notrack

 

위에서 cilium을 helm으로 설치할 때에 설정한 옵션 중 installNoConntrackIptablesRules가 적용되었는지 위의 명령어를 통해  iptables의 raw 테이블에서 NOTRACK 규칙이 설정된 내용들을 살펴보겠습니다. 

NOTRACK은 conntrack을 사용하지 않는다는 의미입니다. NOTRACK 규칙을 설정하면 특정 패킷이 연결 추적(conntrack)을 거치지 않고 처리됩니다. 이렇게 하면 패킷이 conntrack 테이블에 기록되지 않으므로 연결 상태를 유지하지 않아도 되는 패킷에 대해 성능이 향상될 수 있습니다.

 

Cilium CLI 설치

환경 변수 지정

CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64

 

원활한 설치를 위해 위의 값을 변수로 설정해줍니다.

 

Cilium CLI 설치

if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}

 

설치 확인

cilium status --wait

 

 

cilium 데몬셋 파드 내에서 cilium 명령어로 상태 확인

export CILIUMPOD0=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-s  -o jsonpath='{.items[0].metadata.name}')
alias c0="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- cilium"

 

위 명령어를 통해 c0 명령어로 Cilium 에이전트 내부에서 명령을 빠르게 실행할 수 있도록 설정합니다.

 

Direct Routing 확인

c0 status | grep KubeProxyReplacement

 

위 명령어는 Cilium 에이전트의 상태를 확인하고, 그 결과에서 KubeProxyReplacement 설정과 관련된 정보를 필터링합니다.

192.168.0.0/16 대역은 IP Masq 없이 라우팅하는 것을 확인할 수 있습니다. 즉, 위에서 설정한 것 처럼 KubeProxyReplacement 이 설정이 활성화되어있어서 Cilium이 kube-proxy 역할을 대신하며 네트워크 성능 최적화와 추가 기능을 제공하는 Direct Routing 모드인지 알 수 있습니다.

 

masquerade 확인

cilium config view | grep -i masq

 

iptables의 masquerade을 사용하지 않고, ebpf의 masquerade를 사용하는지 확인해보겠습니다.

 

ipMasqAgent.enabled 설정 

helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values --set ipMasqAgent.enabled=true

클러스터 외부로 나가는 Pod 트래픽의 IP 주소를 클러스터 노드의 IP로 변환하여 NAT를 적용합니다. 이 기능을 통해 Pod IP가 외부에 노출되지 않도록 보호하고, 클러스터 외부와의 통신 호환성을 높여줍니다.

 

cilium 데몬셋 파드 내에서 cilium 명령어로 상태 확인

export CILIUMPOD0=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-s  -o jsonpath='{.items[0].metadata.name}')
alias c0="kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- cilium"


이때 Cilium Pod가 재생성되는데, 그때마다 위의 명령어로 설정을 다시 해줍니다.

 

기본 정보 확인

명령어를 입력할 때에 기본정보를 매번 일일이 불러올 수 없으니 환경 변수로 설정하도록 하겠습니다.

cilium 파드 이름

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}')

 

단축키(alias) 지정

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"

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 확인

Hubble UI 웹 접속

kubectl patch -n kube-system svc hubble-ui -p '{"spec": {"type": "NodePort"}}'
HubbleUiNodePort=$(kubectl get svc -n kube-system hubble-ui -o jsonpath={.spec.ports[0].nodePort})

 

Hubble에 접속하기 위해 hubble-ui의 svc type을 nodePort로 변경하겠습니다.

echo -e "Hubble UI URL = http://$(curl -s ipinfo.io/ip):$HubbleUiNodePort"

 

위의 명령어를 통해 Hubble 접속 주소를 확인하고 접속해보겠습니다.

 

접속이 가능해졌습니다!

 

Hubble Client 설치

Hubble Client는 Cilium Hubble CLI인데, Kubernetes 네트워크의 흐름을 실시간으로 모니터링하고 분석하는 도구입니다.

HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
HUBBLE_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
sha256sum --check hubble-linux-${HUBBLE_ARCH}.tar.gz.sha256sum
sudo tar xzvfC hubble-linux-${HUBBLE_ARCH}.tar.gz /usr/local/bin
rm hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}

 

Hubble API Access

cilium hubble port-forward &

위 명령어를 통해 Hubble의 포트 포워딩을 백그라운드에서 실행하여, 로컬 시스템에서 Hubble UI나 CLI를 통해 Cilium Hubble에 접근할 수 있도록 합니다. 

 

CLI 로 Hubble API 상태 확인

hubble status

 

네트워크 트래픽 흐름 확인

hubble observe

eBPF 기반의 네트워크 트래픽의 흐름을 확인할 수 있습니다. 

 

이를 통해 Pod 간 통신, 요청 및 응답 상태, 네트워크 정책의 적용 결과 등을 확인할 수 있습니다. 필터를 적용하여 특정 Pod, 네임스페이스, 서비스, 또는 IP에 대한 트래픽만 관찰할 수도 있어 네트워크 진단과 보안 분석에 유용합니다.

 

Node 간 Pod 통신 확인

namespace 생성 및 설정

kubectl create ns test
kubectl config set-context --current --namespace=test

Pod 생성 

apiVersion: v1
kind: Pod
metadata:
  name: netpod
  namespace: test
  labels:
    app: netpod
spec:
  nodeName: k8s-s
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: webpod1
  namespace: test
  labels:
    app: webpod
spec:
  nodeName: k8s-w1
  containers:
  - name: container
    image: traefik/whoami
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: webpod2
  namespace: test
  labels:
    app: webpod
spec:
  nodeName: k8s-w2
  containers:
  - name: container
    image: traefik/whoami
  terminationGracePeriodSeconds: 0

Pod 생성 확인

kubectl get pod -o wide

 

c0 status --verbose | grep Allocated -A5
c1 status --verbose | grep Allocated -A5
c2 status --verbose | grep Allocated -A5

위 명령어를 통해 Cilium이 할당한 IP 주소네트워크 리소스 상태를 확인합니다.

 

kubectl get ciliumendpoints

 

ciliumendpoint의 정보도 확인해보겠습니다.

 

Pod 변수 지정

테스트 Pod들 IP

NETPODIP=$(kubectl get pods netpod -o jsonpath='{.status.podIP}')
WEBPOD1IP=$(kubectl get pods webpod1 -o jsonpath='{.status.podIP}')
WEBPOD2IP=$(kubectl get pods webpod2 -o jsonpath='{.status.podIP}')

 

단축키(alias) 지정

alias p0="kubectl exec -it netpod  -- "
alias p1="kubectl exec -it webpod1 -- "
alias p2="kubectl exec -it webpod2 -- "

 

 

Pod의 ARP 동작 확인

netpod 네트워크 정보 확인

p0 ip -c -4 addr

 

netpod에서 IPv4 주소 정보를 확인해보겠습니다.

 

p0 route -n

 

netpod에서 route -n 명령어를 통해 네트워크 라우팅 테이블을 확인합니다.

 

p0 ping -c 1 $WEBPOD1IP && p0 ping -c 1 $WEBPOD2IP

 

nepod에서 webpod1과 webpod2로 ping 통신을 해보겠습니다. 

hubble ui의 화면

 

 

p0 curl -s $WEBPOD1IP && p0 curl -s $WEBPOD2IP

netpod에서 webpod1과 webpod2로 요청의 응답 본문만 출력해보겠습니다.

hubble ui의 화면

p0 curl -s $WEBPOD1IP:8080 ; p0 curl -s $WEBPOD2IP:8080

netpod에서 webpod1과 webpod2의 8080 port로 접근해보겠습니다.

 

hubble ui의 화면

 

p0 ping -c 1 8.8.8.8 && p0 curl -s wttr.in/seoul

이제 netpod내에서 외부로 통신해보겠습니다.

 

 

ㄷㅈ ㅁhubble ui의 화면

Service 통신 확인

Service 생성

apiVersion: v1
kind: Service
metadata:
  name: svc
  namespace: test
spec:
  ports:
    - name: svc-webport
      port: 80
      targetPort: 80
  selector:
    app: webpod
  type: ClusterIP

 

Service 생성 확인

kubectl get svc,ep svc

 

 

iptables-save | grep KUBE-SVC

node의 iptables에 더 이상 KUBE-SVC rule 이 생성되지 않습니다!

 

iptables-save | grep CILIUM

모두 Cilium이 처리하고 있습니다.

 

서비스IP를 변수에 지정

SVCIP=$(kubectl get svc svc -o jsonpath='{.spec.clusterIP}')

 

트래픽 발생

kubectl exec netpod -- curl -s $SVCIP

Pod1 에서 Service(ClusterIP) 접속 트래픽 발생해보겠습니다.

 

 

지속적으로 접속 트래픽 발생

while true; do kubectl exec netpod -- curl -s $SVCIP | grep Hostname;echo "-----";sleep 1;done

 

위의 명령어로 지속적으로 접속 트래픽을 발생시켜보겠습니다.

kubectl exec netpod -- tcpdump -enni any -q

그리고 파드에서 SVC(ClusterIP) 접속 시의 로그들을  tcpdump로 확인해보겠습니다. 

파드 내부 캡쳐인데, cluster ip가 보이지 않고, DNAT 된 web-pod 의 IP가 확인됩니다! 

 

kubectl exec netpod -- sh -c "ngrep -tW byline -d eth0 '' 'tcp port 80'"

마찬가지로 netpod에 접속해 ngrep을 사용하여 eth0 인터페이스의 TCP 포트 80 트래픽을 실시간으로 캡처하고 확인해보겠습니다.

 

pod 내에서 목적지 IP가 이미 Pod의 IP로 바뀌어져 있는 것을 확인하실 수 있습니다.

 

cilium 파드의 Init Containers 에서 cgroup 마운트!

위와같은 동작이 어떻게 가능할까요?

kubectl describe pod -n kube-system {Cilium-pod-name}

cilium pod의 명세를 살펴보겠습니다.

Init Containers에 mount-cgroup 컨테이너에 보면 Command로 nsenter 명령어를 통해 네임스페이스에 접근해 cgroup과 마운트 네임스페이스를 설정합니다. 이로 인해서 Pod 간 통신 설정이 최적화되며, Cilium이 네트워크 트래픽을 효율적으로 관리할 수 있습니다.

 

 

728x90

'스터디 이야기 > Kubernetes Advanced Networking Study' 카테고리의 다른 글

[KANS] AWS EKS  (4) 2024.11.02
[KANS] Cilium CNI - eBPF  (3) 2024.10.23
[KANS] Service Mesh - Istio  (7) 2024.10.17
[KANS] Gateway API  (1) 2024.10.12