Maglev 알고리즘 사용해보기

이전 글에서 maglev가 어떻게 동작하는지 대충(?) 살펴봤는데 이젠 그럼 실제로 어떤지도 살펴보려고 한다.

이전글 읽어보기

2024.10.03 - [K8S/cilium] - Maglev: Google의 로드밸런싱 알고리즘

 

테스트용 클러스터 만들기

클러스터 만들기

kind

 

gateway api crd 설치

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.0/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml

 

cilium 설치하기

# API 확인 
API_SERVER_IP=$( kubectl get nodes -l node-role.kubernetes.io/control-plane -o yaml | yq '.items[0].status.addresses[] | select(.type=="InternalIP").address' )
API_SERVER_PORT=6443

# 시드 생성
SEED=$( head -c12 /dev/urandom | base64 -w0 )

helm install cilium cilium/cilium --version 1.17.1 \
    --namespace kube-system \
    --set kubeProxyReplacement=true \
    --set loadBalancer.algorithm=maglev \
    --set maglev.tableSize=251 \
    --set maglev.hashSeed=$SEED \
    --set k8sServiceHost=${API_SERVER_IP} \
    --set k8sServicePort=${API_SERVER_PORT} \
    --set l2announcements.enabled=true \
    --set externalIPs.enabled=true \
    --set gatewayAPI.enabled=true \
    --set nodePort.enabled=true

 

maglev

 

테스트 해보기

LoadBlanacer 타입으로 만들어보기

external ip로 통신해보기 위한 설정

apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
  name: default
spec:
  externalIPs: true
  loadBalancerIPs: true
---
apiVersion: cilium.io/v2alpha1
kind: CiliumLoadBalancerIPPool
metadata:
  name: ipam
spec:
  blocks:
    - cidr: 172.17.0.100/32
    - cidr: 172.17.0.101/32

 

파드 생성하기

kubectl create deployment nginx --image=nginx:latest --replicas=3
kubectl expose deployment/nginx --port=80 --type=LoadBalancer

 

NodePort 타입으로 만들어보기

kubectl create deployment nginx --image=nginx:latest --replicas=3
kubectl expose deployment/nginx --port=80 --type=NodePort

 

map 리스트 확인해보기 

cilium bpf lb maglev list

 

 

앞에 있는 SVC ID 확인해보기

cilium bpf lb list --revnat

 

Gateway API로 만들어보기

먼저 class는 잘 생성이 되어있음 

 

테스트용 파드 띄우기 

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.25/samples/httpbin/httpbin.yaml

 

gateway랑 httproute 추가하기

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
spec:
  gatewayClassName: cilium
  listeners:
  - name: default
    hostname: "*.example.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http
spec:
  parentRefs:
  - name: gateway
  hostnames: ["httpbin.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /get
    backendRefs:
    - name: httpbin
      port: 8000
EOF

 

생성 후 

 

테스트용 nginx 띄우기

docker run -d --rm --name nginx --network kind nginx:latest

 

호출해보기

GATEWAY_API_IP=$( kubectl get gateway -n ga gateway -o yaml | yq '.status.addresses[0].value' )
docker exec -it nginx curl -s -I -HHost:httpbin.example.com "http://$GATEWAY_API_IP/get"

 

하지만 maglev list에는 나오지 않는다.. 왜일까..

 

map 정보에는 크게 2개가 있다 어떤 서비스에서 어떤 맵을 봐야하는지에 대한 정보가 있는 outer map(cilium_lb4_maglev) 그리고 실제 hashed된 maglev 테이블 정보가 있는 inner map (cilium_maglev_inner)

root@aya-worker:/home/cilium# cilium map list
Name                       Num entries   Num errors   Cache enabled
cilium_lb_affinity_match   0             0            true
cilium_runtime_config      256           0            true
cilium_lb4_reverse_sk      0             0            true
cilium_lb4_backends_v3     15            0            true
cilium_lb4_reverse_nat     17            0            true
cilium_ratelimit_metrics   0             0            true
cilium_lb4_affinity        0             0            true
cilium_policy_v2_01286     3             0            true
cilium_policy_v2_01185     3             0            true
cilium_lxc                 7             0            true
cilium_ratelimit           0             0            true
cilium_policy_v2_00185     3             0            true
cilium_policy_v2_00772     2             0            true
cilium_policy_v2_02626     3             0            true
cilium_ipcache             23            0            true
cilium_tunnel_map          2             0            true
cilium_lb4_services_v2     47            0            true
cilium_lb4_source_range    0             0            true
cilium_auth_map            0             0            false
cilium_metrics             0             0            false
cilium_lb4_maglev          0             0            false  # <-- outer map
cilium_skip_lb4            0             0            false
cilium_l2_responder_v4     0             0            false
cilium_maglev_inner        0             0            false  # <-- inner map
cilium_node_map            0             0            false
cilium_node_map_v2         0             0            false

 

하지만 2개의 맵 모두 엔트리 값이 없다고 나온다.. 왜지..?

보통은 cilium map get <map 이름> 으로 값을 가져올 수 있지만 

root@aya-worker:/home/cilium# cilium map get cilium_lxc
Key            Value                                                                                            State   Error
10.0.1.111:0   id=2626  sec_id=7966  flags=0x0000 ifindex=13  mac=82:DF:2E:70:CD:C5 nodemac=5E:DB:B5:F7:80:2D   sync
10.0.1.58:0    id=185   sec_id=7966  flags=0x0000 ifindex=11  mac=86:92:55:24:BE:66 nodemac=B2:AB:F7:A5:3A:42   sync
10.0.1.50:0    id=1185  sec_id=10061 flags=0x0000 ifindex=15  mac=12:EF:5B:44:EC:10 nodemac=E2:05:9C:66:94:EA   sync
172.17.0.4:0   (localhost)                                                                                      sync
10.0.1.123:0   (localhost)                                                                                      sync
10.0.1.118:0   id=925   sec_id=8     flags=0x0002 ifindex=0   mac=00:00:00:00:00:00 nodemac=00:00:00:00:00:00   sync
10.0.1.78:0    id=1286  sec_id=4     flags=0x0000 ifindex=9   mac=CE:DD:B4:3E:06:57 nodemac=92:E7:A7:6B:54:C0   sync

 

map of map 구조라서 그렇다는 듯.. 

 

root@aya-worker:/home/cilium# cilium map get cilium_lb4_maglev
Error: [GET /map/{name}][404] getMapNameNotFound

 

bpftool로 검색해보니 근데 값이 나오긴하넹..

sudo bpftool map dump pinned /sys/fs/bpf/tc/globals/cilium_lb4_maglev