Azure IPAM

Azure IPAM

Azure IPAM 할당자는 Azure 클라우드의 Cilium 배포에 특화되어 있으며 Azure Private IP 주소에 기반해 IP 할당을 수행해요. 이 글에서는 아키텍처, 구성, 운영 세부 사항, 필요한 권한에 대해 알아볼게요.

출처: Azure IPAM

본문

Note

AKS에서 Cilium을 실행하는 권장 방법은 다음과 같습니다:

Azure IPAM(이 페이지)은 Azure VM 또는 VMSS에서 실행되는 비-AKS 자체 관리 클러스터를 위해 설계되었습니다.

Azure IPAM 할당자는 Azure 클라우드에서 실행되는 Cilium 배포에 특화되어 있으며 Azure Private IP 주소에 기반해 IP 할당을 수행합니다.

아키텍처는 대규모 클러스터에서 속도 제한 문제를 피하기 위해 단일 operator만 Azure API와 통신하도록 보장합니다. 사전 할당 워터마크는 클러스터에 새 Pod가 스케줄될 때 Azure API에 연락할 필요 없이 노드에서 항상 사용 가능한 IP 주소 수를 유지할 수 있게 해 줍니다.

아키텍처

Azure IPAM 할당자는 CRD 기반 할당자 위에 구축됩니다. 각 노드는 해당 노드에서 Cilium이 처음 시작될 때 노드 이름과 일치하는 ciliumnodes.cilium.io 사용자 지정 리소스를 만듭니다. 각 노드에서 실행되는 Cilium 에이전트는 Kubernetes v1.Node 리소스를 검색하고 Azure 인스턴스 ID를 유도하기 위해 .Spec.ProviderID 필드를 추출합니다. Azure 할당 매개변수는 에이전트 구성 옵션으로 제공되고 사용자 지정 리소스에도 전달됩니다.

Cilium operator는 새 ciliumnodes.cilium.io 사용자 지정 리소스를 수신하고 IPAM 측면을 자동으로 관리하기 시작합니다. 연결된 IP가 있는 기존 인터페이스에 대해 Azure 인스턴스를 스캔하고 spec.ipam.available 필드를 통해 사용 가능하게 만듭니다. 그런 다음 status.ipam.used 필드의 사용된 IP 주소를 지속적으로 모니터링하고 IP 사전 할당 워터마크를 충족하기 위해 필요에 따라 더 많은 IP를 할당합니다. 이렇게 하면 항상 IP가 사용 가능하도록 보장됩니다.

구성

Cilium 에이전트와 operator는 --ipam=azure 옵션으로 실행되거나 ConfigMap에서 ipam: azure 옵션이 설정되어야 합니다. 이렇게 하면 노드 에이전트와 operator 모두에서 Azure IPAM 할당이 활성화됩니다.

대부분의 시나리오에서 에이전트가 노드에서 처음 시작할 때 ciliumnodes.cilium.io 사용자 지정 리소스를 자동으로 만드는 것이 합리적입니다. 이를 활성화하려면 --auto-create-cilium-node-resource 옵션을 지정하거나 ConfigMap에서 auto-create-cilium-node-resource: "true" 를 설정하세요.

Operator에서 --enable-metrics 옵션으로 메트릭을 활성화하는 것도 일반적으로 좋습니다. Prometheus 설치 및 Grafana 대시보드 실행 방법을 포함한 추가 정보는 Prometheus & Grafana 실행하기 섹션을 참고하세요.

Operator 범위: 구독, 리소스 그룹, 아이덴티티

Operator는 세 가지 컨텍스트를 사용해 Azure와 통신합니다. 각각은 Azure Instance Metadata Service (IMDS)에서 자동 감지되거나 --azure-* operator 플래그로 명시적으로 설정될 수 있어요.

  • 구독 ( --azure-subscription-id ): 모든 Azure SDK 클라이언트는 단일 구독에 바인딩됩니다. 설정하지 않으면 operator는 IMDS를 통해 실행 중인 노드의 구독을 감지합니다.
  • 리소스 그룹 ( --azure-resource-group ): 인터페이스 목록, VMSS, Public IP Prefixes 같은 리소스 그룹별 API 호출을 범위 지정합니다. 이는 클러스터 노드의 리소스 그룹이어야 해요. 설정하지 않으면 operator는 IMDS를 통해 실행 중인 노드의 리소스 그룹을 감지하는데, 이는 operator Pod가 클러스터의 나머지 노드와 같은 리소스 그룹의 노드에서 실행될 때만 정확합니다. 워커 VM/VMSS가 다른 리소스 그룹에 있을 때(예: 컨트롤 플레인과 워커 풀을 리소스 그룹으로 나누는 자체 관리 Azure VM 클러스터)는 이 플래그를 명시적으로 설정하세요.
  • VNet / 서브넷 리소스 그룹: operator는 런타임에 각 인터페이스의 서브넷 ID에서 VNet과 서브넷 리소스 그룹을 유도합니다. 이를 위한 플래그는 없어요. VNet이 공유 네트워킹 리소스 그룹에 있으면 operator의 아이덴티티가 거기에 읽기 접근 권한이 있어야 합니다.

인증

Operator는 Azure Identity SDK를 사용해 인증합니다. 두 가지 모드가 지원됩니다:

  • 기본 자격 증명 체인 (플래그 미설정): --azure-user-assigned-identity-id 가 비어 있으면 operator는 DefaultAzureCredential을 호출하며, 이는 순서대로 환경 변수, workload identity(프로젝션된 토큰), 시스템 할당 관리 아이덴티티, 그다음 Azure CLI를 시도합니다. Azure AD Workload Identity를 사용하는 AKS 클러스터에 권장되는 경로예요.
  • 사용자 할당 관리 아이덴티티 ( --azure-user-assigned-identity-id ): 설정하면 operator는 특정 사용자 할당 관리 아이덴티티로 인증합니다. 값은 아이덴티티의 client ID(UUID)여야 하며, 전체 Azure 리소스 ID( /subscriptions/.../userAssignedIdentities/... )가 아니어야 해요. client ID는 Azure 포털의 아이덴티티 개요 블레이드 또는 az identity show -g -n --query clientId -o tsv 를 통해 볼 수 있습니다.

사용자 지정 Azure IPAM 구성

사용자 지정 Azure IPAM 구성은 Helm 또는 사용자 지정 CNI 구성 ConfigMap 으로 정의할 수 있어요.

같은 필드에 대해 helm과 Custom CNI를 모두 구성하면 Custom CNI가 Helm 구성보다 우선합니다.

Helm

Azure IPAM 구성은 --set 플래그 또는 helm 값 파일을 사용해 Helm으로 지정할 수 있어요.

다음 예시는 Cilium을 다음과 같이 구성합니다:

  • Pod IP 할당에 eth0 인터페이스 사용
  • 최소 할당 IP 수를 10으로 설정

Helm RepositoryOCI Registry

helm upgrade cilium cilium/cilium --version 1.20.2 \
   --namespace kube-system \
   --reuse-values \
   --set azure.enabled=true \
   --set azure.nodeSpec.azureInterfaceName=eth0 \
   --set ipam.nodeSpec.ipamMinAllocate=10
helm upgrade cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
   --namespace kube-system \
   --reuse-values \
   --set azure.enabled=true \
   --set azure.nodeSpec.azureInterfaceName=eth0 \
   --set ipam.nodeSpec.ipamMinAllocate=10

사용 가능한 옵션의 전체 목록은 Helm Reference 섹션의 azure.nodeSpec 과 ipam.nodeSpec 섹션에서 찾을 수 있어요.

CNI 구성 만들기

아래 템플릿을 기반으로 cni-config.yaml 파일을 만드세요. interface-name 필드를 채웁니다:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cni-configuration
  namespace: kube-system
data:
  cni-config: |-
    {
      "cniVersion":"0.3.1",
      "name":"cilium",
      "plugins": [
        {
          "cniVersion":"0.3.1",
          "type":"cilium-cni",
          "azure": {
            "interface-name":"eth0"
          }
        }
      ]
    }

CNI 구성 파일의 azure 또는 ipam 섹션에 추가 매개변수를 구성할 수 있어요. 지원되는 옵션에 대한 참조는 아래 Azure 할당 매개변수 목록을 참고하세요.

ConfigMap 을 배포합니다:

kubectl apply -f cni-config.yaml

사용자 지정 CNI 구성을 사용하도록 Cilium 구성

위의 지침으로 Cilium과 CNI 구성을 배포할 때 Helm에 다음 추가 인자를 지정하세요:

--set cni.customConf=true \
--set cni.configMap=cni-configuration

Azure 할당 매개변수

IP 할당을 제어하는 다음 매개변수가 있습니다:

spec.ipam.min-allocate

노드가 처음 부트스트랩될 때 반드시 할당되어야 하는 최소 IP 수입니다. 사용 가능해야 하는 최소 기본 주소 소켓 수를 정의합니다. 이 워터마크에 도달하면 PreAllocate와 MaxAboveWatermark 로직이 인계받아 IP 할당을 계속합니다.

지정하지 않으면 최소 IP 수가 요구되지 않습니다.

spec.ipam.pre-allocate

항상 할당에 사용 가능해야 하는 IP 주소 수입니다. operator가 개입할 필요 없이 즉시 사용 가능한 주소 버퍼를 정의합니다.

지정하지 않으면 이 값은 기본적으로 8입니다.

spec.azure.interface-name

IP 할당에 사용할 인터페이스의 이름입니다.

운영 세부 사항

Interfaces, Subnets, VirtualNetworks 캐시

Operator는 Azure 구독과 연관된 모든 Azure ScaleSets, Instances, Interfaces, VirtualNetworks, Subnets 목록을 캐시에 유지합니다.

캐시는 분당 한 번 또는 IP 할당이 수행된 후 업데이트됩니다. 할당에 기반해 트리거되면 작업은 최대 초당 한 번 수행됩니다.

사용 가능한 IP 발행

캐시 업데이트 후, 노드를 나타내는 모든 CiliumNode 사용자 지정 리소스가 업데이트되어 사용 가능해진 새로운 IP를 발행합니다.

이 과정에서 모든 인터페이스가 모든 사용 가능한 IP에 대해 스캔됩니다. 발견된 모든 IP는 spec.ipam.available 에 추가됩니다. 각 인터페이스도 status.azure.interfaces 에 추가됩니다.

이 업데이트로 사용자 지정 리소스가 변경되면, 사용자 지정 리소스는 사용 가능한 경우 Kubernetes API 메서드 Update() 및/또는 UpdateStatus() 를 사용해 업데이트됩니다.

IP 부족 또는 초과 결정

Operator는 모든 노드를 지속적으로 모니터링하고 사용 가능한 IP 주소의 부족을 감지합니다. 부족을 인식하는 검사는 두 경우에 수행됩니다:

  • CiliumNode 사용자 지정 리소스가 업데이트될 때
  • 모든 노드가 정기 간격(분당 한 번)으로 스캔될 때

노드에 IP 주소 부족이 있는지 결정할 때 다음 계산이 수행됩니다:

spec.ipam.pre-allocate - (len(spec.ipam.available) - len(status.ipam.used))

IP 초과 계산:

(len(spec.ipam.available) - len(status.ipam.used)) - (spec.ipam.pre-allocate + spec.ipam.max-above-watermark)

부족이 감지되면 노드는 IP 주소 할당이 필요한 노드 목록에 추가됩니다. 간격 기반 스캔으로 부족이 감지되면, 노드의 할당 순서는 부족의 심각도에 따라 결정됩니다. 즉 부족이 가장 큰 노드가 할당 큐의 앞에 옵니다. IP를 해제해야 하는 노드는 할당이 필요한 노드 뒤에 옵니다.

할당 큐는 요청 시 처리되지만 최대 초당 한 번입니다.

IP 할당

주소 부족이 있는 노드에 대해 IP 할당을 수행할 때, operator는 먼저 CiliumNode 리소스가 나타내는 인스턴스에 이미 연결된 인터페이스를 봅니다.

그런 다음 operator는 다음 기준을 충족하는 첫 번째 인터페이스를 선택합니다:

인터페이스에 할당되는 IP 수를 결정하는 데 다음 공식이 사용됩니다:

min(AvailableOnSubnet, min(AvailableOnInterface, NeededAddresses + spec.ipam.max-above-watermark))

즉 단일 할당 주기에서 할당되는 IP 수가 spec.ipam.pre-allocate 를 충족하는 데 필요한 것보다 적을 수 있습니다.

정적 공용 IP 할당

노드는 태그된 Azure Public IP Prefixes에서 정적 공용 IP를 할당받을 수 있습니다.

노드와 같은 Resource Group에 Public IP Prefix를 만들고 태그하세요:

$ az network public-ip prefix create \
  --resource-group $RESOURCE_GROUP \
  --name $PREFIX_NAME \
  --length 28 \
  --tags prefix-tag-key=prefix-tag-value

CNI 구성에서 ipam.static-ip-tags 를 설정하세요:

{
  "ipam": {
    "static-ip-tags": {
      "prefix-tag-key": "prefix-tag-value"
    }
  }
}

Operator는 사용 가능한 용량이 있는 첫 번째 일치 Prefix에서 공용 IP를 할당합니다. Prefix ID는 CiliumNode의 status.ipam.assigned-static-ip 에 저장됩니다.

IP 해제

IP 초과가 있는 노드에 대해 IP 해제를 수행할 때, operator는 노드에 연결된 인터페이스를 스캔합니다. 인터페이스에서 해제할 수 있는 IP 수를 결정하는 데 다음 공식이 사용됩니다:

min(FreeOnInterface, (TotalFreeIPs - spec.ipam.pre-allocate - spec.ipam.max-above-watermark))

노드 종료

노드 또는 인스턴스가 종료되면 Kubernetes apiserver가 노드 삭제 이벤트를 보냅니다. 이 이벤트는 operator가 받아들이고 operator는 해당 ciliumnodes.cilium.io 사용자 지정 리소스를 삭제합니다.

마스커레이딩

마스커레이딩은 eBPF ip-masq-agent 또는 --ipv4-native-routing-cidr 설정을 통해 지원됩니다.

필요한 권한

Operator가 사용하는 아이덴티티(관리 아이덴티티, 서비스 주체 또는 workload identity federation)는 토폴로지에 따라 두세 개의 범위에서 Azure RBAC 권한이 필요합니다:

  • 노드 리소스 그룹: VMSS에 대한 읽기와 노드 NIC에 IP 구성을 연결하는 데 필요한 쓰기를 부여합니다. VMSS에서는 VMSS 인스턴스의 VM 모델에 대한 쓰기이고, 독립형 VM에서는 네트워크 인터페이스 자체에 대한 쓰기입니다(정확한 권한은 아래 Actions 분류 참고). 이는 --azure-resource-group 으로 전달되는 리소스 그룹입니다(operator가 노드와 함께 있을 때 IMDS에서 자동 감지).
  • VNet / 서브넷 리소스 그룹: VNet과 서브넷에 대한 읽기, 그리고 새 개인 IP를 연결할 때 사용되는 subnets/join/action 을 부여합니다. 종종 노드 리소스 그룹과 같지만 별도의 네트워킹 리소스 그룹일 수 있어요.
  • 구독 (선택): 단일 역할 할당에서 여러 리소스 그룹에 걸친 VNet 발견이 동작하도록 하려는 경우에만 필요합니다. List 호출은 RBAC로 필터링되므로 구독 전체 Reader는 필수가 아니며, 각 관련 리소스 그룹에 같은 작업을 범위 지정하는 것으로 충분합니다.

사용자 지정 역할의 최소 Actions

필요한 Actions 집합은 노드 유형(VMSS 인스턴스 vs 독립형 VM)과 정적 공용 IP 할당 활성화 여부에 따라 달라집니다.

모든 배포에 공통:

Microsoft.Network/networkInterfaces/read
Microsoft.Network/virtualNetworks/read
Microsoft.Network/virtualNetworks/subnets/read
Microsoft.Network/virtualNetworks/subnets/join/action
Microsoft.Compute/virtualMachineScaleSets/read

VMSS 기반 클러스터의 경우 추가:

Microsoft.Compute/virtualMachineScaleSets/virtualMachines/read
Microsoft.Compute/virtualMachineScaleSets/virtualMachines/write

독립형 VM 클러스터의 경우 추가:

Microsoft.Network/networkInterfaces/write

Public IP Prefixes로 정적 공용 IP 할당을 사용하는 경우 추가:

Microsoft.Network/publicIPPrefixes/read
Microsoft.Network/publicIPPrefixes/join/action
Microsoft.Compute/virtualMachines/read

Note

Microsoft.Compute/virtualMachineScaleSets/virtualMachines/write 는 광범위한 권한으로, NIC 변경뿐만 아니라 인스턴스의 VM 모델에 대한 모든 PATCH를 승인합니다. 하지만 VMSS 토폴로지에는 필요합니다. VMSS에서 인스턴스별 NIC 구성은 인스턴스 모델 자체( Properties.NetworkProfileConfiguration )의 일부이며, NIC 블록만 편집을 허용하는 더 좁은 RBAC 작업이 없어요. operator는 이 권한을 기존 NIC의 IP 구성을 추가하거나 제거하는 데만 사용합니다. VMSS 인스턴스 수명 주기 작업은 발행하지 않습니다. 독립형 VM 배포는 NIC가 Microsoft.Network/networkInterfaces/write 로 편집되는 일급 리소스이므로 이 문제가 없습니다.

Note

노드 리소스 그룹은 AKS 클러스터의 리소스 그룹이 아닙니다. 단일 리소스 그룹에 여러 AKS 클러스터가 있을 수 있지만, 각 AKS 클러스터는 자동 관리되는 보조 리소스 그룹에 모든 리소스를 재그룹화합니다. 자세한 내용은 왜 AKS로 두 개의 리소스 그룹이 만들어지나요?를 참고하세요.

트러블슈팅

Microsoft.Network/virtualNetworks/read 의 AuthorizationFailed

operator의 아이덴티티가 VNet을 소유한 리소스 그룹에 읽기 접근 권한이 없습니다. VNet 리소스 그룹(노드 리소스 그룹과 다를 수 있음)을 범위로 하는 역할 할당을 추가하세요.

spec.ipam.available 이 비어 있고 할당이 발생하지 않음

--azure-resource-group 이 잘못된 리소스 그룹을 가리키고 있습니다. 값이 실제 VMs 또는 VMSS가 포함된 리소스 그룹과 일치하는지 확인하세요. operator 자신의 리소스 그룹이나 AKS 클러스터 리소스 그룹이 아니어야 합니다.

ManagedIdentityCredential authentication failed

--azure-user-assigned-identity-id 가 전체 리소스 ID( /subscriptions/.../userAssignedIdentities/ )로 설정되었습니다. 대신 아이덴티티의 client ID (UUID)를 전달하세요.

메트릭

메트릭은 IPAM 섹션에 문서화되어 있습니다.

더 알아보기 (Learn more)