클러스터 범위에서 Multi-Pool로 마이그레이션

클러스터 범위에서 Multi-Pool로 마이그레이션 (Migrating from Cluster Scope to Multi-Pool)

이 섹션은 실행 중인 클러스터를 Cluster Scope (Default) IPAM 모드에서 Multi-Pool IPAM 모드로 마이그레이션하는 방법을 설명해요. 마이그레이션은 기존 per-node PodCIDR 할당을 안정적으로 유지하므로 Pod가 IP를 유지하고 클러스터 마이그레이션 중에도 연결이 중단되지 않습니다.

출처: Migrating from Cluster Scope to Multi-Pool

본문

이 섹션은 실행 중인 클러스터를 Cluster Scope (Default) IPAM 모드에서 Multi-Pool IPAM 모드로 마이그레이션하는 방법을 설명합니다. 마이그레이션은 기존 per-node PodCIDR 할당을 안정적으로 유지하므로, Pod가 IP 주소를 유지하고 클러스터가 마이그레이션되는 동안 연결이 중단되지 않아요. 이는 BGP 컨트롤 플레인이 광고하는 PodCIDR에 의존하는 연결에는 적용되지 않습니다. 아래 BGP 마이그레이션 경고를 참고하세요.

마이그레이션 동안 Cilium operator는 각 CiliumNode 를 spec.ipam.podCIDRs 의 클러스터-풀 표현에서 spec.ipam.pools.allocated 의 멀티-풀 표현으로 변환합니다. 그러면 Cilium 에이전트를 점진적으로 재시작할 수 있어요. 여전히 클러스터-풀 모드로 실행되는 노드와 이미 멀티-풀 모드로 실행되는 노드는 이 롤링 재시작 동안 pod 연결을 계속 제공할 수 있습니다.

한계

마이그레이션에는 다음 한계가 적용됩니다:

  • 마이그레이션은 클러스터-풀 IPAM 모드에서 멀티-풀 IPAM 모드로의 이동만 지원합니다. 실패 시 롤백은 사용할 수 없어요.
  • 클러스터-풀 IPAM에서 할당된 IP를 가진 모든 Pod는 기본 멀티-풀 IP 풀로 마이그레이션됩니다. 기존 Pod는 pod 애노테이션, 네임스페이스 애노테이션 또는 풀 셀렉터에 따라 서로 다른 풀로 분산되지 않아요.
  • operator가 마이그레이션을 수행할 때 기본 풀이 operator에게 제공되어야 합니다. CiliumPodIPPool 을 operator를 재시작하기 전에 수동으로 만들거나, auto-create-cilium-pod-ip-pools 옵션을 설정해 operator가 시작 시 만들도록 할 수 있습니다. Helm에서는 이 옵션을 ipam.operator.autoCreateCiliumPodIPPools 값으로 구성합니다.
  • 기본 풀은 노드에 이미 할당된 클러스터-풀 CIDR을 포괄해야 하고, 기존 클러스터-풀 할당과 같은 마스크 크기를 사용해야 해요.
  • 기본 풀 이름은 ipam-default-ip-pool 옵션으로 변경하지 않는 한 default 입니다.
  • 마이그레이션에 사용되는 기본 풀 이름은 CiliumNodeConfig 를 통해 노드별로 덮어써서는 안 됩니다. 기본이 아닌 풀 이름을 사용해야 한다면, operator를 재시작할 때 ipam-default-ip-pool 옵션으로 전역적으로 변경하세요.

마이그레이션 단계

마이그레이션에 이 높은 수준의 워크플로를 사용하세요:

  1. 기본 CiliumPodIPPool 을 만들거나 auto-create-cilium-pod-ip-pools 를 구성해 Cilium operator가 시작할 때 만들도록 합니다.
  2. Cilium Helm 릴리스를 업그레이드해 Cilium 구성을 ipam: cluster-pool 에서 ipam: multi-pool 로 변경하고, operator 옵션 enable-cluster-pool-to-multi-pool-migration 을 true 로 설정하며, Cilium operator만 재시작합니다.
  3. 각 CiliumNode 의 기존 PodCIDR이 spec.ipam.pools.allocated 아래에 나열될 때까지 기다립니다.
  4. BGP 컨트롤 플레인이 PodCIDR을 광고한다면, CiliumBGPAdvertisement 를 업데이트해 기본 CiliumPodIPPool 에서 마이그레이션된 CIDR을 광고합니다. 구성 세부 사항은 BGP MultiPool IPAM advertisements를 참고하세요.
  5. Cilium 에이전트를 한 번에 또는 점진적으로 재시작합니다.

Warning

BGP 컨트롤 플레인이 PodCIDR을 광고하면 마이그레이션 중 광고된 경로에 일시적인 중단이 예상됩니다. Cilium operator가 각 할당을 spec.ipam.podCIDRs 에서 spec.ipam.pools.allocated 로 옮기므로, 여전히 클러스터-풀 모드로 실행되는 에이전트는 PodCIDR 광고를 철회합니다. 이 에이전트들은 멀티-풀 모드로 재시작하기 전까지는 advertisementType: CiliumPodIPPool 로 마이그레이션된 할당을 광고할 수 없어요.

마이그레이션을 완료하려면 에이전트를 재시작하기 전에 CiliumBGPAdvertisement 를 advertisementType: PodCIDR 에서 advertisementType: CiliumPodIPPool 로 업데이트하고 마이그레이션된 기본 풀을 선택하세요. 중단을 최소화하려면 Cilium operator가 모든 CiliumNode 를 마이그레이션하고 BGP 광고를 업데이트한 후 가능한 한 빨리 모든 Cilium 에이전트를 재시작하세요.

실용 예시

다음 예시는 하나의 컨트롤 플레인 노드와 세 개의 워커 노드가 있는 kind 클러스터를 마이그레이션합니다. 클러스터는 10.0.0.0/8 을 클러스터 전체 풀로, /24 per-node PodCIDR로 클러스터-풀 IPAM 모드에서 시작합니다.

마이그레이션 전에 각 CiliumNode 는 spec.ipam.podCIDRs 에 per-node 할당을 저장합니다:

$ kubectl get ciliumnode kind-worker -o yaml | yq .spec.ipam
podCIDRs:
  - 10.0.3.0/24
pools: {}

$ kubectl get ciliumnode kind-worker2 -o yaml | yq .spec.ipam
podCIDRs:
  - 10.0.0.0/24
pools: {}

$ kubectl get ciliumnode kind-worker3 -o yaml | yq .spec.ipam
podCIDRs:
  - 10.0.1.0/24
pools: {}

$ kubectl get ciliumnode kind-control-plane -o yaml | yq .spec.ipam
podCIDRs:
  - 10.0.2.0/24
pools: {}

Cilium Helm 릴리스를 업그레이드해 멀티-풀 IPAM 모드로 전환하고 operator 마이그레이션을 활성화합니다. 이 예시는 ipam.operator.autoCreateCiliumPodIPPools 를 사용해 operator가 클러스터-풀 IPAM이 사용하는 것과 같은 CIDR과 per-node 마스크 크기로 default CiliumPodIPPool 을 만들게 합니다. 이 명령은 Cilium ConfigMap을 업데이트하고 Cilium operator만 재시작합니다:

$ helm upgrade cilium cilium/cilium \
    --namespace kube-system \
    --reuse-values \
    --set ipam.mode=multi-pool \
    --set ipam.operator.autoCreateCiliumPodIPPools.default.ipv4.cidrs='{10.0.0.0/8}' \
    --set ipam.operator.autoCreateCiliumPodIPPools.default.ipv4.maskSize=24 \
    --set-string extraConfig.enable-cluster-pool-to-multi-pool-migration=true \
    --set operator.rollOutPods=true \
    --set rollOutCiliumPods=false

마이그레이션에 다른 기본 풀 이름을 사용하려면 operator를 재시작하는 같은 Helm 업그레이드에서 --set-string extraConfig.ipam-default-ip-pool= 로 전역적으로 구성하세요.

operator가 기본 풀을 만들 때까지 기다립니다:

$ kubectl get ciliumpodippool default -o yaml
apiVersion: cilium.io/v2alpha1
kind: CiliumPodIPPool
metadata:
  name: default
spec:
  ipv4:
    cidrs:
    - 10.0.0.0/8
    maskSize: 24

operator가 마이그레이션을 수행한 후, 각 노드는 기본 멀티-풀 IP 풀에서 할당된 같은 per-node CIDR을 갖습니다:

$ kubectl get ciliumnode kind-worker -o yaml | yq .spec.ipam
pools:
  allocated:
    - cidrs:
        - 10.0.3.0/24
      pool: default

$ kubectl get ciliumnode kind-worker2 -o yaml | yq .spec.ipam
pools:
  allocated:
    - cidrs:
        - 10.0.0.0/24
      pool: default

$ kubectl get ciliumnode kind-worker3 -o yaml | yq .spec.ipam
pools:
  allocated:
    - cidrs:
        - 10.0.1.0/24
      pool: default

$ kubectl get ciliumnode kind-control-plane -o yaml | yq .spec.ipam
pools:
  allocated:
    - cidrs:
        - 10.0.2.0/24
      pool: default

하나의 Cilium 에이전트를 재시작합니다. 에이전트 Pod를 직접 삭제하거나 노드 이름으로 선택할 수 있어요:

$ kubectl -n kube-system delete pod \
    --field-selector spec.nodeName=kind-worker \
    --selector="app.kubernetes.io/name=cilium-agent"

에이전트가 재시작된 후, 멀티-풀 IPAM 모드로 실행되며 복원된 엔드포인트의 IP를 유지하면서 기본 풀에서 IP를 요청합니다:

$ kubectl get ciliumnode kind-worker -o yaml | yq .spec.ipam
pools:
  allocated:
    - cidrs:
        - 10.0.3.0/24
      pool: default
  requested:
    - needed:
        ipv4-addrs: 16
      pool: default

$ kubectl -n kube-system exec -ti cilium-qvz4n -- cilium-dbg status --all-addresses
IPAM:                   IPv4: 1 IPAM pool(s) available,
Allocated addresses:
  10.0.3.190 (router)
  10.0.3.203 (default/nginx-66686b6766-9v2sb [restored])
  10.0.3.240 (health)

일부 에이전트가 이미 멀티-풀 모드로 이동하고 다른 에이전트가 여전히 클러스터-풀 모드로 실행되는 동안에도 노드 간 연결이 유지됩니다:

$ kubectl exec -ti nginx-66686b6766-9v2sb -- curl 10.0.0.30:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

$ kubectl exec -ti nginx-66686b6766-ktpgn -- curl 10.0.3.203:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

롤링 마이그레이션 중에도 새 Pod를 스케줄할 수 있습니다. 멀티-풀 에이전트는 마이그레이션된 기본 풀에서 새 IP를 할당하고, 클러스터-풀 에이전트는 재시작될 때까지 기존 클러스터-풀 할당을 계속 사용합니다:

$ kubectl scale deployment nginx --replicas=8
deployment.apps/nginx scaled

$ kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE
nginx-66686b6766-26jkc   1/1     Running   0          12s   10.0.3.209   kind-worker
nginx-66686b6766-hcnlz   1/1     Running   0          12s   10.0.0.101   kind-worker2
nginx-66686b6766-9v2sb   1/1     Running   0          21m   10.0.3.203   kind-worker
nginx-66686b6766-ktpgn   1/1     Running   0          21m   10.0.0.30    kind-worker2
...

모든 노드가 멀티-풀 IPAM 모드로 실행될 때까지 나머지 Cilium 에이전트의 재시작을 계속합니다:

$ kubectl -n kube-system delete pod \
    --field-selector spec.nodeName=kind-worker2 \
    --selector="app.kubernetes.io/name=cilium-agent"

$ kubectl -n kube-system delete pod \
    --field-selector spec.nodeName=kind-worker3 \
    --selector="app.kubernetes.io/name=cilium-agent"

$ kubectl -n kube-system delete pod \
    --field-selector spec.nodeName=kind-control-plane \
    --selector="app.kubernetes.io/name=cilium-agent"

마지막 에이전트가 재시작되면 클러스터는 멀티-풀 IPAM으로 실행됩니다. 기존 pod IP는 기본 멀티-풀 IP 풀에서 안정적으로 유지됩니다.

마이그레이션 완료 후, 기본 풀에 CIDR을 추가하거나(기존 풀 변경에 대한 안내는 Updating existing CiliumPodIPPools 참고) 추가 풀을 만들어 할당 가능한 PodCIDR을 확장할 수 있어요. 이는 노드에 추가 CIDR을 추가하는 것이 지원되지 않는 클러스터-풀 IPAM 모드의 한계를 극복합니다.

Warning

모든 Cilium 에이전트가 멀티-풀 IPAM 모드로 재시작된 후에만 기본이 아닌 풀을 참조하는 Pod를 스케줄하세요. 롤링 마이그레이션 동안 Kubernetes는 참조된 풀이 사용 불가능한 클러스터-풀 IPAM 모드로 여전히 실행되는 Cilium 에이전트가 있는 노드에 Pod를 스케줄할 수 있어요.

새 풀을 만듭니다:

apiVersion: cilium.io/v2alpha1
kind: CiliumPodIPPool
metadata:
  name: test-pool
spec:
  ipv4:
    cidrs:
    - 11.0.0.0/8
    maskSize: 24

그런 다음 새 풀에서 IP를 명시적으로 요청하는 Pod를 만듭니다:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-other-pool
  annotations:
    ipam.cilium.io/ip-pool: test-pool
spec:
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80

리소스를 적용합니다:

$ kubectl apply -f test-pool.yaml
ciliumpodippool.cilium.io/test-pool created
$ kubectl apply -f nginx-other-pool.yaml
pod/nginx-other-pool created

새 Pod는 새 풀에서 IP를 받습니다:

$ kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE
nginx-other-pool         1/1     Running   0          28s   11.0.0.15    kind-worker
...

Pod를 호스팅하는 노드는 이제 마이그레이션된 기본 풀과 새 풀 모두에서 할당을 갖습니다:

$ kubectl get ciliumnode kind-worker -o yaml | yq .spec.ipam
pools:
  allocated:
    - cidrs:
        - 10.0.3.0/24
      pool: default
    - cidrs:
        - 11.0.0.0/24
      pool: test-pool
  requested:
    - needed:
        ipv4-addrs: 16
      pool: default
    - needed:
        ipv4-addrs: 1
      pool: test-pool

$ kubectl -n kube-system exec -ti cilium-qvz4n -- cilium-dbg status --all-addresses
IPAM:                   IPv4: 2 IPAM pool(s) available,
Allocated addresses:
  10.0.3.190 (router)
  10.0.3.203 (default/nginx-66686b6766-9v2sb [restored])
  10.0.3.209 (default/nginx-66686b6766-26jkc)
  10.0.3.240 (health)
  test-pool/11.0.0.15 (default/nginx-other-pool)

더 알아보기 (Learn more)