본문 바로가기

Kubernetes

bookinfo + kiali를 이용한 Istio 모니터링

 

이 포스팅은 1월 부터 3월까지 진행되었던 KANS 쿠버네티스 네트워킹 스터디에서 배운 내용을 기반으로 작성했습니다. 

 

 

kiali는 Istio ServiceMash 용 관리 콘솔이다. kiali를 통해 ServiceMash를 구성하고 효과적으로 모니터링이 가능하다.

이 포스팅에서는 Bookinfo라는 샘플 애플리케이션을 배포하고 kiali를 통하여 Bookinfo 페이지를 호출했을 때 트래픽의 구조 및 흐름을 간단하게 확인해 보고자 한다.

 

 

kiali의 Bookinfo 모니터링 화면이다.

 

트래픽의 흐름을 파악 가능하며 트래픽이 완벽(?) 균등하게 로드밸런싱 되는것을 확인할 수 있다.

 

 

재미있어 보인다면 본격적으로 kiali에 대해서 알아보자.

 

 

📖Bookinfo란?

 

Bookinfo는 4개의 개별 마이크로 서비스로 구성된 샘플 애플리케이션이다.

 

 

Bookinfo Application

Deploys a sample application composed of four separate microservices used to demonstrate various Istio features.

istio.io

Bookinfo 샘플 애플리케이션 아키텍처

  • Bookinfo는 다중 언어로 개발되었고. Python, Java, Ruby, node로 나눠져 있다.
  • Python으로 개발된 ProductPage에서 요청을 받으면 Java로 개발된 도서 리뷰를 보여주는 Reviews 서비스와 Ruby로 개발된 Details에 접속하고, ProductPage는 Reviews와 Details의 결과를 사용자에게 응답한다.
  • Reviews 서비스는 v1, v2, v3 총 3개의 버전이 존재하며 v2, v3 버전의 경우 node로 개발된 Ratings 서비스에 접속하여 도서에 대한 평가를 가져온다.
  • 버전 v1은 Ratings 서비스를 호출 하지 않고, 버전 v2의 경우 Ratings를 호출하며 각 등급을 1~5개의 검은색 별로 표시하며, 버전 v3의 경우 Ratings를 호출하며 각 등급을 1~5개의 빨간색 별로 표시한다.

 

Bookinfo Web Page이며 세부적인 Page 구조는 다음과 같이 되어 있다.

 

배포가 완료된 Bookinfo Sample Page

 

💎실습 환경 준비

실습은 VirtualBox에서 진행되었다. Freeware이므로 개인 PC에 자유롭게 설치 후 가상화 환경을 통해서 Kubernetes 환경 실습이 가능하다. 가시다 님의 Vagrant File를 통해서 명령어 한 번으로 아래 그림에 보이는 Kubernetes Cluster 환경을 바로 구성할 수 있다.

 

(그림 출처 : KANS 가시다님)VM은 총 4대로 구성되며 각각 Control Plane인 k8s-m, 2개의 node(k8s-w1, k8s-w2)로 클러스터가 구성되며 외부에서 테스트 환경을 접속하기 위한 k8s-pc 가 VM으로 배포된다 (K8S v1.23.4, Node OS(Ubuntu 20.04.3), CNI(Calico v3.21.4, Direct mode), IPTABLES Porxy mode)

 

# 배포
curl -O https://raw.githubusercontent.com/gasida/KANS/main/8/Vagrantfile
vagrant up

# metrics-server 확인
kubectl top node
kubectl top pod
kubectl top pod -A

 

위 Vagrant File을 가지고 배포를 했을 때 실제 VirtualBox에 다음과 같이 VM이 구성된다.

 

 

Control Plane에 접속하여 클러스터 정보를 확인해보자.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# k get nodes
NAME     STATUS   ROLES                  AGE     VERSION
k8s-m    Ready    control-plane,master   10m     v1.23.4 #Control Plane
k8s-w1   Ready    <none>                 7m22s   v1.23.4 #Node01
k8s-w2   Ready    <none>                 4m17s   v1.23.4 #Node02

 

테스트를 진행하기 위해 istio 부터 설치해 보자. 스터디 당시에는 Istio 버전이 1.13.1 이였는데 지금은 버전이 1.13.2로 올라갔다.

 

#Istio 다운로드
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# curl -L https://istio.io/downloadIstio | sh -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   101  100   101    0     0    183      0 --:--:-- --:--:-- --:--:--   183
100  4549  100  4549    0     0   5609      0 --:--:-- --:--:-- --:--:-- 85830

Downloading istio-1.13.2 from https://github.com/istio/istio/releases/download/1.13.2/istio-1.13.2-linux-amd64.tar.gz ...

Istio 1.13.2 Download Complete!

Istio has been successfully downloaded into the istio-1.13.2 folder on your system.

Next Steps:
See https://istio.io/latest/docs/setup/install/ to add Istio to your Kubernetes cluster.

To configure the istioctl client tool for your workstation,
add the /root/istio-1.13.2/bin directory to your environment path variable with:
         export PATH="$PATH:/root/istio-1.13.2/bin"

Begin the Istio pre-installation check by running:
         istioctl x precheck

Need more information? Visit https://istio.io/latest/docs/setup/install/



#하위 버전으로 설치가 필요할 경우 다음과 같이 버전을 명시하여 다운로드 받는다.
#curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.12.3 sh -



#Istio 설치
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# ISTIO_VERSION=1.13.2
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~cp istio-$ISTIO_VERSION/bin/istioctl /usr/bin/istioctl
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# istioctl operator init
Installing operator controller in namespace: istio-operator using image: docker.io/istio/operator:1.13.2
Operator controller will watch namespaces: istio-system
✔ Istio operator installed
✔ Installation complete

 

operator controller가 istio-operator에 설치됨을 알 수 있다.

 

* istio 설치 시 네임스페이스를 직접 설정하여 구성하거나 helm을 통해서 구성할 수도 있다.

 

#nameSpace 설정
$ istioctl operator init --watchedNamespaces=istio-namespace1,istio-namespace2

 

#Helm으로 설치

$ kubectl create namespace istio-operator 

$ helm install istio-operator manifests/charts/istio-operator \
--set watchedNamespaces="istio-namespace1\,istio-namespace2" \
-n istio-operator

 

정상적으로 설치되었는지 확인한다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# k get ns
NAME              STATUS   AGE
default           Active   47m
istio-operator    Active   34m
istio-system      Active   34m
kube-node-lease   Active   47m
kube-public       Active   47m
kube-system       Active   47m
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# k get all -n istio-operator
NAME                                  READY   STATUS    RESTARTS   AGE
pod/istio-operator-67b876d65f-x578n   1/1     Running   0          34m

NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/istio-operator   ClusterIP   10.110.135.225   <none>        8383/TCP   34m

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/istio-operator   1/1     1            1           34m

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/istio-operator-67b876d65f   1         1         1       34m
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#

 

Istio 설치가 완료되었다. Bookinfo 설치에 앞서 적당한 리소스 요구 사항으로 Istio 기능을 확인해 볼 수 있는 Demo Profile를 제공한다. Demo 외에도 Default, Minimum 등 여러 가지 옵션이 있다. 참고하면 좋을 만한 내용들이다.

 

  1. default: enables components according to the default settings of the IstioOperator API. This profile is recommended for production deployments and for primary clusters in a multicluster mesh. You can display the default settings by running the istioctl profile dump command.
  2. demo: configuration designed to showcase Istio functionality with modest resource requirements. It is suitable to run the Bookinfo application and associated tasks. This is the configuration that is installed with the quick start instructions. This profile enables high levels of tracing and access logging so it is not suitable for performance tests.
  3. minimal: same as the default profile, but only the control plane components are installed. This allows you to configure the control plane and data plane components (e.g., gateways) using separate profiles.
  4. external: used for configuring a remote cluster that is managed by an external control plane or by a control plane in a primary cluster of a multicluster mesh.
  5. empty: deploys nothing. This can be useful as a base profile for custom configuration.
  6. preview: the preview profile contains features that are experimental. This is intended to explore new features coming to Istio. Stability, security, and performance are not guaranteed - use at your own risk.

 

demo profile로 구성할 경우, istio-egressgateway, istio-ingressgateway, istiod 로 구성이 된다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl apply -f - <<EOF
> apiVersion: install.istio.io/v1alpha1
> kind: IstioOperator
> metadata:
>   namespace: istio-system
>   name: example-istiocontrolplane
> spec:
>   profile: demo
> EOF
istiooperator.install.istio.io/example-istiocontrolplane created

 

구성이 완료된 것을 확인해보자.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# istioctl version
client version: 1.13.2
control plane version: 1.13.2
data plane version: 1.13.2 (2 proxies)
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# k get all -n istio-system
NAME                                        READY   STATUS    RESTARTS   AGE
pod/istio-egressgateway-77568fc45c-nx8xh    1/1     Running   0          7m30s
pod/istio-ingressgateway-76b86f6b45-f5cf6   1/1     Running   0          7m30s
pod/istiod-587f7bd8ff-b7qwt                 1/1     Running   0          7m40s

NAME                           TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)
                                  AGE
service/istio-egressgateway    ClusterIP      10.109.4.121     <none>        80/TCP,443/TCP
                                  7m30s
service/istio-ingressgateway   LoadBalancer   10.109.205.191   <pending>     15021:31062/TCP,80:31966/TCP,443:30305/TCP,31400:31633/TCP,15443:30914/TCP   7m30s
service/istiod                 ClusterIP      10.102.203.149   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP                                        7m40s

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/istio-egressgateway    1/1     1            1           7m30s
deployment.apps/istio-ingressgateway   1/1     1            1           7m30s
deployment.apps/istiod                 1/1     1            1           7m40s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/istio-egressgateway-77568fc45c    1         1         1       7m30s
replicaset.apps/istio-ingressgateway-76b86f6b45   1         1         1       7m30s
replicaset.apps/istiod-587f7bd8ff                 1         1         1       7m40s
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#

 

istio-egressgateway, istio-ingressgateway, istiod 가 구성된 것을 확인할 수 있다.

 

istio servicemash를 구성하기 위해서는 pod에 sidecar 컨테이너로 injection되어 동작할 수 있도록 설정해야 한다. Sidecar 설정은 Pod마다 수동으로 설정을 하거나 namespace의 label 설정을 통해 해당 label에 배포되는 pod들은 자동으로 istio sidecar 컨테이너가 injection 될 수 있도록 설정할 수 있다.

 

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl label ns default istio-injection=enabled
namespace/default labeled

 

다음 명령어를 통해 label이 정상적으로 적용됨을 확인할 수 있다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# k get ns --show-labels
NAME              STATUS   AGE   LABELS
default           Active   69m   istio-injection=enabled,kubernetes.io/metadata.name=default
istio-operator    Active   56m   kubernetes.io/metadata.name=istio-operator
istio-system      Active   56m   kubernetes.io/metadata.name=istio-system
kube-node-lease   Active   69m   kubernetes.io/metadata.name=kube-node-lease
kube-public       Active   69m   kubernetes.io/metadata.name=kube-public
kube-system       Active   69m   kubernetes.io/metadata.name=kube-system

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"type":"NodePort"}}'
service/istio-ingressgateway patched
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"externalTrafficPolicy":"Local"}}'
service/istio-ingressgateway patched
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# k get all -n istio-system
NAME                                        READY   STATUS    RESTARTS   AGE
pod/istio-egressgateway-77568fc45c-nx8xh    1/1     Running   0          22m
pod/istio-ingressgateway-76b86f6b45-f5cf6   1/1     Running   0          22m
pod/istiod-587f7bd8ff-b7qwt                 1/1     Running   0          23m

NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)
                               AGE
service/istio-egressgateway    ClusterIP   10.109.4.121     <none>        80/TCP,443/TCP
                               22m
service/istio-ingressgateway   NodePort    10.109.205.191   <none>        15021:31062/TCP,80:31966/TCP,443:30305/TCP,31400:31633/TCP,15443:30914/TCP   22m
service/istiod                 ClusterIP   10.102.203.149   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP
                               23m

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/istio-egressgateway    1/1     1            1           22m
deployment.apps/istio-ingressgateway   1/1     1            1           22m
deployment.apps/istiod                 1/1     1            1           23m

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/istio-egressgateway-77568fc45c    1         1         1       22m
replicaset.apps/istio-ingressgateway-76b86f6b45   1         1         1       22m
replicaset.apps/istiod-587f7bd8ff                 1         1         1       23m
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#

 

 

📖Bookinfo 배포

 

bookinfo를 배포해보자. 정말 간단하다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# ISTIO_VERSION=1.13.2
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl apply -f ~/istio-$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

 

Bookinfo 배포가 완료되면 각각의 productpage, details, ratings, reviews pod가 정상적으로 Running 상태인지 확인한다. 간혹 늦게 Running 상태로 올라오는 경우도 있다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl get all,sa
NAME                                  READY   STATUS    RESTARTS   AGE
pod/details-v1-5498c86cf5-p5j7t       2/2     Running   0          72s
pod/productpage-v1-65b75f6885-p5rlq   2/2     Running   0          71s
pod/ratings-v1-b477cf6cf-hcwnk        2/2     Running   0          72s
pod/reviews-v1-79d546878f-2dcc2       2/2     Running   0          71s
pod/reviews-v2-548c57f459-tdwkk       2/2     Running   0          71s
pod/reviews-v3-6dd79655b9-zbmld       2/2     Running   0          71s

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/details       ClusterIP   10.110.81.184    <none>        9080/TCP   72s
service/kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP    83m
service/productpage   ClusterIP   10.103.208.102   <none>        9080/TCP   71s
service/ratings       ClusterIP   10.99.109.44     <none>        9080/TCP   72s
service/reviews       ClusterIP   10.98.132.161    <none>        9080/TCP   72s

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/details-v1       1/1     1            1           72s
deployment.apps/productpage-v1   1/1     1            1           71s
deployment.apps/ratings-v1       1/1     1            1           72s
deployment.apps/reviews-v1       1/1     1            1           71s
deployment.apps/reviews-v2       1/1     1            1           71s
deployment.apps/reviews-v3       1/1     1            1           71s

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/details-v1-5498c86cf5       1         1         1       72s
replicaset.apps/productpage-v1-65b75f6885   1         1         1       71s
replicaset.apps/ratings-v1-b477cf6cf        1         1         1       72s
replicaset.apps/reviews-v1-79d546878f       1         1         1       71s
replicaset.apps/reviews-v2-548c57f459       1         1         1       71s
replicaset.apps/reviews-v3-6dd79655b9       1         1         1       71s

NAME                                  SECRETS   AGE
serviceaccount/bookinfo-details       1         72s
serviceaccount/bookinfo-productpage   1         71s
serviceaccount/bookinfo-ratings       1         72s
serviceaccount/bookinfo-reviews       1         72s
serviceaccount/default                1         82m

 

bookinfo에 접근할 수 있는 istio gateway와 virtualservice를 설정한다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl apply -f ~/istio-$ISTIO_VERSION/samples/bookinfo/networking/bookinfo-gaway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

 

설정이 제대로 되었는지 확인해본다. 

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl get gw,vs
NAME                                           AGE
gateway.networking.istio.io/bookinfo-gateway   7s

NAME                                          GATEWAYS               HOSTS   AGE
virtualservice.networking.istio.io/bookinfo   ["bookinfo-gateway"]   ["*"]   7s

 

Control Plane에서 curl을 통해 ProductPage에 접근이 되는지 확인해본다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#

 

bookinfo에 접근하기 위해 메인 페이지인 ProductPage에 접근할 수 있도록 접근 URL을 확인한다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# ISTIOINGRESSGWHostIP=$(kubectl get pod -n istio-system -l app=istio-ingressgateway -o jsonpath='{.items[0].status.hostIP}')
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# ISTIOINGRESSGWNodePort=$(kubectl get svc -n istio-system istio-ingressgateway -o jsonpath={.spec.ports[1].nodePort})
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# echo -e "PRODUCTPAGE UI URL = http://$ISTIOINGRESSGWHostIP:$ISTIOINGRESSGWNodePort/productpage"
PRODUCTPAGE UI URL = http://192.168.10.102:31966/productpage
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~#

 

정상적으로 bookinfo 페이지가 출력되는 것을 확인할 수 있다. 

 

 

💎kiali 설치

 

Istio/samples/addons의 경로의 내용들을 확인해 보자. Istio에서는 grafana, jaeger, kiali, prometheus 등 여러 가지 모니터링과 관련된 애드온이 있다. 이 애드온을 설치해 보자.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# tree ~/istio-$ISTIO_VERSION/samples/addons/
/root/istio-1.13.2/samples/addons/
├── README.md
├── extras
│   ├── prometheus-operator.yaml
│   ├── prometheus_vm.yaml
│   ├── prometheus_vm_tls.yaml
│   └── zipkin.yaml
├── grafana.yaml
├── jaeger.yaml
├── kiali.yaml
└── prometheus.yaml

1 directory, 9 files

 

우선 여러 가지 애드온을 체험해 보기 위해서 모든 애드온을 설치했다. kiali만 별도로 설치해도 된다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl apply -f ~/istio-$ISTIO_VERSION/samples/addons
serviceaccount/grafana created
configmap/grafana created
service/grafana created
deployment.apps/grafana created
configmap/istio-grafana-dashboards created
configmap/istio-services-grafana-dashboards created
deployment.apps/jaeger created
service/tracing created
service/zipkin created
service/jaeger-collector created
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created
serviceaccount/prometheus created
configmap/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
service/prometheus created
deployment.apps/prometheus created

 

kiali 관련 서비스가 정상적으로 Running 되는 것을 확인할 수 있다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl get all,sa -n istio-system
NAME                                        READY   STATUS    RESTARTS   AGE
pod/grafana-67f5ccd9d7-jk6pl                1/1     Running   0          84s
pod/istio-egressgateway-77568fc45c-nx8xh    1/1     Running   0          42m
pod/istio-ingressgateway-76b86f6b45-f5cf6   1/1     Running   0          42m
pod/istiod-587f7bd8ff-b7qwt                 1/1     Running   0          42m
pod/jaeger-78cb4f7d4b-th5mc                 1/1     Running   0          84s
pod/kiali-c946fb5bc-9nrf8                   1/1     Running   0          84s
pod/prometheus-7cc96d969f-rl6ft             2/2     Running   0          84s

NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)
                                AGE
service/grafana                ClusterIP   10.111.243.70    <none>        3000/TCP
                                84s
service/istio-egressgateway    ClusterIP   10.109.4.121     <none>        80/TCP,443/TCP
                                42m
service/istio-ingressgateway   NodePort    10.109.205.191   <none>        15021:31062/TCP,80:31966/TCP,443:30305/TCP,31400:31633/TCP,15443:30914/TCP   42m
service/istiod                 ClusterIP   10.102.203.149   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP                                        42m
service/jaeger-collector       ClusterIP   10.110.64.202    <none>        14268/TCP,14250/TCP,9411/TCP
                                84s
service/kiali                  ClusterIP   10.103.95.91     <none>        20001/TCP,9090/TCP
                                84s
service/prometheus             ClusterIP   10.109.164.116   <none>        9090/TCP
                                84s
service/tracing                ClusterIP   10.107.70.150    <none>        80/TCP,16685/TCP
                                84s
service/zipkin                 ClusterIP   10.107.200.22    <none>        9411/TCP
                                84s

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/grafana                1/1     1            1           84s
deployment.apps/istio-egressgateway    1/1     1            1           42m
deployment.apps/istio-ingressgateway   1/1     1            1           42m
deployment.apps/istiod                 1/1     1            1           42m
deployment.apps/jaeger                 1/1     1            1           84s
deployment.apps/kiali                  1/1     1            1           84s
deployment.apps/prometheus             1/1     1            1           84s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/grafana-67f5ccd9d7                1         1         1       84s
replicaset.apps/istio-egressgateway-77568fc45c    1         1         1       42m
replicaset.apps/istio-ingressgateway-76b86f6b45   1         1         1       42m
replicaset.apps/istiod-587f7bd8ff                 1         1         1       42m
replicaset.apps/jaeger-78cb4f7d4b                 1         1         1       84s
replicaset.apps/kiali-c946fb5bc                   1         1         1       84s
replicaset.apps/prometheus-7cc96d969f             1         1         1       84s

NAME                                                  SECRETS   AGE
serviceaccount/default                                1         78m
serviceaccount/grafana                                1         84s
serviceaccount/istio-egressgateway-service-account    1         42m
serviceaccount/istio-ingressgateway-service-account   1         42m
serviceaccount/istio-reader-service-account           1         42m
serviceaccount/istiod                                 1         42m
serviceaccount/istiod-service-account                 1         42m
serviceaccount/kiali                                  1         84s
serviceaccount/prometheus                             1         84s

 

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl rollout status deployment/kiali -n istio-system
deployment "kiali" successfully rolled out

 

kiali 서비스를 외부에서 접근하기 위해서 kiali에 연결된 서비스를 NodePort로 변경한다.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# kubectl patch svc -n istio-system kiali -p '{"spec":{"type":"NodePort"}}'
service/kiali patched

 

kiali에 접근하기 위한 Endpoint URL을 확인해 보고 인터넷 브라우저를 통해 확인해 보자.

 

(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~KIALIHostIP=$(kubectl get pod -n istio-system -l app=kiali -o jsonpath='{.items[0].status.hostIP}')
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~KIALINodePort=$(kubectl get svc -n istio-system kiali -o jsonpath={.spec.ports[0].nodePort})
(🧑‍🎓 |Istio-k8s:default) root@k8s-m:~# echo -e "KIALI UI URL = http://$KIALIHostIP:$KIALINodePort"
KIALI UI URL = http://192.168.10.101:32698

 

초기 접근 시에는 30초~최대 1분까지 소요된다. 정상적으로 접근이 완료되면 kiali 메인 Dashboard를 확인할 수 있다.

로그인 직후에 나타나는 Overview 페이지에서는 간략하게 서비스가 있는 모든 네임스페이스가 표시된다. 아래와 같이 확인할 수 있다.

 

* kiali의 경우 아주 많은 기능을 제공한다.. 이 포스팅에서는 트래픽 흐름에 대해서만 간단히 알아보려고 한다. 상세 메뉴 구성이나 자세한 내용이 필요한 사람은 공식 홈페이지에 들어가면 아주 자세히 나와있다.

 

https://kiali.io/docs/

 

Documentation

Kiali Project site

kiali.io

 

 

 

네임스페이스의 그래프를 보려면 왼쪽 상단의 Graph 메뉴를 클릭하면 된다. Bookinfo 그래프를 보기 위해 상단의 네임스페이스 선택에서 Bookinfo를 배포한 default를 선택한다. 아래 그림과 같이 초기에 배포하려고 했던 4개의 마이크로 서비스가 있는 Bookinfo를 시각화하여 볼 수 있다.  화면 우측의 엣지 패널을 통해서도 간략한 정보들을 확인할 수 있다.

 

 

다양한 그래프 유형을 사용하여 ServiceMash를 확인할 수 있다. 상단의 그래프 유형 드롭다운 메뉴에서 선택할 수 있다. App, Versioned App, Workload, Service 중 선택할 수 있으며 각각 유형에 따른 화면이다.

 

App Graph

 

Service Graph

 

Versioned App Graph

 

Workload Graph

 

트래픽의 흐름을 확인하기 위해 그래프 유형을 Versioned App Graph로 변경하고 좌측 상단의 Display에서 Service Nodes를 체크해 보자. 앞서 말한 Bookinfo의 구성과 비슷해졌다.

 

 

다시 소환한 Bookinfo 샘플 애플리케이션 아키텍처

 

 

이제 트래픽 흐름을 확인하기 위해서 Bookinfo 서비스에 VirtualBox에 준비된 k8s-pc에서 curl을 통해 Bookinfo를 지속적으로 호출해 보자.

 

root@k8s-pc:~# while true; do curl -s 192.168.10.102:31966/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 1; done
<title>Simple Bookstore App</title>
--------------
<title>Simple Bookstore App</title>
--------------
<title>Simple Bookstore App</title>
--------------
<title>Simple Bookstore App</title>
--------------
<title>Simple Bookstore App</title>
--------------

 

이후 다시 kiali 화면으로 돌아와 좌측 상단의 Display에서 Traffic Distribution, Traffic Animitaion를 체크해 보자. 앞서 말한 Bookinfo의 구성과 비슷해졌다.

 

 

Traffic Distribution을 통해 트래픽의 분산을 퍼센티지로 시각화하여 확인할 수 있다.

Traffic Animitaion을 통해 트래픽의 흐름을 확인할 수 있다.

 

 

 

각각의 App를 더블클릭하여 세부적인 내용도 확인할 수 있다.

 

 

 

이 외에도 kiali는 아주 많은 시각화 기능을 가지고 있다. 좌측 상단의 Display을 클릭하고 Security를 선택해 보자. 마이크로 서비스간의 통신에서 mTLS가 활성화된 요청이 있음을 확인할 수 있다. 

 

 

 

하나만 더 진행해 보자면, 현재 Product Page에서 Reviews로 가는 트래픽이 v1, v2, v3로 균등 분산되고 있다. Kiali에서 트래픽 설정을 통해서 v2와 v3에만 트래픽을 시프팅 해 보자.

 

Reviews를 클릭하고 우측 상단의 Service(S) reviews를 클릭한 뒤, 우측 상단의 Actions에서 Traffic Shifting를 클릭한다.

 

 

 

 

v2의 경우 80%, v3의 경우 20%로 조절하고. v1의 경우 트래픽을 받지 않도록 설정해 보자. 우측 상단에 설정이 완료됐다는 팝업 알림이 뜬다.

 

 

잠시 기다려보면.. kiali dashboard에서 reviews-v1이 사라지는 것을 볼 수 있다. 트래픽이 흐르지 않기 때문이다. 설정을 v2, v3 각각 8 대 2 비율로 할당했지만 7 대 3 정도로 나오는 것을 확인할 수 있었다. 정확히 8 대 2로 나눠지지는 않는 걸까.

 

 

기존 k8s-pc에서 curl을 1초마다 호출했지만 이제는 더 많은 트래픽을 보내 분배 설정이 제대로 되었는지 확인해 보자.

0.05초마다 한 번씩 호출하도록 명령을 입력한다.

 

root@k8s-pc:~# while true; do curl -s 192.168.10.102:31966/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 0.05; done
<title>Simple Bookstore App</title>
--------------
<title>Simple Bookstore App</title>
--------------

 

 

 

징그러운(?) 트래픽 흐름이 보이지만 나름 8 대 2 비율로 트래픽이 시프팅 되는 것을 확인할 수 있었다. 

 

 

이제 처음에 보여줬던 그림이 이해가 됐을 것이다.

 

게임이름이 떠오르지 않아 인터넷 게시판에 물어봐서 찾아봤고,, 놀랍게도 아직도 이 게임은 버전 릴리즈가 되고 있었다.. 커스텀 맵 제작 기능이 있다는 내용을 듣고 재미있는 짤방 하나를 만들어 봤다.

 

 

 

 

📖 마치며

 

KubeInvaders라는 카오스 엔지니어링 도구가 있다. 갤러그인데 화면에 나오는 몬스터 들은 Pod로 되어있으며 주인공 비행체가 Pod를 공격하게 되면 실제로 Pod가 죽는다.. 그리고 다시 Pod가 살아난다. 이는 Kubernetes의 탄력성을 테스트하기 위해서 만든 재미있는 툴이다.

 

https://www.youtube.com/watch?v=wD7ngPlNEjY 

 

Lemmings에 대해서도 이러한 카오스 엔지니어링을 사용한 게임이 나오면 매우 재미있을 것 같다.

 

"레밍즈(lemmings) 게임의 경우 아래 사이트에서 다운로드 받을 수 있다."
"여러가지 버전이 있는데 클래식 환경과 동일한 분위기를 느끼고 싶다면 Lemmings Reunion 으로 시작해 보자"

#Lemmings
https://www.lemmingsforums.net/index.php?topic=3232.0

#Lemmings Reunion
https://www.lemmingsforums.net/index.php?topic=2175.0