Oracle Kubernetes Engine
Oracle Kubernetes Engine (OKE) VCN-Native 파드 네트워킹과 체이닝하기 (Oracle Kubernetes Engine (OKE) VCN-Native Pod Networking)
오라클의 CNI 스택이 가상 네트워크 장치 설정과 IP 주소 관리(IPAM)를 담당하는 하이브리드 모드에서, Oracle Kubernetes Engine(OKE)의 VCN-Native Pod Networking 위에 Cilium을 설정하는 방법을 설명할게요.
출처: Oracle Kubernetes Engine (OKE) VCN-Native Pod Networking
본문
이 가이드는 VCN-Native Pod Networking을 사용하는 Oracle Kubernetes Engine(OKE) 위에 Cilium을 설정하는 방법을 설명해요. 이 하이브리드 모드에서 Oracle의 CNI 스택은 가상 네트워크 장치 설정과 VCN 서브넷에서의 IP 주소 관리(IPAM)를 담당해요. 특정 파드에 초기 네트워킹이 설정된 후, Cilium CNI 플러그인은 eBPF 프로그램을 붙여 네트워크 정책을 강제하고, 로드밸런싱을 수행하며, 가시성을 제공해요.
VCN-Native Pod Networking은 OKE를 위한 Oracle이 권장하는 프로덕션 CNI 모드예요. VCN 서브넷에서 직접 파드 IP를 할당하므로, 오버레이 없이 파드가 기본적으로 라우팅 가능해요. 이는 AWS VPC CNI나 Azure CNI에 해당하는 Oracle 방식이에요.
참고: 다른 CNI 플러그인과 체이닝할 때는 일부 고급 Cilium 기능이 제한될 수 있어요.
동작 원리 (How it works)
OKE CNI 스택은 두 플러그인을 순차적으로 실행해요.
-
oci-ipvlan: OCI IPAM을 통해 VCN 서브넷에서 파드 IP를 할당하고, 기본 컴퓨트 인스턴스에서 VNIC 부착을 관리해요.
-
oci-ptp: 파드 네트워크 네임스페이스와 호스트 사이에 veth 쌍을 생성해요.
oci-ipvlan 플러그인 이름과 달리 실제 파드-facing 인터페이스는 표준 veth 쌍이에요. 파드는 VCN-native IP를 받고, 호스트는 파드별 veth 피어를 가지며, 라우팅은 169.254.1.1의 proxy-ARP 게이트웨이를 사용해요. 이 모델은 AWS VPC CNI와 기능적으로 동일해요.
Cilium은 generic-veth 체이닝 모드를 통해 체인의 세 번째 플러그인으로 실행돼요. cni.chainingTarget=oci가 설정되면 Cilium 에이전트가 각 노드의 기존 OCI conflist("oci" 이름)를 발견해 자신을 플러그인 배열에 병합하고, 결과를 /etc/cni/net.d/05-cilium.conflist에 작성해요. 원본 10-oci.conflist는 수정되지 않아요 — 그 파일을 확인하면 cilium-cni 항목이 보이지 않아요. 05-cilium.conflist가 10-oci.conflist보다 앞서 정렬되므로, kubelet은 모든 새 파드에 대해 이를 자동으로 선택해요. 수동 CNI ConfigMap이 필요하지 않아요.
사전 요구사항 (Prerequisites)
-
VCN-Native Pod Networking이 활성화된 OKE 클러스터(Flannel 아님)
-
클러스터를 가리키도록 구성된
kubectl -
Helm v3+
Cilium 설정 (Setting up Cilium)
Helm 저장소를 설정해요.
Helm Repository
helm repo add cilium https://helm.cilium.io/
Cilium 차트는 OCI 레지스트리(Quay.io 및 Docker Hub)에서도 사용할 수 있어요. 추가 설정 없이 oci:// URL로 직접 설치할 수 있어요. 차트 서명 검증과 digest 기반 설치를 포함한 자세한 내용은 OCI Registry 섹션을 참고하세요.
Helm으로 Cilium을 배포해요.
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set cni.chainingTarget=oci \
--set cni.exclusive=false \
--set routingMode=native \
--set enableIPv4Masquerade=false \
--set kubeProxyReplacement=false \
--set ipam.mode=cluster-pool \
--set ipam.operator.clusterPoolIPv4PodCIDRList=100.64.0.0/16
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set cni.chainingTarget=oci \
--set cni.exclusive=false \
--set routingMode=native \
--set enableIPv4Masquerade=false \
--set kubeProxyReplacement=false \
--set ipam.mode=cluster-pool \
--set ipam.operator.clusterPoolIPv4PodCIDRList=100.64.0.0/16
cni.chainingTarget=oci를 설정하면 Cilium 에이전트가 기존 OCI CNI conflist를 찾아 스스로 자동 주입하도록 지시해요. 파드 IP가 VCN 내에서 직접 라우팅되므로 터널링은 비활성화돼요. OCI가 VCN 수준에서 라우팅을 처리하므로 마스커레이딩도 비활성화돼요. cni.exclusive=false는 Cilium이 CNI 구성 디렉터리의 소유권을 갖지 않게 해 OKE의 vcn-native-ip-cni DaemonSet이 제어를 유지하도록 해요.
참고:
ipam.operator.clusterPoolIPv4PodCIDRList는 RFC 6598 CGNAT 범위인 100.64.0.0/16으로 설정돼요. 이는 VCN 서브넷과 충돌하지 않으며, Cilium이 내부 목적으로만 사용해요. 실제 파드 IP는 항상 OCI IPAM이 VCN 서브넷에서 할당해요.
참고: OKE는 기본적으로 kube-proxy를 실행해요.
kubeProxyReplacement=false플래그는 그것을 그대로 둬요. Cilium이 kube-proxy를 대체하게 하려면, 체이닝 설정이 안정된 후 표준 Kubernetes Without kube-proxy 가이드를 따르세요.
기존 파드 재시작하기 (Restart existing pods)
새 CNI 체이닝 구성은 Cilium 설치 전에 이미 실행 중이던 파드에는 적용되지 않아요. 그 파드들은 연결이 가능하고 Cilium이 그쪽으로 로드밸런싱하지만, 재시작하기 전에는 정책 강제가 적용되지 않아요.
재시작이 필요한 파드를 식별하려면 다음을 사용하세요.
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
ceps=$(kubectl -n "${ns}" get cep \
-o jsonpath='{.items[*].metadata.name}')
pods=$(kubectl -n "${ns}" get pod \
-o custom-columns=NAME:.metadata.name,NETWORK:.spec.hostNetwork \
| grep -E '\s(<none>|false)' | awk '{print $1}' | tr '\n' ' ')
ncep=$(echo "${pods} ${ceps}" | tr ' ' '\n' | sort | uniq -u | paste -s -d ' ' -)
for pod in $(echo $ncep); do
echo "${ns}/${pod}";
done
done
제거 (Uninstall)
$ helm uninstall cilium -n kube-system
경고:
helm uninstall은 Kubernetes 리소스를 제거하지만 노드 호스트 경로에 작성된 파일은 정리하지 않아요. 제거 후에도/etc/cni/net.d/05-cilium.conflist파일은 모든 노드에 남아요. 그것이10-oci.conflist보다 앞서 정렬되므로 kubelet은 새 파드 생성에 계속 그것을 사용해요. Cilium 에이전트가 사라진 상태에서 cilium-cni는 소켓에 도달할 수 없고, 새 파드는dial unix /var/run/cilium/cilium.sock: connect: no such file or directory오류와 함께 ContainerCreating에 갇히게 돼요. 이미 실행 중인 파드는 CNI가 파드 생성 시에만 호출되므로 영향을 받지 않아요. 제거 후 각 노드에 SSH로 접속해 파일을 제거하세요. 그러면 OKE의vcn-native-ip-cniDaemonSet이10-oci.conflist를 통해 모든 새 파드 네트워킹을 처리해요.
설치 검증 (Validate the Installation)
Cilium CLI의 최신 버전을 설치해요. Cilium CLI는 Cilium 설치, Cilium 설치 상태 검사, 그리고 다양한 기능(예: clustermesh, Hubble)의 활성화/비활성화에 사용할 수 있어요.
Linux
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
macOS
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "arm64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
shasum -a 256 -c cilium-darwin-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-darwin-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
전체 릴리스 목록은 releases 페이지에서 확인할 수 있어요.
Cilium이 제대로 설치됐는지 검증하려면 다음을 실행하면 돼요.
$ cilium status --wait
/¯\
/¯\__/¯\ Cilium: OK
\__/¯\__/ Operator: OK
/¯\__/¯\ Hubble: disabled
\__/¯\__/ ClusterMesh: disabled
\__/
DaemonSet cilium Desired: 2, Ready: 2/2, Available: 2/2
Deployment cilium-operator Desired: 2, Ready: 2/2, Available: 2/2
Containers: cilium-operator Running: 2
cilium Running: 2
Image versions cilium quay.io/cilium/cilium:v1.9.5: 2
cilium-operator quay.io/cilium/operator-generic:v1.9.5: 2
다음 명령을 실행해 클러스터가 올바른 네트워크 연결성을 갖췄는지 검증해요.
$ cilium connectivity test
ℹ️ Monitor aggregation detected, will skip some flow validation steps
✨ [k8s-cluster] Creating namespace for connectivity check...
(...)
---------------------------------------------------------------------------------------------------------------------
📋 Test Report
---------------------------------------------------------------------------------------------------------------------
✅ 69/69 tests successful (0 warnings)
참고: 연결성 테스트는 일부 파드에서 열려 있는 파일이 너무 많아 배포에 실패할 수도 있어요. 이런 오류가 보이면 호스트 머신의 inotify 리소스 한도를 늘려 보세요 (즉, "too many open files"로 인한 파드 오류 참고).
축하해요! 이제 Cilium이 완전히 동작하는 Kubernetes 클러스터를 갖추셨어요. 🎉
Cilium과 필요한 모든 컴포넌트가 설치되는 과정을 모니터링할 수 있어요.
$ kubectl -n kube-system get pods --watch
NAME READY STATUS RESTARTS AGE
cilium-operator-cb4578bc5-q52qk 0/1 Pending 0 8s
cilium-s8w5m 0/1 PodInitializing 0 7s
coredns-86c58d9df4-4g7dd 0/1 ContainerCreating 0 8m57s
coredns-86c58d9df4-4l6b2 0/1 ContainerCreating 0 8m57s
모든 컴포넌트가 뜨기까지 몇 분 걸릴 수 있어요.
cilium-operator-cb4578bc5-q52qk 1/1 Running 0 4m13s
cilium-s8w5m 1/1 Running 0 4m12s
coredns-86c58d9df4-4g7dd 1/1 Running 0 13m
coredns-86c58d9df4-4l6b2 1/1 Running 0 13m
파드 간 연결성을 테스트하려면 "connectivity-check"를 배포할 수 있어요. 이를 위한 별도 네임스페이스를 만드는 것을 권장해요.
kubectl create ns cilium-test
다음으로 검사(check)를 배포하면 돼요.
kubectl apply -n cilium-test -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/connectivity-check/connectivity-check.yaml
이것은 다양한 연결성 경로로 서로 연결되는 일련의 배포(deployment)들을 배포해요. 연결성 경로에는 서비스 로드밸런싱 유무와 다양한 네트워크 정책 조합이 포함돼요. 파드 이름은 연결성 변형을 나타내며, readiness와 liveness 게이트는 테스트의 성공 또는 실패를 나타내요.
$ kubectl get pods -n cilium-test
NAME READY STATUS RESTARTS AGE
echo-a-76c5d9bd76-q8d99 1/1 Running 0 66s
echo-b-795c4b4f76-9wrrx 1/1 Running 0 66s
echo-b-host-6b7fc94b7c-xtsff 1/1 Running 0 66s
host-to-b-multi-node-clusterip-85476cd779-bpg4b 1/1 Running 0 66s
host-to-b-multi-node-headless-dc6c44cb5-8jdz8 1/1 Running 0 65s
pod-to-a-79546bc469-rl2qq 1/1 Running 0 66s
pod-to-a-allowed-cnp-58b7f7fb8f-lkq7p 1/1 Running 0 66s
pod-to-a-denied-cnp-6967cb6f7f-7h9fn 1/1 Running 0 66s
pod-to-b-intra-node-nodeport-9b487cf89-6ptrt 1/1 Running 0 65s
pod-to-b-multi-node-clusterip-7db5dfdcf7-jkjpw 1/1 Running 0 66s
pod-to-b-multi-node-headless-7d44b85d69-mtscc 1/1 Running 0 66s
pod-to-b-multi-node-nodeport-7ffc76db7c-rrw82 1/1 Running 0 65s
pod-to-external-1111-d56f47579-d79dz 1/1 Running 0 66s
pod-to-external-fqdn-allow-google-cnp-78986f4bcf-btjn7 1/1 Running 0 66s
참고: 연결성 검사를 단일 노드 클러스터에 배포하면, 멀티 노드 기능을 확인하는 파드는 Pending 상태로 남아 있어요. 이는 정상이에요. 이 파드들은 성공적으로 스케줄링되려면 최소 2개의 노드가 필요하기 때문이에요.
테스트가 끝나면 cilium-test 네임스페이스를 제거하세요.
kubectl delete ns cilium-test
다음 단계 (Next Steps)
-
Hubble Observability 설정
-
CLI로 네트워크 플로우 검사
-
Service Map과 Hubble UI
-
Identity-Aware 및 HTTP-Aware 정책 강제
-
Cluster Mesh 설정