eBPF 모드로 설치하기
eBPF 모드로 설치하기 (Install in eBPF mode)
이 가이드는 Calico를 설치하면서 eBPF 데이터플레인을 직접 활성화하는 방법을 알려줘요. eBPF 모드는 표준 Linux 네트워킹 파이프라인 모드보다 높은 처리량, 낮은 CPU 사용량, kube-proxy 없이 가능한 Kubernetes 서비스 네이티브 지원이 장점이에요. 클러스터 구성 단계에서 eBPF 모드를 켜는 방법과 배포판별 주의 사항을 하나씩 짚어볼게요.
출처: 문서
본문
이 가이드는 Calico 설치 중에 eBPF 데이터플레인을 수동으로 활성화하는 방법을 보여줘요.
성공 팁: 셀프 관리 kubeadm 클러스터에 Calico를 설치한다면, 온프레미스 배포용 Calico 설치의 operator 설치 방법을 따라 eBPF 모드를 자동으로 활성화할 수 있어요. 이런 종류의 클러스터에서는 eBPF 모드가 기본 데이터플레인이라 이 가이드의 단계를 따를 필요가 없어요.
가치 (Value)
eBPF 데이터플레인 모드는 표준 Linux 네트워킹 파이프라인 모드에 비해 몇 가지 장점이 있어요:
- 더 높은 처리량까지 확장돼요.
- GBit당 CPU를 더 적게 써요.
- Kubernetes 서비스를 네이티브로 지원해요(kube-proxy가 필요 없어요). 덕분에:
- 서비스로 가는 패킷의 첫 패킷 지연이 줄어들어요.
- 외부 클라이언트 소스 IP 주소가 파드까지 그대로 보존돼요.
- DSR(Direct Server Return)을 지원해서 서비스 라우팅이 더 효율적이에요.
- 데이터플레인을 동기화 상태로 유지하는 데 kube-proxy보다 CPU를 적게 써요.
더 자세히 알아보고 테스트 환경의 성능 지표를 보려면 블로그 글, Introducing the Calico eBPF data plane을 참고하세요.
개념 (Concepts)
eBPF
eBPF(또는 "extended Berkeley Packet Filter")는 안전한 미니 프로그램을 Linux 커널의 여러 저수준 훅에 붙일 수 있게 해주는 기술이에요. eBPF는 네트워킹, 보안, 트레이싱 등 아주 다양한 용도로 쓰여요. 네트워킹이 아닌 프로젝트들도 eBPF를 많이 활용하지만, Calico의 관심사는 네트워킹, 특히 최신 Linux 커널의 네트워킹 능력을 한계까지 끌어올리는 거예요.
시작하기 전에 (Before you begin)
지원됨 (Supported)
-
x86-64
-
arm64 (little-endian)
-
Kubernetes 데이터스토어 드라이버.
-
배포판:
- Generic 또는 kubeadm
- kOps
- OpenShift
- EKS
- AKS
- MKE
-
Linux 배포판/커널:
- Ubuntu 22.04 이상.
- Linux 커널 v4.18.0-305 이상인 Red Hat v8.4 (Red Hat이 필요한 기능을 해당 빌드에 백포트했어요).
- Linux 커널 v5.10 이상인 지원되는 다른 배포판.
- 불변(immutable) 운영체제(예: Talos Linux):
FelixConfigurationCRD의CgroupV2Path를 쓰기 가능한 경로로 설정했는지 확인하세요.
eBPF 기능별 커널 버전 요구 사항
일부 eBPF 기능은 기본 eBPF 데이터플레인보다 높은 커널 버전을 필요로 해요.
| 기능 | 최소 커널 버전 | 세부 사항 |
|---|---|---|
| 기본 eBPF 데이터플레인 | v5.10 (RHEL: v4.18.0-305) | 이 버전에서 CO-RE 지원으로 더 나은 성능 |
| eBPF 모드의 Log rules | v5.16 | bpftool prog tracelog를 통해 trace pipe로 로그 전송 |
| QoS 대역폭 제어 | v6.6 | tcx 지원 필요. eBPF에서는 기존 연결(established connection) 제한 미지원 |
경고: eBPF 데이터플레인에 필요한 최소 커널 버전은 CO-RE (Compile Once - Run Everywhere)를 지원하는 v5.10이에요. CO-RE는 커널 버전 간 호환성과 성능을 크게 개선해요. 모든 eBPF 기능을 사용하려면 커널 v6.6 이상을 권해요.
-
호스트 간 VXLAN 트래픽을 허용하는 기반 네트워크 패브릭. eBPF 모드에서는 Kubernetes NodePort 트래픽 전달에 VXLAN을 사용해요.
-
IPv6
제한 사항:
- IPIP는 지원되지 않아요(Calico iptables도 지원하지 않아요). eBPF 모드에는 VXLAN 오버레이가 권장돼요.
eBPF 모드에서 IPv6를 활성화하려면 듀얼 스택 또는 IPv6 전용 구성을 참고하세요. Calico가 아닌 IPAM으로도 실행할 수 있어요. eks-cni는 동작한다고 알려져 있어요.
지원되지 않음 (Not supported)
-
그 외 프로세서 아키텍처.
-
etcd 데이터스토어 드라이버. etcd 데이터스토어 드라이버는 Kubernetes 서비스 감시(watching)를 지원하지 않는데, eBPF 모드의 일부 기능에는 이 기능이 필요해요.
-
배포판:
-
GKE. GKE CNI 플러그인과 호환되지 않기 때문이에요.
-
RKE: RKE는 API 서버에 안정적인 주소를 제공하지 않아서 설치 시점에는 eBPF 모드를 활성화할 수 없어요. 하지만 이 지침을 따르면 설치 후 단계로 활성화할 수 있어요.
-
-
일부 노드는 eBPF, 일부 노드는 표준 데이터플레인이거나 Windows 노드인 클러스터.
-
Floating IP.
-
SCTP(정책이든 서비스든).
-
태그된 VLAN 디바이스.
성능 (Performance)
최고의 파드 간 성능을 위해서는 Calico가 오버레이를 쓰지 않아도 되는 기반 네트워크를 권해요. 예를 들면:
- 단일 AWS 서브넷 안의 클러스터.
- 호환되는 클라우드 공급자의 CNI를 사용하는 클러스터(예: AWS VPC CNI 플러그인).
- BGP 피어링이 구성된 온프레미스 클러스터.
오버레이를 꼭 써야 한다면 IPIP가 아니라 VXLAN을 권해요. 여러 커널 최적화 덕분에 eBPF 모드에서는 VXLAN이 IPIP보다 성능이 좋아요.
방법 (How to)
eBPF 모드로 설치하려면 Tigera Operator로 Calico를 설치하는 걸 권하고, 그래서 이 지침은 operator를 기준으로 설명해요. Calico 설치는 보통 다음 단계로 이루어지고, 각 단계는 메인 설치 가이드에서 다뤄요:
- Calico를 실행할 수 있는 클러스터를 만들어요.
- Tigera Operator(가능하면 Helm 차트로)와 관련 Custom Resource Definitions을 설치해요.
- Custom Resource 집합을 적용해 operator에게 무엇을 설치할지 알려줘요.
- operator가 관련 리소스를 모두 프로비저닝하고 status 리소스로 보고할 때까지 기다려요.
eBPF 모드로 바로 설치하는 것도 아주 비슷해요. 이 가이드는 차이점을 설명해요:
- Calico를 실행할 수 있는 클러스터를 만들어요. 단, 노드가 충분히 최신 커널을 사용해야 한다는 추가 요구 사항이 있어요.
- API 서버의 "실제" 주소로 config map을 만들어요. 이렇게 하면 operator가 API 서버에 직접 연결해 Calico를 설치하고,
kube-proxy를 대신할 수 있어요. - Tigera Operator를 설치해요(가능하면 Helm 차트로). 관련 Custom Resource Definitions도 설치해요.
- 설치 Custom Resource를 내려받아 수정해 operator에게 eBPF 모드를 사용하라고 알려줘요.
- Custom Resource 집합을 적용해 operator에게 무엇을 설치할지 알려줘요.
- operator가 관련 리소스를 모두 프로비저닝하고 status 리소스로 보고할 때까지 기다려요.
- kube-proxy를 비활성화하거나 충돌을 피해요.
각 단계는 아래에서 더 자세히 설명해요.
적합한 클러스터 만들기 (Create a suitable cluster)
eBPF 모드의 기본 요구 사항은 충분히 최신 커널이에요(위 참고).
배포판별 지침은 아래에서 알맞은 탭을 선택하세요:
탭: Generic 또는 kubeadm
성공 팁: 셀프 관리 kubeadm 클러스터에 Calico를 설치한다면, 온프레미스 배포용 Calico 설치의 operator 설치 방법을 따라 eBPF 모드를 자동으로 활성화할 수 있어요. 이런 종류의 클러스터에서는 eBPF 모드가 기본 데이터플레인이라 이 가이드의 단계를 따를 필요가 없어요.
kubeadm은 여러 기본 OS를 지원해요. 선택한 기본 OS(예: Ubuntu 22.04)가 커널 요구 사항을 충족하면 kubeadm으로 프로비저닝한 클러스터도 지원돼요.
eBPF 모드에서는 kube-proxy가 필요 없으므로 설치 시점에 kube-proxy를 비활성화해야 해요. kubeadm에서는 kubeadm init에 --skip-phases=addon/kube-proxy 플래그를 넘기면 돼요:
kubeadm init --skip-phases=addon/kube-proxy
탭: kOps
kops도 여러 기본 OS를 지원해요. 선택한 기본 OS(예: Ubuntu 22.04 또는 RHEL 8.4)가 커널 요구 사항을 충족하면 kops로 프로비저닝한 클러스터도 지원돼요.
eBPF 모드에서는 kube-proxy가 필요 없으므로 설치 시점에 kube-proxy를 비활성화해야 해요. kops에서는 kops 구성에 다음을 설정하면 돼요:
kubeProxy:
enabled: false
탭: OpenShift
Calico는 OpenShift에서 기본으로 eBPF 모드를 사용해요. OpenShift에 Calico를 설치하는 방법의 자세한 내용은 Calico로 OpenShift 4 클러스터 설치를 참고하세요.
탭: AKS
Azure Kubernetes Service(AKS)는 여러 기본 OS를 지원해요. 최신 Ubuntu 18.04 이미지는 eBPF 모드에서 쓸 수 있을 만큼 충분히 최신 커널을 갖고 있어요.
AKS는 kube-proxy 비활성화를 지원하지 않기 때문에, 나중 단계에서 Calico가 kube-proxy의 iptables 규칙을 정리하지 않도록 설정해야 해요.
탭: EKS
Amazon의 Elastic Kubernetes Service(EKS)는 노드용으로 여러 기본 OS를 지원해요. 이 문서를 쓰는 시점에 Amazon Linux의 기본 커널은 eBPF 모드를 실행하기 충분하고, Bottlerocket 커널도 그래요. Ubuntu 18.04 이미지는 충분히 최신 커널이 아니었어요(여러분이 이 글을 읽을 때는 바뀌었을 수도 있어요).
탭: MKE
eBPF 데이터플레인은 최소 커널 요구 사항을 충족하는 Linux 운영체제라면 MKE에서 지원돼요.
eBPF 모드에서는 kube-proxy가 필요 없으므로 설치 시점에 kube-proxy를 비활성화해야 해요. MKE에서는 클러스터 설치 시 --kube-proxy-mode=disabled와 --kube-default-drop-masq-bits를 설정하면 돼요.
자세한 내용은 MKE 문서를 참고하세요
경고: MKE의 Docker Swarm 오버레이 네트워킹은 자체 VXLAN 디바이스에 UDP 포트 4789를 사용해요. eBPF 모드에서 노드에 BTF가 있으면(보통 커널 v5.8+) Calico는
vxlan.calico디바이스를 flow 모드로 만들고, 이게 Docker Swarm과 같은 포트를 두고 충돌해요. eBPF를 활성화하기 전에 VXLAN 포트를 바꿔야 해요:kubectl patch felixconfiguration default --type merge -p '{"spec":{"vxlanPort":4790}}'선택한 UDP 포트가 모든 노드 사이 기반 네트워크에서 허용되는지 확인하세요. 자세한 내용은 eBPF 모드 문제 해결을 참고하세요.
kubernetes-service-endpoint config map 만들기
eBPF 모드에서 Calico는 kube-proxy를 대신해요. 그래서 kube-proxy처럼 API 서버의 ClusterIP를 쓰는 게 아니라 API 서버에 직접 도달할 수 있어야 해요. Calico에게 API 서버 도달 방법을 알려주려면 API 서버의 "실제" 주소를 담은 ConfigMap을 만들어요. 이 가이드에서는 Tigera Operator를 설치하기 전에 이 작업을 해요. 그러면 operator 자체도 직접 연결을 쓸 수 있어서 kube-proxy가 실행 중일 필요가 없죠.
아래 탭에서 여러 배포판의 API 서버 "실제" 주소를 찾는 방법을 설명해요. 참고: 어떤 경우든 API 서버가 재시작되거나 스케일 인/아웃되더라도 주소가 안정적(stable)이어야 해요. DNS나 그 외 로드 밸런서 앞에 여러 API 서버가 있다면 로드 밸런서의 주소를 사용해야 해요. 그래야 API 서버 IP가 바뀌어도 Calico의 연결이 끊기지 않아요.
탭: Generic 또는 kubeadm
클러스터를 수동으로 만들었다면(예: kubeadm 사용) 여러 API 서버를 둔 고가용성 클러스터인지, API 서버가 한 노드뿐인 단순 클러스터인지에 따라 쓸 올바른 주소가 달라져요.
- 고가용성 클러스터를 구성했다면 API 서버 앞에 둔 로드 밸런서의 주소를 사용하세요. Kubernetes 문서에서도 설명하듯 HA 구성에는 로드 밸런서가 필요하지만, 로드 밸런서의 정확한 유형은 정해져 있지 않아요.
- 컨트롤 플레인 노드가 하나뿐이라면 컨트롤 플레인 노드 자체의 주소를 쓸 수 있어요. 다만 그 노드에는 전용 DNS 레코드나 고정 IP 같은 안정적인 주소를 써야 해요. 동적 IP(예: EC2 프라이빗 IP)를 쓰면 노드가 재시작될 때 주소가 바뀌어 Calico가 API 서버와의 연결을 잃을 수 있어요.
탭: kOps
kops를 사용하면 kops가 보통 API 서버 앞에 어떤 형태로든 로드 밸런서를 구성해요. API 로드 밸런서의 FQDN과 포트를 사용하세요: api.internal.<clustername>.
탭: OpenShift
Calico는 OpenShift에서 기본으로 eBPF 모드를 사용해요. OpenShift에 Calico를 설치하는 방법의 자세한 내용은 Calico로 OpenShift 4 클러스터 설치를 참고하세요.
탭: AKS
AKS 클러스터에서는 API 서버의 FQDN을 사용하세요. 다음 명령으로 찾을 수 있어요:
kubectl cluster-info
출력은 다음과 비슷하게 나와요:
Kubernetes master is running at https://mycalicocl-calicodemorg-03a087-36558dbb.hcp.canadaeast.azmk8s.io:443
이 예시에서는 config map을 만들 때 KUBERNETES_SERVICE_HOST로 mycalicocl-calicodemorg-03a087-36558dbb.hcp.canadaeast.azmk8s.io, KUBERNETES_SERVICE_PORT로 443을 사용해요.
탭: EKS
EKS 클러스터에서는 API 서버 앞에 있는 EKS 제공 로드 밸런서의 도메인 이름을 사용하는 게 중요해요. 다음 명령으로 찾을 수 있어요:
kubectl cluster-info
출력은 다음과 비슷하게 나와요:
Kubernetes master is running at https://60F939227672BC3D5A1B3EC9744B2B21.gr7.us-west-2.eks.amazonaws.com
...
이 예시에서는 config map을 만들 때 KUBERNETES_SERVICE_HOST로 60F939227672BC3D5A1B3EC9744B2B21.gr7.us-west-2.eks.amazonaws.com, KUBERNETES_SERVICE_PORT로 443을 사용해요.
탭: MKE
MKE는 각 노드에서 api-server에 도달하는 데 쓸 수 있는 리버스 프록시를 실행해요. KUBERNETES_SERVICE_HOST는 proxy.local로, KUBERNETES_SERVICE_PORT는 6444로 설정해야 해요.
Tigera Operator 설치
Tigera Operator를 설치하는 플랫폼별 메인 설치 가이드의 단계를 따르되, custom-resources.yaml은 적용하지 마세요(이 파일은 이 문서의 뒤 단계에서 수정할 거예요).
kOps와 EKS처럼 AWS에 있는 클러스터에서는 tigera-operator 디플로이먼트에 DNS 구성을 패치해서 operator가 apiserver DNS를 해석할 수 있게 해야 해요. AWS DNS 서버 주소는 169.254.169.253이에요.
kubectl patch deployment -n tigera-operator tigera-operator -p '{"spec":{"template":{"spec":{"dnsConfig":{"nameservers":["169.254.169.253"]}}}}}'
Config Map 만들기
위에서 정한 호스트와 포트로 tigera-operator 네임스페이스에 다음 config map을 만드세요:
kubectl apply -f - <<EOF
kind: ConfigMap
apiVersion: v1
metadata:
name: kubernetes-services-endpoint
namespace: tigera-operator
data:
KUBERNETES_SERVICE_HOST: "<API server host>"
KUBERNETES_SERVICE_PORT: "<API server port>"
EOF
설치 Custom Resources 수정하고 적용하기
메인 설치 가이드에서 custom-resources.yaml을 적용하라고 할 때, 보통 파일 URL을 직접 넣어 kubectl create를 실행하라고 안내해요. 그 대신 파일을 내려받아서 수정할 수 있게 하세요:
curl -o custom-resources.yaml https://raw.githubusercontent.com/projectcalico/calico/v3.33.0/manifests/custom-resources.yaml
원하는 에디터로 파일을 열고 파일 맨 위에 있을 Installation 리소스를 찾으세요. eBPF 모드를 켜려면 Installation 리소스의 spec 안에 linuxDataplane 필드를 포함한 새 calicoNetwork 섹션을 추가해야 해요. EKS Bottlerocket OS에서만 아래와 같이 flexVolumePath 설정도 추가해야 해요.
예를 들면:
# This section includes base Calico installation configuration.
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
# Added calicoNetwork section with linuxDataplane field
calicoNetwork:
linuxDataplane: BPF
# EKS with Bottlerocket as node image only:
# flexVolumePath: /var/lib/kubelet/plugins
# Install Calico Open Source
variant: Calico
# This section configures the Calico API server.
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
name: default
spec: {}
그다음 수정한 파일을 적용해요:
kubectl create -f custom-resources.yaml
성공 팁: 이미 custom resources를 만들었다면 installation 리소스를 업데이트해서 클러스터를 eBPF 모드로 전환할 수 있어요. operator가 변경 사항을 자동으로 롤아웃해요.
kubectl patch installation.operator.tigera.io default --type merge -p '{"spec":{"calicoNetwork":{"linuxDataplane":"BPF", "hostPorts":null}}}'
설치 진행 상황 모니터링
다음 명령으로 설치 진행 상황을 모니터링할 수 있어요:
watch kubectl get tigerastatus
kube-proxy 비활성화하기 (또는 충돌 피하기)
eBPF 모드에서 kube-proxy와의 충돌을 피하려면 kube-proxy를 비활성화하거나, Calico가 kube-proxy의 iptables 규칙을 정리하지 않도록 구성해야 해요. 클러스터를 시작할 때 kube-proxy를 비활성화하지 않았다면 아래 단계로 충돌을 피하세요:
경고:
kube-proxy를 IPVS 모드로 실행 중이라면,kube-proxy를 비활성화하거나 eBPF 모드를 활성화하기 전에 iptables 모드로 전환해야 해요. 모든 플랫폼에 적용되며, 성공적인 마이그레이션에 필요해요. iptables 모드로 전환한 뒤에는 진행하기 전에 노드를 재시작하세요.
탭: Generic 또는 kubeadm
DaemonSet으로 kube-proxy를 실행하는 클러스터(kubeadm으로 만든 클러스터 등)에서는 kube-proxy의 DaemonSet에 아무 노드도 매칭되지 않는 node selector를 추가해 되돌릴 수 있는 방식으로 kube-proxy를 비활성화할 수 있어요. 예를 들면:
kubectl patch ds -n kube-system kube-proxy -p '{"spec":{"template":{"spec":{"nodeSelector":{"non-calico": "true"}}}}}'
그러면 나중에 kube-proxy를 다시 시작하고 싶을 때 node selector를 제거하기만 하면 돼요.
탭: kOps
kops는 구성에 다음을 설정해
kubeProxy:
enabled: false
kube-proxy를 비활성화할 수 있어요. 변경 사항을 롤아웃하려면 kops update cluster를 실행해야 해요.
탭: OpenShift
OpenShift에서는 다음과 같이 kube-proxy를 비활성화할 수 있어요:
Calico는 OpenShift에서 기본으로 eBPF 모드를 사용해요. OpenShift에 Calico를 설치하는 방법의 자세한 내용은 Calico로 OpenShift 4 클러스터 설치를 참고하세요.
탭: AKS
Azure CNI를 쓰는 AKS는 kube-proxy 비활성화를 허용하지 않아요. kube-proxy는 애드온 매니저가 배포하고, 구성에 대한 수동 변경은 알아서 되돌려 놔요. kube-proxy와 Calico가 서로 싸우지 않게 하려면 Felix 구성 파라미터 bpfKubeProxyIptablesCleanupEnabled를 false로 설정하세요. kubectl로 다음과 같이 할 수 있어요:
kubectl patch felixconfiguration default --type merge --patch='{"spec": {"bpfKubeProxyIptablesCleanupEnabled": false}}'
탭: EKS
EKS에서는 kube-proxy의 DaemonSet에 아무 노드도 매칭되지 않는 node selector를 추가해 되돌릴 수 있는 방식으로 kube-proxy를 비활성화할 수 있어요. 예를 들면:
kubectl patch ds -n kube-system kube-proxy -p '{"spec":{"template":{"spec":{"nodeSelector":{"non-calico": "true"}}}}}'
그러면 나중에 kube-proxy를 다시 시작하고 싶을 때 node selector를 제거하기만 하면 돼요.
다음 단계 (Next steps)
추천 항목
더 알아보기 (Learn more)
eBPF 모드의 핵심은 kube-proxy를 대체하는 대신 API 서버에 직접 연결해야 한다는 점이에요. 그래서 "실제" API 서버 주소를 담은 config map이 필수예요. 배포판별 kube-proxy 비활성화 방법이 다르니 자신의 플랫폼 탭을 꼭 확인하세요.