이전 글을 참고하면 좋습니다. [DevOps] - [Istio] Telemetry (kiali, jaeger)
카나리 배포
새 버전의 어플리케이션을 기존 버전과 함께 배포하여 모니터링하는 배포 전략이다. 일부 사용자만 새 버전을 이용하게 될 것이고, 새로운 버전에 대한 오류를 조기에 감지하는 것이 목표이다. 새로운 버전에 이상이 없다고 판단되면 모든 트래픽을 새 버전으로 옮긴다.
레플리카를 이용한 카나리 배포
k8s의 기존 기능을 활용해서 카나리 배포를 할 수 있다. 기존 버전 외에 image만 다른 새로운 버전의 deployment를 띄우고, 서비스가 두 deployment를 모두 가리키도록 하면 된다. (selector의 app label) 그리고 replica 수를 조정하여 비율을 조정하여 기존 버전의 비중을 높인다.
일반적으로 카나리는 아주 적은 비율로 배포한다. 1%~10% 가 될 것이다. k8s 자체 기능으로는 특정 replica를 많이 띄우는 식으로 가능하지만, 좋은 방법이 아니며 비용이 많이 들 수 있다. (노드도 많이 필요해질 수 있기 때문이다.)
버전 그룹화
deployment의 labels에 version label을 추가하면, kiali에서 Versioned app graph를 사용하여 배포한 두 deployment를 아래와 같이 구분하여 볼 수 있다.
template:
metadata:
labels:
app: staff-service
version: safe
이상적인 카니라 배포와 단계별 배포
k8s만을 활용한 카나리 배포는, 만약 1%만 새 버전의 컨테이너를 배포해야되면 100개의 pod이 실행되어야한다. istio를 통해 이 문제를 해결할 수 있다. istio의 virutal service외 destination rule를 사용하게 되며, kiali에서 이 부분을 수정할 수도 있다.
해당 service 우클릭 > show detilas > Actions > Create Weighted Routing 을 통해 트래픽 가중치를 조정할 수 있다.
다만 라운드로빈이 아니기 때문에, 정확히 10%만 카나리에게 가진 않을 것이다.
weight 조정도 빠르게 반영되지만, 클러스터에 대한 중요한 엔지니어링에 사용자 인터페이스를 사용하진 않을 것이다. kiali를 사용하면 어떤 일이 일어나는지 알아야한다.
Istio VirtualService
VirtualService를 통해 서비스 메시에 사용자 지정 라우팅 규칙을 구성할 수 있다.
istio의 전체적인 아키텍처에서 VirtualService는 어떻게 동작할까? 우리가 VirtualService를 추가하면, istio pilot (현재는 istiod) 으로 전송된다. pilot이 그걸 우리의 사용자 지정 라우팅 규칙의 결과로서 변경되어야 할 모든 프록시에 배포한다. envoy가 맞춤화된 구성을 갖게될 것이고, 이 과정에서 우리는 envoy를 트래픽 관리 기능을 이용하는 것과 마찬가지이다. 따라서 우리는 시스템을 재시작하거나 pod을 변경하지 않고도, 카나리의 가중치를 변경할 수 있다.
k8s 의 service 와 비슷한 개념이라고 보면 안된다. k8s service는 개별 pod의 ip 주소를 discovery하는 역할을 한다. istio의 VirtualService는 프록시를 재구성하게 해준다.
VirtualService Manifest
kiali로 구성한 VirtualService와 같은 동작을 하는 yaml이다. 트래픽의 90%는 safe-group으로 보내고, 10%는 risky-group으로 보낸다.
VirtualService에 명시하는 service 이름 (host) 은 service dns 전체 이름을 쓰는 것을 추천한다.
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: fleetman-staff-service-vs
namespace: default
spec:
hosts:
# k8s service dns name
# 같은 ns이면 그냥 service 이름이여도 동작하나 정확히 전체 dns 명을 넣는 것을 추천
- fleetman-staff-service.default.svc.cluster.local
http:
- route:
- destination:
host: fleetman-staff-service.default.svc.cluster.local # Target DNS 이름
subset: safe-group # DestinationRule 에 명시한 이름
weight: 90
- destination:
host: fleetman-staff-service.default.svc.cluster.local # Target DNS
subset: risky-group # DestinationRule 에 명시한 이름
weight: 10
Istio DestinationRule
DestinationRule은 로드밸런싱 구성과 같다. 어떤 pod이 어떤 subset으로 포함될 지를 정의한다. label을 통해 대상을 그룹화하며, 이를 subset이라고 부른다. kiali가 'version' label를 잡아 사용자 인터페이스에서 사용하기 때문에 version label를 pod에 정의하고, 해당 값을 사용하는 걸 추천한다.
kind: DestinationRule
apiVersion: networking.istio.io/v1alpha3
metadata:
name: fleetman-staff-service-dr
namespace: default
spec:
host: fleetman-staff-service # service
subsets:
- labels: # selector
version: safe # label "safe" 을 통해 pod을 찾는다.
name: safe-group
- labels:
version: risky
name: risky-group
참고
kiali를 통해서 Routing을 생성하지 않고 kubectl로 객체를 직접 생성해도, kiali는 해당 내용을 보여준다. 대신 kiali로부터 생성되지 않았기 때문에 편집이 불가하다.
또한 kiali는 VirtualService 와 DestinationRule의 내용을 검증한다. 직접 생성하다가 잘못된 정보로 생성했을 경우 (문법 오류 외에 routing 내용 관련해서도) kiali에서 VirtualService 탭에서 오류를 확인할 수 있다.
참고: https://github.com/DickChesterwood/istio-fleetman/tree/master/_course_files
'DevOps' 카테고리의 다른 글
[Istio] Gateway & Edge Proxy (0) | 2024.01.30 |
---|---|
[Istio] 로드밸런싱 (+ConsistentHashing) (0) | 2024.01.29 |
[Istio] Telemetry (kiali, jaeger) (0) | 2024.01.14 |
[Istio] Overview (0) | 2023.12.11 |
[terraform] 테라폼으로 aws 프로비저닝하기 (0) | 2023.05.28 |