반응형

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 트래픽이 다른 노드가 아닌 해당 노드의 파드를 대상으로 한다고 가정하기 때문입니다. 해결 방법은 두 가지입니다:

  1. clusterPoolIPv4PodCIDRList를 충돌하지 않는 CIDR로 명시적으로 설정하기
  2. 노드에 다른 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

아래와 같이 실습 환경에서 그 이유를 알아보겠습니다.

https://github.com/torrenser/study/tree/main/kubernetes/auto-setting

 

실습 환경에서는 아래와 같이 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

+ Recent posts