Search
Duplicate
📌

Istio Internals by port

Category
S/W 엔지니어
Tags
Istio
Kubernetes
Prometheus
Service Mesh
Created time
2024/05/01

Introduction

Istio가 노출하는 port 중심의 Istio의 내부 구조에 관한 기술로서, 사실 상 Istio in Action의 Appendix D에 대한 요약과 약간의 첨언이다.

Motivation

Istio 운영 시 troubleshooting까지 하려면 최소한 traffic 종류 별로 Istio 및 관련 시스템과의 연결 구조는 알아야 하겠다.

Internal Architecture by Port

초록색은 Kubernetes를, 푸른색은 Istio를, 노란색은 Prometheus를, 주황색은 app을 의미한다.
위 diagram에 대한 상세 내용은 아래에 이어진다. Istio component를 중심으로 설명한다.

istiod

Istio의 control plane으로 Pilot은 이에 대한 옛 이름이다(원래 용도에 따라 control plane은 pilot , citadel, gallery 등으로 나뉘었는데 istiod 로 합쳐졌다고). kubectl -n istio-system exec -it deploy/istiod -- netstat -tnl 명령으로 아래와 같은 port 확인이 가능하다.
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:9876 0.0.0.0:* LISTEN tcp6 0 0 :::15017 :::* LISTEN tcp6 0 0 :::15010 :::* LISTEN tcp6 0 0 :::15014 :::* LISTEN tcp6 0 0 :::15012 :::* LISTEN tcp6 0 0 :::8080 :::* LISTEN
Bash
복사
아래 이어지는 port 별 설명 중 각 항목 제목은 포트와 해당 port를 사용하는 client를 나타낸다.

8080: Kubelet, Debug

Kubelet은 /ready path로 istiod 의 readiness probing을 이룬다.
debug용 endpoint로 Kiali나 istioctl 가 사실 상 이 endpoint를 사용하는 듯. istioctl proxy-status~:8080/debug/syncz 을 사용하여 지정한 proxy가 sync 중인지를 확인한다고. 일부는 Istio sidecar의 15004 debug port로 redirect하여 sidecar에 대한 조회용으로 쓰이기도.
매우 다양한 API를 노출하는데 여기에서 다 논하기는 어렵다. kubectl exec -it -n {istiod namespace} {istiod podname} -- curl -i localhost:8080/debug 을 호출하면 HTML이 나오는데, 여기에 전체 목록이 있다.

9876: Admin

istiod process의 instrospection를 노출. istioctl dashboard controlz deployment/istiod.istio-system 에 사용된다고. Istio Introspection에 대해서는 다음 참고.

15010: Istio sidecar (plain text)

gRPC 기반으로 Istio sidecar와 각종 xDS configuration을 동기화한다(SDS의 certificate 포함. xDS는 Istiod 가 open하는 API로, Istio sidecar가 이들 API를 사용하여 자신의 configuration을 동적으로 수정한다. xDS에 대해서는 별도의 글로 다룬다.
plain text 기반이므로 보안에 취약하다.

15012: Istio sidecar (TLS, mTLS)

15010 과 동일 용도이나 TLS, mTLS 를 사용한다. 15010 을 대신하여 default로 사용된다.

15014: Prometheus

Prometheus의 scraping API를 노출하여 control plane의 metrics를 전한다.
다음은 metric 예로 kubectl exec -it -n istio-system deploy/istiod -- curl localhost:15014/metrics 의 호출 결과다(펼쳐야 보인다).

15017: Kubernetes API Server

Kubernetes API의 Mutating Admission Webhook을 통해 k8s API Server로부터 sidecar injection을 위한 pod creation event 및 Istio resource(e.g. Gateway, VirtualService) validation을 위한 event를 수신한다.
참고로, istiod는 이 webhook과 Kubernetes GET API의 watch=true parameter 설정을 통해 상시 Kubernetes와 state를 동기화한다. watch=truekubectl get pod -w-w 에 해당한다. 내부 구현은 아래 링크의 첫번째에서는 Chunked Transfer Encoding 또는 Websocket을 논하며, 두번째의 공식 문서에서는 Chunked Transfer Encoding만 논한다.
watch.go
handlers

Istio-init

Istio sidecar가 생성되기 전에 실행되는 Istio-init은 Istio sidecar가 위치할 pod의 Iptable rule을 설정한다. 이 rule을 따르는 path는 DNS query(from app to DNS proxy)를 포함한 app과 Envoy proxy 간 in/outbound traffic이다.

Istio sidecar

Istio sidecar는 내부적으로 Pilot agent, Envoy proxy 두 개의 process로, DNS proxy는 Pilot agent의 일부로 동작한다. kubectl -n {namespace} exec -it {podname} -c istio-proxy -- netstat -tnl 명령으로 아래와 같이 Istio sidecar가 노출은 port 확인이 가능하다.
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:15053 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:15004 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:15000 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:15021 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:15006 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:15001 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:15090 0.0.0.0:* LISTEN tcp6 0 0 :::80 :::* LISTEN tcp6 0 0 :::15020 :::* LISTEN
Bash
복사
아래 이어지는 port 별 설명 중 각 항목 제목은 포트와 해당 port를 사용하는 client를 나타낸다. 괄호 안은 해당 port를 노출하는 component 이다.

15000 (Envoy proxy): Admin

Envoy proxy의 administration interface port이다.
kubectl exec -n {namespace} {podname} -c istio-proxy -- curl http://localhost:15000/clusters?format=json 와 같은 방식로 호출 가능하다.

15001 (Envoy proxy): App container

Iptable rule에 의해 app의 outbound traffic이 이 port로 들어온다. 이후 해당 traffic을 destination service로 routing한다.

15004 (Envoy proxy): Debug

debugging용으로 istiod8080 과 동일 역할이다.

15006 (Envoy proxy): external services

Iptable rule에 의해 app으로의 inbound traffic이 redirect되고, 이후 이 traffic은 app의 해당 traffic port로 전달된다.

15020 (Pilot agent)

다수의 client가 각기 다른 목적으로 사용한다.
Prometheus: /stat/prometheus path로 scraping API를 노출하여 해당 sidecar 및 app의 metrics를 전한다. 이 request는 Envoy proxy의 15090 port로도 전달되어, 최종적으로 Envoy proxy의 metrics도 포함한 response를 전한다.
다음은 metrics 예로 kubectl -n cluster exec -it docserver-59f78d66f6-ldg79 -- curl localhost:15020/stats/prometheus 의 호출 결과로 Envoy proxy의 항목은 제외한 결과다(펼쳐야 보인다).
Non-Kubernetes worloads(e.g. VM): Envoy proxy와 DNS proxy 및 (설정할 경우) app에 대한 health checking 용도로, Kubernetes 이외의 workload에서 사용된다.
Debug: debugging용으로 istiod8080 과 동일 역할이다.
/healthz/ready: Envoy proxy와 DNS proxy의 health checking
/quitquitquit: Pilot agent 프로세스 삭제
/debug/ndsz: DNS proxy가 보유한 hostname 목록. istiod 의 NDS(Name Discovery Service) API를 통해 설정된 결과
/debug/pprof: Golang의 profiling endpoint. 하위 path로 다양한 항목을 조회 가능하며, 전체 목록은 root 호출을 통한 결과(HTML)을 통해 확인 가능. 상세 내용은 다음 참조.

15021 (Envoy proxy): Kubelet

Kubelet에 의한 readiness probing을 위한 Port. Envoy proxy는 이를 15020 port의 Pilot agent로 route하여 실제는 15020 에서의 health checking의 결과가 나간다.

15053 (DNS proxy): App container

Istio-init이 설정한 Iptable rule에 의해 App의 DNS lookup은 15053 port로 redirect되어 DNS proxy가 DNS lookup request를 처리한다.

15090 (DNS proxy): App container

Envoy의 Prometheus metrics를 노출한다. 여기에는 XDS, connection, HTTP, outlier, health check, circuit-breaker stats 등이 포함된다.
아래는 kubectl -n cluster exec -it docserver-59f78d66f6-ldg79 -- curl localhost:15090/stats/prometheus 호출 결과다(펼쳐야 보인다).