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

자동 멀티클러스터 장애 조치

원문 보기 위키 갱신

자동 멀티클러스터 장애 조치 (Automatic Multicluster Failover)

주 서비스가 사용 불가능해졌을 때 대체 서비스로 트래픽을 자동으로 전환하는 Linkerd Failover 확장을 배우고, 실제로 실패를 시뮬레이션해 보는 튜토리얼이에요.

출처: Linkerd Automatic Multicluster Failover

본문

경고

Linkerd Failover 확장은 더 이상 사용되지 않으며(deprecated) 향후 릴리스에서 제거될 예정이에요. 현재 이 기능을 사용 중이라면, 클러스터 간 고가용성을 달성하는 훨씬 더 간단한 방법인 federated services로 마이그레이션하는 것을 권장해요. federated services는 Linkerd Failover 확장이 필요하지 않아요.

Linkerd Failover 확장은 주 서비스가 사용 불가능해질 때마다 트래픽을 주 서비스에서 하나 이상의 대체(fallback) 서비스로 자동 전환하는 컨트롤러예요. 이는 여러 클러스터에 복제되어 있는 서비스가 있을 때 복원력을 높이는 데 도움이 돼요. 로컬 서비스가 사용 불가능하면 장애 조치 컨트롤러가 그 트래픽을 백업 클러스터로 전환할 수 있어요.

이 확장을 사용하는 간단한 예시를 직접 살펴볼까요. 두 개의 Kubernetes 클러스터에 Emojivoto 애플리케이션을 설치하고, 한쪽 클러스터에서 장애를 시뮬레이션해 볼 거예요. 장애 조치 컨트롤러가 트래픽을 다른 클러스터로 전환해 서비스가 계속 사용 가능한 상태로 유지되는 것을 확인할 수 있어요.

Linkerd 프로덕션 팁

이 페이지는 오픈소스 커뮤니티의 최선(best-effort) 노력으로 작성된 내용이에요. 미션 크리티컬 애플리케이션을 운영하는 프로덕션 사용자는 Linkerd 프로덕션 리소스를 숙지하고, 상용 Linkerd 제공업체와 연결하는 것을 권장해요.

사전 준비 (Prerequisites)

Linkerd가 설치된 두 개의 클러스터가 필요하며, 이 클러스터들이 multicluster 확장으로 서로 연결되어 있어야 해요. 공유 트러스트 루트를 생성하고, Linkerd, Linkerd Viz, Linkerd Multicluster를 설치하고 클러스터를 서로 연결하는 단계를 multicluster 가이드를 따라 수행하세요. 이 가이드에서는 클러스터 컨텍스트 이름이 각각 "east"와 "west"라고 가정할게요. 적절한 곳에서 여러분의 클러스터 컨텍스트 이름으로 바꿔 주세요.

Failover 확장 설치하기

장애 조치는 SMI TrafficSplit 리소스로 설명돼요. 우리는 Linkerd SMI 확장과 Linkerd Failover 확장을 설치할 거예요. 이 둘은 양쪽 클러스터에 설치할 수 있지만, 이 예시에서는 "west" 클러스터에서만 장애 조치를 시작할 것이므로 그 클러스터에만 설치할게요.

# Install linkerd-smi in west cluster
> helm --kube-context=west repo add linkerd-smi https://linkerd.github.io/linkerd-smi
> helm --kube-context=west repo up
> helm --kube-context=west install linkerd-smi -n linkerd-smi --create-namespace linkerd-smi/linkerd-smi

# Install linkerd-failover in west cluster
> helm --kube-context=west repo add linkerd-edge https://helm.linkerd.io/edge
> helm --kube-context=west repo up
> helm --kube-context=west install linkerd-failover -n linkerd-failover --create-namespace --devel linkerd-edge/linkerd-failover

Emojivoto 설치 및 내보내기 (Exporting)

이제 예시 애플리케이션인 Emojivoto를 두 클러스터에 설치할게요.

> linkerd --context=west inject https://run.linkerd.io/emojivoto.yml | kubectl --context=west apply -f -
> linkerd --context=east inject https://run.linkerd.io/emojivoto.yml | kubectl --context=east apply -f -

다음으로 east 클러스터의 web-svc에 mirror.linkerd.io/exported=true 라벨을 설정해 "내보내기(export)"할 거예요. 그러면 multicluster 확장이 west 클러스터에 web-svc-east라는 미러 서비스를 생성해서, east의 Emojivoto 애플리케이션을 west 클러스터에서도 사용할 수 있게 만들어요.

> kubectl --context=east -n emojivoto label svc/web-svc mirror.linkerd.io/exported=true
> kubectl --context=west -n emojivoto get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
emoji-svc     ClusterIP   10.96.41.137            8080/TCP,8801/TCP   13m
voting-svc    ClusterIP   10.96.247.68            8080/TCP,8801/TCP   13m
web-svc       ClusterIP   10.96.222.169           80/TCP              13m
web-svc-east  ClusterIP   10.96.244.245           80/TCP              92s

장애 조치 TrafficSplit 생성

장애 조치 컨트롤러에게 트래픽을 어떻게 장애 조치할지 알려 주려면, failover.linkerd.io/controlled-by: linkerd-failover 라벨이 있는 TrafficSplit 리소스를 west 클러스터에 생성해야 해요. failover.linkerd.io/primary-service 어노테이션은 web-svc 백엔드가 주(primary) 서비스이며, 나머지 백엔드들은 대체(fallback)로 취급된다는 것을 나타내요.

kubectl --context=west apply -f - apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
    name: web-svc-failover
    namespace: emojivoto
    labels:
        failover.linkerd.io/controlled-by: linkerd-failover
    annotations:
        failover.linkerd.io/primary-service: web-svc
spec:
    service: web-svc
    backends:
        - service: web-svc
          weight: 1
        - service: web-svc-east
          weight: 0
EOF

이 TrafficSplit은 로컬(west) web-svc를 주 서비스로 사용하되, 주 서비스가 사용 불가능해지면 트래픽을 원격(east) web-svc-east로 전환해야 한다는 것을 나타내요.

장애 조치 테스트

linkerd viz stat 명령어를 사용해서 west 클러스터의 vote-bot 트래픽 생성기가 로컬 주 서비스인 web-svc로 트래픽을 보내고 있는지 확인할 수 있어요.

> linkerd --context=west viz stat -n emojivoto svc --from deploy/vote-bot
NAME          MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
web-svc            -    96.67%   2.0rps           2ms           3ms           5ms          1
web-svc-east       -         -        -             -             -             -          -

이제 로컬 서비스의 레플리카를 0으로 스케일 다운해서 사용 불가능함을 시뮬레이션해 볼게요.

> kubectl --context=west -n emojivoto scale deploy/web --replicas=0

트래픽을 백업으로 보내도록 TrafficSplit이 조정된 것을 바로 확인할 수 있어요. web-svc 백엔드가 이제 weight 0이고 web-svc-east 백엔드가 weight 1이 된 것을 주목하세요.

> kubectl --context=west -n emojivoto get ts/web-svc-failover -o yaml
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
  annotations:
    failover.linkerd.io/primary-service: web-svc
  creationTimestamp: "2022-03-22T23:47:11Z"
  generation: 4
  labels:
    failover.linkerd.io/controlled-by: linkerd-failover
  name: web-svc-failover
  namespace: emojivoto
  resourceVersion: "10817806"
  uid: 77039fb3-5e39-48ad-b7f7-638d187d7a28
spec:
  backends:
  - service: web-svc
    weight: 0
  - service: web-svc-east
    weight: 1
  service: web-svc

viz stat 명령어를 사용해서 이 트래픽이 대체 서비스로 가고 있다는 것도 확인할 수 있어요.

> linkerd --context=west viz stat -n emojivoto svc --from deploy/vote-bot
NAME          MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
web-svc            -         -        -             -             -             -          -
web-svc-east       -    93.04%   1.9rps          25ms          30ms          30ms          1

마지막으로 디플로이먼트를 다시 스케일 업해서 주 서비스를 복원하고, 트래픽이 다시 주 서비스로 전환되는 것을 관찰할 수 있어요.

> kubectl --context=west -n emojivoto scale deploy/web --replicas=1
deployment.apps/web scaled
> linkerd --context=west viz stat -n emojivoto svc --from deploy/vote-bot
NAME          MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
web-svc            -    89.29%   1.9rps           2ms           4ms           5ms          1
web-svc-east       -         -        -             -             -             -          -

더 알아보기 (Learn more)