지역 장애 조치

지역 장애 조치 (Locality failover)

이 가이드를 따라 메시에 대한 지역(locality) 장애 조치를 설정해 볼게요.

출처: Istio 문서

본문

이 가이드를 따라 메시에 대한 지역(locality) 장애 조치를 설정해 볼게요.

진행하기 전에 시작하기 전에의 단계를 반드시 완료했는지 확인해요.

이 태스크에서는 region1.zone1에 있는 curl pod를 HelloWorld 서비스로 요청을 보내는 소스로 사용할 거예요. 그런 다음 장애를 발생시켜 다음 순서대로 지역 간 장애 조치를 트리거할 거예요:

지역 장애 조치 순서

내부적으로는 Envoy 우선순위(Envoy priorities)가 장애 조치를 제어하는 데 사용돼요. curl pod(region1의 zone1)에서 나오는 트래픽에 대해 이 우선순위는 다음과 같이 할당돼요:

Priority Locality Details
0 region1.zone1 Region, zone, sub-zone이 모두 일치해요.
1 None 이 태스크는 sub-zone을 사용하지 않으므로, 다른 sub-zone에 대한 일치 항목이 없어요.
2 region1.zone2 같은 region 안의 다른 zone이에요.
3 region2.zone3 일치하지 않지만, region1->region2에 대한 장애 조치가 정의돼 있어요.
4 region3.zone4 일치하지도 않고, region1->region3에 대한 장애 조치도 정의되지 않았어요.

지역 장애 조치 구성 (Configure locality failover)

다음을 구성하는 DestinationRule을 적용해요:

  • HelloWorld 서비스에 대한 아웃라이어 감지(Outlier detection). 장애 조치가 제대로 동작하려면 이 설정이 필요해요. 특히, 서비스의 엔드포인트가 언제 비정상인지 사이드카 프록시가 알 수 있게 해주고, 결국 다음 지역으로의 장애 조치를 트리거해요.
  • region 간 장애 조치(Failover) 정책. 이 정책은 region 경계를 넘는 장애 조치가 예측 가능하게 동작하도록 보장해요.
  • 각 HTTP 요청이 새 연결을 사용하도록 강제하는 연결 풀(Connection Pool) 정책. 이 태스크는 Envoy의 drain 기능을 이용해 다음 지역으로의 장애 조치를 강제해요. drain이 되면 Envoy는 새 연결 요청을 거부해요. 각 요청이 새 연결을 사용하기 때문에, drain 직후 장애 조치가 바로 일어나게 돼요. 이 설정은 오직 데모 목적으로만 사용하는 거예요.
$ kubectl --context="${CTX_PRIMARY}" apply -n sample -f - <<EOF
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: helloworld
spec:
  host: helloworld.sample.svc.cluster.local
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 1
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        failover:
          - from: region1
            to: region2
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s
      baseEjectionTime: 1m
EOF

트래픽이 region1.zone1에 머무는지 확인

curl pod에서 HelloWorld 서비스를 호출해요:

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region1.zone1, instance: helloworld-region1.zone1-86f77cd7b-cpxhv

응답의 version이 region1.zone1인지 확인해요.

이 명령을 여러 번 반복해서 응답이 항상 같다는 것을 확인해요.

region1.zone2로 장애 조치

다음으로, region1.zone2로 장애 조치를 트리거해요. 이렇게 하려면 region1.zone1의 HelloWorld에 대해 Envoy 사이드카 프록시를 drain해야 해요:

$ kubectl --context="${CTX_R1_Z1}" exec \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l app=helloworld \
  -l version=region1.zone1 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST localhost:15000/drain_listeners

curl pod에서 HelloWorld 서비스를 호출해요:

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region1.zone2, instance: helloworld-region1.zone2-86f77cd7b-cpxhv

첫 번째 호출은 실패하고, 그것이 장애 조치를 트리거해요. 명령을 몇 번 더 반복해서 응답의 version이 항상 region1.zone2인지 확인해요.

region2.zone3로 장애 조치

이제 region2.zone3으로 장애 조치를 트리거해요. 앞에서 했던 것처럼, region1.zone2의 HelloWorld를 호출 시 실패하도록 구성해요:

$ kubectl --context="${CTX_R1_Z2}" exec \
  "$(kubectl get pod --context="${CTX_R1_Z2}" -n sample -l app=helloworld \
  -l version=region1.zone2 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST localhost:15000/drain_listeners

curl pod에서 HelloWorld 서비스를 호출해요:

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region2.zone3, instance: helloworld-region2.zone3-86f77cd7b-cpxhv

첫 번째 호출은 실패하고, 그것이 장애 조치를 트리거해요. 명령을 몇 번 더 반복해서 응답의 version이 항상 region2.zone3인지 확인해요.

region3.zone4로 장애 조치

이제 region3.zone4로 장애 조치를 트리거해요. 앞에서 했던 것처럼, region2.zone3의 HelloWorld를 호출 시 실패하도록 구성해요:

$ kubectl --context="${CTX_R2_Z3}" exec \
  "$(kubectl get pod --context="${CTX_R2_Z3}" -n sample -l app=helloworld \
  -l version=region2.zone3 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST localhost:15000/drain_listeners

curl pod에서 HelloWorld 서비스를 호출해요:

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region3.zone4, instance: helloworld-region3.zone4-86f77cd7b-cpxhv

첫 번째 호출은 실패하고, 그것이 장애 조치를 트리거해요. 명령을 몇 번 더 반복해서 응답의 version이 항상 region3.zone4인지 확인해요.

축하해요! 지역 장애 조치(locality failover) 설정을 성공적으로 완료했어요!

다음 단계

이 태스크에서 사용한 리소스와 파일 정리를 진행해요.

더 알아보기 (Learn more)