PKOS 2기 2주차 학습 스터디-1

Louis·2023년 3월 18일
0

PKOS 2기

목록 보기
2/7

2023년 3월 6일부터 @cloudnet study를 시작 하였다.

[24단계 실습으로 정복하는 쿠버네티스][이정훈 지음]의 책을 기본으로 학습을 한다.

운영을 하면서도 부족한 부분을 배울 수 있을 것이란 기대감과 함께 시작한 수업이나 숙제를 하지 못해서 발생하는 불상사를 경험하지 않고 5주간의 스터디를 잘 마무리 했으면 좋겠다.

2주차 스터디 내용을 정리해 본다.

2주차에는 네트워크와 스토리지 관련 내용을 스터디 하고 실습 진행하였다.

쿠버네티스 네트워크

K8S CNI 란?

  • CNCF(Cloud Native Computing Foundation)의 프로젝트 중 하나
  • CNI는 컨테이너 간의 네트워킹을 제어할 수 있는 플러그인을 만들기 위한 표준
  • 다양한 형태의 컨테이너 런타임과 오케스트레이터 사이의 네트워크 계층을 구현하는 방식이 다양하게 분리되어 각자만의 방식으로 발전하게 되는 것을 방지하고 공통된 인터페이스를 제공하기 만들어 짐
  • 쿠버네티스에서는 Pod 간의 통신을 위해서 CNI 를 사용
  • 쿠버네티스 뿐만 아니라 Amazon ECS, Cloud Foundry 등 컨테이너 런타임을 포함하고 있는 다양한 플랫폼들은 CNI를 사용
  • 쿠버네티스는 기본적으로 'kubenet' 이라는 자체적인 CNI 플러그인을 제공하지만 네트워크 기능이 매우 제한적인 단점이 있음
  • 그 단점을 보완하기 위해, 3rd-party 플러그인을 사용하는데 그 종류에는
    Flannel, Calico, Weavenet, NSX 등 다양한 종류의 3rd-party CNI 플러그인들이 존재합니다.

K8S Calico CNI와 AWS VPC CNI 차이

  • 네트워크 통신의 최적화(성능, 지연)을 위해서 노드와 파드의 네트워크 대역을 동일하게 설정 함

    • 그림 1 일반적인 K8S CNI 플러그인(Calico)와 AWS CNI 간 노드와 파드 네트워크 대역 비교
  • 파드간 통신 시 일반적으로 K8S CNI는 오버레이(VXLAN, IP-IP) 통신을 하고 AWS VPC CNI 는 동일 대역으로 직접 통신을 한다

- 파드간의 통신을 위해서는 Pod에서 사용하는 IP 대역에서 노드 IP 대역으로 변경해서 전달 하고 다른 노드 IP 와 통신을 통해서 다시 Pod IP 대역으로 변경해서 통신되는게 일반적이였다.
- 파드간 통신 작업을 하면서 패킷을 감싸서 다른 데이터(IP)를 추가해서 전달 하고 수신쪽에선 전달 된 패킷에서 특정 패킷(IP)을 분석하고 다시 그 Pod에 전달해서 Pod IP를 분석해서 통신을 해야 하는 일련의 과정을 거치게 되면서 리소스 사용 및 추가적인 타임이 발생하게 되는 것이다.
- 허나 AWS VPC CNI는 IP 변경 작업이 없이 Pod IP 대역과 노드 IP대역이 동일 하기 때문에 직접 통신이 가능하게 된것이다(정말 신세계였다.. 전혀 알지 못하던 세상….)
- 리소스 낭비(?) 및 타임을 줄일 수 있는 장점이 있다.
- 물론 Pod IP관리와 노드 IP 관리를 하면서 중복 점검 등의 추가 리소스가 발생은 하지만 그것을 감안 하더라도 네트워킹 속도에는 더 많은 장점이 있는 것으로 생각 된다.
- 실습을 통해서 AWS VPC CNI 를 사용하는 클러스터 POD1 과 POD2에서 ping을 통해서 전달 되는 과정을 패킷 dump를 수행한 결과 예상대로 pod간 직접 통신 되는 것을 확인 할 수 있었다

weave-net CNI POD간 통신

  • 실제로 내가 갖고 있는 클러스터에서 pod간 통신을 할 경우 발생하는 패킷을 한번 떠서 직접 비교를 해보았다.
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: netshoot-pod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: netshoot-pod
  template:
    metadata:
      labels:
        app: netshoot-pod
    spec:
      containers:
      - name: netshoot-pod
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
EOF
$ k get pods -owide
NAME                            READY   STATUS    RESTARTS   AGE    IP           NODE                 NOMINATED NODE   READINESS GATES
netshoot-pod-5759484c55-2ql7w   1/1     Running   0          44s    10.36.0.4    dnc-workstation-01   <none>           <none>
netshoot-pod-5759484c55-595x9   1/1     Running   0          44s    10.44.0.23   dnc-workstation-02   <none>           <none>
$ k get nodes -owide
NAME                       INTERNAL-IP
dnc-workstation-01        192.168.253.11
dnc-workstation-02        192.168.253.12
# hanjoo.moon @ Moonui-MacBookPro in ~ [22:27:09]
$ PODIP1=10.36.0.4
$ PODIP2=10.44.0.23
$ PODNAME1=netshoot-pod-5759484c55-2ql7w
$ PODNAME2=netshoot-pod-5759484c55-595x9
$ kubectl exec -it $PODNAME1 -- zsh
/root/.zshrc:source:76: no such file or directory: /root/.oh-my-zsh/oh-my-zsh.sh
                    dP            dP                           dP
                    88            88                           88
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P
88'  `88 88ooood8   88   Y8ooooo. 88'  `88 88'  `88 88'  `88   88
88    88 88.  ...   88         88 88    88 88.  .88 88.  .88   88
dP    dP `88888P'   dP   `88888P' dP    dP `88888P' `88888P'   dP

Welcome to Netshoot! (github.com/nicolaka/netshoot)
  • 근데… 놀랍게도 AWS VPC CNI처럼…. 노드 IP로 변경 없이 통신을 하였다…
    listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
    13:39:29.885366 eth0  In  IP 10.36.0.4 > 10.44.0.23: ICMP echo request, id 42703, seq 1, length 64
    13:39:29.885384 eth0  Out IP 10.44.0.23 > 10.36.0.4: ICMP echo reply, id 42703, seq 1, length 64
    13:39:30.892160 eth0  In  IP 10.36.0.4 > 10.44.0.23: ICMP echo request, id 42703, seq 2, length 64
    13:39:30.892176 eth0  Out IP 10.44.0.23 > 10.36.0.4: ICMP echo reply, id 42703, seq 2, length 64
  • 조금 당황스러웠다. 내가 갖고 있는 클러스터는 weave-net CNI 였고
    스터디에선 Calico CNI와의 비교였지만 3rd-party CNI는 비슷하다고 생각해서 비교하였는데….. 이런결과가 나왔다. 그래서 weave-net 파드간 통신에 대해서 검색을 해 보았다.
  • 클러스터에 설치된 cni는 weave-net 플러그인 이다.
    $ cat /etc/cni/net.d/10-weave.conflist
    {
        "cniVersion": "0.3.0",
        "name": "weave",
        "plugins": [
            {
                "name": "weave",
                "type": "weave-net",
                "hairpinMode": true
            },
            {
                "type": "portmap",
                "capabilities": {"portMappings": true},
                "snat": true
            }
        ]
    }

weave


  • 일반적으로 중간에 라우터를 두어 여러 노드로 라우팅하는 방식은 힘들다.
  • 노드 수가 많아지면 라우팅 테이블에 많은 엔트리를 적어야 하고,
  • 라우팅 테이블 엔트리는 그렇게 많은 수를 지원하지 않기 때문이다.
  • 이에 대한 대안으로 패킷 전달에 특화된 agent를 두어 패킷을 주고 받는 방식이 있다.
  • weave가 이 방식이다.
  • 각 노드에 weave agent를 파견한 후, weave cni는 각 노드마다 weave 브릿지를 만든다.
    (weave는 데몬셋으로 배포된다)
  • 브릿지에 IP 할당 후, 포드들을 붙인다.
  • 포드 내부에서 Routing 테이블을 확인해 보면, weave bridge를 통해서 밖으로 나간다.
  • 다른 노드의 포드로 패킷을 전송할 때는 보내는 노드의 weave agent가 패킷을 encapsulate한 후 이를 다른 노드로 보낸다.
  • 이후 패킷을 받은 노드는 agent를 통해 패킷을 decapsulate하여 포드에게 전달한다.

Calico

  • Calico를 기준으로는 현재 두 가지 방식의 Overlay Network가 지원되는데, vxlan 프로토콜을 사용하는 방식과 IP-in-IP 프로토콜을 사용하는 방식이 있다. 조사해 본 결과로는 vxlan이 IP-in-IP 프로토콜에 비해 범용성이 있는(IP-in-IP 프로토콜은 Azure 클라우드와 같은 특정 환경에서는 사용이 어렵다고 한다) 대신 성능이 IP-in-IP 프로토콜에 비해 근소하게 뒤떨어진 모습을 보여준다고 한다. 하지만 매우 극단적인 트래픽이 아닌 이상 차이를 실감하기 어려운 정도의 수준이어서 오버레이 네트워크를 사용할 때 가장 기본적으로 사용되는 방식이다.
  • 오버레이 네트워크를 사용하면 거의 대부분의 환경에서 기존 네트워크 환경에 영향 없이 CNI 환경을 구성할 수 있지만, BGP 프로토콜을 사용하는 방식에 비해 패킷을 캡슐화 할때 CPU 등의 자원도 소모하고 패킷의 전체 크기에서 캡슐화를 위해 사용하는 영역 만큼 패킷 당 송/수신 할 수 있는 데이터의 양이 줄어들어 상대적으로 비효율 적인 단점도 있다.

weave - calico CNI 차이

  • 통신 방식의 차이인 것이다.
  • agent를 사용해서 노드간의 통신을 대체하는 weave-net 방식에선 당연히 노드 IP로의 변환 없이 파드간 통신이 가능한 것이었다.
  • 오버레이 방식을 사용하는 CNI는 통신의 속도가 느릴 수 밖에 없다. AWS VPC CNI는 오버레이 방식 없이 VPC Native 통신이 가능하기에 속도와 리소스 낭비 없이 사용이 가능한것이다.
  • 각 CNI 별로 장단점이 있고 속도의 차이는 있지만 대규모의 서비스를 구성하지 않는 상황에선 큰 문제는 안되지만 속도차이가 분명히 존재 하기에 대규모의 서비스나 서비스 속도가 중요한 서비스에선 agent 방식보단 더 빠른 속도를 지원해주고 별도의 리소스 사용을 줄이는 CNI를 선택해서 구성하는 것이 맞는 것 같다.
  • 클러스터를 구축함에 있어도 좀 더 이론적인 부분과 장/단점을 인지하고 구성해야겠다는 생각이 들었다.
    (agent 방식의 CNI를 구성해 놓고 pod 통신간의 dump를 뜨고 놀라고 있는 나를 보자니.. 참..ㅡㅡ)

참고

K8S Pod Networking과 Weave CNI 정리

Calico?Weave? CNI에 관하여

AWS VPC CNI

  • 파드의 IP를 할당해 줌
  • 파드의 IP 네트워크 대역과 노드(워커)의 IP대역이 같아서 직접 통신이 가능 함
  • VPC 와 통합 : VPC Flow logs , VPC 라우팅 정책을 사용 가능함
  • kOps 는 SG for Pod 미지원 - 링크
  • VPC ENI 에 미리 할당된 IP를 파드에서 사용할 수 있음
  • 다시 스터디 내용으로 돌아와서 스터디 실습 환경에서는

노드 간 통신 방식

  • 파드간 통신 흐름
    : AWS VPC CNI 경우 별도의 오버레이(Overlay) 통신 기술 없이, VPC Native 하게 파드간 직접 통신이 가능하다

  • [실습] 파드간 통신 테스트 및 확인 : 별도의 NAT 동작 없이 통신 가능!
    ```jsx
    netshoot-pod-7757d5dd99-dprrv# tcpdump -i any -nn icmp
    tcpdump: data link type LINUX_SLL2
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
    15:15:10.721815 eth0  Out IP 172.30.92.211 > 172.30.60.115: ICMP echo request, id 17307, seq 1, length 64
    15:15:10.722754 eth0  In  IP 172.30.60.115 > 172.30.92.211: ICMP echo reply, id 17307, seq 1, length 64
    15:15:11.722256 eth0  Out IP 172.30.92.211 > 172.30.60.115: ICMP echo request, id 17307, seq 2, length 64
    15:15:11.723143 eth0  In  IP 172.30.60.115 > 172.30.92.211: ICMP echo reply, id 17307, seq 2, length 64
    15:15:20.885695 eth0  In  IP 172.30.60.115 > 172.30.92.211: ICMP echo request, id 3013, seq 1, length 64
    15:15:20.885709 eth0  Out IP 172.30.92.211 > 172.30.60.115: ICMP echo reply, id 3013, seq 1, length 64
    15:15:21.897525 eth0  In  IP 172.30.60.115 > 172.30.92.211: ICMP echo request, id 3013, seq 2, length 64
    15:15:21.897541 eth0  Out IP 172.30.92.211 > 172.30.60.115: ICMP echo reply, id 3013, seq 2, length 64
    ```
- Calico나 weave-net과 같은 오버레이 통신이 아닌 VPC native 방식의 파드간 통신이 된 것을 확인 할 수 있다.
- 더 빠른 네트워크 속도와 별도의 리소스 사용(CPU를 통 캡슐/복호화 하는 액션)없이 통신 할 수 있는 건 엄청 간단하고 대단한 장점 인듯 하다.
profile
인프라 운영하는 개발자

0개의 댓글