본문 바로가기
Service Mesh/Linkerd

Linkerd 권한 부여 정책

by wlsdn3004 2023. 4. 5.
728x90
반응형

 

Linkerd는 권한 부여 정책을 사용하여 mesh pod에 트래픽을 제어할 수 있다.

 

Linkerd에서는 두 가지 메커니즘을 사용한다.

  1. Kubernetes annotation을 이용하여 네임스페이스 및 워크로드 레벨에서 설정할 수 있는 기본 정책.
    - 특정 네임스페이스에서 허용되지 않은 트래픽을 차단하거나, 특정 워크로드에서만 제한된 트래픽을 허용하는 등의 제어를 할 수 있다.
  2. Linkerd의 Custom Resource Definition(CRD)를 통해 특정 포트, 경로, 워크로드 등에 대해 세분화된 정책 지정.
    - 특정 경로에서만 특정 유저에게 트래픽을 허용하거나, 특정 포트로 전송되는 트래픽의 유형을 제한하는 등의 제어를 할 수 있다.

 

Default Policy

pod에 Linkerd-proxy 사이드카가 생성되면 다음 정책을 지정하여 사용할 수 있다.

  • all-unauthenticated : 모든 트래픽 허용. 이것은 기본값이다.
  • all-authenticated : 모든 클러스터의 mesh 클라이언트의 트래픽 허용. linkerd-proxy 사이드카가 없는 pod는 허용하지 않는다.
  • cluster-authenticated : 동일한 클러스터에서 mesh 클라이언트의 트래픽 허용.
  • cluster-unauthenticated : 동일한 클러스터에서 모든 트래픽 허용.
  • deny : 모든 트래픽 거부

 

기본 정책은 사이드카 주입하는 방식처럼 pod의 annotation을 이용하여 설정할 수 있다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: static-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: static-server
  template:
    metadata:
      name: static-server
      labels:
        app: static-server
      annotations:
        linkerd.io/inject: enabled
        config.linkerd.io/default-inbound-policy: all-authenticated

 

Dynamic Policy

Linkerd의 CRD를 이용하여 기본 정책보다 세분화된 정책을 사용하여 트래픽을 제어할 수 있다.

 

트래픽 제어를 위한 CRD는 다음과 같다.

 

  • Server : 해당 리소스와 동일한 네임스페이스에 있는 pod에서 port를 선택하는데, 선택된 pod는 더 이상 기본 정책에 관계없이 모든 트래픽이 deny 된다.
  • HTTPRoute : Server에서 처리하는 트래픽의 하위 집합으로 허용할 규칙을 설정한다.
  • ServerAuthorization : 하나 이상의 서버에 대한 트래픽을 허용하는 방법을 제공한다. 향후 releases에서 deprecated 될 예정이다.
  • AuthorizationPolicy : Server, HTTPRoute에 대한 트래픽을 승인하는 방법을 제공한다.
  • MeshTLSAuthentication : mesh identities 집합을 나타낸다.
  • NetworkAuthentication : 서브넷 집합을 나타낸다.

 

이번 글에서는 Linkerd CRD를 이용하여 트래픽을 제어하는 실습을 다룬다.

 

 

정책을 적용할 대상은 static-server 이다.

(static-server는 해당 [Linkerd 사이드카 주입] 글에서 정보를 확인할 수 있다.)

 

Linkerd 사이드카 주입 실습

Linkerd는 linkerd-proxy 컨테이너가 사이드카 패턴으로 Pod에 추가된다. 해당 동작은 Linkerd Control-Plane의 proxy-injector에 의해 이루어진다. 이번 글에서는 Pod 두 개를 Linkerd 사이드카 주입하여 pod끼리 통

wlsdn3004.tistory.com

 

실습 


static-server를 적용하기 위한 Server를 생성한다.

## Server.yaml

apiVersion: policy.linkerd.io/v1beta1
kind: Server
metadata:
  name: static-server
spec:
  podSelector:
    matchLabels:
      app: static-server
  port: 8080

 

특정 path 요청으로만 들어올 수 있게 HTTPRoute 규칙을 생성한다.

## HTTPRoute.yaml

apiVersion: policy.linkerd.io/v1beta1
kind: HTTPRoute
metadata:
  name: authors-probe-route
spec:
  parentRefs:
    - name: static-server
      kind: Server
      group: policy.linkerd.io
  rules:
    - matches:
      - path:
          value: "/test1"
        method: GET

 

특정 서브넷 대역 트래픽만 허용하는 NetworkAuthentication을 생성한다.

## NetworkAuthentication.yaml

apiVersion: policy.linkerd.io/v1alpha1
kind: NetworkAuthentication
metadata:
  name: authors-probe-authn
spec:
  networks:
  - cidr: 192.168.8.0/24

 

NetworkAuthentication에 network cidr 대역과 HTTPRoute에 대한 트래픽을 승인하는 AuthorizationPolicy를 생성

## AuthorizationPolicy.yaml

apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: authors-probe-policy
spec:
  targetRef:
    group: policy.linkerd.io
    kind: HTTPRoute
    name: authors-probe-route
  requiredAuthenticationRefs:
    - name: authors-probe-authn
      kind: NetworkAuthentication
      group: policy.linkerd.io

 

static-server로 호출 테스트 해보자

$ kubectl exec -it deploy/static-client -c static-client -- /bin/sh

$ curl static-server:8080/test1
"hello static-server"

 

위에서 허용하지 않은 path나 cidr대역으로 호출해 보면 어떻게 되는지 확인해보자.

## ip 확인 192.168.7.254
$ ip a
eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 9001 qdisc noqueue state UP
 link/ether e6:3d:06:e0:6d:58 brd ff:ff:ff:ff:ff:ff
 inet 192.168.7.254/32 scope global eth0
    valid_lft forever preferred_lft forever
       
## 권한이 없는 ip로 호출      
$ curl static-server:8080/test1 -vvv
*   Trying 10.100.93.77:8080...
* Connected to static-server (10.100.93.77) port 8080 (#0)
> GET /test1 HTTP/1.1
> Host: static-server:8080
> User-Agent: curl/8.0.1-DEV
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< content-length: 0
< date: Wed, 05 Apr 2023 09:33:24 GMT

## HTTPRoute에 없는 경로로 호출
$ curl static-server:8080/test -vvv
*   Trying 10.100.93.77:8080...
* Connected to static-server (10.100.93.77) port 8080 (#0)
> GET /test HTTP/1.1
> Host: static-server:8080
> User-Agent: curl/8.0.1-DEV
> Accept: */*
>
< HTTP/1.1 404 Not Found

권한이 없는 대역에서 요청할 경우 403 Forbidden

권한이 없는 HTTPRoute에 없는 경로로 요청할 경우 404 Not Found 메시지를 볼 수 있다.

 

static-server의 linkerd-proxy 로그도 확인해 보자.

 

권한이 없는 대역에서 요청

inbound:server{port=8080}: linkerd_app_inbound::policy::http: Request denied server.group=policy.linkerd.io server.kind=server server.name=static-server route.group=policy.linkerd.io route.kind=HTTPRoute route.name=authors-probe-route client.tls=None(NoClientHello) client.ip=192.168.7.254

inbound:server{port=8080}:rescue{client.addr=192.168.7.254:42834}: linkerd_app_core::errors::respond: Request failed error=unauthorized request on route

 

HTTPRoute에 없는 경로로 호출

inbound:server{port=8080}:rescue{client.addr=192.168.8.204:40760}: linkerd_app_core::errors::respond: Request failed error=no route found for request

 

 

위 상황을 그림으로 표현해 보면 아래 그림과 같다.

 

이처럼 Dynamic Policy를 통해 정교하게 트래픽 정책을 설정하여 서비스 간 트래픽의 안정성을 높일 수 있다.

반응형

'Service Mesh > Linkerd' 카테고리의 다른 글

Linkerd 버전 업그레이드  (1) 2023.04.19
Linkerd 트래픽 Retry, Timeout  (0) 2023.04.19
Linkerd mTLS 통신 검증  (0) 2023.04.05
Linkerd 사이드카 주입  (0) 2023.04.05
Linkerd 대시보드 ID, Password 변경  (0) 2023.04.05

댓글