📌 Notice
Istio Hands-on Study (=Istio)
직접 실습을 통해 Isito를 배포 및 설정하는 내용을 정리한 블로그입니다.
CloudNet@
에서 스터디를 진행하고 있습니다.
Gasida
님께 다시한번 🙇 감사드립니다.
EKS 관련 이전 스터디 내용은 아래 링크를 통해 확인할 수 있습니다.
이번 포스팅에서는 Istio의 데이터 플레인과 컨트롤 플레인에서 발생하는 문제를 효과적으로 식별하고 해결하는 방법을 다룹니다.
특히 istioctl
, Kiali, Grafana, Prometheus 등 다양한 도구들을 활용해 잘못된 설정을 탐지하고, Envoy 프록시 및 Istio 에이전트, 파일럿(Pilot) 내부 구조와 상태를 면밀히 조사하는 과정을 실습 중심으로 정리했습니다.
이러한 내용을 통해 Istio 기반의 서비스 메시 운영자는 블랙박스로 느껴질 수 있는 트래픽 흐름과 설정 동기화 과정을 시각화하고, 필요한 정보를 기반으로 빠르게 원인을 파악할 수 있는 기반 역량을 갖출 수 있습니다.
애플리케이션이 네트워크를 통해 통신할 때는 다양한 문제가 발생할 수 있습니다.
Istio가 존재하는 주요 이유 중 하나는 이러한 네트워크 문제를 자동으로 복원하거나 대응할 수 있도록 지원하는 데 있습니다. Istio는 타임아웃, 재시도, 서킷 브레이커 등 복원 기능을 제공하며, 네트워크 상의 문제를 빠르게 조명하고 대처할 수 있는 기반을 마련합니다.
하지만 Istio의 핵심 구성 요소인 서비스 프록시(Envoy) 자체가 예상과 다르게 동작할 경우에는 문제 해결이 쉽지 않을 수 있습니다.
이 장에서는 이러한 상황에서 활용할 수 있는 다양한 도구와 방법을 다루며, 다음과 같은 질문에 대한 실마리를 제공합니다:
- 잘못된 워크로드 설정은 어떻게 파악할 수 있을까?
istioctl
과 Kiali를 통해 설정 오류를 미리 감지하거나 방지할 수 있을까?- Envoy 프록시의 동작은 어떤 설정에 의해 결정되는가?
- 프록시 로그를 해석하여 무엇을 알 수 있을까?
- Istio 텔레메트리를 통해 애플리케이션의 상태를 어떻게 관찰할 수 있을까?
요청이 네트워크를 통해 전달될 때 다음과 같은 구성 요소들이 함께 작동합니다:
이 체인 중 어느 하나라도 문제가 발생하면, 전체 서비스의 동작에 영향을 줄 수 있습니다.
특히 클러스터나 시스템 전체에 영향을 주는 문제가 발생했을 경우, 모든 구성 요소를 일일이 디버깅할 여유는 없습니다.
따라서 이번 장에서는 프록시의 설정과 상태를 빠르게 조사하고 진단하는 도구들에 집중합니다. 이를 통해 예상치 못한 동작의 원인을 찾아내고, 시스템을 정상 상태로 되돌리는 과정에 집중할 예정입니다.
Istio를 사용하는 사용자들이 가장 자주 겪는 실수 중 하나는 데이터 플레인의 잘못된 설정입니다. 특히 VirtualService나 DestinationRule 같은 리소스를 구성할 때 설정 누락이 발생하기 쉽고, 이로 인해 트래픽 전달이 실패할 수 있습니다.
Istio는 사람이 읽을 수 있는 형태의 리소스(CRD)들을 사용합니다.
예를 들어:
VirtualService
,DestinationRule
같은 CRD(Custom Resource Definition)를 정의- 이 리소스들은 Envoy의 설정으로 변환되어 데이터 플레인에 적용됨
하지만, 리소스를 적용한 후 트래픽이 정상적으로 동작하지 않는 경우, 대부분은 설정이 잘못되었기 때문입니다.
다음 예제는 부분집합(subset) 설정이 누락된 상황에서 트래픽이 실패하는 사례를 통해 트러블슈팅 방법을 소개합니다.
catalog.istioinaction.io
호스트로 트래픽을 받음version-v1
, 80%는 version-v2
로 라우팅# 샘플 애플리케이션 배포
kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction # catalog v1
kubectl apply -f ch10/catalog-deployment-v2.yaml -n istioinaction # catalog v2
kubectl apply -f ch10/catalog-gateway.yaml -n istioinaction # Gateway
kubectl apply -f ch10/catalog-virtualservice-subsets-v1-v2.yaml -n istioinaction # VirtualService
# 리소스 확인
kubectl get deploy,svc -n istioinaction
kubectl get gw,vs -n istioinaction
VirtualService는 subset: version-v1과 version-v2
로 트래픽을 라우팅하지만, DestinationRule 리소스가 존재하지 않으면 해당 subset은 클러스터에 존재하지 않게 됩니다.
그 결과:
- Envoy는 subset에 대응되는 Upstream Cluster를 찾지 못하고
- 모든 요청이 실패하며 503 Service Unavailable을 반환
Envoy에서는 해당 오류를 NC (No Cluster) 플래그로 기록합니다:
kubectl logs -n istio-system -l app=istio-ingressgateway -f
# 예시로그
[2025-05-09T01:54:51.145Z] "GET /items HTTP/1.1" 503 NC cluster_not_found - "-" 0 0 0 - "172.18.0.1" "curl/8.7.1" "90a7d941-cbc4-91ae-9da1-bc95695d5c50" "catalog.istioinaction.io:30000" "-" - - 10.10.0.7:8080 172.18.0.1:64130 - -
# 반복 호출 시도
for i in {1..100}; do curl http://catalog.istioinaction.io:30000/items -w "\nStatus Code %{http_code}\n"; sleep .5; done
Status Code 503
Istio 운영 중 발생하는 문제의 대부분은 데이터 플레인에서 발생합니다. 그로 인해 많은 운영자들이 곧바로 Envoy 로그를 들여다보거나 서비스 프록시 설정을 점검하는 등의 디버깅을 시작하곤 합니다. 그러나 이 장에서는 먼저 컨트롤 플레인 문제를 배제하는 것이 얼마나 중요한지를 강조합니다.
Istio에서 컨트롤 플레인의 주요 역할은 다음과 같습니다:
따라서 데이터 플레인에서 발생하는 문제를 정확히 진단하기 위해서는, 컨트롤 플레인과 데이터 플레인이 제대로 동기화되었는지를 먼저 확인해야 합니다.
문제가 발생했을 때 곧바로 Envoy 로그나 애플리케이션 설정만 들여다보는 접근은, 문제의 근본 원인이 컨트롤 플레인의 동기화 실패일 경우 잘못된 방향으로 디버깅을 유도할 수 있습니다.
Istio에서 데이터 플레인 설정은 설계상 결국 일관성(eventual consistency)을 가지도록 되어 있습니다.
다시 말해, 서비스나 설정이 변경되더라도, 그것이 즉시 데이터 플레인에 반영되는 것은 아니며, 컨트롤 플레인과의 동기화 과정을 거쳐야 합니다.
예를 들어, 컨트롤 플레인은 서비스의 각 파드 IP 주소와 같은 엔드포인트 정보를 데이터 플레인으로 전달합니다.
이 중 하나가 비정상 상태가 되면 다음과 같은 흐름이 발생합니다:
kubelet
이 주기적으로 파드 상태를 확인istiod
가 설정을 갱신하고 비정상 엔드포인트를 제거👉🏻 대규모 클러스터에서는 이 과정이 느려질 수 있으며, 이에 대한 성능 개선은 Chapter 11에서 다룰 예정입니다.
istioctl proxy-status
로 동기화 상태 확인하기컨트롤 플레인과 데이터 플레인이 제대로 동기화되었는지를 확인하려면 다음 명령어를 사용할 수 있습니다:
docker exec -it myk8s-control-plane istioctl proxy-status
출력 예시:
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
catalog-6cf4b97d-l44zk.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-8d74787f-ltkhs 1.17.8
catalog-v2-56c97f6db-d74kv.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-8d74787f-ltkhs 1.17.8
catalog-v2-56c97f6db-m6pvj.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-8d74787f-ltkhs 1.17.8
istio-egressgateway-85df6b84b7-2f4th.istio-system Kubernetes SYNCED SYNCED SYNCED NOT SENT NOT SENT istiod-8d74787f-ltkhs 1.17.8
istio-ingressgateway-6bb8fb6549-hcdnc.istio-system Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-8d74787f-ltkhs 1.17.8
각 컬럼의 의미:
- SYNCED: Envoy가 istiod로부터 보낸 최신 설정을 수신했음을 의미
- NOT SENT: istiod가 해당 컴포넌트에 설정을 보낼 필요가 없어 아무것도 보내지 않았음을 의미
- STALE: istiod가 설정을 보냈지만 Envoy가 이를 확인하지 못한 상태
(원인: istiod 과부하, 연결 문제, 혹은 Istio 버그)
위 출력 결과에 따르면, 모든 컴포넌트가 SYNCED 상태이며 설정 누락이나 동기화 지연이 없음을 알 수 있습니다.
따라서 컨트롤 플레인의 문제 가능성은 낮고, 다음 단계로 데이터 플레인 구성 요소, 특히 워크로드 설정을 집중적으로 조사해야 합니다.
이 과정에서 Kiali는 유용한 시각화 도구로, 잘못된 설정을 빠르게 검증할 수 있습니다.
Istio 설정이 예상대로 작동하지 않는다면, 가장 먼저 확인할 수 있는 도구 중 하나가 Kiali입니다.
Kiali는 시각적인 대시보드와 함께 리소스 유효성 검사(validation) 기능을 제공하여, 잘못된 설정을 빠르게 식별할 수 있도록 도와줍니다.
Overview
탭을 확인합니다.istioinaction
네임스페이스에 경고 아이콘이 표시되어 있음을 확인합니다.Istio Config
탭으로 이동합니다.경고 아이콘 위에 마우스를 올리면, "KIA1107 - Subset not found"
와 같은 메시지가 나타납니다.
이 오류는 VirtualService에서 참조한 subset이 DestinationRule에 정의되어 있지 않을 때 발생합니다.
원인:
- 오타 또는 존재하지 않는 subset 참조
- DestinationRule 내 subset 정의 누락
🔗 공식 문서 참고: Kiali Validation Docs - KIA1107
Istio 설정에서 문제가 발생했을 때, istioctl
은 가장 강력한 CLI 기반 진단 도구입니다.
특히 다음 두 명령어는 잘못된 워크로드 설정을 자동으로 분석하는 데 매우 유용합니다:
istioctl analyze
istioctl describe
(또는x des
단축어)
istioctl analyze
명령어는 현재 클러스터 상태나 적용 전 설정 파일을 검사하여 잠재적인 문제를 사전에 발견합니다.
# 도움말 및 분석기 목록 보기
docker exec -it myk8s-control-plane istioctl analyze -h
docker exec -it myk8s-control-plane istioctl analyze --list-analyzers
# 네임스페이스 단위로 실행
docker exec -it myk8s-control-plane istioctl analyze -n istioinaction
# 출력 예시:
Error [IST0101] (VirtualService istioinaction/catalog-v1-v2) Referenced host+subset in destinationrule not found: "catalog.istioinaction.svc.cluster.local+version-v1"
Error [IST0101] (VirtualService istioinaction/catalog-v1-v2) Referenced host+subset in destinationrule not found: "catalog.istioinaction.svc.cluster.local+version-v2"
Error: Analyzers found issues when analyzing namespace: istioinaction.
IST0101 오류는 DestinationRule에 정의되지 않은 subset을 VirtualService가 참조할 때 발생합니다.
특정 워크로드(Pod) 기준으로 어떤 Istio 설정이 적용되었는지 요약하여 보여줍니다.
# 대상 파드 이름 조회
CATALOG_POD1=$(kubectl get pod -n istioinaction -l app=catalog -o jsonpath='{.items[0].metadata.name}')
# describe 실행
docker exec -it myk8s-control-plane istioctl x des pod -n istioinaction $CATALOG_POD1
# 출력 예시 (문제 발생 시):
VirtualService: catalog-v1-v2
WARNING: No destinations match pod subsets (checked 1 HTTP routes)
Warning: Route to subset version-v1 but NO DESTINATION RULE defining subsets!
Warning: Route to subset version-v2 but NO DESTINATION RULE defining subsets!
# DestinationRule 정의 추가
kubectl apply -f ch10/catalog-destinationrule-v1-v2.yaml
# 다시 describe 실행
docker exec -it myk8s-control-plane istioctl x des pod -n istioinaction $CATALOG_POD1
# 출력 예시 (해결 후):
DestinationRule: catalog for "catalog.istioinaction.svc.cluster.local"
Matching subsets: version-v1
(Non-matching subsets version-v2)
Istio 설정의 문제를 식별하고 해결책을 제시하는 데 충분하며, 대부분의 일반적인 오류를 빠르게 파악할 수 있습니다.
앞에서 소개한 istioctl analyze
, describe
, Kiali 대시보드 등을 사용했음에도 불구하고 여전히 문제가 해결되지 않는다면, 이제는 엔보이 설정 전체를 수동으로 조사해야 할 시점입니다.
이러한 저수준 진단은 다소 번거롭지만, Istio 내부의 구성이나 프록시 설정이 예상대로 반영되지 않았을 때 매우 유용합니다.
Envoy는 각 서비스 프록시마다 관리 인터페이스(admin interface)를 노출하며, 이를 통해 설정을 직접 확인하거나 디버깅용 설정을 수정할 수 있습니다.
기본 포트: 15000
접근 방법: kubectl port-forward
로 포트 포워딩 후 웹 브라우저 또는 curl로 확인 가능
# catalog 파드에서 Envoy admin 포트 열기
kubectl port-forward deploy/catalog -n istioinaction 15000:15000
# 브라우저로 확인
open http://localhost:15000
# 엔보이 전체 설정 덤프 (매우 방대한 출력)
curl -s localhost:15000/config_dump | wc -l
# 출력 예시:
13952
config_dump
명령어로 출력되는 JSON은 수천 줄에 달하며, 사람의 눈으로 일일이 분석하기엔 어려움이 큽니다.istioctl proxy-config
명령어는 Envoy 프록시가 보유한 설정을 xDS API 기반으로 쿼리할 수 있도록 해줍니다.
방대한 설정 덤프(config_dump
) 대신, 클러스터, 엔드포인트, 리스너, 라우트, 시크릿 설정 등을 개별적으로 확인할 수 있습니다.
명령어 | 설명 |
---|---|
cluster | 클러스터 설정 확인 |
endpoint | 엔드포인트 설정 확인 |
listener | 리스너 설정 확인 |
route | 라우트 설정 확인 |
secret | TLS 등 비밀 설정 확인 |
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway -n istio-system
# 출력 예시:
ADDRESS PORT MATCH DESTINATION
0.0.0.0 8080 ALL Route: http.8080
0.0.0.0 15021 ALL Inline Route: /healthz/ready
0.0.0.0 15090 ALL Inline Route: /stats/prometheus
kubectl get svc -n istio-system istio-ingressgateway -o yaml | grep "ports:" -A10
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway -n istio-system --name http.8080
# 출력 예시:
NAME DOMAINS MATCH VIRTUAL SERVICE
http.8080 catalog.istioinaction.io / catalog-v1-v2.istioinaction
# 상세 JSON 출력:
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway -n istio-system --name http.8080 -o json
→ outbound|80|version-v1|catalog..., version-v2로 라우팅 설정이 되어 있음을 확인
docker exec -it myk8s-control-plane istioctl proxy-config clusters deploy/istio-ingressgateway -n istio-system \
--fqdn catalog.istioinaction.svc.cluster.local --port 80
→ subset이 정의되지 않은 상태에서는 version-v1, v2 클러스터가 존재하지 않음
# 해결을 위해 DestinationRule 정의 필요:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: catalog
namespace: istioinaction
spec:
host: catalog.istioinaction.svc.cluster.local
subsets:
- name: version-v1
labels:
version: v1
- name: version-v2
labels:
version: v2
# 적용 전 검증
docker exec -it myk8s-control-plane istioctl analyze /istiobook/ch10/catalog-destinationrule-v1-v2.yaml -n istioinaction
✔ No validation issues found
# 적용 후 재확인:
kubectl apply -f ch10/catalog-destinationrule-v1-v2.yaml
docker exec -it myk8s-control-plane istioctl proxy-config clusters deploy/istio-ingressgateway -n istio-system \
--fqdn catalog.istioinaction.svc.cluster.local --port 80
출력:
SUBSET DESTINATION RULE
version-v1 catalog.istioinaction
version-v2 catalog.istioinaction
docker exec -it myk8s-control-plane istioctl proxy-config clusters deploy/istio-ingressgateway -n istio-system \
--fqdn catalog.istioinaction.svc.cluster.local --port 80 --subset version-v1 -o json
# 출력 예시
- "type": "EDS": Endpoint Discovery Service
- "ads": {}: Aggregated Discovery Service (ADS) 사용
docker exec -it myk8s-control-plane istioctl proxy-config endpoints deploy/istio-ingressgateway -n istio-system \
--cluster "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local"
# 출력 예시:
ENDPOINT STATUS CLUSTER
10.10.0.12:3000 HEALTHY outbound|80|version-v1|catalog...
→ IP가 실제 워크로드인지 확인:
kubectl get pod -n istioinaction --field-selector status.podIP=10.10.0.12 -owide --show-labels
proxy-config 명령어는 Envoy 설정의 특정 항목만 필터링해서 보기 좋게 보여줍니다.
listener → route → cluster → endpoint 순으로 요청이 라우팅되며, 이 체인을 수동으로 검증할 수 있습니다.
이 과정을 통해 설정 누락이나 mismatch 문제를 빠르게 확인하고 복구할 수 있습니다.
마이크로서비스 아키텍처에서는 서비스 프록시가 남기는 로그와 메트릭이 매우 유용한 트러블슈팅 도구가 됩니다.
예를 들어, 성능 병목, 비정상적인 엔드포인트, 반복되는 요청 실패 등의 문제를 Envoy 로그와 Istio 메트릭을 통해 분석할 수 있습니다.
이번 실습에서는 catalog 서비스 중 일부 인스턴스가 간헐적으로 응답 지연을 일으키도록 설정한 뒤, 이를 다양한 도구로 확인하고 원인을 추적해 봅니다.
latency
장애를 주입합니다.# 정상 상태에서 통신 확인
for i in {1..9999}; do curl http://catalog.istioinaction.io:30000/items -w "\nStatus Code %{http_code}\n"; sleep 1; done
# Kiali와 Grafana로 성공률 및 p99 레이턴시 확인
# catalog v2 파드 중 하나에 지연 장애 주입
CATALOG_POD=$(kubectl get pods -l version=v2 -n istioinaction -o jsonpath={.items..metadata.name} | cut -d ' ' -f1)
kubectl -n istioinaction exec -c catalog $CATALOG_POD -- curl -s -X POST -H "Content-Type: application/json" \
-d '{"active": true, "type": "latency", "volatile": true}' localhost:3000/blowup
# Istio timeout 설정
kubectl patch vs catalog-v1-v2 -n istioinaction --type json \
-p '[{"op": "add", "path": "/spec/http/0/timeout", "value": "0.5s"}]'
# 결과 확인: HTTP 504 오류, Envoy 로그의 response_timeout, UT 응답 플래그
Envoy 기본 로그는 TEXT 형식이라 읽기 어려움 → JSON 형식으로 변경 추천
# ConfigMap 수정
KUBE_EDITOR="nano" kubectl edit -n istio-system cm istio
# 아래 항목 추가
accessLogEncoding: JSON
- 이후 로그를 jq로 확인하면 다음과 같이 해석 가능:
{
"upstream_host": "10.10.0.13:3000",
"duration": 501,
"response_code": 504,
"response_flags": "UT",
...
}
→ 504 응답이며 response_timeout 발생, 해당 IP를 가진 파드 조회하여 문제 파드 식별 가능
kubectl get pod -n istioinaction -o wide | grep 10.10.0.13
디버깅을 위해 istioctl proxy-config log
명령어로 로깅 범위와 수준을 조정할 수 있습니다.
각 범위에 로깅 수준을 서로 다르게 지정할 수 있는 덕분에 엔보이가 만들어내는 로그에 질식하지 않고 관심 영역의 로깅 수준만 정확하게 높일 수 있습니다.
docker exec -it myk8s-control-plane istioctl proxy-config log deploy/istio-ingressgateway -n istio-system \
--level http:debug,router:debug,connection:debug,pool:debug
# 로그 파일 저장 및 분석
kubectl logs -n istio-system -l app=istio-ingressgateway -f > istio-igw-log.txt
이러한 Envoy의 상세 로그는 서비스 프록시가 어떻게 동작하는지를 깊이 있게 보여주며,
복잡한 마이크로서비스 환경에서의 트러블슈팅 능력을 크게 향상시켜 줍니다.
실패한 요청 비율을 그라파나를 통해서 찾아보겠습니다.
Grafana - Istio Service 대시보드 ⇒ Service(catalog.istioinaction..) , Reporter(source) 선택
504 (Gateway Timeout)
으로 나타나며, 클라이언트 측 실패율로 집계됩니다.0
으로 처리하며, 이 응답은 서버 실패로 간주되지 않기 때문입니다.UT
, 상태 코드 504
→ 요청 제한 시간 초과DC
, 상태 코드 0
→ 다운스트림 연결 종료 감지이 차이로 인해 Grafana는 클라이언트에서는 실패율을 높게, 서버에서는 100% 성공으로 표시하게 됩니다.
Grafana 대시보드는 전체 서비스 수준의 정보를 제공하지만, 문제가 발생한 특정 파드를 정확히 식별하기엔 한계가 있습니다.
이럴 때는 Prometheus를 직접 쿼리하여 파드 단위의 세부 메트릭을 확인하는 것이 효과적입니다.
다음 조건을 만족하는 PromQL 쿼리를 통해 실패율이 높은 파드를 식별할 수 있습니다:
DC
(Downstream Connection termination)인 요청만 필터링sort_desc(
sum(
irate(
istio_requests_total{
reporter="destination",
destination_service=~"catalog.istioinaction.svc.cluster.local",
response_flags="DC"
}[5m]
)
) by (response_code, pod, version)
)
이 쿼리는 다음을 의미합니다:
위 결과는 단 하나의 catalog v2 파드만 DC 응답 플래그를 반복적으로 보고하고 있음을 보여줍니다.
이 특정 파드가 문제를 일으키는 인스턴스임을 정확히 확인할 수 있습니다.
Internal Architecture by Port : Istiod(컨트롤플레인) + Istio Proxy(데이터플레인) 도식화 - Blog
이스티오 사이드카에 포함된 에이전트(pilot-agent)는 트래픽 프록시 역할 외에도 다양한 디버깅/모니터링 기능을 제공합니다.
이 절에서는 에이전트와 관련된 포트와 엔드포인트를 실습을 통해 탐색하고, 이들을 활용한 트러블슈팅 방법을 다룹니다.
# 기존 리소스 삭제
kubectl delete -n istioinaction deploy,svc,gw,vs,dr,envoyfilter --all
# 샘플 애플리케이션 배포
kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
kubectl apply -f services/webapp/kubernetes/webapp.yaml -n istioinaction
kubectl apply -f services/webapp/istio/webapp-catalog-gw-vs.yaml -n istioinaction
# 정상 작동 확인
curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
# 반복 호출
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
이스티오 사이드카는 많은 기능을 제공합니다.
# 포트 확인
kubectl -n istioinaction exec -it deploy/webapp -c istio-proxy -- netstat -tnl
# 포트별 프로세스 확인
kubectl -n istioinaction exec -it deploy/webapp -c istio-proxy -- ss -tnlp
# 주요 포트 및 역할:
포트 프로세스 설명
15000 envoy Envoy 관리 인터페이스 (config dump 등)
15001 envoy 애플리케이션 → 외부로 나가는 트래픽
15006 envoy 외부 → 애플리케이션으로 들어오는 트래픽
15020 pilot-agent 메트릭, 헬스체크, 디버깅 등
15021 envoy Kubernetes readinessProbe 포트
15004 pilot-agent Istiod 디버깅 요청 라우팅
15090 envoy Prometheus 메트릭 노출
15053 pilot-agent 로컬 DNS 프록시
🔹 15020 포트 (pilot-agent)
/healthz/ready
: envoy 및 DNS 프록시 준비 상태 확인/stats/prometheus
: envoy + agent 메트릭 병합 출력/quitquitquit
: agent 프로세스 종료/app-health/<app>/livez
: 애플리케이션의 Liveness Probe 결과/debug/ndsz
: DNS 프록시 대상 호스트 이름 목록/debug/pprof/
: 성능/메모리 디버깅용 Go pprof# 예시: /app-health/ 연동 실습
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: liveness-http
namespace: istioinaction
spec:
selector:
matchLabels:
app: liveness-http
version: v1
template:
metadata:
labels:
app: liveness-http
version: v1
spec:
containers:
- name: liveness-http
image: docker.io/istio/health:example
ports:
- containerPort: 8001
livenessProbe:
httpGet:
path: /foo
port: 8001
initialDelaySeconds: 5
periodSeconds: 5
EOF
# 에이전트에서 쿠버네티스 liveness 프로브를 프록시로 라우팅
kubectl exec -n istioinaction deploy/liveness-http -c istio-proxy -- \
curl -s localhost:15020/app-health/liveness-http/livez -v
#
kubectl exec -n istioinaction deploy/webapp -c istio-proxy -- curl -s localhost:15020/healthz/ready -v
# webapp 워크로드의 병합된 통계 확인 : istio_agent로 시작하는 메트릭(에이전트에서 온 것) + envoy로 시작하는 메트릭(프록시에서 온 것)
kubectl exec -n istioinaction deploy/webapp -c istio-proxy -- curl -s localhost:15020/stats/prometheus
## 응답에서는 istio_agent로 시작하는 메트릭(에이전트에서 온 것)과 envoy로 시작하는 메트릭(프록시에서 온 것)을 볼 수 있는데,
## 이는 이 둘이 병합됐음을 보여준다.
#
kubectl exec -n istioinaction deploy/webapp -c istio-proxy -- curl -s localhost:15020/quitquitquit
#
kubectl exec -n istioinaction deploy/webapp -c istio-proxy -- curl -s localhost:15020/debug/ndsz
#
kubectl port-forward deploy/webapp -n istioinaction 15020:15020
open http://localhost:15020/debug/pprof # 혹은 웹 브라우저에서 열기
에이전트는 기본적으로 15004 포트에서 몇 가지 istiod 디버그 엔드포인트들을 노출하고 있습니다.
이 엔드포인트들에 한 요청은 xDS 이벤트 형태
로 안전하게 istiod로 전달되는데, 이는 에이전트에서 컨트롤 플레인으로의 연결 상태를 확인 할 수 있는 좋은 방법입니다.
이를 보려면, 프록시 중 하나의 셸 커넥션을 가져와서 파일럿 에이전트의 15004 포트에 /debug/sync
엔드포인트로 요청합니다.
#
kubectl exec -n istioinaction deploy/webapp -c istio-proxy -- curl -s localhost:15004/debug/syncz -v
kubectl exec -n istioinaction deploy/webapp -c istio-proxy -- curl -s localhost:15004/debug/syncz | jq
...
"@type": "type.googleapis.com/envoy.service.status.v3.ClientConfig",
"node": {
"id": "catalog-6cf4b97d-fbftr.istioinaction", # 워크로드 ID
"metadata": {
"CLUSTER_ID": "Kubernetes"
}
},
"genericXdsConfigs": [
{
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
"configStatus": "SYNCED" # xDS API는 최신 상태로 동기화됬다
},
{
"typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
"configStatus": "SYNCED" # xDS API는 최신 상태로 동기화됬다
},
{
"typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
"configStatus": "SYNCED" # xDS API는 최신 상태로 동기화됬다
},
{
"typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"configStatus": "SYNCED" # xDS API는 최신 상태로 동기화됬다
},
...
# 하위 명령 출력 내용과 동일
docker exec -it myk8s-control-plane istioctl x internal-debug -h
docker exec -it myk8s-control-plane istioctl x internal-debug syncz
이스티오의 컨트롤 플레인 구성요소인 파일럿(pilot) 은 전체 서비스 메시의 구성 상태를 관리하며,
이를 점검하고 디버깅하기 위한 다양한 정보를 외부에 노출합니다. 이 정보는 운영자뿐 아니라 외부 도구나 서비스에도 유용하게 활용될 수 있습니다.
# 포트 및 프로세스 확인
kubectl -n istio-system exec -it deploy/istiod -- netstat -tnl
kubectl -n istio-system exec -it deploy/istiod -- ss -tnlp
# Pod 내부 구성 확인
kubectl describe pod -n istio-system -l app=istiod
주요 포트 역할은 다음과 같습니다:
포트 기능 설명
15010 - xDS API 및 인증서를 평문(HTTP)으로 노출. 보안상 사용 지양
15012 - xDS API 및 인증서를 TLS로 보호. 상호 인증이 포함됨
15014 - 컨트롤 플레인 메트릭 노출
15017 - 쿠버네티스 API 서버와 연동되는 웹훅 서버. 사이드카 주입 및 Istio 리소스 검증
8080 - Istio 디버그 엔드포인트 (비보안, 민감 정보 주의)
9876 - 파일럿 내부 상태 확인용 ControlZ 관리자 인터페이스
이스티오의 파일럿(Pilot)은 클러스터 내 전체 서비스 메시 설정을 관리하는 컨트롤 플레인 구성 요소입니다.
이 파일럿은 디버깅 목적으로 여러 HTTP 기반의 디버그 엔드포인트를 노출하며, 이를 통해 운영자는 현재 설정된 서비스 메시 상태를 확인하고 프록시와의 동기화 여부, xDS API 상태 등을 조사할 수 있습니다.
이러한 엔드포인트는 다음과 같은 질문들에 대한 답을 제공합니다:
- 프록시는 동기화되었는가? (Are the proxies synchronized?)
- 프록시에 대한 마지막 설정 푸시는 언제 발생했는가? (When was the last push to a proxy performed?)
- xDS API의 구성 상태는 어떤가? (What’s the state of the xDS APIs?)
#
kubectl -n istio-system port-forward deploy/istiod 8080
open http://localhost:8080/debug
# 파일럿이 알고 있는 서비스 메시 상태
## 클러스터, 루트, 리스너 설정
curl -s http://localhost:8080/debug/adsz | jq
## 이 파일럿이 관리하는 모든 프록시에 대한 푸시를 트리거한다.
curl -s http://localhost:8080/debug/adsz?push=true
Pushed to 4 servers
## /debug/edsz=proxyID=<pod>.<namespace> : 프록시가 알고 있는 엔드포인트들
curl -s http://localhost:8080/debug/edsz=proxyID=webapp.istioninaction
## /debug/authorizationz : 네임스페이스에 적용되는 인가 정책 목록
curl -s http://localhost:8080/debug/authorizationz | jq
# 파일럿이 알고 있는 데이터 플레인 설정을 나타내는 엔드포인트
## 이 파일럿 인스턴스에 연결된 모든 엔보이의 버전 상태 : 현재 비활성화되어 있음
curl -s http://localhost:8080/debug/config_distribution
Pilot Version tracking is disabled. It may be enabled by setting the PILOT_ENABLE_CONFIG_DISTRIBUTION_TRACKING environment variable to true
## 이스티오 파일럿의 현재 알려진 상태에 따라 엔보이 설정을 생성한다.
curl -s http://localhost:8080/debug/config_dump?=proxyID=webapp.istioninaction
## 이 파일럿이 관리하는 프록시들을 표시한다.
curl -s http://localhost:8080/debug/syncz | jq
...
{
"cluster_id": "Kubernetes",
"proxy": "webapp-7685bcb84-lwsvj.istioinaction",
"istio_version": "1.17.8",
"cluster_sent": "ff5e6b2c-e857-4e12-b17e-46ad968567f4",
"cluster_acked": "ff5e6b2c-e857-4e12-b17e-46ad968567f4",
"listener_sent": "7280c908-010d-4788-807f-7138e74fe72e",
"listener_acked": "7280c908-010d-4788-807f-7138e74fe72e",
"route_sent": "2a1916c3-9c05-4ce5-8cfa-d777105b9205",
"route_acked": "2a1916c3-9c05-4ce5-8cfa-d777105b9205",
"endpoint_sent": "dffacd32-2674-4e39-8e76-17016ff32514",
"endpoint_acked": "dffacd32-2674-4e39-8e76-17016ff32514"
},
...
/debug/adsz
: 클러스터, 루트, 리스너 설정/debug/adsz?push=true
: 이 파일럿이 관리하는 모든 프록시에 대한 푸시를 트리거한다./debug/edsz=*proxyID*=*<pod>.<namespace>*
: 프록시가 알고 있는 엔드포인트들/debug/authorizationz
: 네임스페이스에 적용되는 인가 정책 목록/debug/config_distribution
: 이 파일럿 인스턴스에 연결된 모든 엔보이의 버전 상태/debug/config_dump?proxyID=<pod>.<namespace>
: 이스티오 파일럿의 현재 알려진 상태에 따라 엔보이 설정을 생성한다./debug/syncz
: 이 파일럿이 관리하는 프록시들을 표시한다.it shows the latest nonce sent to the proxy and the latest nonce acknowledged. When those are the same, the proxy has the latest configuration.
이스티오 파일럿에는 파일럿 프로세스의 현재 상태와 몇 가지 사소한 설정 가능성을 확인 할 수 있는 관리자 인터페이스가 함께 제공합니다.
이 인터페이스는 아래 표 D.1 에서 다룬 것 처럼 파일럿 인스턴스와 관련된 정보를 빠르게 조회할 수 있습니다.
페이지 | 설명 |
---|---|
로깅 범위 (Logging Scopes) | 이 프로세스에 대한 로깅은 범위별로 구성돼 있으며, 각 범위별로 로깅 단계를 별도로 설정할 수 있습니다. |
메모리 사용량 (Memory Usage) | Go 런타임에서 수집한 정보로, 해당 프로세스의 메모리 소비량을 나타냅니다. |
환경 변수 (Environment Variables) | 프로세스에 정의된 모든 환경 변수들의 집합을 확인할 수 있습니다. |
프로세스 정보 (Process Information) | 현재 실행 중인 파일럿 프로세스에 대한 기본 정보를 제공합니다. |
명령줄 인수 (Command-Line Arguments) | 이스티오 파일럿이 시작될 때 사용된 명령줄 인수 목록입니다. |
버전 정보 (Version Info) | 실행 중인 이스티오 바이너리의 버전과 함께 사용 중인 Go 런타임 버전 정보를 보여줍니다. |
메트릭 (Metrics) | 파일럿에서 수집되고 노출되는 메트릭 데이터를 확인할 수 있는 항목입니다. |
시그널 (Signals) | 실행 중인 프로세스에 SIGUSR1 등의 시그널을 직접 보낼 수 있는 제어 기능입니다. |
#
kubectl -n istio-system port-forward deploy/istiod 9876
open http://localhost:9876
Istio 환경에서는 네트워크 문제나 트래픽 설정 오류가 단순히 서비스 간 통신 장애로 그치지 않고, 비즈니스 영향으로 직결될 수 있는 민감한 요소가 됩니다.
이번 블로그에서 소개한 다양한 실습과 도구들은 그러한 장애를 조기에 탐지하고, 정확한 원인을 신속히 파악해 대응할 수 있도록 도와주는 무기입니다.
특히, 다음과 같은 핵심 관점을 갖는 것이 중요합니다:
- 문제 발생 시 컨트롤 플레인을 빠르게 배제하고 데이터 플레인 쪽 설정과 상태를 집중적으로 확인하라.
- Envoy의
proxy-config
명령, Grafana의 P99 지표, Prometheus 쿼리 등을 적절히 조합해 특정 파드/버전 단위로 원인을 좁혀 나가라.- Pilot과 Agent의 디버그 엔드포인트는 예외 상황에서 서비스 메시 내부의 실제 동작 상태를 깊이 파악하는 도구가 될 수 있다.
이러한 실습 경험은 단지 장애 대응 뿐 아니라, 서비스 메시 성능 개선 및 아키텍처 안정성 확보에도 중요한 기초 체력이 됩니다.