Kubernetes

[ Kans 3 Study - 3w ] 4. Calico 네트워크 모드

su''@ 2024. 9. 22. 04:12
CloudNetaStudy - Kubernets Networtk 3기 실습 스터디 게시글입니다.

 

 

Calico Mode 

 

[ IP-in-IP: 기본값; encapsulated ]

파드 간 통신이 노드와 노드 구간에서는 IPIP 인캡슐레이션을 통해서 이루어진다.

  • 다른 노드 간의 파드 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대측 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
  • 다른 노드의 파드 대역은 BGP로 전달 받아 호스트 라우팅 테이블에 업데이트됨
  • Azure 네트워크에서는 IPIP 통신이 불가능하여 IPIP 모드 대신 VXLAN 모드 사용
    • 멀티 캐스트, 브로드캐스트, IP-IP 캡슐화 패킷 및 GRE(일반 라우팅 캡슐화) 패킷은 Azure VNet 내에서 차단됩니다 - 링크
  • calico-ipip.pcap

calico-ipip.pcap
0.00MB

 

  • 기본 설정 확인
    calicoctl 및 네트워크 정보 확인
    # 모드 정보 확인
    calicoctl get ippool -o wide
    
    # 노드(BGP) Peer 정보 확인
    calicoctl node status
    IPv4 BGP status
    +----------------+-------------------+-------+----------+-------------+
    |  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
    +----------------+-------------------+-------+----------+-------------+
    | 192.168.20.100 | node-to-node mesh | up    | 10:03:45 | Established |
    | 192.168.10.101 | node-to-node mesh | up    | 10:05:26 | Established |
    | 192.168.10.102 | node-to-node mesh | up    | 10:07:16 | Established |
    +----------------+-------------------+-------+----------+-------------+
    
    # BGP 로 전달 받은 파드 네트워크 대역이 호스트 라우팅 테이블에 적용되었는지 확인 
    route -n | egrep '(Destination|tunl0)'
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    172.16.8.128    192.168.20.100  255.255.255.192 UG    0      0        0 tunl0
    172.16.46.0     192.168.10.102  255.255.255.192 UG    0      0        0 tunl0
    172.16.228.64   192.168.10.101  255.255.255.192 UG    0      0        0 tunl0
    
    calicoctl ipam show --show-blocks
    +----------+-----------------+-----------+------------+--------------+
    | GROUPING |      CIDR       | IPS TOTAL | IPS IN USE |   IPS FREE   |
    +----------+-----------------+-----------+------------+--------------+
    | IP Pool  | 172.16.0.0/16   |     65536 | 6 (0%)     | 65530 (100%) |
    | Block    | 172.16.116.0/24 |       256 | 4 (2%)     | 252 (98%)    |
    | Block    | 172.16.158.0/24 |       256 | 1 (0%)     | 255 (100%)   |
    | Block    | 172.16.34.0/24  |       256 | 1 (0%)     | 255 (100%)   |
    +----------+-----------------+-----------+------------+--------------+
    
    # 워커 노드마다 할당된 dedicated subnet (podCIDR) 확인
    kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'
    
    kubectl get node k8s-m -o json | jq '.spec.podCIDR'
    "172.16.0.0/24"
    kubectl get node k8s-w1 -o json | jq '.spec.podCIDR'
    "172.16.1.0/24"
    ...
    
    # 기본제공 
    cat /etc/cni/net.d/10-calico.conflist
    ...
    "ipam": {
              "type": "calico-ipam"
          },
    ...
    
    # IPAM 우선순위 - 링크 링크2
    1. Kubernetes annotations
    2. CNI configuration << Calico IPAM
    3. IP pool node selectors << host-local IPAM
    
    # IPIP 인캡슐레이션 동작을 수행하는 터널 인터페이스 확인
    ip -c -d addr show tunl0


  • 동작 확인
    node3-pod3.yaml : 동작 확인을 위한 파드
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod1
    spec:
      containers:
      - name: pod1
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod2
    spec:
      containers:
      - name: pod2
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod3
    spec:
      containers:
      - name: pod3
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0

파드 생성 및 패킷 캡쳐 확인

# 파드 생성
curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/5/node3-pod3.yaml
kubectl apply -f node3-pod3.yaml

# 파드 IP 정보 확인
kubectl get pod -o wide

# 파드 Shell 접속(zsh)
kubectl exec -it pod1 -- zsh
## 파드 Shell 에서 아래 입력
ping <pod2 혹은 pod3 IP>

# 파드가 동작하는 워커노드1의 eth0(예시)에서 IPIP 패킷(proto 4) 덤프
tcpdump -i <eth0> -nn proto 4
tcpdump -i enp0s8 -nn proto 4
혹은 아래 처럼 파일로 저장 후 해당 파일을 다운받아서 확인(wireshark 등 사용)
tcpdump -i <eth0> proto 4 -w /tmp/calico-ipip.pcap
tcpdump -i enp0s8 proto 4 -w /tmp/calico-ipip.pcap

 

 

파드 삭제 kubectl delete -f node3-pod3.yaml

 


 

[ Direct: unencapsulated ]

  • 통신흐름 : 파드 통신 패킷이 출발지 노드의 라우팅 정보를 보고 목적지 노드로 원본 패킷 그대로 전달합니다

  • 클라우드 사업자 네트워크의 경우 NIC 에 매칭되지 않는 IP 패킷은 차단되니, NIC에 Source/Destination Check 기능을 Disable 해야힌디 - 링크
    # AWS CLI 로 특정 인스턴스의 Source/Destination Check 기능을 Disable 하기
    aws ec2 modify-instance-attribute --instance-id <INSTANCE_ID> --source-dest-check "{\"Value\": false}"

  • Direct 모드 설정 및 확인
    # Calico 모드 정보 확인
    calicoctl get ippool -o wide
    NAME                  CIDR            NAT    IPIPMODE   VXLANMODE   DISABLED   SELECTOR
    default-ipv4-ippool   172.16.0.0/16   true   Always     Never       false      all()
    
    # (옵션) 모니터링
    watch -d "route -n | egrep '(Destination|UG)'"
    
    # 설정
    calicoctl get ippool default-ipv4-ippool -o yaml
    calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f -
    
    # 모드 정보 확인 : IPIPMODE 가 Never 로 변경!
    calicoctl get ippool -o wide
    root@k8s-m:~/yaml# calicoctl get ippool -o wide
    NAME                  CIDR            NAT    IPIPMODE   VXLANMODE   DISABLED   SELECTOR
    default-ipv4-ippool   172.16.0.0/16   true   Never      Never       false      all()
    
    # BGP 로 전달 받은 파드 네트워크 대역이 호스트 라우팅 테이블에 적용되었는지 확인 : Iface 가 tunl0 에서 ens5 혹은 enp0s8 로 변경!
    route -n | egrep '(Destination|UG)'
    root@k8s-w1:~# route -n | egrep '(Destination|UG)'
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    172.16.29.0     192.168.100.10  255.255.255.192 UG    0      0        0 ens5 혹은 enp0s8
    172.16.46.0     192.168.100.102 255.255.255.192 UG    0      0        0 ens5 혹은 enp0s8
    172.16.197.0    192.168.100.103 255.255.255.192 UG    0      0        0 ens5 혹은 enp0s8

  • 동작확인
    파드생성
    # 파드 생성
    curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/5/node3-pod3.yaml
    kubectl apply -f node3-pod3.yaml
    
    # 파드 IP 정보 확인
    kubectl get pod -o wide
    calicoctl get wep


    파드간 ping 통신 실행 및 패킷 캡쳐 확인
    # 파드 Shell 접속(zsh)
    kubectl exec -it pod1 -- zsh
    ## 파드 Shell 에서 아래 입력
    ping <pod2 혹은 pod3 IP>
    
    # 파드가 동작하는 노드의 eth0(예시)에서 패킷 덤프
    tcpdump -i <eth0> -nn icmp
    tcpdump -i ens5 -nn icmp   # [실습환경 A Type]
    tcpdump -i enp0s8 -nn icmp # [실습환경 B Type]
    
    # 파일로 저장 후 해당 파일을 다운받아서 확인(wireshark 등 사용)
    tcpdump -i <eth0> icmp -w /tmp/calico-direct.pcap
    tcpdump -i ens5 icmp -w /tmp/calico-direct.pcap   # [실습환경 A Type]
    tcpdump -i enp0s8 icmp -w /tmp/calico-direct.pcap # [실습환경 B Type]


    VPC route table 에 노드에 파드 대역 라우팅 추가로 통신 가능

 

파드 삭제 kubectl delete -f node3-pod3.yaml

 

 


 

  • CrossSubnet 모드
    동작 : 노드 간 같은 네트워크 대역(Direct 모드로 동작) , 노드 간 다른 네트워크 대역(IPIP 모드로 동작)
    • 설정 및 확인
      # CrossSubnet 모드 설정
      calicoctl patch ippool default-ipv4-ippool -p '{"spec":{"ipipMode":"CrossSubnet"}}'
      
      # 모드 확인
      calicoctl get ippool -o wide
      NAME                  CIDR            NAT    IPIPMODE      VXLANMODE   DISABLED   SELECTOR
      default-ipv4-ippool   172.16.0.0/16   true   CrossSubnet   Never       false      all()
      
      # 파드 생성
      kubectl apply -f node3-pod3.yaml
      calicoctl get wep
      
      # 호스트 라우팅 정보 확인
      route -n | grep UG
      root@ip-172-20-63-146:~# route -n | grep UG
      100.105.79.128  172.20.61.184   255.255.255.192 UG    0      0        0 ens5  # 노드간 같은 네트워크 대역 - Direct 모드
      100.125.78.64   172.20.59.153   255.255.255.192 UG    0      0        0 ens5  # 노드간 같은 네트워크 대역 - Direct 모드
      100.127.64.128  172.20.64.181   255.255.255.192 UG    0      0        0 tunl0 # 노드간 다른 네트워크 대역 - IPIP 모드
      
      # 파드 Shell 접속(zsh)
      kubectl exec -it pod1 -- zsh
      ## 파드 Shell 에서 아래 입력
      ping <pod2 혹은 pod3 IP>

    • 파드 삭제 kubectl delete -f node3-pod3.yaml

 


 

[ VXLAN 모드 ]

통신 흐름 : 파드 간 통신이 노드와 노드 구간에서는 VXLAN 인캡슐레이션을 통해서 이루어 집니다

  • calico-vxlan.pcap

calico-vxlan.pcap
0.00MB

 

  • 다른 노드 간의 파드 통신은 vxlan 인터페이스를 통해 L2 프레임이 UDP - VXLAN에 감싸져서 상대측 노드로 도달 후 vxlan 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
  • BGP 미사용, VXLAN L3 라우팅을 통해서 동작
  • Azure 네트워크에서도 사용 가능 🙆🏻 (UDP를 사용하므로)