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

[KANS] AWS EKS

by lakescript 2024. 11. 2.
728x90
더보기

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

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

 

이번 내용은 지난번에 참여한 스터디와 중첩되는 내용이 많아서 겹치는 내용은 링크로 대체 합니다.

AWS VPC CNI

https://lakescript.net/entry/AEWS-2-1-Amazon-EKS-Networking-CNI

 

[AEWS] 2-1. Amazon EKS Networking - CNI

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

aws vpc cni에 대한 간단한 소개는 이전 스터디글로 대신 하며, 이 포스팅에선 조금 더 네트워크적으로 다뤄보겠습니다.

 

VPC CNI란?

Amazon EKS는 VPC CNI라는 Amazon VPC 컨테이너 네트워크 인터페이스(Container Network Interface) 플러그인을 통해 클러스터 네트워킹을 구현합니다. 특히, VPC CNI 플러그인은 Kubernetes의 Pod가 동일한 VPC안에서 Pod내 모든 컨테이너가 동일한 네트워크 네임스페이스를 공유하여 서로 로컬 포트를 사용해 통신할 수 있게 동일한 IP 주소를 갖도록 합니다.

 

구성 요소

CNI 바이너리

Pod 간의 통신을 설정하는 Pod 네트워크를 구축합니다.  CNI 바이너리는 노드의 root filesystem에서 실행되며, kubelet이 새로운 Pod를 노드에 추가하거나 기존 Pod를 제거할 때 호출됩니다.

ipamd

ipamd는 노드 로컬 IP 주소 관리(IPAM)를 수행하는 장기 실행 데몬으로, 노드에 ENI 관리, 사용 가능한 IP 주소나 prefix의 warm-pool 관리합니다.

 

동작 방식

 

인스턴스가 생성될 때, EC2는 기본 서브넷과 연결된 기본 ENI를 생성하고 연결합니다. 이때, hostNetwork 모드에서 실행되는 Pod는 기본 ENI에 할당된 기본 IP 주소를 사용하며, 호스트와 동일한 네트워크 네임스페이스를 공유합니다.

 

ENI 및 warm-pool 관리

노드가 프로비저닝되면, CNI 플러그인은 자동으로 기본 ENI에 노드의 서브넷에서 슬롯(IP 또는 프리픽스)을 할당하여 pool을 생성(크기는 인스턴스 유형에 따라 결정)합니다. 또한, ENI의 슬롯(IP 주소나 prefix)이 할당되면, CNI는 노드에 추가 ENI를 부착하여 warm-pool을 확장할 수 있습니다. CNI는 필요한 슬롯 수(주로 Pod 수)에 따라 인스턴스에 더 많은 ENI를 붙이게 되고, 더 이상 ENI를 붙일 수 없을 때까지 계속됩니다. 각 인스턴스 유형에는 부착할 수 있는 최대 ENI 수가 있습니다.

 

Warm-Pool이란?
Amazon VPC CNI 플러그인이 Kubernetes 노드에 할당하는 IP 주소 또는 prefix slot을 의미합니다. 웜 풀의 역할은 Kubernetes 클러스터에서 새롭게 생성될 Pod들이 즉시 사용할 수 있는 IP 주소나 네트워크 자원을 사전에 확보하여, Pod의 시작 시간을 단축하는 것입니다. warm-pool의 크기와 slot 수는 인스턴스 유형에 따라 달라지며, 자동으로 확장될 수 있습니다.

 

인스턴스 유형에 따른 ENI 및 슬롯 제한

사용 가능한 네트워크 인터페이스 수와 슬롯 수는 EC2 인스턴스 유형에 따라 다릅니다. 각 Pod는 슬롯의 IP 주소를 사용하므로, 특정 EC2 인스턴스에서 실행할 수 있는 Pod 수는 인스턴스에 부착할 수 있는 ENI 수와 각 ENI가 지원할 수 있는 슬롯 수에 따라 달라집니다. 

 

워커 노드에 생성 가능한 최대 파드 갯수

https://lakescript.net/entry/AEWS-2-2-AWS-EKS-Networking-Node-Pod-Network

 

[AEWS] 2-2. AWS EKS Networking - Node & Pod Network

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

노드 간 파드 통신

https://lakescript.net/entry/AEWS-2-2-AWS-EKS-Networking-Node-Pod-Network

 

[AEWS] 2-2. AWS EKS Networking - Node & Pod Network

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

Service & AWS LoadBalancer Controller

https://lakescript.net/entry/AEWS-2-3-Amazon-EKS-Service-AWS-LoadBalancer-Controller

 

[AEWS] 2-3. Amazon EKS Networking - Service

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

Ingress

https://lakescript.net/entry/AEWS-2-4-Amazon-EKS-Networking-Ingress

 

[AEWS] 2-4. Amazon EKS Networking - Ingress

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

ExternalDNS

 

https://lakescript.net/entry/AEWS-2-5-Amazon-EKS-Networking-ExternalDNS

 

[AEWS] 2-5. Amazon EKS Networking - ExternalDNS

사전 준비 더보기 위와 같이 사전 준비가 필요합니다. 저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion E

lakescript.net

CoreDNS

https://lakescript.net/entry/Kubernetes%EC%97%90%EC%84%9C-DNS-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95-%EB%8F%84%EB%A9%94%EC%9D%B8%EC%9D%84-%EC%B0%BE%EC%95%84%EC%84%9C

 

Kubernetes에서 DNS 다루는 방법 - 도메인을 찾아서

https://tv.naver.com/v/56456809 NAVER D2Kubernetes에서 DNS 다루는 방법 - 도메인을 찾아서tv.naver.com naver D2에서 소개된 Kubernetes에서 DNS 다루는 방법에 대한 영상 내용이 너무 좋아 블로그에 따로 정리하려고

lakescript.net

 

이 부분도 예전에 제가 정리해놓은 글이 있어 이것으로 대체합니다😉

Topology Aware Routing

https://docs.aws.amazon.com/eks/latest/best-practices/cost-opt-networking.html

 

Topology Aware Routing은 네트워크 트래픽이 가능한 가까운 Zone의 리소스를 사용하도록 하여 성능을 최적화하고 네트워크 비용을 줄이는 기능입니다. 이 기능을 통해 클러스터 내에서 서비스 요청이 물리적 위치에 더 가까운 Pod로 라우팅되므로 대기 시간이 줄어들고 네트워크 비용이 절감됩니다. 

다른 zone이면 비용이 증가하는 이유?
다른 가용 영역(zone)이나 리전(region)에 걸쳐 트래픽이 발생할 때 비용이 증가하는 이유는, 클라우드 제공업체(예: AWS, GCP, Azure)에서 영역 간 또는 리전 간 데이터 전송에 추가 요금을 부과하기 때문입니다.

 

실습 - 환경 구성

현재 노드 AZ 배포 확인

kubectl get node --label-columns=topology.kubernetes.io/zone

현재 node는 ap-northeast-2a, 2b, 2c에 각각 생성되어있는 것을 확인하실 수 있습니다.

테스트를 위한 deployments와 service 배포

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: websrv
        image: registry.k8s.io/echoserver:1.5
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
spec:
  ports:
    - name: svc-webport
      port: 80
      targetPort: 8080
  selector:
    app: deploy-websrv
  type: ClusterIP

 

배포된 리소스 확인

kubectl get deploy,svc,ep,endpointslices

먼저, deploy와 svc, enpoint, enpointslices 목록을 확인해보겠습니다.

 

kubectl get pod -owide

pod의 정보를 간략히 출력하는데, node의 정보까지 확인해보기 위해 -owide 옵션을 주어 출력해보겠습니다.

현재 pod들이 각 node에 골고루 배포된 것을 확인하실 수 있습니다.

 

접속 테스트를 수행할 클라이언트 Pod 배포

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

 

접속 테스트를 위한 netshot pod를 생성합니다.

전체 Pod 확인

kubectl get pod -owide

 

실습 - 테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인

디플로이먼트 파드가 배포된 AZ(zone) 확인

kubectl get pod -l app=deploy-websrv -owide

테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인

kubectl exec -it netshoot-pod -- curl svc-clusterip | grep Hostname

 

netshot-pod에 접속하여 svc-clusterip로 접속해보겠습니다!

 

여러번 하면 모두 다르게 접속합니다.

 

kubectl exec -it netshoot-pod -- zsh -c "for i in {1..100}; do curl -s svc-clusterip | grep Hostname; done | sort | uniq -c | sort -nr"

100번 접속해보겠습니다.

 

3개의 파드로 AZ(zone) 상관없이 랜덤 확률 부하분산 동작하는 것을 확인할 수 있습니다.

 

IPTables 정책 확인 (Topology Mode 설정 전) 

ssh ec2-user@$N1 sudo iptables -t nat -nvL

현재 접속한 ec2가 bastionHost라는 가정하에 node1의 ec2로 접근하여 iptables nat 규칙을 확인해보겠습니다.

많이 보던 iptables rule이 쫘르륵 나오게 됩니다. 너무 많으니 하나씩 필터해서 보도록 하겠습니다.

 

ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list PREROUTING

먼저 PREROUTING Chain부터 확인해보겠습니다.

KUBE_SERVICES가 보이네요.

 

ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SERVICES

 

KUBE_SERVICES Chain을 확인해보겠습니다.

clusterIP를 기리키는 KUBE-SVC-KBDEBIL6IU6WL7RF으로 연결되어있습니다.

 

ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF

KUBE-SVC-KBDEBIL6IU6WL7RF Chain을 확인해보겠습니다.

 

즉, svc-clusterip:svc-webport라는 Kubernetes 서비스가 로드 밸런싱을 위해 세 개의 Pod(192.168.1.240, 192.168.2.36, 192.168.3.13 각각의 8080 포트)로 트래픽을 분배하고 있음을 확인할 수 있습니다. 또한, 각 규칙의 random probability에 따라 트래픽이 세 개의 대상 중 하나로 전달되며, Kubernetes는 이러한 방식으로 서비스에 들어오는 트래픽을 각 Pod로 균등하게 분배합니다.

 

Topology Mode 설정 후 테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인

Topology Aware Routing 설정

kubectl annotate service svc-clusterip "service.kubernetes.io/topology-mode=auto"

100번 반복 접속

kubectl exec -it netshoot-pod -- zsh -c "for i in {1..100}; do curl -s svc-clusterip | grep Hostname; done | sort | uniq -c | sort -nr"

100번 정도 반복 접속을 통해 테스트 파드(netshoot-pod)와 같은 AZ(zone)의 목적지 파드로만 접속하는 것을 확인해보겠습니다.

100번 모두 하나의 Pod로만 접속한 것을 확인하실 수 있습니다.

 

IPTables 정책 확인 (Topology Mode 설정 후)

ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SERVICES

마찬가지로 KUBE-SERVICES Chain을 확인해보겠습니다.

아까와 동일하게 clusterIP는 KUBE-SVC-KBDEBIL6IU6WL7RF으로 연결된 것을 확인하실 수 있습니다. 

 

ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF

KUBE-SVC-KBDEBIL6IU6WL7RF Chain을 확인해보겠습니다.

 

이번엔 아까와 다르게 해당 노드와 같은 AZ에 배포된 Pod의 Endpoint만 출력됩니다. 

 

 

즉, Topology Mode를 설정한 후에는 클러스터 내에서 서비스 요청이 지리적으로 가까운 Pod로 우선 라우팅됩니다. 이를 통해 네트워크 대기 시간을 줄이고, 리전 간 트래픽을 최소화하여 네트워크 비용을 절감할 수 있습니다.

728x90

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

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