AKS(Azure Kubernetes Service)에서 이중 스택 네트워킹 사용

이중 스택 Azure 가상 네트워크를 사용하는 경우 이중 스택 모드로 AKS 클러스터를 배포할 수 있습니다. 이 구성에서 노드는 Azure 가상 네트워크 서브넷에서 IPv4 및 IPv6 주소를 모두 받습니다. Pod는 IPv4 및 IPv6 주소를 모두 논리적으로 다른 주소 공간에서 노드의 Azure 가상 네트워크 서브넷으로 받습니다. 그런 다음 Pod가 Azure 가상 네트워크의 리소스에 도달할 수 있도록 NAT(네트워크 주소 변환)를 구성합니다. 트래픽의 원본 IP 주소는 동일한 패밀리(IPv4-IPv4 및 IPv6-IPv6)의 노드 기본 IP 주소로 변환(NAT)됩니다.

이 문서에서는 AKS 클러스터에서 이중 스택 네트워킹을 사용하는 방법을 보여 줍니다. 네트워킹 옵션 및 고려 사항에 대한 자세한 내용은 Kubernetes 및 AKS에 대한 네트워크 개념을 참조하세요.

중요합니다

2025년 11월 30일부터 AKS(Azure Kubernetes Service)는 더 이상 Azure Linux 2.0에 대한 보안 업데이트를 지원하거나 제공하지 않습니다. Azure Linux 2.0 노드 이미지는 202512.06.0 릴리스에 고정되어 있습니다. 2026년 10월 31일부터 노드 이미지가 제거되며 노드 풀의 크기를 조정할 수 없습니다. 노드 풀을 지원되는 Kubernetes 버전으로 업그레이드하거나 osSku AzureLinux3으로 마이그레이션하여 지원되는 Azure Linux 버전으로 마이그레이션합니다. 자세한 내용은 사용 중지 GitHub 문제 및 Azure 업데이트 사용 중지 공지 사항을 참조하세요. 공지 사항 및 업데이트에 대한 정보를 유지하려면 AKS 릴리스 정보를 따르세요.

제한점

  • Azure Linux 노드 풀에서 IPv6 서비스에는 externalTrafficPolicy: Local가 필요합니다.
  • 이중 스택 네트워킹은 Azure 가상 네트워크 및 Pod CIDR에 필요합니다.
    • 단일 스택 IPv6 전용은 노드 또는 Pod IP 주소에 지원되지 않습니다. 서비스는 IPv4 또는 IPv6에서 프로비전할 수 있습니다.
  • Azure CNI 오버레이는 이중 스택 네트워킹을 사용하여 Azure 또는 Calico 네트워크 정책을 지원하지 않습니다. 네트워크 정책을 사용하려면 Cilium에서 제공하는 Azure CNI를 사용합니다.
  • 표준 NAT 게이트웨이는 IPv4만 지원합니다. 듀얼 스택 아웃바운드의 경우 StandardV2 NAT Gateway를 사용합니다. AKS 관리 managedNATGatewayV2 형 아웃바운드 형식은 미리 보기로 제공됩니다.
  • 가상 노드 추가 기능은 이중 스택 네트워킹에서 지원되지 않습니다.

필수 조건

이 문서에서는 Azure CNI 오버레이를 사용합니다. Kubernetes 버전 1.29 이상을 실행하는 Linux 클러스터의 Cilium에서 제공하는 Azure CNI를 사용하여 이중 스택 클러스터를 배포할 수도 있습니다.

Kubernetes의 이중 스택 네트워킹에 대한 개요

Kubernetes v1.23에서는 Pod 및 서비스 네트워킹을 포함하여 IPv4/IPv6 이중 스택 클러스터에 대한 안정적인 업스트림 지원이 제공됩니다. 노드 및 Pod에는 항상 IPv4 주소와 IPv6 주소가 모두 할당되지만, 어느 주소 패밀리에서든 서비스는 이중 스택이거나 단일 스택일 수 있습니다.

AKS는 이중 스택 네트워킹에 필요한 지원 서비스를 구성합니다. 이 구성은 다음과 같습니다.

  • 관리형 가상 네트워크를 사용하는 경우 이중 스택 가상 네트워크 구성입니다.
  • IPv4 및 IPv6 노드 및 Pod 주소.
  • IPv4 및 IPv6 트래픽 모두의 아웃바운드 규칙.
  • IPv4 및 IPv6 서비스의 부하 분산 장치 설정.

비고

아웃바운드 유형의 사용자 정의 라우팅에서 이중 스택 네트워킹을 사용하는 경우 인터넷에 연결하기 위해 IPv6 트래픽이 필요한지 여부에 따라 IPv6에 대한 기본 경로를 선택할 수 있습니다. IPv6에 대한 기본 경로가 없는 경우 클러스터를 만들 때 경고가 표시되지만 클러스터 생성을 방지하지는 않습니다.

이중 스택 클러스터 매개 변수

다음 매개 변수는 이중 스택 클러스터를 지원합니다.

매개 변수 허용되는 값 기본값 Constraints
--ip-families ipv4 또는 ipv4,ipv6 지정되지 않음 클러스터에서 사용하도록 설정할 IP 패밀리의 쉼표로 구분된 목록을 제공합니다.
--pod-cidrs 쉼표로 구분된 CIDR 범위 10.244.0.0/16,fd12:3456:789a::/64 범위의 개수와 순서는 --ip-families와 일치해야 합니다.
--service-cidrs 쉼표로 구분된 CIDR 범위 10.0.0.0/16,fd12:3456:789a:1::/108 범위의 개수와 순서는 --ip-families와 일치해야 합니다. IPv6 서브넷은 /108보다 클 수 없습니다.

이중 스택 AKS 클러스터 배포

  1. az group create 명령을 사용하여 클러스터의 Azure 리소스 그룹을 만듭니다.

    az group create --location <region> --name <resourceGroupName>
    
  2. az aks create 매개 변수가 --ip-families으로 설정된 ipv4,ipv6 명령을 사용하여 이중 스택 AKS 클러스터를 만듭니다.

    az aks create \
        --location <region> \
        --resource-group <resourceGroupName> \
        --name <clusterName> \
        --network-plugin azure \
        --network-plugin-mode overlay \
        --ip-families ipv4,ipv6 \
        --generate-ssh-keys
    
  3. 클러스터를 만든 후 명령을 사용하여 클러스터 자격 증명을 가져옵니다 az aks get-credentials .

    az aks get-credentials --resource-group <resourceGroupName> --name <clusterName>
    

노드를 검사하여 두 IP 패밀리 모두 확인

클러스터가 프로비전된 후 명령을 사용하여 kubectl get nodes 노드가 이중 스택 네트워킹으로 프로비전되는지 확인합니다.

kubectl get nodes -o=custom-columns="NAME:.metadata.name,ADDRESSES:.status.addresses[?(@.type=='InternalIP')].address,PODCIDRS:.spec.podCIDRs[*]"

kubectl get nodes 명령의 출력은 노드에 IPv4 및 IPv6 모두의 주소 및 Pod IP 할당 공간이 있음을 보여 줍니다.

NAME                                ADDRESSES                           PODCIDRS
aks-nodepool1-14508455-vmss000000   10.240.0.4,2001:1234:5678:9abc::4   10.244.0.0/24,fd12:3456:789a::/80
aks-nodepool1-14508455-vmss000001   10.240.0.5,2001:1234:5678:9abc::5   10.244.1.0/24,fd12:3456:789a:0:1::/80
aks-nodepool1-14508455-vmss000002   10.240.0.6,2001:1234:5678:9abc::6   10.244.2.0/24,fd12:3456:789a:0:2::/80

예제 워크로드 만들기

3개의 복제본이 있는 NGINX 웹 서버를 배포하여 이중 스택 Pod IP 할당을 확인합니다.

NGINX 웹 서버 배포

  1. 명령을 실행하여 NGINX 웹 서버를 만듭니다 kubectl create deployment nginx .

    kubectl create deployment nginx --image=nginx:latest --replicas=3
    
  2. kubectl get pods 명령을 실행하여 pod 리소스를 확인합니다.

    kubectl get pods -o custom-columns="NAME:.metadata.name,IPs:.status.podIPs[*].ip,NODE:.spec.nodeName,READY:.status.conditions[?(@.type=='Ready')].status"
    

    출력은 Pod에 IPv4 주소와 IPv6 주소가 모두 있음을 보여 줍니다. Pod는 준비될 때까지 IP 주소를 표시하지 않습니다.

    NAME                     IPs                                NODE                                READY
    nginx-55649fd747-9cr7h   10.244.2.2,fd12:3456:789a:0:2::2   aks-nodepool1-14508455-vmss000002   True
    nginx-55649fd747-p5lr9   10.244.0.7,fd12:3456:789a::7       aks-nodepool1-14508455-vmss000000   True
    nginx-55649fd747-r2rqh   10.244.1.2,fd12:3456:789a:0:1::2   aks-nodepool1-14508455-vmss000001   True
    

LoadBalancer 형식 서비스를 통해 워크로드 공개

중요합니다

Azure Load Balancer는 상태 프로브를 링크 로컬 주소에서 IPv6 대상으로 보냅니다. Azure Linux 노드 풀에서 사용하는 externalTrafficPolicy: Cluster IPv6 서비스에 대한 트래픽이 실패합니다. 다음 예에서는 IPv6 서비스에 kube-proxy를 설정하여 externalTrafficPolicy: Local가 노드의 프로브에 응답하도록 합니다.

  1. kubectl expose deployment nginx 명령을 사용하여 별도의 IPv4 및 IPv6 LoadBalancer 서비스로 NGINX 배포를 노출하세요.

    kubectl expose deployment nginx --name=nginx-ipv4 --port=80 --type=LoadBalancer
    kubectl expose deployment nginx --name=nginx-ipv6 --port=80 --type=LoadBalancer --overrides='{"spec":{"externalTrafficPolicy":"Local","ipFamilies":["IPv6"]}}'
    

    서비스가 노출되었음을 보여 주는 출력이 표시됩니다.

    service/nginx-ipv4 exposed
    service/nginx-ipv6 exposed
    
  2. 배포를 노출한 후 LoadBalancer 서비스를 완전히 프로비저닝한 다음, kubectl get services 명령을 사용하여 서비스의 IP 주소를 가져옵니다.

    kubectl get services
    
    NAME         TYPE           CLUSTER-IP               EXTERNAL-IP         PORT(S)        AGE
    nginx-ipv4   LoadBalancer   10.0.88.78               20.46.24.24         80:30652/TCP   97s
    nginx-ipv6   LoadBalancer   fd12:3456:789a:1::981a   2603:1030:8:5::2d   80:32002/TCP   63s
    
  3. IPv6 주소가 할당되고 IPv6 라우팅이 구성된 Linux VM 또는 온-프레미스 컴퓨터에서 기능을 확인합니다. Azure Cloud Shell IPv6을 지원하지 않습니다.

    SERVICE_IP=$(kubectl get services nginx-ipv6 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    curl -s "http://[${SERVICE_IP}]" | head -n5
    
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>