Linkerd는 권한 부여 정책을 사용하여 mesh pod에 트래픽을 제어할 수 있다.
Linkerd에서는 두 가지 메커니즘을 사용한다.
- Kubernetes annotation을 이용하여 네임스페이스 및 워크로드 레벨에서 설정할 수 있는 기본 정책.
- 특정 네임스페이스에서 허용되지 않은 트래픽을 차단하거나, 특정 워크로드에서만 제한된 트래픽을 허용하는 등의 제어를 할 수 있다. - 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 사이드카 주입] 글에서 정보를 확인할 수 있다.)
실습
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 |
댓글