이전 글을 참고하면 좋습니다.
Istio Ingress Gateway & Edge Proxy
k8s를 사용한다면 대게 ingress controller를 이용할 것이다. istio 문서에서는 istio ingress gateway를 권장하고 있는데, 이를 사용해야하는 이유를 알아보자.
클라이언트가 접근하게 되는 webapp을 카나리로 비율을 설정하여 배포해보자. 아마 테스트를 해보면, 비율대로 카나리가 나오지 않을 것이다. VirtualService가 제대로 작동하지 않는다는 것과 같다.
이유는 프록시에 있다. pod안에 있는 컨테이너가 다른 pod의 컨테이너를 호출하게 되면, 이 요청은 사이드카 프록시를 통해 전달된다. microservice 간 통신에는 트래픽 규칙을 통해 트래픽을 제어할 수 있었다. 하지만 앞단에 있는 webapp의 경우, 브라우저를 통해 접근할때 프록시를 통하지 않는다. 다시 말해 우리가 설정해온 (앞 포스팅에서) VirtualService 설정과는 연관이 없다는 것이다.
여기서 Istio Gateway의 역할을 알 수 있다. Istio Gateway는 엣지 프록시를 설정하게 해준다. 외부에서 만나게 되는 앞단에 프록시를 설정하는 것이다.
이 동작은 기본적으로 istio-system의 Istio-ingressgateway가 수행하며, Istio Gateway 객체를 통해 동작시킬 수 있다.
$ kubectl get all -n istio-system | grep istio-ingressgateway
Istio-ingressgateway service를 nodeport 등으로 노출시키고, 우리는 Istio-ingressgateway를 통해 서비스에 접근할 것이다.
ingress controller와 ingress를 다뤄봤다면 유사하게 이해할 수 있을 것이다.
외부에서 ingressgateway로 접속하려면 Gateway 객체를 통해 트래픽을 클러스터로 보내는 설정을 해주어야한다. 아래 Gateway는 80번 port를 리스닝하고 있음을 의미한다. 만약 https 트래픽을 리스닝하려면 443 port를 추가해야할 것이다.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ingress-gateway-configuration
spec:
selector:
istio: ingressgateway # istio-ingressgateway에 기본적으로 붙는 label이다.
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*" # 서비스에 사용할 도메인을 추가한다. 테스트용이므로 전체로 열어둔다.
여기까지 하면, Istio-ingressgateway를 통해 접근했을 때 연결은 될 것이다. gateway에 연결된 것이다. 이제 어느 서비스로 요청을 전달할지 정의해야한다.
VirtualService의 hosts 에는 인커밍 호스트를 정의한다. 여태까지는 service 들이 인커밍 호스트였지만, 이번에는 ingress Gateway에 있는 프록시가 인커밍 호스트가 된다. VirtualService와 DestinationRule을 적용하고, Istio-ingressgateway의 nodeport를 통해 서비스에 접근하자.
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp
namespace: default
spec:
hosts: # proxy rule이 적용될 타겟과 같다. 그 동안은 service 명을 썼었지만, 이번에는 gateway host를 사용한다.
- "*"
gateways:
- ingress-gateway-configuration
http:
- route:
- destination:
host: webapp
subset: original
weight: 90
- destination:
host: webapp
subset: experimental
weight: 10
---
kind: DestinationRule
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp
namespace: default
spec:
host: webapp
subsets:
- labels:
version: original
name: original
- labels:
version: experimental
name: experimental
이제 Webapp에 접근할때도, 프록시를 통해 카나리를 적용할 수 있다. Istio Gateway도 그저 어플리케이션 앞에 존재하는 프록시라고 생각하면 쉽다. 제일 앞단에 커스텀 트래픽 규칙을 정의하는 것이다.
다시 말해 Istio Gateway는, 엣지에 있는 서비스에 트래픽 규칙을 적용할 때 필요하다. 만약 해당 동작에 니즈가 없다면 필요하지 않을 것이다.
Prefix Routing
Ingress Gateway는 카나리 외에도 다른 용도로 사용할 수 있다. 예를들어, 서비스 path에 / 만 붙이면 일반 서비스로가고, /experimental 을 붙이면 실험버전으로 가도록 해보자. 어플리케이션을 수정하지 않고 ingress gateway의 prefix routing으로 설정할 수 있다.
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp
namespace: default
spec:
hosts:
- "*"
gateways:
- ingress-gateway-configuration
http:
- match:
- uri: # if
prefix: "/experimental"
- uri: # or
prefix: '/canary'
route: # then
- destination:
host: webapp
subset: experimental
- match:
- uri:
prefix: "/"
route:
- destination:
host: webapp
subset: original
---
kind: DestinationRule
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp
namespace: default
spec:
host: webapp
subsets:
- labels:
version: original
name: original
- labels:
version: experimental
name: experimental
prefix 외에도, exact, regex 또는 scheme을 통한 매치도 가능하다. 상황에 맞게 활용하자.
prefix routing을 적용하려면, 어플리케이션이 일정 부분 고려를 해야할 수도있다. 경로에 민감한 어플레케이션이면 라우팅이 망가질 수 있기 때문이다.
Subdomain Routing
일반 버전과 experimental 버전의 어플리케이션을 다른 url로 배포한다고 가정하자. subdomain 기반 라우팅을 적용하면, prefix routing의 부작용을 방지할 수 있다. (경로를 바꾸지 않기 때문에, 경로에 대한 고려를 덜 할 수 있다.)
local에서 도메인이 필요한 테스트를 진행할 때는 local에 존재하는 hosts 파일을 활용하자.
(window의 경우, C:\Windows\System32\drivers\etc 에 존재한다. (관리자 권한으로 실행))
아래와 같이 지정했다고 가정하자.
- kdeon.test.com localhost
- experimental.kdeon.test.com localhost
아래와 같이 기존 버전과 experimental 버전을 가리키는 VirtualService 두 개를 생성한다.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ingress-gateway-configuration
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*.kdeon.test.com" # experimental.kdeon.test.com 을 위해 기재한다.
- "kdeon.test.com"
---
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp
namespace: default
spec:
hosts:
- "kdeon.test.com"
gateways:
- ingress-gateway-configuration
http:
- route:
- destination:
host: webapp
subset: original
---
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp-experiment
namespace: default
spec:
hosts:
- "experimental.kdeon.test.com"
gateways:
- ingress-gateway-configuration
http:
- route:
- destination:
host: webapp
subset: experimental
---
kind: DestinationRule
apiVersion: networking.istio.io/v1alpha3
metadata:
name: webapp
namespace: default
spec:
host: webapp
subsets:
- labels:
version: original
name: original
- labels:
version: experimental
name: experimental
이제 각각의 도메인을 통해 다른 두 버전의 서비스로 접근할 수 있다.
'DevOps' 카테고리의 다른 글
[Istio] 결함 주입 (Fault Injection) (0) | 2024.01.31 |
---|---|
[Istio] Dark Release (0) | 2024.01.30 |
[Istio] 로드밸런싱 (+ConsistentHashing) (0) | 2024.01.29 |
[Istio] 트래픽 관리 (+카나리 배포) (0) | 2024.01.23 |
[Istio] Telemetry (kiali, jaeger) (0) | 2024.01.14 |