AKS 네트워킹 이해하기: Underlay Network

발행: (2026년 3월 3일 오후 02:35 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

VM에서 Kubernetes Service IPcurl을 시도했는데 그냥… 멈춰버린 적이 있다면, 이 가이드는 바로 당신을 위한 것입니다.

다음 내용을 차근차근 살펴보겠습니다:

  • AKS 네트워크 설계
  • CIDR 레이아웃 (VNet, 서브넷, Service CIDR, Pod CIDR)
  • VM에서 ClusterIP가 실패하는 이유
  • NodePort가 동작하는 이유
  • 단계별 패킷 흐름
  • 전체 Azure CLI 설정

모두 Azure Kubernetes Service (AKS) 를 Microsoft Azure 환경에서 테스트한 결과입니다.

🧱 1️⃣ 네트워크 설계 개요

랩 토폴로지

구성 요소CIDR
VNet10.0.0.0/16
AKS 서브넷10.0.1.0/24
VM 서브넷10.0.2.0/24
Service CIDR10.240.0.0/16
Overlay Pods (선택 사항)192.168.0.0/16

언더레이 모드 (Azure CNI)

🗺️ 아키텍처 다이어그램 (PlantUML)

Architecture diagram

🧠 CIDR 이해

CIDR용도
10.0.0.0/16Azure VNet
10.0.1.0/24AKS 노드
10.0.2.0/24테스트 VM
10.240.0.0/16쿠버네티스 서비스(가상)
192.168.0.0/16Overlay Pods(활성화된 경우)

핵심 개념: Service CIDR은 Azure VNet 라우팅에 포함되지 않으므로, VM에서 ClusterIP로 향하는 트래픽은 Azure 라우터에 의해 차단됩니다.

⚙️ 2️⃣ 전체 Azure CLI 설정

변수

LOCATION=eastus2
RG=aks-networking-lab
VNET_NAME=aks-vnet
UNDERLAY_SUBNET=aks-underlay-subnet
VM_SUBNET=vm-subnet
AKS_NAME=aks-underlay

리소스 그룹 만들기

az group create \
  --name $RG \
  --location $LOCATION

VNet 및 AKS 서브넷 만들기

az network vnet create \
  --resource-group $RG \
  --name $VNET_NAME \
  --address-prefix 10.0.0.0/16 \
  --subnet-name $UNDERLAY_SUBNET \
  --subnet-prefix 10.0.1.0/24

VM 서브넷 만들기

az network vnet subnet create \
  --resource-group $RG \
  --vnet-name $VNET_NAME \
  --name $VM_SUBNET \
  --address-prefix 10.0.2.0/24

서브넷 ID 가져오기 (AKS용)

SUBNET_ID=$(az network vnet subnet show \
  --resource-group $RG \
  --vnet-name $VNET_NAME \
  --name $UNDERLAY_SUBNET \
  --query id -o tsv)

AKS 클러스터 만들기

az aks create \
  --resource-group $RG \
  --name $AKS_NAME \
  --network-plugin azure \
  --vnet-subnet-id $SUBNET_ID \
  --service-cidr 10.240.0.0/16 \
  --dns-service-ip 10.240.0.10 \
  --node-count 2 \
  --generate-ssh-keys

클러스터에 연결하기

az aks get-credentials \
  --resource-group $RG \
  --name $AKS_NAME

🚀 3️⃣ 테스트 애플리케이션 배포

kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=2

ClusterIP 로 노출

kubectl expose deployment nginx \
  --name nginx-svc \
  --port 80 \
  --type ClusterIP

서비스 확인

kubectl get svc

예시 출력

nginx-svc   ClusterIP   10.240.225.54   80/TCP

IP (10.240.225.54)는 Service CIDR에서 할당됩니다.

🔥 4️⃣ Packet Flow: ClusterIP (VM 접근이 실패하는 이유)

VM에서 시도해 보세요:

curl 10.240.225.54

Azure 라우팅이 다음을 확인하기 때문에 요청이 멈춥니다:

Is 10.240.0.0/16 in the VNet? → No
→ Drop packet

패킷이 어떤 AKS 노드에도 도달하지 못합니다.

🧭 패킷 흐름 다이어그램

Packet flow diagram

🧪 5️⃣ NodePort 로 변환

kubectl patch svc nginx-svc \
  -p '{"spec":{"type":"NodePort"}}'

확인:

kubectl get svc nginx-svc

예시 출력

nginx-svc   NodePort   10.240.225.54   80:31598/TCP

이제 서비스는 할당된 노드 포트(예시에서는 31598)를 통해 모든 노드의 IP 주소로 접근할 수 있습니다.

✅ 6️⃣ VM에서 테스트하는 올바른 방법

  1. 노드의 내부 IP를 확인합니다:

    kubectl get nodes -o wide

    샘플 출력

    NAME                                STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
    aks-nodepool1-42091994-vmss000000   Ready    <none>  34m   v1.33.6   10.0.1.33      <none>        Ubuntu 22.04.5 LTS   5.15.0-1103-azure   containerd://1.7.30-2
    aks-nodepool1-42091994-vmss000001   Ready    <none>  34m   v1.33.6   10.0.1.4       <none>        Ubuntu 22.04.5 LTS   5.15.0-1103-azure   containerd://1.7.30-2
  2. 노드 IP와 노드‑포트를 이용해 서비스를 curl 합니다:

    curl http://10.0.1.4:31598

기본 Nginx 응답이 반환되면, NodePort 로 노출된 서비스가 VM에서 접근 가능함을 확인한 것입니다.

가이드 종료.

전체 화면 모드 종료

예시

azureuser@test-vm:~$ curl -s 10.0.1.33:31598 | grep -i "welcome"
Welcome to nginx!

nginx에 오신 것을 환영합니다!


## Flow  

1. VM → Node IP  
2. Node가 트래픽을 수신  
3. `kube-proxy`가 NodePort 규칙과 일치  
4. Pod IP로 DNAT  
5. 응답 반환

## 🧠 깊은 기술 분석  

패킷이 노드에 도달하면 `kube-proxy`는 다음과 같은 iptables 규칙을 설치합니다:

```text
KUBE-NODEPORTS
KUBE-SERVICES
KUBE-SEP-XXXX

DNAT 예시

10.0.1.4:31598 → 10.0.1.10:80

왜 ClusterIP가 Pod 내부에서 작동하는가

  • 패킷이 먼저 노드에 도달합니다.
  • kube-proxy가 목적지를 Pod IP로 재작성합니다.

왜 VM에서는 실패하는가

  • 패킷이 노드에 도달하지 않습니다.
  • Azure 라우팅이 이를 차단합니다.

🎯 주요 요점

  • ClusterIP = 가상 내부 Kubernetes IP.
  • NodePort = 노드가 실제 VNet IP에서 수신 대기합니다.
  • Service CIDR은 VNet CIDR과 겹치면 안 됩니다.
  • Azure는 VNet CIDR만 라우팅합니다.
  • kube-proxy가 Service IP 변환을 처리합니다.

🏁 Final Mental Model

Azure가 담당:

10.0.0.0/16

Kubernetes가 담당:

10.240.0.0/16

다른 라우팅 도메인.

0 조회
Back to Blog

관련 글

더 보기 »

일이 정신 건강 위험이 될 때

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...