istio는 제공하는 다양한 기능을 시각화하기 위해 여러가지 툴을 제공한다. 대표적으로 네트워크 시각화 - Kiali, 트래픽 트레이싱(추적) - jaeger, 리소스 모니터링 - Prometheus/Grafana 이 있다.
Kiali
kiali는 service mesh의 전체 네트워크 토폴로지와 서비스 인스턴스 상태, 서비스간의 네트워크 트래픽을 시각화한다. kiali를 사용해서 현재 어떤 서비스에 문제가 발생했고, 어떻게 라우팅 되고있는지 시각화하여 확인할 수 있다.
kiali 또한 bookinfo 예제와 동일하게 쉽게 구성할 수 있도록 yaml파일로 배포하고 있다.
$ kubectl -f samples/addons/kiali.yaml
$ kubectl -n istio-system get all -l app=kiali
NAME READY STATUS RESTARTS AGE
pod/kiali-dc84967d9-jg25k 1/1 Running 0 5d13h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kiali ClusterIP 10.98.115.47 <none> 20001/TCP,9090/TCP 5d13h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kiali 1/1 1 1 5d13h
NAME DESIRED CURRENT READY AGE
replicaset.apps/kiali-dc84967d9 1 1 1 5d13h
Istio 설치 패키지는 Bookinfo 예제와 같이 제공된다. Bookinfo는 4개의 서비스로 이루어진 MSA 예제이다. Istio의 여러가지 기능들을 테스트할 수 있도록 폴리글랏 구조로 버저닝되어있는 4가지 서비스를 제공한다.
productpage : python project. 제품 설명 페이지를 완성하기 위해 details, reviews 서비스를 호출하는 서비스
details : ruby project. 책 정보 제공 서비스
reviews : java. 책 리뷰 제공 서비스. rating 서비스를 호출한다.
ratings : nodejs. 책의 ranking 정보를 제공한다. 버저닝 관련된 테스틑 할 수 있도록 v1, v2, v3가 제공된다.
v1 : ratings 서비스를 호출하지 않는 버전
v2 : ratings 서비스를 호출, black start를 사용하여 rating
v3 : ratings 서비스를 호출, red start를 사용하여 rating
Install on Kubernetes
istioctl install
Istio의 거의 대부분의 작업은 istioctl 명령어를 사용해서 진행한다. 아래의 스크립트를 사용하여 istioctl을 다운로드받을 수 있다.
# 가장 최신 배포 버전 다운로드
$curl -L https://istio.io/downloadIstio | sh -
# 특정 버전을 다운받을 경우
$curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.8 TARGET_ARCH=x86_64 sh -
# 패키지 설치
$update-alternatives --install /usr/bin/istioctl istioctl /opt/istio/bin/istioctl 0
# 확인
$istioctl version
client version: 1.9.1
control plane version: 1.9.1
data plane version: 1.9.1 (2 proxies
# install istio on k8s
$istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
위의 과정이 정상적으로 완료되면 istioctl은 istio-system 네임스페이스를 생성하고 해당 네임스페이스의 pod 오브젝트를 확인하면 istio architecture에서 나왔던, istio service mesh의 traffic in/out을 담당하는 istio-ingressgateway, istio-egressgateway, 메인 코어 컴포넌트인 Pilot, Citadel, Galley를 담당하는 istiod가 생성되어 있는것을 확인할 수 있다.
$ kubectl -n istio-system get pod
NAME READY STATUS RESTARTS AGE
istio-egressgateway-bd477794-rwrhp 1/1 Running 0 16d
istio-ingressgateway-79df7c789f-qnmxs 1/1 Running 0 16d
istiod-6dc55bbdd-sgjrj 1/1 Running 0 16d
...
추가로 istio-ingressgateway, istio-egressgateway의 yaml파일을 보면 envoy를 사용하고 있다.
Deploy BookInfo
demo profile로 설치를 진행하였을 때 istiod는 네임스페이스의 라벨들 중 istio-injection 라벨이 있고 값이 enabled이며, webhook이 enabled되어 있으면 그 내부의 pod들은 자동으로 sidecar를 구성(injection)한다.
# 라벨링
$kubectl label namespace istio istio-injection=enabled
# 서비스 배포. yaml 내부의 모든 k8s 오브젝트의 네임스페이스를 istio로 설정하는 것을 추천
$kubectl -n istio apply -f samples/bookinfo/platform/kube/bookinfo.yaml
위의 과정에서, 현재 모든 서비스는 클러스터 내부의 호스트들에서만 접속가능한 ClusterIP 형태로 설정되어있다. 외부 연결을 위해서 쿠버넷에서는 serivce 오브젝트가 제공하는 NodePort, LoadBalancer 등과 Ingress 오브젝트를 이용할 수 있지만 istio에서는 훨씬더 넓은 범위에서 네트워크 in/out 트래픽을 처리하기 위해 gateway를 제공한다.
gateway에서는 애플리케이션(예제에서 bookinfo의 모든 애플리케이션)과 독립적으로, 별도의 애플리케이션 코드 추가, 수정 없이 Layer 4~6와 관련된 정보를 컨트롤하며 Load Balancing, TLS 등을 구성할 수있는 설정을 제공한다.
예제에서 제공하는 gateway를 아래 명령어로 배포할 수 있다.
$kubectl -n istio apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
# check
$kubectl -n istio get gateway
NAME AGE
bookinfo-gateway 2d12h
아래 명령을 통해 gateway를 등록함으로써 istio가 정상적으로 ingress를 설정하였는지 테스트해보자.
# 현재 ingress 호스트의 주소, 포트를 확인(Load Balancer 형태)
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
# 서비스 확인
$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
$ curl -s "http://${GATEWAY_URL}/productpage" | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
bookinfo-gateway.yaml 파일 구성을 보면 생성했던 서비스들을 외부로 노출시키기 위한 Gateway와 VirtualService의 yaml 파일을 볼 수 있다. 아래는 Gateway의 yaml 부분이다.
bookinfo-gateway라는 이름을 가진 gateway에 바인딩하고 http로 들어오는 요청 중 match 조건에 맞는 url을 route 항목의 룰에따라 라우팅한다. route에 있는 host는 위에서 사용했던 host의 의미와는 다르게 kubernetes에 생성한 service의 이름을 의미한다. 위 룰은 /productpage. /static/**/. /login, /logout, /api/v1/products/**의 요청을 kubernetes에 생성된 productpage 서비스의 9080포트로 라우팅하는 설정이다.
위 설정이 정상적으로 완료되었다면 외부 시스템에서 Gateway, VirtualService를 통해 내부 서비스에 연결이 가능하다.
$ echo http://${GATEWAY_URL}/productpage
웹페이지에 접속하면 새로고침 할 때마다 Book Review 부분이 계속 바뀌는 것을 확인할 수 있다. 현재 ingress 방식이 기본 round-robin방식으로 되어있기 때문이다.
위는 istio의 Gateway, VirtualService가 제공하는 기능 중 기본적인 기능들만 설명하였고, TCP, TLS등의 설정을 포함하여 다양한 설정을 추가로 할 수 있다.