eBPF 데이터플레인 활성화하기
기존에 운영 중인 Calico 클러스터를 eBPF 데이터플레인으로 전환하는 방법을 안내해요. kubeadm 등으로 만든 셀프 매니지드(self-managed) 클러스터라면 Tigera Operator가 eBPF를 자동으로 활성화하도록 구성할 수 있어요. 그 외의 클러스터에서는 수동 구성 절차로 eBPF를 켜게 돼요. 전환 전 확인 사항, kube-proxy 처리, DSR 모드까지 단계별로 살펴봅시다.
출처: 문서
본문
이 페이지는 기존 클러스터에서 eBPF 데이터플레인을 활성화하는 방법을 보여줘요. kubeadm 또는 유사한 도구로 클러스터를 만든 셀프 매니지드(self-managed) 클러스터라면, Tigera Operator를 구성해 eBPF를 자동으로 활성화할 수 있어요. 그 외의 모든 클러스터에서는 수동 구성 절차로 eBPF를 활성화해요.
셀프 매니지드 클러스터에서 eBPF 데이터플레인 자동 활성화하기
Tigera Operator를 구성하면 eBPF 데이터플레인을 빠르게 활성화할 수 있어요. kubeadm 또는 유사한 도구로 클러스터를 만드는 대부분의 셀프 매니지드 클러스터에서 권장되는 방식이에요.
사전 준비
- 클러스터가
kubeadm또는kubeadm기반 도구로 만들어졌어요. - Calico Open Source가 Tigera Operator를 사용해 클러스터에 설치되어 있어요.
- 클러스터의
kube-system네임스페이스에서kube-proxy가 실행 중이에요. kube-proxy가 Helm이나 ArgoCD 같은 자동화 도구로 관리되지 않아요.- Tigera Operator가
kubernetes서비스와 엔드포인트에 접근할 수 있어요.
절차
-
자동 구성으로 eBPF 모드를 활성화하려면 operator의
Installation리소스에서spec.calicoNetwork.bpfNetworkBootstrap과spec.calicoNetwork.kubeProxyManagement파라미터를 "Enabled"로,spec.calicoNetwork.linuxDataplane파라미터를 "BPF"로 설정해요.kubectl patch installation.operator.tigera.io default --type merge -p '{"spec":{"calicoNetwork":{"linuxDataplane":"BPF", "bpfNetworkBootstrap":"Enabled", "kubeProxyManagement":"Enabled"}}}'SECONDARY: operator는 변경 사항을 롤링 업데이트(서비스 중단 없음)로 배포한 뒤, 모든 노드를 빠르게 eBPF 모드로 전환해요. 다만 일부 노드가 다른 노드보다 먼저 eBPF 모드에 들어갈 수밖에 없어요. 이 때문에 node port를 통과하는 트래픽 흐름이 방해받을 수 있어요.
이 변경 이후 operator는 API 서버 주소를 구성하고
kube-proxy를 비활성화해요.
다음 단계
- 최고 성능을 위해 클러스터가 direct server return 모드를 사용하도록 구성해요.
모든 클러스터에서 eBPF 데이터플레인 수동 활성화하기
이 섹션은 호환되는 모든 클러스터에서 eBPF 데이터플레인을 활성화하는 방법을 설명해요.
시작하기 전에
지원됨
-
x86-64
-
arm64 (리틀 엔디안)
-
Kubernetes 데이터스토어 드라이버
-
배포판:
-
제네릭 또는 kubeadm
-
kOps
-
OpenShift
-
EKS
-
제한 사항이 있는 AKS:
- Azure CNI와 Calico 네트워크 정책을 사용하는 AKS는 동작하지만, kube-proxy를 비활성화할 수 없어서 리소스가 낭비되고 성능이 최적이 아니에요.
- Calico 네트워킹을 사용하는 AKS는 eBPF 데이터플레인과 함께 테스트 중이에요. 전반적으로는 더 나은 해법이겠지만, 글을 쓰는 시점에는 테스트가 완료되지 않았어요.
-
RKE (RKE2는
kube-proxy비활성화를 지원하므로 권장해요) -
MKE
-
-
Linux 배포판/커널:
- Ubuntu 22.04.
- Linux 커널 v4.18.0-305 이상이 포함된 Red Hat v8.4 (필요한 기능들이 Red Hat이 해당 빌드에 백포트했어요).
- Linux 커널 v5.10 이상을 사용하는 지원되는 다른 배포판.
-
호스트 간 VXLAN 트래픽을 허용하는 하부 네트워크 패브릭. eBPF 모드에서는 Kubernetes NodePort 트래픽을 포워딩할 때 VXLAN을 사용해요.
-
IPv6
제한 사항:
- IPIP는 지원되지 않아요(Calico iptables도 IPIP를 지원하지 않아요). eBPF 모드에서는 VXLAN이 권장되는 오버레이예요.
eBPF 모드에서 IPv6를 활성화하려면 Configure dual stack or IPv6 only를 참고하세요. Calico가 아닌 IPAM으로도 운영할 수 있어요. eks-cni가 동작한다고 알려져 있어요.
지원되지 않음
-
그 외의 프로세서 아키텍처.
-
etcd 데이터스토어 드라이버. etcd 데이터스토어 드라이버는 Kubernetes 서비스 감시(watching)를 지원하지 않는데, eBPF 모드의 일부 기능에는 이 감시가 필요해요.
-
배포판:
- GKE. GKE CNI 플러그인과의 비호환성 때문이에요.
-
일부 노드만 eBPF를 쓰고 나머지는 표준 데이터플레인 및/또는 Windows 노드인 클러스터.
-
플로팅 IP(Floating IPs).
-
SCTP(정책이든 서비스든). BPF에서 SCTP 체크섬을 위한 커널 지원이 부족하기 때문이에요.
-
하드웨어 오프로딩이 없는 VLAN 기반 트래픽.
SUCCESS: 하부/물리 디바이스가 VLAN 오프로딩을 지원한다면
bpfDataIfacePatternFelix 구성 변수를 사용해 VLAN 디바이스로 노드를 클러스터에 연결할 수 있어요. 자세한 내용은 Debugging Connectivity in Calico eBPF를 참고하세요.
클러스터가 eBPF 모드를 위한 준비가 됐는지 확인하기
이 섹션은 클러스터가 eBPF 모드에 적합한지 확인하는 방법을 설명해요.
노드의 커널이 적합한지 확인하려면 다음을 실행할 수 있어요.
uname -rv
출력은 대략 이렇게 생겼어요.
5.10.0-26-generic #28~20.04.1-Ubuntu SMP Fri Jan 27 14:30:10 UTC 2023
이 경우 커널 버전은 v5.10이라 적합해요.
Red Hat 계열 배포판에서는 이런 출력을 볼 수 있어요.
4.18.0-305.el8.x86_64 (mockbuild@x86-vm-08.build.eng.bos.redhat.com)
Red Hat 커널은 v4.18이고 빌드 번호가 최소 305(RHEL 8.4) 이상이므로, 이 커널은 적합해요.
성능
pod-to-pod 성능을 극대화하려면 Calico가 오버레이를 쓰지 않아도 되는 하부 네트워크를 사용하는 게 좋아요. 예를 들면:
- 하나의 AWS 서브넷 안에 있는 클러스터.
- 호환되는 클라우드 제공자의 CNI(예: AWS VPC CNI 플러그인)를 사용하는 클러스터.
- BGP 피어링이 구성된 온프레미스 클러스터.
오버레이를 꼭 써야 한다면 IPIP가 아니라 VXLAN을 권장해요. 여러 커널 최적화 덕분에 eBPF 모드에서는 VXLAN이 IPIP보다 성능이 훨씬 좋아요.
Calico가 API 서버와 직접 통신하도록 구성하기
eBPF 모드에서 Calico는 kube-proxy에 의존하지 않고 Kubernetes 서비스 네트워킹을 직접 구현해요. 그래서 eBPF 모드에서는 kube-proxy를 비활성화해 리소스를 아끼고, 서비스를 누가 처리하는지 혼란을 피하는 게 아주 좋아요.
kube-proxy를 비활성화하려면 Calico가 kube-proxy를 거치지 않고 API 서버와 직접 통신할 수 있어야 해요. 그게 가능하려면 API 서버에 도달하는 지속적이고 고정적인 방법이 필요해요. 최선의 방법은 Kubernetes 배포판마다 달라요:
-
클러스터를 수동으로 만들었다면(예:
kubeadm사용) 어떤 주소를 쓸지는 API 서버가 여러 개인 고가용성(HA) 클러스터를 택했는지, 단일 노드 API 서버를 택했는지에 따라 달라져요.- 고가용성 클러스터를 구성했다면 API 서버들 앞에 둔 로드 밸런서의 주소를 사용해야 해요. Kubernetes 문서에 언급됐듯 HA 구성에는 로드 밸런서가 필요하지만, 로드 밸런서의 정확한 유형은 정해져 있지 않아요.
- 단일 컨트롤 플레인 노드를 택했다면 컨트롤 플레인 노드 자체의 주소를 쓸 수 있어요. 다만 이 노드에는 전용 DNS 레코드나 고정 IP 같은 안정적인(stable) 주소를 사용하는 게 중요해요. 동적 IP(예: EC2 프라이빗 IP)를 쓰면 노드가 재시작될 때 주소가 바뀌어 Calico가 API 서버와의 연결을 잃을 수 있어요.
-
kops는 보통 API 서버 앞에 어떤 형태로든 로드 밸런서를 구성해요. 아래의KUBERNETES_SERVICE_HOST로는 API 로드 밸런서의 FQDN과 포트, 예를 들어api.internal.<clustername>을,KUBERNETES_SERVICE_PORT로는 443을 사용하세요. -
OpenShift는 클러스터를 위해 여러 DNS 레코드를 만들어야 해요. 그중 하나가 바로 우리가 필요로 하는 것이에요:
api-int.<cluster_name>.<base_domain>은 API 서버 또는 그 앞의 로드 밸런서를 가리켜야 해요. 아래의KUBERNETES_SERVICE_HOST로 그 주소를 사용하세요(클러스터에 맞게<cluster_name>과<base_domain>을 채우면 돼요). OpenShift는KUBERNETES_SERVICE_PORT로 6443을 사용해요. -
MKE는 각 노드에서 API 서버에 도달할 수 있는 리버스 프록시를 실행해요.
KUBERNETES_SERVICE_HOST로proxy.local을,KUBERNETES_SERVICE_PORT로6444를 사용하세요. -
AKS와 EKS 클러스터에서는 API 서버 로드 밸런서의 FQDN을 사용해야 해요. 다음으로 찾을 수 있어요.
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을 사용하면 돼요.
다음 단계는 operator로 Calico를 설치했는지, 매니페스트로 설치했는지에 따라 달라져요:
탭: Operator
operator로 Calico를 설치했다면, 위에서 정한 호스트와 포트로 tigera-operator 네임스페이스에 다음 config map을 만드세요.
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>'
operator는 config map 변경을 자동으로 감지해 Calico를 롤링 업데이트하며 변경 사항을 전달해요. 다음 명령으로 pod들이 재시작되고 Running 상태에 도달하는지 확인해요.
watch kubectl get pods -n calico-system
pod들이 재시작되지 않는다면 ConfigMap이 적용되지 않았을 가능성이 있어요(때로는 Kubernetes가 ConfigMap 전파를 느리게 해요. Kubernetes 이슈 #30189 참고). operator를 재시작해 볼 수 있어요.
탭: Manifest
매니페스트로 Calico를 설치했다면, 위에서 정한 호스트와 포트로 kube-system 네임스페이스에 다음 config map을 만드세요.
kind: ConfigMap
apiVersion: v1
metadata:
name: kubernetes-services-endpoint
namespace: kube-system
data:
KUBERNETES_SERVICE_HOST: '<API server host>'
KUBERNETES_SERVICE_PORT: '<API server port>'
kubelet이 ConfigMap을 적용할 때까지 60초 기다리고(Kubernetes 이슈 #30189 참고), 변경 사항을 적용하도록 Calico pod들을 재시작해요.
kubectl delete pod -n kube-system -l k8s-app=calico-node
kubectl delete pod -n kube-system -l k8s-app=calico-kube-controllers
그리고 Typha를 사용한다면:
kubectl delete pod -n kube-system -l k8s-app=calico-typha
다음 명령으로 pod들이 재시작되고 Running 상태에 도달하는지 확인해요.
watch "kubectl get pods -n kube-system | grep calico"
calico/node pod 중 하나의 로그를 확인하면 변경이 적용됐는지 검증할 수 있어요.
kubectl get po -n kube-system -l k8s-app=calico-node
pod가 하나 이상 보여야 해요.
NAME READY STATUS RESTARTS AGE
calico-node-d6znw 1/1 Running 0 48m
...
그다음 로그를 검색하려면 pod를 하나 골라 다음을 실행해요.
kubectl logs -n kube-system <pod name> | grep KUBERNETES_SERVICE_HOST
올바른 KUBERNETES_SERVICE_... 값이 담긴 다음 로그가 보여야 해요.
2020-08-26 12:26:29.025 [INFO][7] daemon.go 182: Kubernetes server override env vars. KUBERNETES_SERVICE_HOST="172.16.101.157" KUBERNETES_SERVICE_PORT="6443"
kube-proxy 구성하기
eBPF 모드에서 Calico는 kube-proxy를 대체하므로, 둘을 함께 실행하면 리소스가 낭비되고(성능도 떨어져요)요. 이 섹션은 흔한 환경에서 kube-proxy를 비활성화하는 방법을 설명해요.
WARNING:
kube-proxy를 IPVS 모드로 실행 중이라면kube-proxy를 비활성화하거나 eBPF 모드를 활성화하기 전에 반드시 iptables 모드로 전환해야 해요. 이는 모든 플랫폼에 적용되며 성공적인 마이그레이션에 필수예요. iptables 모드로 전환한 뒤에는 진행하기 전에 노드를 재시작하세요.
DaemonSet으로 kube-proxy를 실행하는 클러스터(예: kubeadm)
kube-proxy를 DaemonSet으로 실행하는 클러스터(예: 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만 제거하면 돼요.
SECONDARY: 이 방식은 AKS with Azure CNI에는 적합하지 않아요. 해당 플랫폼은 Kubernetes 애드온 매니저를 사용하므로 변경이 시스템에 의해 되돌려져요. AKS라면 아래의 Avoiding conflicts with kube-proxy를 따르세요.
OpenShift
OpenShift를 실행 중이라면 다음처럼 kube-proxy를 비활성화할 수 있어요.
kubectl patch networks.operator.openshift.io cluster --type merge -p '{"spec":{"deployKubeProxy": false}}'
다시 활성화하려면:
kubectl patch networks.operator.openshift.io cluster --type merge -p '{"spec":{"deployKubeProxy": true}}'
MKE
MKE를 실행 중이라면 다음처럼 kube-proxy를 비활성화할 수 있어요.
Modify an existing MKE configuration의 단계별 절차를 따라 MKE 구성을 내려받고, 편집하고, 업로드하세요. 편집 단계에서 kube_proxy_mode=disabled와 kube_default_drop_masq_bits=true 구성을 추가해요.
kube-proxy와의 충돌 피하기
kube-proxy를 비활성화할 수 없다면(예: Kubernetes 배포판이 관리하는 경우), Felix 구성 파라미터 BPFKubeProxyIptablesCleanupEnabled를 false로 바꿔야 해요. 다음처럼 kubectl로 할 수 있어요.
kubectl patch felixconfiguration default --patch='{"spec": {"bpfKubeProxyIptablesCleanupEnabled": false}}'
kube-proxy와 BPFKubeProxyIptablesCleanupEnabled가 둘 다 활성화되어 있으면, kube-proxy가 iptables 규칙을 쓰고 Felix가 그것을 정리하려 해서 두 컴포넌트 사이에서 iptables가 떌림(flapping) 현상을 겪게 돼요.
또한 bpfKubeProxyHealthzPort를 0으로 설정해 Calico의 BPF kube-proxy 대체 구현에 포함된 헬스 체크 서버를 꺼야 해요. 이 서버는 기본적으로 포트 10256에 바인딩하며 노드에서 이미 실행 중인 Kubernetes kube-proxy와 충돌해요. Kubernetes kube-proxy가 헬스 체크를 똑같이 잘 처리해 주므로 기능 저하는 없어요.
kubectl patch felixconfiguration default --patch='{"spec": {"bpfKubeProxyHealthzPort": 0}}'
MKE: eBPF 활성화 전에 VXLAN 포트 바꾸기
WARNING: MKE는 Docker Swarm 오버레이 네트워킹을 사용하는데, Docker 네트워크 네임스페이스 안에서 UDP 포트 4789로 VXLAN 디바이스를 만들어요. BTF를 사용할 수 있는 커널(보통 v5.8+)에서 Calico가 eBPF 모드로 전환하면 Felix는
vxlan.calico디바이스를 flow 모드로 만들고, 이 디바이스는 자신의 UDP 포트를 전부(catch-all) 점유해요. 같은 포트를 다른 VXLAN 디바이스(Docker Swarm의)가 이미 점유 중이면 커널이 이를 거부하고vxlan.calico가address already in use오류와 함께 DOWN 상태로 남아요.MKE 클러스터에서 eBPF를 활성화하기 전에 반드시 VXLAN 포트를 바꿔야 해요:
kubectl patch felixconfiguration default --type merge -p '{"spec":{"vxlanPort":4790}}'모든 calico-node pod가 새 포트로 VXLAN 디바이스를 다시 만들 때까지 기다린 뒤, 각 노드에서 확인해요.
kubectl exec -n calico-system <calico-node-pod> -- ip -d link show vxlan.calico진행하기 전에 디바이스가
dstport 4790(또는 여러분이 고른 포트)을 표시하고 UP 상태인지 확인하세요. 고른 UDP 포트가 모든 노드 사이의 하부 네트워크에서 허용되는지도 확인하세요.
eBPF 모드 활성화하기
다음 단계는 operator로 Calico를 설치했는지, 매니페스트로 설치했는지에 따라 달라져요:
탭: Operator
eBPF 모드를 활성화하려면 operator의 Installation 리소스에서 spec.calicoNetwork.linuxDataplane 파라미터를 "BPF"로 바꿔요.
kubectl patch installation.operator.tigera.io default --type merge -p '{"spec":{"calicoNetwork":{"linuxDataplane":"BPF"}}}'
SECONDARY: operator는 변경 사항을 롤링 업데이트(서비스 중단 없음)로 배포한 뒤, 모든 노드를 빠르게 eBPF 모드로 전환해요. 다만 일부 노드가 다른 노드보다 먼저 eBPF 모드에 들어갈 수밖에 없어요. 이 때문에 node port를 통과하는 트래픽 흐름이 방해받을 수 있어요.
탭: Manifest
매니페스트로 Calico를 설치했다면, Felix 구성 파라미터 BPFEnabled를 true로 바꿔요. 다음처럼 calicoctl로 할 수 있어요.
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfEnabled": true}}'
eBPF 모드를 활성화할 때 기존 연결은 표준 데이터플레인을 계속 사용해요. eBPF 모드의 이점은 누리지 못하고, 전환을 넘겨 살아남는지는 프로토콜에 따라 달라져요.
- TCP 연결은 계속 동작해요. 적용된 주소 변환까지 포함해서요. 변환 정보는
kube-proxy규칙이 아니라 Linux conntrack 엔트리에 살아 있어서, 서비스를 통하는 연결이 이미 사용 중이던 백엔드를 계속 찾아가요. - TCP가 아닌 트래픽은 새 연결로 취급돼요. eBPF 모드는 기존 UDP 플로우에 대한 기록이 없어서 정책을 다시 적용하고 서비스 백엔드를 다시 고르게 돼요. 백엔드가 여러 개인 서비스로 가는 UDP 플로우는 다른 백엔드로 옮겨갈 수 있고, 연결이 이미 established였다는 이유로만 응답 방향이 허용됐던 플로우는 드랍돼요.
- VXLAN 오버레이 위의 연결은 살아남지 못해요. Calico가 eBPF 모드로 전환할 때 VXLAN 디바이스를 다시 만들고, 커널은 그 디바이스를 통과하던 플로우의 conntrack 상태를 버려요.
다음 단계
- 최고 성능을 위해 클러스터가 direct server return 모드를 사용하도록 구성해요.
direct server return 모드 활성화하기
direct server return(DSR) 모드는 클러스터 밖에서 서비스(예: node port)로 향하는 트래픽이 네트워크를 한 번 더 홉하는 과정을 건너뛰게 해요. 지연 시간과 CPU 오버헤드가 줄지만, 노드들이 서로의 IP로 트래픽을 보낼 수 있도록 하부 네트워크가 허용해야 해요.
AWS에서는 모든 노드가 같은 서브넷에 있어야 하고 source/dest check를 꺼야 해요. GCP에서도 source/dest check를 꺼야 하는데, IP 포워딩을 활성화하면 돼요.
DSR 모드는 기본적으로 꺼져 있어요. 활성화하려면 BPFExternalServiceMode Felix 구성 파라미터를 "DSR"로 설정해요. 다음처럼 calicoctl로 할 수 있어요.
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfExternalServiceMode": "DSR"}}'
터널 모드로 되돌리려면 구성 파라미터를 "Tunnel"로 설정해요.
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfExternalServiceMode": "Tunnel"}}'
외부 트래픽 모드를 바꾸면 진행 중인 연결이 방해받을 수 있어요.
netkit pod 인터페이스 사용하기 (테크 프리뷰)
SECONDARY: 이 기능은 테크 프리뷰(tech preview)예요. 테크 프리뷰 기능은 GA가 되기 전에 크게 바뀔 수 있어요.
기본적으로 Calico CNI 플러그인은 각 pod의 네트워크 인터페이스에 veth 페어를 만들어요. Linux 6.7 이상에서는 CNI 플러그인이 veth 대신 netkit L2 페어를 만들도록 선택할 수 있어요. netkit에서는 eBPF 데이터플레인이 ndo_start_xmit() 내부의 BPF_NETKIT_PRIMARY를 통해 정책과 포워딩 프로그램을 붙이는데, veth에 TC/TCX로 붙이는 것보다 경합 상황에서 처리량과 꼬리 지연(tail latency)이 개선돼요.
netkit은 eBPF 데이터플레인에서 권장돼요. iptables와 nftables 데이터플레인에서는 veth와 기능적으로 동일해요.
사전 준비
- netkit 인터페이스를 원하는 모든 노드에 커널 6.7 이상이 필요해요. 오래된 커널은 조용히 veth로 폴백하므로 이기종 클러스터에서 필드를 설정해도 안전해요. 다만 성능 이득은 6.7+ 커널 노드에서만 있어요.
- Calico CNI 플러그인을 사용 중이어야 해요 (
spec.cni.type: Calico).
절차
operator의 Installation 리소스에서 spec.calicoNetwork.linuxPodInterfaceType을 Netkit으로 설정해요.
kubectl patch installation.operator.tigera.io default --type merge -p '{"spec":{"calicoNetwork":{"linuxPodInterfaceType":"Netkit"}}}'
operator는 각 노드의 CNI 구성을 갱신해요. 기존 pod는 veth 인터페이스를 유지하고, 새 pod(그리고 재시작된 pod)는 지원하는 노드에서 netkit 인터페이스를 가져요.
veth로 되돌리려면 필드를 다시 Veth로 설정하거나(또는 제거해요).
kubectl patch installation.operator.tigera.io default --type merge -p '{"spec":{"calicoNetwork":{"linuxPodInterfaceType":"Veth"}}}'
기존 pod는 netkit 인터페이스를 유지하고, bpfAttachType이 다르게 말하지 않는 한(아래 참고) eBPF 데이터플레인은 netkit 연결 방식으로 그 인터페이스들을 계속 구동해요. 새로 만들어지는 pod만 veth 인터페이스를 가져요.
연결 메커니즘
FelixConfiguration의 bpfAttachType 필드는 eBPF 데이터플레인이 프로그램을 붙이는 방식을 고릅니다.
Netkit(기본값) — netkit 인터페이스에는 netkit 연결 방식, 그 외 모든 인터페이스에는 TCX.TCX— netkit 인터페이스를 포함한 모든 인터페이스에 TCX.TC— 모든 인터페이스에 qdisc 기반 레거시 연결 방식.TC에서는 pod 대역폭 QoS 애노테이션을 지원하지 않아요.
TCX 또는 TC로 설정하면 기존 netkit 인터페이스도 그 메커니즘으로 옮겨가요. 인터페이스는 netkit인 채로 남고 pod는 재생성되지 않으며, 연결 방식만 바뀌어요. 이 필드를 바꾸면 모든 노드에서 Felix가 재시작해요.
netkit을 지원하지 않는 릴리스로 다운그레이드하기
netkit 연결 개념이 없는 릴리스는 netkit 프로그램을 제거할 수 없어요. 그런 노드를 직접 다운그레이드하면 pod는 netkit 프로그램이 붙은 채로 남아(다운그레이드 시점에 유효하던 정책을 계속 강제해요) 다운그레이드된 Felix가 같은 인터페이스를 TC/TCX로 구동하고, 결국 한 인터페이스에 두 데이터플레인이 남아요.
다운그레이드 전에 인터페이스를 netkit 연결 방식에서 떼어내세요.
kubectl patch felixconfiguration default --type merge -p '{"spec":{"bpfAttachType":"TCX"}}'
각 노드에서 Felix가 재시작하고 프로그램을 다시 붙여 netkit 링크를 제거해요.
다시 업그레이드한 후에는 필드를 제거해 기본값으로 돌아가세요.
kubectl patch felixconfiguration default --type json -p '[{"op":"remove","path":"/spec/bpfAttachType"}]'
절차 되돌리기
표준 Linux 네트워킹으로 되돌리려면:
-
(operator로 설치했는지 매니페스트로 설치했는지에 따라) operator의
Installation또는FelixConfiguration리소스에 대한 변경을 되돌려요.탭: Operator
kubectl patch installation.operator.tigera.io default --type merge -p '{"spec":{"calicoNetwork":{"linuxDataplane":"Iptables"}}}'탭: Manifest
calicoctl patch felixconfiguration default --patch='{"spec": {"bpfEnabled": false}}' -
kube-proxy를 수동으로 비활성화했다면 다시 활성화해요(예: 위에서 추가한 node selector 제거). Auto config를 선택했다면 operator가 변경을 되돌리고kube-proxy를 다시 배포해요.kubectl patch ds -n kube-system kube-proxy --type merge -p '{"spec":{"template":{"spec":{"nodeSelector":{"non-calico": null}}}}}' -
MKE를 실행 중이라면 Modify an existing MKE configuration의 단계별 절차를 따라 MKE 구성을 내려받고, 편집하고, 업로드하세요. 편집 단계에서
kube_proxy_mode를iptables로 추가해요. -
eBPF 모드를 끄는 건 기존 연결에 영향을 주므로, 전환 때문에 끊긴 연결들이 다시 맺어지는지 기존 워크로드를 모니터링하세요.
더 알아보기 (Learn more)
eBPF 데이터플레인의 개념과 장점이 궁금하면 eBPF 소개 문서를 먼저 읽어보세요. 전환 전에는 커널 버전 확인과 kube-proxy 처리 방식 결정이 가장 중요한 준비 단계예요. DSR 모드는 노드가 같은 서브넷에 있을 때 가장 잘 동작한다는 점도 기억해 두면 좋아요.