본문 바로가기
Work/개발 노트

[Cilium study] 6주차 - Cilium ServiceMesh

by ★용호★ 2025. 8. 24.

실습 환경 소개

curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/6w/Vagrantfile

vagrant up

현재 실습 환경은 다음과 같이 구성되어 있습니다:

  • Kubernetes 1.33.4
  • Cilium 1.18.1
  • 가상 머신: k8s-ctr(컨트롤 플레인), k8s-w1(워커 노드)
    • 각 노드: vCPU 4코어, 메모리 2560MB (기본 설정보다 상향)
  • pwru 도구 설치됨 (ARM64 CPU 지원 추가)

서비스 메시 개념 소개

서비스 메시는 마이크로서비스 아키텍처에서 애플리케이션 네트워킹과 관련된 공통 관심사를 애플리케이션 코드와 분리하여 인프라 수준에서 투명하게 제공하는 기술입니다. 다양한 개발팀이 각자의 언어로 인증, 암호화, 서킷 브레이커와 같은 기능을 구현하는 것은 어렵기 때문에, 중간에 서비스 레이어를 두어 이러한 공통 기능을 제공합니다.

전통적인 마이크로서비스 환경에서는:

  1. 진입점에 API Gateway를 두어 외부 요청을 처리
  2. 하지만 내부 서비스 간의 통신 제어는 어려움
  3. 서비스 메시는 모든 서비스 간 통신 경로에 프록시를 배치하여 트래픽을 모니터링하고 제어

Cilium 서비스 메시의 특징

Cilium 서비스 메시는 Istio와 같은 전통적인 서비스 메시와 달리 eBPF를 활용한 접근 방식을 취합니다:

  • 데이터 처리 방식:
    • L3/L4 레벨 프로토콜(IP, TCP, UDP): eBPF를 사용한 커널 내 효율적인 처리
    • L7 애플리케이션 레벨 프로토콜(HTTP, Kafka, gRPC, DNS): Envoy 프록시 사용
  • 아키텍처 구현:
    • 각 노드마다 공통의 Cilium Envoy 프록시가 배포됨
    • Cilium은 CNI로서 네트워크 플랫폼 자체를 제어하는 이점 보유
    • Istio Ambient 모드와 유사하지만 eBPF를 활용하는 점이 차별화됨
    • 노드별 프록시를 통해 L7 기능을 제공하므로 사이드카 컨테이너가 필요 없음

Cilium이 제공하는 서비스 메시 기능

Cilium은 다음과 같은 서비스 메시 기능을 제공합니다:

  1. Kubernetes Ingress 지원
  2. Gateway API 지원
  3. Mutual Authentication (상호 인증, 현재 베타 상태)
  4. L7 Traffic Management (L7 트래픽 관리)

Kubernetes Ingress 지원

Cilium은 표준 Kubernetes Ingress 리소스를 지원하며, ingressClassName: cilium 설정으로 사용할 수 있습니다.

로드밸런서 모드

Cilium Ingress는 두 가지 로드밸런서 모드를 제공합니다:

  • shared: 모든 Ingress 리소스가 하나의 로드밸런서 설정을 공유 (기본값)
  • dedicated: 각 Ingress마다 전용 로드밸런서 생성

모드 변경 시 Ingress 리소스에 새로운 로드밸런서 IP가 할당되어 기존 연결이 종료될 수 있습니다.

필수 조건

  • NodePort 활성화 (nodePort.enabled=true) 또는 kube-proxy 대체 기능 활성화 (kubeProxyReplacement=true)
  • L7 프록시 활성화 (l7Proxy=true, 기본적으로 활성화됨)
  • 기본적으로 LoadBalancer 타입 서비스 필요, 또는 직접 Cilium L7 프록시를 호스트 네트워크에 노출

다른 Ingress 컨트롤러와의 차이점

Cilium Ingress의 가장 큰 특징은 CNI와 긴밀하게 통합되어 있다는 점입니다:

  • 전통적인 Ingress 컨트롤러는 Deployment나 DaemonSet으로 배포되고 LoadBalancer 서비스로 노출됨
  • Cilium Ingress는 모든 노드에 트래픽 처리 기능 제공
  • 트래픽이 서비스 포트에 도착하면 eBPF 코드가 투명하게 가로채어 TPROXY 커널 기능을 통해 Envoy로 전달
  • 커널의 TPROXY 기능 덕분에 원본 소스 IP/포트를 유지한 채 Envoy가 트래픽을 처리

Cilium Ingress 설정 확인

현재 환경에서 Cilium Ingress 구성 확인:

cilium config view | grep -E '^loadbalancer|l7'

출력 결과를 통해 L7 프록시가 활성화되었고, Envoy를 백엔드로 사용하고 있으며, 로드밸런싱 알고리즘이 round_robin으로 설정된 것을 확인할 수 있습니다.

Ingress 예약 IP 확인

각 노드의 Cilium Agent는 Ingress 처리를 위한 내부 IP를 예약합니다:

kubectl exec -it -n kube-system ds/cilium -- cilium ip list | grep ingress

Cilium Envoy 확인

kubectl get ds -n kube-system cilium-envoy -owide
kubectl get pod -n kube-system -l k8s-app=cilium-envoy -owide

각 노드마다 cilium-envoy 파드가 배포되어 있으며, 이들은 9964 포트를 통해 통신하고 호스트 파일 시스템의 여러 경로를 마운트합니다.

LB-IPAM 설정

외부 접근을 위한 로드밸런서 IP 풀 설정:

cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2" 
kind: CiliumLoadBalancerIPPool
metadata:
  name: "cilium-lb-ippool"
spec:
  blocks:
  - start: "192.168.10.211"
    stop:  "192.168.10.215"
EOF

L2 Announcement 정책 설정으로 해당 IP들을 네트워크에 알림:

cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
  name: policy1
spec:
  interfaces:
  - eth1
  externalIPs: true
  loadBalancerIPs: true
EOF

HTTP Ingress 예제

Bookinfo 애플리케이션을 위한 기본 Ingress 구성:

cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
  namespace: default
spec:
  ingressClassName: cilium
  rules:
  - http:
      paths:
      - backend:
          service:
            name: details
            port:
              number: 9080
        path: /details
        pathType: Prefix
      - backend:
          service:
            name: productpage
            port:
              number: 9080
        path: /
        pathType: Prefix
EOF

이 설정으로 /details 경로는 details 서비스로, 루트 경로(/)는 productpage 서비스로 라우팅됩니다.

Ingress 상태를 확인하면 LoadBalancer IP가 할당된 것을 볼 수 있습니다:

kubectl get ingress
NAME            CLASS    HOSTS   ADDRESS          PORTS   AGE
basic-ingress   cilium   *       192.168.10.211   80      33s

트래픽 검증:

curl -so /dev/null -w "%{http_code}\n" http://$LBIP/
curl -so /dev/null -w "%{http_code}\n" http://$LBIP/details/1
curl -so /dev/null -w "%{http_code}\n" http://$LBIP/ratings

Hubble을 통해 트래픽 모니터링:

cilium hubble port-forward&
hubble observe -f -t l7

트래픽 흐름 분석

TCP 덤프를 통해 실제 트래픽 흐름을 분석할 수 있습니다:

kubectl exec -it -n istioinaction deploy/webapp -c istio-proxy -- \
  sudo tcpdump -l --immediate-mode -vv -s 0 '(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) and not (port 53)'

주요 특징:

  1. 외부 클라이언트 IP는 X-Forwarded-For 헤더에 보존됨
  2. 노드 간 통신에서는 원래 소스 IP가 보존되거나 적절히 변환됨
  3. Envoy가 프록시로서 트래픽을 처리하고 있음을 확인할 수 있음

Nginx Ingress와 Cilium Ingress 공존

Cilium Ingress와 Nginx Ingress 컨트롤러는 같은 클러스터에서 공존할 수 있습니다:

cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: webpod-ingress-nginx
  namespace: default
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.webpod.local
    http:
      paths:
      - backend:
          service:
            name: webpod
            port:
              number: 80
        path: /
        pathType: Prefix
EOF

각 Ingress 리소스는 ingressClassName을 통해 어떤 컨트롤러를 사용할지 지정합니다.

Dedicated 모드 Ingress

특정 Ingress에 전용 로드밸런서를 할당할 수 있습니다:

cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: webpod-ingress
  namespace: default
  annotations:
    ingress.cilium.io/loadbalancer-mode: dedicated
spec:
  ingressClassName: cilium
  rules:
  - http:
      paths:
      - backend:
          service:
            name: webpod
            port:
              number: 80
        path: /
        pathType: Prefix
EOF

dedicated 모드로 설정된 Ingress는 cilium-ingress-webpod-ingress라는 전용 LoadBalancer 서비스를 생성합니다.

Ingress Network Policy

Cilium은 클러스터 전체에 적용되는 네트워크 정책을 설정할 수 있습니다:

cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "external-lockdown"
spec:
  description: "Block all the traffic originating from outside of the cluster"
  endpointSelector: {}
  ingress:
  - fromEntities:
    - cluster
EOF

특정 IP에서의 접속을 허용하는 정책:

cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "allow-cidr"
spec:
  description: "Allow all the traffic originating from a specific CIDR"
  endpointSelector:
    matchExpressions:
    - key: reserved:ingress
      operator: Exists
  ingress:
  - fromCIDRSet:
    - cidr: 192.168.10.200/32
    - cidr: 127.0.0.1/32
EOF

TLS 인증서를 사용한 Ingress

mkcert 도구를 사용해 로컬 개발용 인증서를 생성하고 적용하기:

apt install mkcert -y
mkcert '*.cilium.rocks'
kubectl create secret tls demo-cert --key=_wildcard.cilium.rocks-key.pem --cert=_wildcard.cilium.rocks.pem

인증서 내용 확인:

openssl x509 -in _wildcard.cilium.rocks.pem -text -noout

TLS를 사용한 Ingress 예제:

cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
  namespace: default
spec:
  ingressClassName: cilium
  rules:
  - host: webpod.cilium.rocks
    http:
      paths:
      - backend:
          service:
            name: webpod
            port:
              number: 80
        path: /
        pathType: Prefix
  - host: bookinfo.cilium.rocks
    http:
      paths:
      - backend:
          service:
            name: details
            port:
              number: 9080
        path: /details
        pathType: Prefix
      - backend:
          service:
            name: productpage
            port:
              number: 9080
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - webpod.cilium.rocks
    - bookinfo.cilium.rocks
    secretName: demo-cert
EOF

시스템 신뢰 저장소에 CA 추가:

mkcert -install

HTTPS 요청 테스트:

curl -s --resolve bookinfo.cilium.rocks:443:${LBIP} https://bookinfo.cilium.rocks/details/1 | jq

Gateway API 지원

Gateway API는 Ingress API의 개선된 버전으로, 더 풍부한 기능과 유연성을 제공합니다.

Gateway API의 주요 특징

  1. 개선된 리소스 모델: GatewayClass, Gateway, Route(HTTPRoute, TCPRoute 등) 리소스를 통해 세분화된 라우팅 설정
  2. 프로토콜 독립적: HTTP뿐만 아니라 TCP, UDP, TLS 등 다양한 프로토콜 지원
  3. 강화된 보안: TLS 구성 및 더 세밀한 액세스 제어
  4. 교차 네임스페이스 지원: 다른 네임스페이스의 서비스로 트래픽 라우팅 가능
  5. 확장성: 사용자 정의 리소스 및 정책으로 쉽게 확장 가능
  6. 역할 지향적: 클러스터 운영자, 애플리케이션 개발자, 보안 팀 간의 책임 분리

Cilium Gateway API 설정

Ingress 컨트롤러를 비활성화하고 Gateway API를 활성화:

helm upgrade cilium cilium/cilium --version 1.18.1 --namespace kube-system --reuse-values \
--set ingressController.enabled=false --set gatewayAPI.enabled=true

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 config view | grep gateway-api

Gateway 예제

HTTP Gateway 및 Route 생성:

cat << EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: cilium
  listeners:
  - protocol: HTTP
    port: 80
    name: web-gw
    allowedRoutes:
      namespaces:
        from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-app-1
spec:
  parentRefs:
  - name: my-gateway
    namespace: default
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /details
    backendRefs:
    - name: details
      port: 9080
  - matches:
    - headers:
      - type: Exact
        name: magic
        value: foo
      queryParams:
      - type: Exact
        name: great
        value: example
      path:
        type: PathPrefix
        value: /
      method: GET
    backendRefs:
    - name: productpage
      port: 9080
EOF

Gateway 상태 확인:

kubectl get gateway
NAME         CLASS    ADDRESS          PROGRAMMED   AGE
my-gateway   cilium   192.168.10.211   True         14s

Gateway 서비스와 요청 테스트:

GATEWAY=$(kubectl get gateway my-gateway -o jsonpath='{.status.addresses[0].value}')
curl --fail -s http://"$GATEWAY"/details/1 | jq

헤더와 쿼리 파라미터를 이용한 고급 라우팅:

curl -v -H 'magic: foo' http://"$GATEWAY"\?great\=example

HTTPS Gateway 예제

HTTPS Gateway 및 Route 설정:

cat << EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: tls-gateway
spec:
  gatewayClassName: cilium
  listeners:
  - name: https-1
    protocol: HTTPS
    port: 443
    hostname: "bookinfo.cilium.rocks"
    tls:
      certificateRefs:
      - kind: Secret
        name: demo-cert
  - name: https-2
    protocol: HTTPS
    port: 443
    hostname: "webpod.cilium.rocks"
    tls:
      certificateRefs:
      - kind: Secret
        name: demo-cert
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-app-route-1
spec:
  parentRefs:
  - name: tls-gateway
  hostnames:
  - "bookinfo.cilium.rocks"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /details
    backendRefs:
    - name: details
      port: 9080
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-app-route-2
spec:
  parentRefs:
  - name: tls-gateway
  hostnames:
  - "webpod.cilium.rocks"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: webpod
      port: 80
EOF

TLS Passthrough 예제

NGINX TLS 서버 설정 및 TLSRoute를 이용한 패스스루:

# NGINX 설정 생성
cat <<'EOF' > nginx.conf
events {
}

http {
  log_format main '$remote_addr - $remote_user [$time_local]  $status '
  '"$request" $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"';
  access_log /var/log/nginx/access.log main;
  error_log  /var/log/nginx/error.log;

  server {
    listen 443 ssl;

    root /usr/share/nginx/html;
    index index.html;

    server_name nginx.cilium.rocks;
    ssl_certificate /etc/nginx-server-certs/tls.crt;
    ssl_certificate_key /etc/nginx-server-certs/tls.key;
  }
}
EOF

kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf

# NGINX 서버 및 서비스 배포
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  ports:
    - port: 443
      protocol: TCP
  selector:
    run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
        - name: my-nginx
          image: nginx
          ports:
            - containerPort: 443
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx
              readOnly: true
            - name: nginx-server-certs
              mountPath: /etc/nginx-server-certs
              readOnly: true
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-configmap
        - name: nginx-server-certs
          secret:
            secretName: demo-cert
EOF

# Gateway와 TLSRoute 생성
cat << EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: cilium-tls-gateway
spec:
  gatewayClassName: cilium
  listeners:
    - name: https
      hostname: "nginx.cilium.rocks"
      port: 443
      protocol: TLS
      tls:
        mode: Passthrough
      allowedRoutes:
        namespaces:
          from: All
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: nginx
spec:
  parentRefs:
    - name: cilium-tls-gateway
  hostnames:
    - "nginx.cilium.rocks"
  rules:
    - backendRefs:
        - name: my-nginx
          port: 443
EOF

TLS Passthrough 테스트:

GATEWAY=$(kubectl get gateway cilium-tls-gateway -o jsonpath='{.status.addresses[0].value}')
curl -v --resolve "nginx.cilium.rocks:443:$GATEWAY" "https://nginx.cilium.rocks:443"

Mutual Authentication (베타)

Cilium의 상호 인증(Mutual Authentication) 기능은 서비스 간 통신에서 mTLS 기반 인증을 제공합니다. 이 기능은 현재 베타 상태입니다.

특징

Cilium의 상호 인증은 다음과 같은 특징을 가집니다:

  1. 대역 외(out-of-band) 상호 인증 핸드셰이크를 통한 효율적인 처리
  2. SPIFFE(Secure Production Identity Framework for Everyone)를 사용한 ID 관리
  3. 암호화와 함께 사용 시 종단 간 보안 제공

SPIFFE와 SPIRE 소개

SPIFFE는 동적이고 이질적인 환경에서 워크로드에 신뢰할 수 있는 ID를 제공하는 프레임워크입니다:

  • SPIFFE ID: spiffe://trust.domain/path/with/encoded/info 형식의 URI
  • SPIRE: SPIFFE의 참조 구현체로, 서버와 에이전트 구조로 구성

Cilium은 SPIRE와 통합하여 워크로드 신원을 관리합니다:

  1. 중앙 SPIRE 서버가 신뢰의 루트 역할
  2. 노드별 SPIRE 에이전트가 워크로드의 ID 요청을 검증
  3. SVID(SPIFFE Verifiable Identity Document)를 통한 신원 증명

설정

Cilium에서 상호 인증 활성화:

helm upgrade cilium cilium/cilium --version 1.18.1 --namespace kube-system --reuse-values \
--set authentication.mutual.spire.enabled=true --set authentication.mutual.spire.install.enabled=true

설정 확인:

cilium config view | grep mesh-auth

SPIRE 서버와 에이전트 확인:

kubectl get all -n cilium-spire
kubectl exec -n cilium-spire spire-server-0 -c spire-server -- \
  /opt/spire/bin/spire-server healthcheck

스타워즈 데모 애플리케이션에 상호 인증 적용

기본 데모 애플리케이션 배포:

kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/minikube/http-sw-app.yaml
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/minikube/sw_l3_l4_policy.yaml

기본 통신 테스트:

kubectl exec tiefighter -- \
  curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing

상호 인증이 필요한 네트워크 정책 적용:

cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "Mutual authentication enabled L7 policy"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
    - fromEndpoints:
        - matchLabels:
            org: empire
      authentication:
        mode: "required"
      toPorts:
        - ports:
            - port: "80"
              protocol: TCP
          rules:
            http:
              - method: "POST"
                path: "/v1/request-landing"
EOF

정책 적용 후 테스트:

kubectl exec tiefighter -- \
  curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing

상호 인증 과정에서 발생하는 로그 확인:

CILIUM_KIND_WORKER=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="kind-worker")].metadata.name}')
kubectl -n kube-system -c cilium-agent logs $CILIUM_KIND_WORKER --timestamps=true | grep "Policy is requiring authentication\|Validating Server SNI\|Validated certificate\|Successfully authenticated"

SPIFFE ID 및 인증서 확인

SPIRE 서버에 등록된 ID 확인:

kubectl exec -n cilium-spire spire-server-0 -c spire-server -- \
  /opt/spire/bin/spire-server entry show -parentID spiffe://spiffe.cilium/ns/cilium-spire/sa/spire-agent

데모 애플리케이션의 SPIFFE ID 확인:

IDENTITY_ID=$(kubectl get cep -l app.kubernetes.io/name=deathstar -o=jsonpath='{.items[0].status.identity.id}')
kubectl exec -n cilium-spire spire-server-0 -c spire-server -- \
  /opt/spire/bin/spire-server entry show -spiffeID spiffe://spiffe.cilium/identity/$IDENTITY_ID

L7-Aware Traffic Management

Cilium은 Envoy를 사용하여 L7(애플리케이션 계층) 트래픽을 관리하고 다양한 고급 기능을 제공합니다.

설정 활성화

helm upgrade cilium cilium/cilium --version 1.18.1 --namespace kube-system --reuse-values \
--set ingressController.enabled=true --set gatewayAPI.enabled=false \
--set envoyConfig.enabled=true --set loadBalancer.l7.backend=envoy

샘플 애플리케이션 배포

kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes/servicemesh/envoy/test-application.yaml

L7 정책 적용

HTTP 요청에 대한 L7 정책 적용:

kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes/servicemesh/envoy/client-egress-l7-http.yaml

이 정책은 특정 HTTP 경로와 메서드만 허용합니다. 정책 적용 후에는 허용되지 않은 경로에 대한 요청이 403 Forbidden으로 거부됩니다.

L7 로드밸런싱 및 URL 재작성

CiliumClusterwideEnvoyConfig를 통해 고급 트래픽 관리 기능 설정:

kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.18.1/examples/kubernetes/servicemesh/envoy/envoy-traffic-management-test.yaml

이 구성은 다음 기능을 제공합니다:

  1. 두 백엔드 서비스(echo-service-1, echo-service-2) 간에 50/50 로드밸런싱
  2. /foo 경로를 /로 재작성하는 URL 재작성 규칙

이로 인해 기존에 404 Not Found가 반환되던 /foo 경로가 정상 응답을 반환합니다.

Envoy 트래픽 모니터링

Hubble을 통해 HTTP 트래픽 상세 정보 확인:

hubble observe --protocol http --from-pod default/tiefighter -o jsonpb | \
  head -n 1 | jq '.flow.l7'

X-Request-Id를 사용한 요청 추적:

# 요청 기록
hubble observe --namespace default --protocol http -o jsonpb > flows.json

# 특정 요청 ID로 흐름 추적
REQUEST_ID=$(cat flows.json | jq -r '.flow | select(.source.labels[0]=="k8s:app.kubernetes.io/name=tiefighter" and .traffic_direction=="EGRESS") .l7.http.headers[] | select(.key=="X-Request-Id") .value' | head -n1)

# 동일한 요청 ID를 가진 모든 흐름 표시
cat flows.json | \
  jq 'select(.flow.l7.http.headers[] | .value == "'$REQUEST_ID'") .flow | {src_label: .source.labels[0], dst_label: .destination.labels[0], traffic_direction, type: .l7.type, time}'

이 분석을 통해 요청의 전체 생명주기를 추적할 수 있습니다.

댓글