연재 시리즈

쿠버네티스 네트워크 스터디 3주차 1편: Calico 기본 통신 과정

악분 2022. 1. 24. 18:43
반응형

스터디 목차

 

안녕하세요. 이 글은 facebook 쿠버네티스 그룹에서 올라온 "쿠버네티스 네트워크 스터디" 3주차 내용을 정리했습니다.

스터디 모집글: https://www.facebook.com/groups/k8skr/posts/3202691746679143

 

1. 3주차 주제

3주차 첫번째 주제는 calico 컨셉과 pod통신 이해입니다. 스터디 진행 목차는 아래 그림과 같습니다.

 

2. calico 이해

calico는 쿠버네티스 CNI 인터페이스를 준수한 쿠버네티스 네트워크 모델로서 pod, 노드, 외부 네트워크 등 쿠버네티스 리소스의 네트워크 통신을 담당합니다. calico 공식문서[1]에 설명되어 있는 것처럼 쿠버네티스 네트워크 통신을 위해 정말 많은 컴퍼넌트가 있습니다. 저는 네트워크 엔지니어가 아니므로 calico 컨셉만 이해하기로 했습니다.

  • 컴퍼넌트 목록: Calico API server, Felix, BIRD, confd, Dikastes, CNI plugin, Datastore plugin, IPAM plugin, kube-controllers, Typha, calicoctl

 

2.1 컨셉

Calico 컨셉은 vRouter(가상 라우터)를 구현하고 BGP프로토콜을 이용하여 라우팅 정보를 공유합니다. 그리고 공유한 라우팅 정보를 이용하여 pod, service 네트워크 통신을 수행합니다. 외부 pod통신은 overlay 또는 Direct로 통신합니다.

 

calico 컨셉이 라우터관리이므로 쿠버네티스 외부에 있는 물리 또는 가상 라우터와 연결해서 사용할 수 있습니다.

calico 컨셉

 

2.2 Calico pod

vRouter를 구축하기 위한 컴퍼넌트는 쿠버네티스 pod로 배포되어 네트워크 통신을 수행합니다. controlplane노드에는 calico controller pod가 실행되고 각 노드마다 daemonset으로 calico node pod가 실행됩니다. calico에 대한 라우팅 정보 등을 datastore 컴퍼넌트에 저장되며 default?로 쿠버네티스 ETCD를 사용합니다.

쿠버네티스 노드관점에서 calico pod

 

calico pod는 kube-system 네임스페이스에 있습니다. kube-controller와 node pod가 보입니다. 

kubectl get po -n kube-system -o wide | grep calico

 

2.3 IPAM 컴퍼넌트

calico는 IP를 관리하기 위해 IPAM 컴퍼넌트가 있습니다.

 

calicoctl 명령어로 calico가 관리하는 IP범위를 볼 수 있습니다.

calicoctl ipam show

 

각 노드는 IPAM 범위안에 속하는 pod cidr를 가집니다. pod cidr는 calico는 IPAM block으로 관리합니다.

 

2.4 Felix 컴퍼넌트

felix컴퍼넌트는 라우팅 테이블과 iptables를 관리합니다. 라우팅테이블과 iptables는 같은 노드의 pod간 통신, ,다른 노드의 pod간 통신, pod와 외부 통신을 위한 설정이 있습니다.

 

felix가 관리하는 iptables은 아래 명령어로 확인할 수 있습니다.

iptables -t filter -S | grep cali
iptables -t nat -S | grep cali

 

2.5 bird컴퍼넌트

bird컴퍼넌트는 각 노드의 라우팅 정보를 공유합니다. BGP프로토콜을 사용합니다.

 

Felix과 bird의 역할을 요약하면 아래 그림과 같습니다.

출처: 스터디 공유자료

 

3. 네트워크 인터페이스

calico가 생성하고 관리하는 (가상)네트워크 인터페이스에 대해 살펴봅니다.

 

3.1 tunl 인터페이스

pod가 다른 노드의 pod와 통신하기 위해 tunl네트워크 인터페이스가 host(root 네트워크 네임스페이스)에 생성됩니다. tunl은 노드간 통신에 관여하지만 외부와 통신할때는 사용되지 않습니다.

출처: 스터디 공유자료

 

라우팅 테이블을 보면 다른 노드와 통신할 때 tunl인터페이스를 사용하는 것을 볼 수 있습니다. 라우팅 정보는 bird컴퍼넌트가 담당하고 있기 때문에 bird키워드로 필터링 했습니다.

ip -c route | grep bird

 

3.2 calice 인터페이스

calice는 pod와 가상 라우터 연결하는 인터페이스입니다. pod가 생성되면 자동으로 calice인터페이스가 생성됩니다.

출처: 스터디 공유자료

 

calice인터페이스를 구별하기 위해 고유번호가 설정됩니다. 

ip -c addr show

 

pod가 어떤 calice인터페이스를 사용하는지 calicoctl로 확인할 수 있습니다.아래 예제에서는 pod1, pod2이름을 갖는 pod가 사용하는 calice인터페이스 정보를 출력합니다.

calicoctl get workloadendpoints

 

4. pod통신

챕터 4에서는 calico가 어떻게 pod간 통신을 하는지 설명합니다. 실습환경은 스터디에서 공유한 vagrant와 virtualbox를 이용하여 구축했습니다.

출처: 스터디 공유자료

 

4.1 같은 노드 pod간 통신 - proxy ARP

실습을 위해 한 노드에 pod 2개를 생성했습니다.

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  nodeName: k8s-w1
  containers:
  - name: pod1
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  nodeName: k8s-w1
  containers:
  - name: pod2
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0

 

pod1에서 pod2통신을 하기 위해서 각 pod eth0, calice인터페이스와 vRouter를 사용합니다

출처: 스터디 공유자료

 

pod1<->pod2 처음 통신한다면 pod는 ARP Table(정확히 말하면 pod의 컨테이너)에 데이터가 없기 때문에 ARP Request를 날립니다. 여기서 calico가 proxy_arp를 사용해서 재밌는 과정이 생깁니다. pod1->pod2로 arp request요청하지만 실제로는 pod1->calico default gw로 arg request요청이 됩니다. arp reploy로 calico가 약속한 MAC address인 ee:ee:ee:ee:ee:ee를 받습니다. 그럼에도 불구하고 pod1 -> pod2 통신은 잘됩니다. (음.. 아직 proxy_arp에 대해 정확히 몰라서 흐름만 이해했습니다)

  • 의도: pod1 -> pod2 arp request
  • 실제: pod1 -> calico default gw

 

calico default gw는 169.254.1.1로 설정되어 있습니다. 169.254.1.1은 라우팅 테이블에 설정된 값이기도 합니다.

169.254.1.1주소는 calico가 설정한 값입니다. 관련 문서는 https://projectcalico.docs.tigera.io/reference/faq#why-cant-i-see-the-16925411-address-mentioned-above-on-my-host에 있습니다.

 

proxy_arp는 각 노드에 리눅스 커널 파라미터로 설정되어 있습니다. 커널파라미터 설정은 calice인터페이스마다 존재합니다. proxy_arp를 비활성화 하면 pod간 통신은 되지 않습니다.

cat /proc/sys/net/ipv4/conf/{calice 인터페이스}/proxy_arp

 

네트워크 엔지니어가 아니므로 정확한 정보가 아니지만.. 마치 nginx(리버시 프록시)처럼 calico가 arp 프로토콜을 이용하여 모든 내부통신을 calico를 거쳐가게 하는 것 같습니다.

 

4.2 다른 노드 pod간 통신

실습을 위해 기존 pod를 삭제한 후, k8s-w1노드에 pod 1개, k8s-w2노드에 pod1개를 생성했습니다.

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  nodeName: k8s-w1
  containers:
  - name: pod1
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  nodeName: k8s-w2
  containers:
  - name: pod2
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0

 

pod가 다른 pod통신을 할 때는 tunl인터페이스와 enp0s3(노드가 외부와 통신할때 사용하는 인터페이스)를 사용합니다. tunl인터페이스는 2편에서 다루게 될 calico모드에 따라 pod IP를 설정합니다. 디폴트로 IPIP모드로서 IP헤더에 pod에관한 IP헤더를 추가합니다. enp0s3인터페이스는 노드 밖으로 빠져나가기 때문에 사용됩니다.

 

tunl인터페이스와 enp0s3에 tcpdump를 실행한 후, pod1->pod2 ping 명령어를 실행합니다. tcpdump결과에서 pod간 통신 내용을 볼 수 있습니다.

kubectl exec -it pod1 -- ping <pod2 ip>

출처: 스터디 공유자료

 

tcpdump결과를 파일로 덤프를 뜨고 wireshark로 확인해봅시다. calico 디폴트 모드인 IPIP모드는 IP헤더에 노드IP, pod IP가 있습니다. node IP정보가 있는 헤더를 Outer IP, pod IP정보가 있는 헤더를 Inner IP헤더라고 합니다.

# tcpdump를 파일로 덤프하는 명령어
tcpdump -i enp0s8 -nn proto 4 -w /tmp/calico-ipip.pcap

출처: 스터디 공유자료

 

4.4 pod와 외부 통신

pod는 외부와 통신할 때 iptables MASQUERADE설정을 사용합니다. calico가 설치되면 각 노드는 MASQUERADE와 기타 iptables, route 설정을 합니다.

출처: 스터디 공유자료

 

챕터 [4.3]에서 생성한 pod1을 실습으로 사용합니다. MASQUERADE 설정은 iptables nat 테이블에서 조회할 수 있습니다.

iptables -n -v -t nat --list cali-nat-outgoing

 

enp0s3(노드가 외부와 통신할때 사용하는 인터페이스)에 tcpdump를 실행합니다.

tcpdump -i enp0s3 -nn icmp

 

그리고 pod1에서 google(8.8.8.8)로 ping을 실행합니다. MASQUERADE설정때문에 구글로 호출하는 IP가 변경된 것을 확인할 수 있습니다. enp0s3 IP가 10.0.2.15입니다.

 kubectl exec -it pod1 -- ping 8.8.8.8

 

5. 참고자료

[1] [공식문서] calico 아키텍처: https://projectcalico.docs.tigera.io/reference/architecture/overview

[2] [블로그] https://feisky.gitbooks.io/sdn/content/container/calico/

[3] [블로그] https://www.360kuai.com/pc/9df55556a29286b9e?cota=3&kuai_so=1&sign=360_e39369d1

[4] [블로그] 커피고래: https://coffeewhale.com/packet-network2

[5] [블로그] proxyarp: https://blog.naver.com/goduck2/220161816991

여백

반응형