[cilium] 스타워즈 데모로 cilium 테스트 해보기

스타워즈 데모로 테스트 해보기

cilium에서는 샘플 애플리케이션으로 스타워즈 데모를 제공합니다.

https://docs.cilium.io/en/stable/gettingstarted/demo/

 

 

데모 환경 소개

아래의 파일을 배포하면 데모환경은 구성 완료됩니다.

kubectl create -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/minikube/http-sw-app.yaml

 

데모를 설치하면 3개의 애플리케이션이 설치되는데 제국 우주선들의 착륙서비스를 제공하는 deathstar, 제국 측 클라이언트와 tiefighter, 연합군 측 클라이언트 xwing 3개의 파드로 구성되어있습니다. 

 

직접 파드를 확인해보면 이렇습니다.

 

 

cilium-agent에서 엔드포인트 리스트도 확인해봅니다.

파드가 worker노드와 worker3 노드에 떠있어서 2개의 노드에서 확인해보면 다음과 같습니다. 

 

그리고 아무런 정책을 배포하지 않았기 때문에 서로간의 통신(전투기 -> 인공위성)도 잘됩니다. 

kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
# 출력: Ship landed

kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
# 출력: Ship landed

 

 

hubble-ui로 확인해봐도 통신이 잘되는것을 확인할 수 있습니다. 

 

l3/l4 정책 적용해보기

cilium에 networkpolicy를 적용할땐 아이피보다는 라벨을 통해서 정책을 적용하게 됩니다. 

 

org=empire 라벨을 가진 우주선만 데스스타 인공위성에 접근가능하도록 하는 L3/L4정책을 적용해보도록 하겠습니다.

 

아래의 정책은 IP(fromEndpoint)와 포트의 조합으로 정책을 적용하기 때문에 L3/L4정책입니다.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "L3-L4 policy to restrict deathstar access to empire ships only"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
  - fromEndpoints:
    - matchLabels:
        org: empire
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP

 

위의 룰을 저장하고 다시 아래처럼 테스트를 해보겠습니다. 

kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing -m 3
Ship landed

kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing -m 3

command terminated with exit code 28

 

 

xwing (org=alliance)인 파드에서는 패킷이 dropped된것이 보입니다. 

 

 

 

이 상태에서 Policy를 한번 확인해보겠습니다. 데스스타로 들어가는 트래픽에 대한 정책이 활성화된것을 알 수 있습니다. 

 

l7 정책 적용해보기 

위의 시나리오에서는 단순하게 아이피와 포트를 조합하여 접근을 못하게 했다면

최소 권한 격리(least-privilege isolation)을 실행하기 위해 필요한 HTTP 요청만 처리할 수 있도록 허용할수도 있습니다.  

 

예를 들어 데스스타 인공위성에는 유지보수용 API가 있기 때문에 이런 API는 아무 우주선에서 호출되게해서는 안됩니다. 

다음과 같이 호출해봅니다.

kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port

 

이런식으로 무단접근을 허용하는건 문제를 초래할 수 있습니다. 

제국 전투기에서 특정 API를 접근 못하도록 하게 하는 정책을 적용해보겠습니다.

 

허용 API: POST /v1/request-landing 

나머지 차단: (PUT /v1/exhaust-port)

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "rule1"
spec:
  description: "L7 policy to restrict access to specific HTTP call"
  endpointSelector:
    matchLabels:
      org: empire
      class: deathstar
  ingress:
  - fromEndpoints:
    - matchLabels:
        org: empire
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "POST"
          path: "/v1/request-landing"

 

이제 확인해보겠습니다. 

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

kubectl exec tiefighter -- curl -s -XPUT deathstar.default.svc.cluster.local/v1/exhaust-port
Access denied

 

 

hubble에서 확인해보면 /v1/exhaust-port는 차단되고 /v1/request-landing 은 허용된것을 확인할 수 있습니다. 

 

rule의 path에는 정확하게 매칭되는 것만 처리되기 때문에 여러개의 룰을 적용시키고 싶다면 정규 표현식을 사용하면 됩니다.

 

cilium monitor 명령어를 사용해서도 확인할 수 있습니다.