
Kiali는 Istio 기반의 서비스 메쉬(Service Mesh)를 시각화하고 관리하는 오픈소스 도구이다. 마이크로서비스 아키텍처에서 서비스 간의 네트워크 흐름을 쉽게 모니터링하고, 트래픽 제어, 보안, 성능 분석 등의 기능을 제공한다.
vagrant@master:~$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/kiali.yaml
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
service/kiali created
deployment.apps/kiali created
vagrant@master:~$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/prometheus.yaml
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
vagrant@master:~$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/grafana.yaml
serviceaccount/grafana created
configmap/grafana created
service/grafana created
deployment.apps/grafana created
configmap/istio-grafana-dashboards created
configmap/istio-services-grafana-dashboards created
kubectl label ns default istio-injection=enabled
vagrant@master:~$ kubectl apply -n default -f https://raw.githubusercontent.com/istio/istio/1.20.2/samples/helloworld/helloworld.yaml
service/helloworld created
deployment.apps/helloworld-v1 created
deployment.apps/helloworld-v2 created
kubectl label ns default istio-injection=enabled 명령어 수행 후 다시 설치할 시 애플리케이션의 컨테이너가 2개씩 생성되는 것을 확인할 수 있다.
vagrant@master:~$ k get po
NAME READY STATUS RESTARTS AGE
helloworld-v1-867747c89-s9xhq 2/2 Running 0 24s
helloworld-v2-7f46498c69-gqp6j 2/2 Running 0 24s
POD 상세 정보 조회 후 PROXY 컨테이너가 자동으로 할당되었다는 것을 알수 있다.
k describe po helloworld-v1-867747c89-s9xhq
...
istio-proxy:
Container ID: containerd://25c79961b0451ddbd3e199c2090961cc73370e6d45c593d0a0e80e1698e10409
Image: docker.io/istio/proxyv2:1.24.3
Image ID: docker.io/istio/proxyv2@sha256:534f7589b085450b5b94e6c955f5106892df88d81676f53ac5e06a0cf5ec45da
Port: 15090/TCP
Host Port: 0/TCP
이 상태에서 Kiali 를 확인하면 그래프는 보이지 않는다.

트래픽을 흘려야 보인다는 메시지를 확인할 수 있다. 인그레스가 구성되지 않은 상태에서 트래픽을 송출하는 방법은 POD 내로 들어가서 내부 네트워크를 이용하면 된다.
vagrant@master:~$ k get po
NAME READY STATUS RESTARTS AGE
helloworld-v1-867747c89-s9xhq 2/2 Running 0 6m54s
helloworld-v2-7f46498c69-gqp6j 2/2 Running 0 6m54s
vagrant@master:~$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloworld ClusterIP 10.105.122.14 <none> 5000/TCP 8m28s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 64m
vagrant@master:~$ k exec -it helloworld-v1-867747c89-s9xhq -- bash
root@helloworld-v1-867747c89-s9xhq:/opt/microservices# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
내부 도메인이 default.svc.cluster.local 인것을 확인했다. 서비스명이 helloworld 이므로 helloworld 에 접근하는 stateless 내부 도메인은 helloworld.default.svc.cluster.local 이다.
이제 아래처럼 1초 간격으로 트래픽을 발생시킨다. v1,v2 를 이용해서 부하 분산을 하고 있음을 알 수 있다.
root@helloworld-v1-867747c89-s9xhq:/opt/microservices# while true; do curl "http://helloworld.default.svc.cluster.local:5000/hello";sleep 1s; done
Hello version: v1, instance: helloworld-v1-867747c89-s9xhq
Hello version: v1, instance: helloworld-v1-867747c89-s9xhq
Hello version: v2, instance: helloworld-v2-7f46498c69-gqp6j
Hello version: v1, instance: helloworld-v1-867747c89-s9xhq
Hello version: v1, instance: helloworld-v1-867747c89-s9xhq
Hello version: v2, instance: helloworld-v2-7f46498c69-gqp6j
Hello version: v2, instance: helloworld-v2-7f46498c69-gqp6j
이제 Kiali 로 가서 그래프가 생성됨을 확인한다. 드래그하여 모양을 만들어주자.



Workload는 Kubernetes의 배포 단위이다. 이것은 Deployment, StatefulSet, DaemonSet, Job, CronJob 등의 리소스를 포함할 수 있다.
Workload는 직접 Pod를 생성하고 관리하는 역할을 한다. 애플리케이션을 실행하는 실제 프로세스(Pod)와 이를 관리하는 컨트롤러의 집합이다.

Kiali에서의 "Application"은 Istio에서 애플리케이션을 논리적으로 그룹화한 개념이다. Istio에서 동일한 app 레이블을 가진 여러 워크로드(Pod)를 하나의 애플리케이션으로 간주한다. 따라서, 하나의 애플리케이션이 여러 Workload로 구성될 수도 있다. 예를 들어, Deployment와 StatefulSet이 같은 app=my-service 라벨을 가지고 있다면, Kiali는 이를 하나의 애플리케이션으로 묶어 표현한다.

Kiali에서 Operation은 특정 서비스의 엔드포인트(API 호출, HTTP 메소드, gRPC 메소드 등)를 의미한다.트랜잭션 단위에서 서비스 호출의 세부적인 경로와 행동을 분석하는 데 사용된다.
Operation은 일반적으로 HTTP 요청의 메소드 + 경로(GET /users, POST /orders 등) 또는 gRPC 메소드 이름(SayHello)으로 정의된다. Kiali의 Operation Graph 기능을 통해 특정 서비스 내에서 어떤 엔드포인트가 호출되는지 세밀하게 분석할 수 있다. 특정 API 엔드포인트의 성능, 지연 시간, 오류율 등을 분석하는 데 유용하다.
Client -> frontend (Service) -> backend (Service)
-> GET /api/v1/products (Operation)
-> POST /api/v1/orders (Operation)
frontend 서비스가 backend 서비스의 특정 API를 호출하는 경우 backend 서비스가 여러 개의 API 엔드포인트를 제공하고 있다면, 각각의 엔드포인트가 개별적인 Operation으로 분석된다.
Operation 개념을 활용하여, Kiali에서 서비스 단위(Service Graph) 뿐만 아니라 API 단위(Operation Graph) 까지 분석할 수 있어, 마이크로서비스 환경에서 보다 세밀한 모니터링과 디버깅이 가능해진다.

Kiali에서 Service는 Kubernetes 서비스(Kubernetes Service 리소스)와 동일한 개념이다.
서비스 메시 내에서 요청을 수신하는 기본 엔티티로, 클라이언트(다른 서비스 또는 외부 트래픽)로부터 요청을 받고 적절한 워크로드(예: Pod)로 전달한다.
서비스는 Virtual Service, Destination Rule 등의 Istio 리소스와 연계되어 트래픽 라우팅 정책을 정의할 수 있다. 서비스 간의 트래픽 흐름을 시각화할 때, Kiali의 그래프에서 노드로 표시된다. Service 엔티티 자체는 트래픽을 처리하지 않으며, 실제 요청을 처리하는 것은 워크로드(Pod, Deployment 등) 이다.

ServiceEntry는 Istio에서 외부 서비스와의 통신을 제어하는 리소스이다. 기본적으로 Kubernetes 클러스터 내부의 서비스들은 자동으로 Istio 서비스 메시 내에서 감지되지만, 클러스터 외부의 서비스(Google API, 외부 데이터베이스, SaaS 서비스 등) 와 통신하려면 ServiceEntry를 사용해야 한다.
Kiali에서 ServiceEntry를 사용하여 외부 서비스가 네트워크 그래프에서 어떻게 표시되는지, 트래픽이 어떻게 흐르는지를 시각적으로 확인할 수 있다.
서브스 엔트리의 역할
외부 서비스와의 통신 가능 - Istio는 기본적으로 클러스터 외부 서비스로 직접 나가는 트래픽을 제어하지 않는다. ServiceEntry를 생성하면 외부 서비스를 서비스 메시 내부의 가상 서비스처럼 등록하여 트래픽을 관리할 수 있다.
트래픽 제어 및 정책 적용 - VirtualService, DestinationRule과 함께 사용하여 외부 서비스에 대한 트래픽 라우팅, 로드 밸런싱, 모니터링, 보안 정책 적용이 가능하다.
예를 들어, 특정 외부 API에 대한 트래픽을 제한하거나, TLS 설정을 강제할 수 있다.
Kiali에서 가시성 제공 - ServiceEntry를 통해 외부 서비스로의 호출이 Kiali 네트워크 그래프에 표시된다. 내부 서비스에서 외부 서비스로 가는 트래픽을 모니터링하고 성능을 분석할 수 있다.