Istio Failover 구성 가이드

Istio는 마이크로서비스 아키텍처에서 서비스 간의 통신을 관리하고, 보안 및 모니터링 기능을 제공하는 서비스 메쉬입니다. 특히, Failover는 서비스의 가용성을 높이기 위해 중요한 역할을 합니다. Failover란 일시적인 장애가 발생했을 때, 다른 서비스 인스턴스나 리전을 통해 요청을 자동으로 전환하여 시스템의 연속성을 유지하는 기능입니다. 본 포스트에서는 Istio Failover 구성하는 방법을 단계별로 안내하겠습니다.

목차

1. Failover의 필요성
2. Istio에서의 Failover 구성
3. Istio Failover 구성

3-1. Worker Node에 Region 추가
3-2. 각 region에 애플리케이션 배포
3-3. Gateway 리소스 배포
3-4. VirtualService 리소스 배포
3-5. 애플리케이션 테스트
3-6. Istio Failover 구성을 위한 DestinatinoRule 리소스 배포
4. Istio Failover 테스트
5. 결론

1. Failover의 필요성

마이크로서비스 아키텍처에서는 여러 서비스가 서로 의존하고 있기 때문에, 하나의 서비스가 장애를 일으키면 전체 시스템에 영향을 미칠 수 있습니다. 따라서, Failover는 서비스의 가용성을 높이고, 사용자에게 원활한 경험을 제공하기 위해 필수적입니다. 예를 들어, 특정 지역의 서비스가 다운되었을 때, 다른 지역의 서비스로 자동으로 트래픽을 전환하는 것이 가능합니다.

2. Istio에서의 Failover 구성

Istio에서는 지역 기반의 Failover를 구성할 수 있습니다. 이를 통해 특정 지역의 서비스가 장애를 일으킬 경우, 다른 지역의 서비스로 트래픽을 전환할 수 있습니다. 이러한 Failover 구성은 Istio의 라우팅 기능을 활용하여 설정할 수 있습니다.

이 포스트에서는 간단하게 main과 sub라는 region을 나누어 failover 구성 및 테스트를 진행합니다.

구성 환경:

  • kubernetes 1.32.1
  • istio 1.24.2

3. Istio Failover 구성

이 구성에서는 두 개의 worker node를 main과 sub라는 region으로 나누어 failover를 구성합니다.

3-1. Worker Node에 Region 추가

현재 아래와 같이 node가 구성되어 있습니다.

$ kubectl get nodes
NAME          STATUS   ROLES           AGE     VERSION
k8s-worker1   Ready    <none>          6d22h   v1.32.0
k8s-worker2   Ready    <none>          6d22h   v1.32.0
server        Ready    control-plane   6d22h   v1.32.1

아래와 같이 worker1에는 topology.kubernetes.io/region=main, worker2에는 topology.kubernetes.io/region=sub을 추가 후 label이 추가되었는지 확인합니다.

$ kubectl label node k8s-worker1 topology.kubernetes.io/region=main
$ kubectl label node k8s-worker2 topology.kubernetes.io/region=sub

$ kubectl get nodes --show-labels | grep region
k8s-worker1   Ready    <none>          6d22h   v1.32.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-worker1,kubernetes.io/os=linux,topology.kubernetes.io/region=main
k8s-worker2   Ready    <none>          6d22h   v1.32.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-worker2,kubernetes.io/os=linux,topology.kubernetes.io/region=sub

3-2. 각 region에 애플리케이션 배포

sample 이라는 namespace를 생성하고 간단한 웹 이미지를 배포합니다. 여기서 main deployment 리소스는 topology.kubernetes.io/region: main를 선택하고, sub deployment 리소스는 topology.kubernetes.io/region: sub를 선택하도록 합니다.

apiVersion: v1
kind: Namespace
metadata:
  name: sample
---
apiVersion: v1
kind: Service
metadata:
  name: failover-svc
  namespace: sample
  labels:
    app: failover
spec:
  selector:
    app: failover
  ports:
    - port: 80
      name: http
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: main
  namespace: sample
spec:
  replicas: 2
  selector:
    matchLabels:
      app: failover
  template:
    metadata:
      labels:
        app: failover
    spec:
      nodeSelector:
        topology.kubernetes.io/region: main
      containers:
        - name: main
          image: nginxstore/webapp-example-1
          ports:
            - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sub
  namespace: sample
spec:
  replicas: 2
  selector:
    matchLabels:
      app: failover
  template:
    metadata:
      labels:
        app: failover
    spec:
      nodeSelector:
        topology.kubernetes.io/region: sub
      containers:
        - name: sub
          image: nginxstore/webapp-example-2
          ports:
            - containerPort: 80

배포하게 되면 아래와 같이 생성되게 됩니다.

$ kubectl get svc,deploy,pods -n sample
NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/failover-svc   ClusterIP   10.110.46.47   <none>        80/TCP    6m6s

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/main   2/2     2            2           6m6s
deployment.apps/sub    2/2     2            2           6m6s

NAME                        READY   STATUS    RESTARTS   AGE
pod/main-7bd4cf4c4c-2dm5k   1/1     Running   0          6m6s
pod/main-7bd4cf4c4c-88d4s   1/1     Running   0          6m6s
pod/sub-7584cb944b-2nsfd    1/1     Running   0          6m6s
pod/sub-7584cb944b-d8vtn    1/1     Running   0          6m6s

3-3. Gateway 리소스 배포

브라우저에서 접속하기 위해 Gateway 리소스를 배포합니다.

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: failover-gw
  namespace: sample
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "ho.devops.com"

3-4. VirtualService 리소스 배포

앞서 배포한 서비스에 연결하기 위해 VirtualService 리소스를 배포합니다.

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: failover
  namespace: sample
spec:
  hosts:
    - ho.devops.com
  gateways:
    - failover-gw
  http:
    - route:
        - destination:
            host: failover-svc

3-5. 애플리케이션 테스트

위의 리소스를 전부 배포가 완료되었으면, 현재는 main과 sub 파드로 요청이 분배되는 것을 확인할 수 있습니다.

http://ho.devops.com 접속 시 main 파드의 응답:

http://ho.devops.com 접속 시 sub 파드의 응답:

3-6. Istio Failover 구성을 위한 DestinatinoRule 리소스 배포

Istio failover의 핵심 구성인 DestinationRule 리소스를 배포합니다. 이 리소스에서 서비스의 가용성을 정의하고, main 서비스의 장애 발생 시 sub 서비스로의 전환을 설정합니다.

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: failover-dr
  namespace: sample
spec:
  host: failover-svc
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        failover:
          - from: main
            to: sub
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s

위 구성에서 localityLBSetting.enabled: true를 활성화하여 지역별 로드 밸런싱을 활성화 한 뒤, localityLbSetting.failover에서 failover node를 설정할 수 있습니다.

outlierDetection은 오류 감지 설정이며, outlierDetection.consecutive5xxErrors: 1은 5xx 에러가 1회 발생 시 제외, outlierDetection.interval: 1s은 1초마다 감지를 수행합니다.

4. Istio Failover 테스트

http://ho.devops.com으로 요청을 보내 main 서비스만 응답하는 것을 확인하고, main 서비스에 장애 발생 시 sub 서비스로 이동되는 지 확인합니다.

브라우저에서 http://ho.devops.com으로 요청을 보내 main 서비스만 응답하는 지 확인합니다.

main 서비스에 장애를 발생시키고, 브라우저에서 http://ho.devops.com으로 요청을 보냈을 때, sub 서비스가 응답하는 지 확인합니다.

5. 결론

Istio에서의 Failover 구성은 서비스의 가용성을 높이는 데 매우 중요한 역할을 합니다. 위에서 설명한 방법을 통해 Failover를 설정하고, 서비스의 상태를 모니터링하여 안정적인 서비스를 제공할 수 있습니다.

이를 통해 서비스 중단을 최소화하고 사용자에게 더 나은 경험을 제공합니다. 또한, 로드 밸런싱을 통해 트래픽을 분산시켜 성능을 최적화하며, 장애 발생 시 자동으로 복구 프로세스가 진행되어 관리 부담을 덜어줍니다.

IStio에 대한 추가적인 정보는 여기를 클릭하여 참고하시기 바랍니다.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required