IPAM
IPAM 은 IP 를 관리하는 방법으로 Cilium 에서는 Cluster Scope 방식과 Kubernetes Host Scope 방식이 존재합니다.
Cluster Scope - 기본 모드

Cilium 에서 기본으로 제공하는 IP 주소 관리 방식으로 각 노드마다 별도의 PodCIDR 을 할당하고, 각 노드에서 host-scope allocator 를 사용해 실제 IP 를 배분합니다.
Kubernetes Host Scope 모드와 다르게 Cilium operator 가 v2.CiliumNode 리소스를 통해 IP 를 관리하는 것을 볼 수 있습니다.
실제 운영 환경에서는 Kubernetes 설정을 변경하기 어려운 경우가 많은데, PodCIDR 을 배포하도록 구성되지 않은 환경에서도 podCIDR 을 배포하도록 구성할 수 있다는 장점이 있습니다. 또한 Cilium 이 직접 관리하기 때문에 더 세밀한 제어가 필요한 경우에도 유연한 설정이 가능합니다.
동작 방식
Cilium 에이전트가 시작될 때, v2.CiliumNode 객체를 통해 podCIDRs 범위가 사용 가능해질 때까지 기다립니다.
v2.CiliumNode 리소스의 spec.ipam.podCIDRs 필드에는 IPv4 및/또는 IPv6 PodCIDR 범위가 설정됩니다. 이 정보가 준비되면 각 노드의 Cilium 에이전트가 해당 범위 내에서 파드들에게 IP 주소를 할당하기 시작합니다.
운영하다 보면 IP 주소가 부족해지는 상황이 발생할 수 있습니다. 이때 주의해야 할 점이 있습니다.
이미 할당된 IP 주소들과의 충돌을 방지하기 위해 기존 clusterPoolIPv4PodCIDRList의 요소들은 절대 변경하면 안 됩니다.
새로운 요소를 리스트에 추가해야 합니다. (최소 마스크 길이는 /30이지만, 권장하는 최소 길이는 /29입니다.)
(allocator 가 각 CIDR 블록마다 네트워크 주소와 브로드캐스트 주소용으로 2개의 IP를 예약하기 때문입니다.)
clusterPoolIPv4MaskSize 도 마찬가지로 변경할 수 없습니다.
트러블슈팅
가끔 IP 할당에 문제가 생길 수 있습니다. 이때는 다음 명령어로 확인할 수 있습니다.
kubectl get ciliumnodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.ipam.operator-status}{"\n"}{end}'
이 명령어는 각 노드의 상태를 보여주며, status.ipam.operator-status 필드의 Error 항목을 통해 문제를 파악할 수 있습니다.
가장 흔한 문제 중 하나는 노드 네트워크와 파드 CIDR이 겹치는 경우입니다. 기본 파드 CIDR은 10.0.0.0/8 인데, 만약 노드 네트워크도 같은 범위를 사용한다면 다른 노드로의 연결이 끊어집니다. 모든 egress 트래픽이 다른 노드가 아닌 해당 노드의 파드를 대상으로 한다고 가정하기 때문입니다. 해결 방법은 두 가지입니다:
- clusterPoolIPv4PodCIDRList를 충돌하지 않는 CIDR로 명시적으로 설정하기
- 노드에 다른 CIDR 사용하기
Kubernetes Host Scope

Kubernetes Host Scope IPAM 모드는 Kubernetes 자체의 PodCIDR 할당 메커니즘을 그대로 활용(Kubernetes의 네이티브 기능)
하여 각 노드에 IP 를 배분합니다.
ipam: kubernetes 설정으로 활성화되며, 클러스터의 각 개별 노드에 주소 할당을 위임합니다.
동작 방식
Cilium 에이전트가 시작될 때, Kubernetes v1.Node 객체를 통해 PodCIDR 범위가 사용 가능해질 때까지 기다립니다.
이는 활성화된 모든 주소에 대해 적용되며, 두 가지 방법으로 정보를 받아올 수 있습니다.
v1.Node 리소스 필드를 통한 방법
가장 일반적인 방법으로, v1.Node 리소스의 다음 필드들을 사용합니다:
- spec.podCIDR: IPv4 및/또는 IPv6 PodCIDR 범위
- spec.podCIDRs: IPv4 또는 IPv6 PodCIDR 범위 (배열 형태)
이 방법을 사용하려면 kube-controller-manager 를 --allocate-node-cidrs 플래그와 함께 실행해야 합니다.
kubernetes 에게 podCIDR 범위를 할당해야 한다고 알려주는 플래그입니다.
v1.Node 어노테이션을 통한 방법
두 번째 방법은 어노테이션을 활용하는 것입니다. 이 방법은 주로 spec.podCIDRs를 아직 지원하지 않는 구버전 Kubernetes와 함께 IPv4와 IPv6를 모두 사용할 때 유용합니다. 사용되는 어노테이션들은 다음과 같습니다:
- network.cilium.io/ipv4-pod-cidr: IPv4 PodCIDR 범위
- network.cilium.io/ipv6-pod-cidr: IPv6 PodCIDR 범위
- network.cilium.io/ipv4-cilium-host: cilium host 인터페이스의 IPv4 주소
- network.cilium.io/ipv6-cilium-host: cilium host 인터페이스의 IPv6 주소
- network.cilium.io/ipv4-health-ip: cilium-health 엔드포인트의 IPv4 주소
- network.cilium.io/ipv6-health-ip: cilium-health 엔드포인트의 IPv6 주소
- network.cilium.io/ipv4-ingress-ip: cilium-ingress 엔드포인트의 IPv4 주소
- network.cilium.io/ipv6-ingress-ip: cilium-ingress 엔드포인트의 IPv6 주소
설정 방법
ConfigMap을 통한 설정
Kubernetes hostscope 를 구성하는 ConfigMap 옵션들은 다음과 같습니다.
- ipam: kubernetes: Kubernetes IPAM 모드를 활성화합니다. 이 옵션을 활성화하면 enable-ipv4가 true일 때 k8s-require-ipv4-pod-cidr이 자동으로 활성화되고, enable-ipv6가 true일 때 k8s-require-ipv6-pod-cidr이 자동으로 활성화됩니다.
- k8s-require-ipv4-pod-cidr: true: Cilium 에이전트가 Kubernetes 노드 리소스를 통해 IPv4 PodCIDR이 사용 가능해질 때까지 기다리도록 지시합니다.
- k8s-require-ipv6-pod-cidr: true: Cilium 에이전트가 Kubernetes 노드 리소스를 통해 IPv6 PodCIDR이 사용 가능해질 때까지 기다리도록 지시합니다.
Helm을 통한 설정
Helm 차트를 사용할 때는 다음과 같이 설정할 수 있습니다.
- ipam: kubernetes: --set ipam.mode=kubernetes
- k8s-require-ipv4-pod-cidr: true: --set k8s.requireIPv4PodCIDR=true (이는 --set ipam.mode=kubernetes와 함께 사용해야 함)
- k8s-require-ipv6-pod-cidr: true: --set k8s.requireIPv6PodCIDR=true (이는 --set ipam.mode=kubernetes와 함께 사용해야 함)
IPAM 변경 금지
Cilium 공식문서에 따르면 이미 IPAM 이 운영 중인 환경에서는 가급적 IPAM 모드를 변경하지 않는 것을 권장하고 있습니다.

https://docs.cilium.io/en/stable/network/concepts/ipam/index.html
아래와 같이 실습 환경에서 그 이유를 알아보겠습니다.

실습 환경에서는 아래와 같이 ipam 모드가 kubernetes 이지만,
helm get values cilium -n kube-system

ipam.mode 를 cluster-pool 형식으로 변경하려고 합니다.
IP 대역을 10.244.0.0/16 에서 172.20.0.0/16 으로 변경하면서 실제로 쿠버네티스 IP 대역들로 변경되는지 체크하려고 합니다.
helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
--set ipam.mode="cluster-pool"
--set ipam.operator.clusterPoolIPv4PodCIDRList={"172.20.0.0/16"}
--set ipv4NativeRoutingCIDR=172.20.0.0/16
kubectl -n kube-system rollout restart deploy/cilium-operator
kubectl -n kube-system rollout restart ds/cilium
위에서 cilium-operator 가 ipam 을 주관한다고 했으므로 cilim-operator 도 같이 rollout 합니다.



결과를 확인해보면 ipam 모드는 정상적으로 변경되었지만, podCIDR 대역은 변경되지 않았습니다.
cilium node 의 ip 부터 변경해봅니다.
kubectl delete ciliumnode k8s-w1
kubectl delete ciliumnode k8s-ctr
kubectl -n kube-system rollout restart ds/cilium

cilium node 의 pod CIDR 대역은 변경되었지만, 실제 enpdoint 의 주소들 중 coreDNS 만 변경된 것을 볼 수 있습니다. (???)
심지어 pod 의 IP 들은 아직도 변경되지 않았습니다. pod 생성 당시 ip 들을 이전 ip 로 배정받아 그런 것으로 보입니다.

문제가 되는 deploy 들과 pod 들을 롤아웃하여 재시작해봅니다.
kubectl -n kube-system rollout restart deploy/hubble-relay deploy/hubble-ui
kubectl -n cilium-monitoring rollout restart deploy/prometheus deploy/grafana
kubectl rollout restart deploy/webpod
kubectl delete pod curl-pod
# curl-pod 재시작
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: curl-pod
labels:
app: curl
spec:
nodeName: k8s-ctr
containers:
- name: curl
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF

재시작하니 pod 의 ip 들이 변경되었습니다. IPAM 모드를 변경하면 서비스 중단이 발생하고, 재시작 해주어야 한다는 것을 알 수 있습니다. 운영환경에서는 신중하게 작업할 필요가 있어보입니다.
'인프라 > 쿠버네티스' 카테고리의 다른 글
| [cilium] Overlay Network (1) | 2025.08.09 |
|---|---|
| [cilium] Routing & Masquerading (1) | 2025.07.31 |
| [cilium] Hubble Exporter (2) | 2025.07.23 |
| [cilium] Hubble 개념과 설치 (5) | 2025.07.21 |
| [cilium] Cilium Network Policy (0) | 2025.07.21 |