본문 바로가기
WIKI 기술 지식 베이스

포드-투-포드 멀티클러스터 통신

원문 보기 위키 갱신

기본적으로 Linkerd의 멀티클러스터 확장은 모든 교차-클러스터 트래픽을 대상 클러스터의 게이트웨이를 통해 보내요. 하지만 여러 Kubernetes 클러스터가 한 클러스터의 포드가 다른 클러스터의 포드와 직접 통신할 수 있는 평면 네트워크에 배포된 경우, Linkerd는 멀티클러스터 서비스를 포드-투-포드 모드로 내보낼 수 있어요. 이 모드에서는 교차-클러스터 트래픽이 게이트웨이를 거치지 않고 대상 포드로 직접 가요. 이 가이드에서는 포드-투-포드 모드로 멀티클러스터 서비스를 내보내고, 인가 정책을 설정하고, 트래픽을 모니터링하는 방법을 살펴볼게요.

출처: Linkerd Pod-to-Pod Multi-cluster communication

본문

기본적으로 Linkerd의 멀티클러스터 확장은 모든 교차-클러스터 트래픽을 대상 클러스터의 게이트웨이를 통해 보내요. 하지만 여러 Kubernetes 클러스터가 한 클러스터의 포드가 다른 클러스터의 포드와 직접 통신할 수 있는 평면 네트워크에 배포된 경우, Linkerd는 멀티클러스터 서비스를 포드-투-포드 모드로 내보낼 수 있어요. 이때 교차-클러스터 트래픽은 게이트웨이를 거치지 않고 대상 포드로 직접 가요.

이 가이드는 포드-투-포드 모드로 멀티클러스터 서비스를 내보내고, 인가 정책을 설정하고, 트래픽을 모니터링하는 방법을 안내할게요.

사전 준비

  • 두 개의 클러스터. 이 가이드에서는 동쪽(east)과 서쪽(west)이라고 부를게요.
  • 클러스터는 평면 네트워크 위에 있어야 해요. 즉 한 클러스터의 포드는 다른 클러스터의 포드에 주소를 지정하고 연결할 수 있어야 해요.
  • 각 클러스터는 kubectl 컨텍스트로 구성되어야 해요. 이 가이드를 따라가기 쉽도록 east와 west라는 이름을 쓰는 걸 권장해요. kubectl로 컨텍스트 이름을 바꾸는 것은 쉬우니, 계속 이 이름으로 두어야 한다고 느낄 필요는 없어요.

1단계: Linkerd와 Linkerd-Viz 설치

먼저 멀티클러스터 가이드에 설명된 대로 두 클러스터에 Linkerd와 Linkerd-Viz를 설치해요. 두 클러스터가 공통 트러스트 앵커를 공유하도록 주의해 주세요.

2단계: Linkerd-Multicluster 설치

두 클러스터에 멀티클러스터 확장을 설치할게요. 직접 포드-투-포드 통신을 사용할 것이므로 게이트웨이 없이 설치할 수 있어요. 서비스가 west 클러스터에서 미러링되므로 거기에 컨트롤러를 만들어요.

`> linkerd --context east multicluster install --gateway=false | kubectl --context east apply -f -
> linkerd --context east check

> linkerd --context west multicluster install --gateway=false \
>   --set controllers[0].link.ref.name=east |
>   kubectl --context west apply -f -
> linkerd --context west check
`

3단계: 클러스터 연결

linkerd multilcuster link-gen 명령으로 두 클러스터를 연결해요. 게이트웨이가 필요 없는 Link를 만들기 위해 --gateway=false 플래그를 전달한다는 점만 제외하면 일반적인 Multicluster 가이드와 정확히 같아요.

`> linkerd --context east multicluster link-gen --cluster-name=target --gateway=false | kubectl --context west apply -f -
`

4단계: 서비스 배포 및 내보내기

이 가이드에서는 단순히 정적 응답을 반환하는 간단한 서버인 bb 서비스를 배포할게요. 대상 클러스터에 배포해요.

`> cat ---
apiVersion: v1
kind: Namespace
metadata:
  name: mc-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bb
  namespace: mc-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bb
  template:
    metadata:
      labels:
        app: bb
    spec:
      containers:
      - name: terminus
        image: buoyantio/bb:v0.0.6
        args:
        - terminus
        - "--h1-server-port=8080"
        - "--response-text=hello\n"
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: bb
  namespace: mc-demo
spec:
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  selector:
    app: bb
EOF
`

그런 다음 소스 클러스터에 해당 네임스페이스를 만들어요.

`> kubectl --context west create ns mc-demo
`

그리고 대상 서비스에 레이블을 달아 내보내요. 보통의 mirror.linkerd.io/exported=true 레이블 대신 mirror.linkerd.io/exported=remote-discovery를 설정하는 것에 주목하세요. 이는 서비스를 원격 디스커버리 모드로 내보내라는 뜻이며, 게이트웨이를 건너뛰고 서로 다른 클러스터의 포드가 직접 통신할 수 있게 해 줘요.

`> kubectl --context east -n mc-demo label svc/bb mirror.linkerd.io/exported=remote-discovery
`

소스 클러스터에 미러 서비스가 즉시 생성되는 걸 볼 수 있어요.

`> kubectl --context west -n mc-demo get svc
NAME        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
bb-target   ClusterIP   10.43.56.245           8080/TCP   114s
`

5단계: 트래픽 보내기!

소스 클러스터의 로드 생성기로 slow-cooker를 사용해 대상 클러스터의 bb 서비스로 보낼게요. slow-cooker가 bb-target 미러 서비스로 보내도록 구성하는 것에 주목하세요.

`> cat ---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: slow-cooker
  namespace: mc-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: slow-cooker
  namespace: mc-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: slow-cooker
  template:
    metadata:
      labels:
        app: slow-cooker
    spec:
      serviceAccountName: slow-cooker
      containers:
      - args:
        - -c
        - |
          sleep 5 # wait for pods to start
          /slow_cooker/slow_cooker --qps 10 http://bb-target:8080
        command:
        - /bin/sh
        image: buoyantio/slow_cooker:1.3.0
        name: slow-cooker
EOF
`

이제 대상 클러스터에서 bb가 초당 약 10개 요청을 성공적으로 받는 것을 볼 수 있을 거예요.

`> linkerd --context east viz stat -n mc-demo deploy
NAME   MESHED   SUCCESS       RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
bb        1/1   100.00%   10.3rps           1ms           1ms           1ms          3
`

6단계: 인가 정책

직접 포드-투-포드 통신의 한 가지 장점은 서버가 특정 클라이언트만 연결하도록 허용하는 인가 정책을 사용할 수 있다는 거예요. 게이트웨이를 사용할 때는 클라이언트 identity가 게이트웨이를 통과하면서 사라지기 때문에 이는 불가능해요. 인가 정책이 어떻게 동작하는지 자세한 배경은 Restricting Access To Services 문서를 참고해 주세요.

slow-cooker 서비스 계정만 bb에 연결하도록 허용하는 인가 정책을 만들어 그걸 증명해 볼게요.

`> kubectl --context east apply -f - ---
apiVersion: policy.linkerd.io/v1beta1
kind: Server
metadata:
  namespace: mc-demo
  name: bb
spec:
  podSelector:
    matchLabels:
      app: bb
  port: 8080
---
apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  namespace: mc-demo
  name: bb-authz
spec:
  targetRef:
    group: policy.linkerd.io
    kind: Server
    name: bb
  requiredAuthenticationRefs:
    - group: policy.linkerd.io
      kind: MeshTLSAuthentication
      name: bb-good
---
apiVersion: policy.linkerd.io/v1alpha1
kind: MeshTLSAuthentication
metadata:
  namespace: mc-demo
  name: bb-good
spec:
  identities:
  - 'slow-cooker.mc-demo.serviceaccount.identity.linkerd.cluster.local'
EOF
`

정책이 적용된 상태에서 bb가 slow-cooker의 모든 트래픽을 허용하는 것을 볼 수 있어요.

`> linkerd --context east viz authz -n mc-demo deploy
ROUTE    SERVER                       AUTHORIZATION                 UNAUTHORIZED  SUCCESS      RPS  LATENCY_P50  LATENCY_P95  LATENCY_P99
default  bb                           authorizationpolicy/bb-authz        0.0rps  100.00%  10.0rps          1ms          1ms          1ms
default  default:all-unauthenticated  default/all-unauthenticated         0.0rps  100.00%   0.1rps          1ms          1ms          1ms
probe    default:all-unauthenticated  default/probe                       0.0rps  100.00%   0.2rps          1ms          1ms          1ms
`

slow-cooker가 bb로 보낼 수 있는 유일한 서비스 계정임을 보여주기 위해, 서로 다른 서비스 계정을 사용하며 거부되어야 하는 두 번째 로드 생성기 slow-cooker-evil을 만들게요.

`> cat ---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: slow-cooker-evil
  namespace: mc-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: slow-cooker-evil
  namespace: mc-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: slow-cooker-evil
  template:
    metadata:
      labels:
        app: slow-cooker-evil
    spec:
      serviceAccountName: slow-cooker-evil
      containers:
      - args:
        - -c
        - |
          sleep 5 # wait for pods to start
          /slow_cooker/slow_cooker --qps 10 http://bb-target:8080
        command:
        - /bin/sh
        image: buoyantio/slow_cooker:1.3.0
        name: slow-cooker
EOF
`

악성 버전의 slow-cooker가 잠시 실행된 후, bb가 10rps를 받아들이고(slow-cooker에서) 10rps를 거부하는(slow-cooker-evil에서) 것을 볼 수 있어요.

`> linkerd --context east viz authz -n mc-demo deploy
ROUTE    SERVER                       AUTHORIZATION                 UNAUTHORIZED  SUCCESS      RPS  LATENCY_P50  LATENCY_P95  LATENCY_P99
default  bb                                                              10.0rps    0.00%   0.0rps          0ms          0ms          0ms
default  bb                           authorizationpolicy/bb-authz        0.0rps  100.00%  10.0rps          1ms          1ms          1ms
default  default:all-unauthenticated  default/all-unauthenticated         0.0rps  100.00%   0.1rps          1ms          1ms          1ms
probe    default:all-unauthenticated  default/probe                       0.0rps  100.00%   0.2rps          1ms          1ms          1ms
`

더 알아보기 (Learn more)