3.Istio Hands-on Study - 3주차 Traffic control, Resilience

김성중·2025년 4월 25일

Istio Hands-on Study

목록 보기
3/10

가시다(gasida) 님이 진행하는 Istio Hands-on Study 1기 과정을 참여하여 정리한 글입니다. 3주차는 Traffic control, Resilience 주제로 학습을 진행하였습니다

1. Fine-grained traffic routing

5장에서는 서비스 간 트래픽을 세밀하게 제어하는 방법에 대해 다룹니다.

  • 들어온 트래픽을 어디로 보낼지 (라우팅)을 VirtualService로 정의하고,
  • 새로운 버전으로의 트래픽 분할이나 미러링을 통해 점진적 배포와 안정성을 확보하며,
  • 외부 서비스와의 통신ServiceEntry로 통제하고,
  • 프록시의 스코프Sidecar 리소스로 제한하거나 조정하며,
  • 클러스터 외부에서의 접근Gateway를 통해 제어한다.

이런 구성들을 통해 Istio는 안정적이고 유연한 트래픽 관리를 가능하게 한다.

✅ 리소스에 대한 한 줄 요약

리소스한 줄 설명
VirtualService서비스에 대한 세부적인 트래픽 라우팅 규칙을 정의한다.
ServiceEntry클러스터 외부 서비스와의 통신을 허용하고 이를 제어한다.
Sidecar특정 네임스페이스 또는 워크로드의 프록시 설정 범위와 아웃바운드 제어를 구성한다.
Gateway클러스터 외부에서 내부로 들어오는 트래픽을 제어하는 진입 지점이다.
MeshConfigIstio 메시 전역 설정을 담은 기본 설정값들의 모음이다.

1.1 [실습 환경 구성] k8s(1.23.17) 배포 : NodePort(30000 HTTP, 30005 HTTPS)

#
git clone https://github.com/AcornPublishing/istio-in-action
cd istio-in-action/book-source-code-master
pwd # 각자 자신의 pwd 경로
code .

# 아래 extramounts 생략 시, myk8s-control-plane 컨테이너 sh/bash 진입 후 직접 git clone 가능
kind create cluster --name myk8s --image kindest/node:v1.23.17 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000 # Sample Application (istio-ingrssgateway) HTTP
    hostPort: 30000
  - containerPort: 30001 # Prometheus
    hostPort: 30001
  - containerPort: 30002 # Grafana
    hostPort: 30002
  - containerPort: 30003 # Kiali
    hostPort: 30003
  - containerPort: 30004 # Tracing
    hostPort: 30004
  - containerPort: 30005 # Sample Application (istio-ingrssgateway) HTTPS
    hostPort: 30005
  - containerPort: 30006 # TCP Route
    hostPort: 30006
  - containerPort: 30007 # kube-ops-view
    hostPort: 30007
  extraMounts: # 해당 부분 생략 가능
  - hostPath: /Users/sjkim/Labs/CloudNeta/istio/istio-in-action/book-source-code-master
 # 각자 자신의 pwd 경로로 설정
    containerPath: /istiobook
networking:
  podSubnet: 10.10.0.0/16
  serviceSubnet: 10.200.1.0/24
EOF

Creating cluster "myk8s" ...
 ✓ Ensuring node image (kindest/node:v1.23.17) 🖼 
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-myk8s"
You can now use your cluster with:

kubectl cluster-info --context kind-myk8s

Have a nice day! 👋

# 설치 확인
docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED              STATUS              PORTS                                                             NAMES
35c362211d0d   kindest/node:v1.23.17   "/usr/local/bin/entr…"   About a minute ago   Up About a minute   0.0.0.0:30000-30007->30000-30007/tcp, 127.0.0.1:55153->6443/tcp   myk8s-control-plane

# 노드에 기본 툴 설치
docker exec -it myk8s-control-plane sh -c 'apt update && apt install tree psmisc lsof wget bridge-utils net-tools dnsutils tcpdump ngrep iputils-ping git vim -y'

# (옵션) kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30007 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kube-ops-view   1/1     1            1           6m31s

NAME                                 READY   STATUS    RESTARTS   AGE
pod/kube-ops-view-79df45849b-92ksk   1/1     Running   0          6m31s

NAME                    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/kube-ops-view   NodePort   10.200.1.144   <none>        8080:30007/TCP   6m31s

NAME                      ENDPOINTS        AGE
endpoints/kube-ops-view   10.10.0.3:8080   6m31s

## kube-ops-view 접속 URL 확인
open "http://localhost:30007/#scale=1.5"
open "http://localhost:30007/#scale=1.3"

# (옵션) metrics-server
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm install metrics-server metrics-server/metrics-server --set 'args[0]=--kubelet-insecure-tls' -n kube-system
kubectl get all -n kube-system -l app.kubernetes.io/instance=metrics-server

1.2 [실습 환경 구성] istio 1.17.8 설치 (addon 필수) - Docs , Install , profile

# myk8s-control-plane 진입 후 설치 진행
docker exec -it myk8s-control-plane bash
-----------------------------------
# (옵션) 코드 파일들 마운트 확인
tree /istiobook/ -L 1
혹은
git clone ... /istiobook

# istioctl 설치
export ISTIOV=1.17.8
echo 'export ISTIOV=1.17.8' >> /root/.bashrc

curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV sh -
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
istioctl version --remote=false

# default 프로파일 컨트롤 플레인 배포
istioctl install --set profile=default -y

# 설치 확인 : istiod, istio-ingressgateway, crd 등
kubectl get istiooperators -n istio-system -o yaml
kubectl get all,svc,ep,sa,cm,secret,pdb -n istio-system
NAME                                       READY   STATUS    RESTARTS   AGE
pod/istio-ingressgateway-996bc6bb6-n6trq   1/1     Running   0          81s
pod/istiod-7df6ffc78d-fhwmc                1/1     Running   0          97s

NAME                           TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                      AGE
service/istio-ingressgateway   LoadBalancer   10.200.1.172   <pending>     15021:32112/TCP,80:31965/TCP,443:30838/TCP   80s
service/istiod                 ClusterIP      10.200.1.182   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        97s

NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/istio-ingressgateway   1/1     1            1           81s
deployment.apps/istiod                 1/1     1            1           97s

NAME                                             DESIRED   CURRENT   READY   AGE
replicaset.apps/istio-ingressgateway-996bc6bb6   1         1         1       81s
replicaset.apps/istiod-7df6ffc78d                1         1         1       97s

NAME                                                       REFERENCE                         TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/istio-ingressgateway   Deployment/istio-ingressgateway   7%/80%    1         5         1          80s
horizontalpodautoscaler.autoscaling/istiod                 Deployment/istiod                 0%/80%    1         5         1          97s

NAME                             ENDPOINTS                                                     AGE
endpoints/istio-ingressgateway   10.10.0.8:15021,10.10.0.8:8080,10.10.0.8:8443                 80s
endpoints/istiod                 10.10.0.7:15012,10.10.0.7:15010,10.10.0.7:15017 + 1 more...   97s

NAME                                                  SECRETS   AGE
serviceaccount/default                                1         98s
serviceaccount/istio-ingressgateway-service-account   1         81s
serviceaccount/istio-reader-service-account           1         98s
serviceaccount/istiod                                 1         97s
serviceaccount/istiod-service-account                 1         98s

NAME                                            DATA   AGE
configmap/istio                                 2      97s
configmap/istio-ca-root-cert                    1      82s
configmap/istio-gateway-deployment-leader       0      83s
configmap/istio-gateway-status-leader           0      83s
configmap/istio-leader                          0      83s
configmap/istio-namespace-controller-election   0      82s
configmap/istio-sidecar-injector                2      97s
configmap/kube-root-ca.crt                      1      98s

NAME                                                      TYPE                                  DATA   AGE
secret/default-token-mt7sx                                kubernetes.io/service-account-token   3      98s
secret/istio-ca-secret                                    istio.io/ca-root                      5      83s
secret/istio-ingressgateway-service-account-token-q82j8   kubernetes.io/service-account-token   3      81s
secret/istio-reader-service-account-token-hwmrs           kubernetes.io/service-account-token   3      98s
secret/istiod-service-account-token-x7bk2                 kubernetes.io/service-account-token   3      98s
secret/istiod-token-kmnq7                                 kubernetes.io/service-account-token   3      97s

NAME                                              MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
poddisruptionbudget.policy/istio-ingressgateway   1               N/A               0                     81s
poddisruptionbudget.policy/istiod                 1               N/A               0                     97s

kubectl get cm -n istio-system istio -o yaml
kubectl get crd | grep istio.io | sort
NAME                                              MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
poddisruptionbudget.policy/istio-ingressgateway   1               N/A               0                     81s
poddisruptionbudget.policy/istiod                 1               N/A               0                     97s
root@myk8s-control-plane:/# kubectl get crd | grep istio.io | sort
authorizationpolicies.security.istio.io    2025-04-26T06:39:16Z
destinationrules.networking.istio.io       2025-04-26T06:39:16Z
envoyfilters.networking.istio.io           2025-04-26T06:39:16Z
gateways.networking.istio.io               2025-04-26T06:39:16Z
istiooperators.install.istio.io            2025-04-26T06:39:16Z
peerauthentications.security.istio.io      2025-04-26T06:39:16Z
proxyconfigs.networking.istio.io           2025-04-26T06:39:16Z
requestauthentications.security.istio.io   2025-04-26T06:39:16Z
serviceentries.networking.istio.io         2025-04-26T06:39:16Z
sidecars.networking.istio.io               2025-04-26T06:39:16Z
telemetries.telemetry.istio.io             2025-04-26T06:39:16Z
virtualservices.networking.istio.io        2025-04-26T06:39:16Z
wasmplugins.extensions.istio.io            2025-04-26T06:39:16Z
workloadentries.networking.istio.io        2025-04-26T06:39:16Z
workloadgroups.networking.istio.io         2025-04-26T06:39:16Z

# 보조 도구 설치
kubectl apply -f istio-$ISTIOV/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

kubectl get pod -n istio-system
grafana-b854c6c8-87bw8                 1/1     Running   0          86s
istio-ingressgateway-996bc6bb6-n6trq   1/1     Running   0          3m46s
istiod-7df6ffc78d-fhwmc                1/1     Running   0          4m2s
jaeger-5556cd8fcf-v9n2x                1/1     Running   0          86s
kiali-648847c8c4-mnwfb                 1/1     Running   0          86s
prometheus-7b8b9dd44c-8jqrb            2/2     Running   0          86s

# 빠져나오기
exit
-----------------------------------

# 실습을 위한 네임스페이스 설정
kubectl create ns istioinaction
kubectl label namespace istioinaction istio-injection=enabled
kubectl get ns --show-labels

# istio-ingressgateway 서비스 : NodePort 변경 및 nodeport 지정 변경 , externalTrafficPolicy 설정 (ClientIP 수집)
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 8080, "nodePort": 30000}]}}'
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 443, "targetPort": 8443, "nodePort": 30005}]}}'
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"externalTrafficPolicy": "Local"}}'
kubectl describe svc -n istio-system istio-ingressgateway

# NodePort 변경 및 nodeport 30001~30003으로 변경 : prometheus(30001), grafana(30002), kiali(30003), tracing(30004)
kubectl patch svc -n istio-system prometheus -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 30001}]}}'
kubectl patch svc -n istio-system grafana -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "targetPort": 3000, "nodePort": 30002}]}}'
kubectl patch svc -n istio-system kiali -p '{"spec": {"type": "NodePort", "ports": [{"port": 20001, "targetPort": 20001, "nodePort": 30003}]}}'
kubectl patch svc -n istio-system tracing -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 16686, "nodePort": 30004}]}}'

# Prometheus 접속 : envoy, istio 메트릭 확인
open http://127.0.0.1:30001

# Grafana 접속
open http://127.0.0.1:30002

# Kiali 접속 1 : NodePort
open http://127.0.0.1:30003

# (옵션) Kiali 접속 2 : Port forward
kubectl port-forward deployment/kiali -n istio-system 20001:20001 &
open http://127.0.0.1:20001

# tracing 접속 : 예거 트레이싱 대시보드
open http://127.0.0.1:30004


# 내부 접속 테스트용 netshoot 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: netshoot
spec:
  containers:
  - name: netshoot
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

1.3 🚀 배포(Deployment)와 릴리스(Release)의 차이

DevOps, MSA, 그리고 서비스 운영을 하다 보면 "배포"와 "릴리스"를 비슷하게 쓰는 경우가 많다. 하지만 이 둘은 실제로 다루는 범위와 목적이 다르다.

배포는 코드를 서버에 올리는 것, 릴리스는 사용자에게 기능을 오픈하는 것이다.

📦 배포(Deployment)란?

배포는 새로운 버전의 코드, 바이너리, 애플리케이션을 운영 환경(Production)에 설치하거나 배치하는 과정을 말한다.

  • 코드나 컨테이너가 서버에 올라감
  • 하지만 이 시점에 모든 사용자가 이 변화를 보는 것은 아니다
  • 배포는 기술적인 과정이다

예시: 새로운 버전의 백엔드 API를 서버에 배포했지만, 아직 모든 트래픽을 보내진 않은 상태

🌟 릴리스(Release)란?

릴리스는 운영 환경에 배포된 버전을 사용자가 실제로 사용할 수 있게 하는 과정이다.

  • 실제로 사용자에게 새로운 기능이 노출된다
  • 점진적 노출(카나리 릴리스, 블루그린, A/B 테스트 등)이 가능하다
  • 릴리스는 비즈니스적 이벤트

예시: 일부 사용자(5%)에게만 새로운 기능을 오픈하고 문제 없으면 점진적으로 전체 공개하는 것

1.4 🛠 배포와 릴리스를 분리하는 이유

과거에는 "배포 = 릴리스"였다. 하지만 현대 소프트웨어에서는 이 둘을 분리해서 다음과 같은 이점을 얻는다:

  • 리스크 최소화: 문제가 발생해도 롤백 없이 트래픽만 돌리면 된다
  • 빠른 배포: 배포는 미리 해두고 릴리스는 비즈니스 일정에 맞춰 진행할 수 있다
  • A/B 테스트: 특정 그룹에만 기능을 공개하여 데이터 기반 검증 가능
  • 안정성 확보: 장애 발생 시 빠른 차단(릴리스 롤백)이 가능하다

1.5 실습

1.5.1 VirtualService란?

VirtualService는 요청을 어떤 서비스의 어떤 버전(서브셋)으로 보낼지 정의하는 Istio 리소스다.

🔧 주요 기능

  • 트래픽 분할 (예: 90%는 v1, 10%는 v2)
  • 조건부 라우팅 (예: 특정 헤더, 경로, 쿠키에 따라)
  • A/B 테스트
  • 카나리 릴리스
  • HTTP, gRPC, TCP 라우팅 지원

1.5.2 Deploying v1 of the catalog service

# Let’s deploy v1 of our catalog service. From the root of the book’s source code, run the following command
kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
serviceaccount/catalog created
service/catalog created
deployment.apps/catalog created

# 확인
kubectl get pod -n istioinaction -owide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE                  NOMINATED NODE   READINESS GATES
catalog-6cf4b97d-5hwg7   2/2     Running   0          26s   10.10.0.14   myk8s-control-plane   <none>           <none>

# 도메인 질의를 위한 임시 설정 : 실습 완료 후에는 삭제 해둘 것
echo "127.0.0.1       catalog.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 1
127.0.0.1       catalog.istioinaction.io

# netshoot로 내부에서 catalog 접속 확인
kubectl exec -it netshoot -- curl -s http://catalog.istioinaction/items | jq
[
  {
    "id": 1,
    "color": "amber",
    "department": "Eyewear",
    "name": "Elinor Glasses",
    "price": "282.00"
  },
  {
    "id": 2,
    "color": "cyan",
    "department": "Clothing",
    "name": "Atlas Shirt",
    "price": "127.00"
  },
  {
    "id": 3,
    "color": "teal",
    "department": "Clothing",
    "name": "Small Metal Shoes",
    "price": "232.00"
  },
  {
    "id": 4,
    "color": "red",
    "department": "Watches",
    "name": "Red Dragon Watch",
    "price": "232.00"
  }
]

# 외부 노출을 위해 Gateway 설정
cat ch5/catalog-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: catalog-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "catalog.istioinaction.io"
    
kubectl apply -f ch5/catalog-gateway.yaml -n istioinaction

# 트래픽을 catalog 서비스로 라우팅하는 VirtualService 리소스 설정
cat ch5/catalog-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: catalog-vs-from-gw
spec:
  hosts:
  - "catalog.istioinaction.io"
  gateways:
  - catalog-gateway
  http:
  - route:
    - destination:
        host: catalog

kubectl apply -f ch5/catalog-vs.yaml -n istioinaction

# 확인
kubectl get gw,vs -n istioinaction
NAME                                          AGE
gateway.networking.istio.io/catalog-gateway   93s

NAME                                                    GATEWAYS              HOSTS                          AGE
virtualservice.networking.istio.io/catalog-vs-from-gw   ["catalog-gateway"]   ["catalog.istioinaction.io"]   10s

# 도메인 질의를 위한 임시 설정 : 실습 완료 후에는 삭제 해둘 것
echo "127.0.0.1       catalog.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 2


# istio-ingressgateway Service(NodePort)에 포트 정보 확인
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath="{.spec.ports}" | jq
[
  {
    "name": "status-port",
    "nodePort": 32112,
    "port": 15021,
    "protocol": "TCP",
    "targetPort": 15021
  },
  {
    "name": "http2",
    "nodePort": 30000, # 순서1
    "port": 80,        
    "protocol": "TCP",
    "targetPort": 8080 # 순서2
  },
  {
    "name": "https",
    "nodePort": 30005,
    "port": 443,
    "protocol": "TCP",
    "targetPort": 8443
  }
]

# 호스트에서 NodePort(Service)로 접속 확인
curl -v -H "Host: catalog.istioinaction.io" http://localhost:30000
* Host localhost:30000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:30000...
* Connected to localhost (::1) port 30000
* using HTTP/1.x
> GET / HTTP/1.1
> Host: catalog.istioinaction.io
> User-Agent: curl/8.13.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< x-powered-by: Express
< vary: Origin, Accept-Encoding
< access-control-allow-credentials: true
< accept-ranges: bytes
< cache-control: public, max-age=0
< last-modified: Sat, 26 Oct 1985 08:15:00 GMT
< etag: W/"46f-7438674ba0"
< content-type: text/html; charset=UTF-8
< content-length: 1135
< date: Sat, 26 Apr 2025 08:36:44 GMT
< x-envoy-upstream-service-time: 28
< server: istio-envoy
< 
<html>

<head>
  <title>JSON Server</title>
<link rel="shortcut icon" href="favicon.ico"><link href="main.css" rel="stylesheet"></head>

<body>
  <header>
    <div class="container">
      <h3>JSON Server</h3>
    </div>
  </header>
  <main>
    <div class="container">
      <h4>Congrats!</h4>
      <p>
        You're successfully running JSON Server
        <br> ✧*。٩(ˊᗜˋ*)و✧*。
      </p>

      <div id="resources"></div>

      <p>
        To access and modify resources, you can use any HTTP method
        <br>
        <code>GET</code>
        <code>POST</code>
        <code>PUT</code>
        <code>PATCH</code>
        <code>DELETE</code>
        <code>OPTIONS</code>
      </p>

      <div id="custom-routes"></div>

      <h4>Documentation</h4>
      <p>
        View
        <a href="https://github.com/typicode/json-server">README</a>
      </p>
    </div>
  </main>

  <footer>
    <div class="container">
      <p>
        To replace this page, create a
        <code>./public/index.html</code> file.
      </p>
    </div>
  </footer>
<script type="text/javascript" src="main.js"></script></body>
</html>

kubectl stern -l app=catalog -n istioinaction
+ catalog-6cf4b97d-5hwg7 › catalog
+ catalog-6cf4b97d-5hwg7 › istio-init
+ catalog-6cf4b97d-5hwg7 › istio-proxy
catalog-6cf4b97d-5hwg7 catalog JSON Server is running
catalog-6cf4b97d-5hwg7 catalog request path: /items
catalog-6cf4b97d-5hwg7 catalog blowups: {}
catalog-6cf4b97d-5hwg7 catalog number of blowups: 0
catalog-6cf4b97d-5hwg7 catalog GET catalog.istioinaction /items 200 502 - 2.367 ms
catalog-6cf4b97d-5hwg7 catalog GET /items 200 2.367 ms - 502
catalog-6cf4b97d-5hwg7 catalog GET catalog.istioinaction.io / 200 1135 - 6.165 ms
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164205Z  info    FLAG: --concurrency="2"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164222Z  info    FLAG: --domain="istioinaction.svc.cluster.local"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164225Z  info    FLAG: --help="false"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164226Z  info    FLAG: --log_as_json="false"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164227Z  info    FLAG: --log_caller=""
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164228Z  info    FLAG: --log_output_level="default:info"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164229Z  info    FLAG: --log_rotate=""
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164230Z  info    FLAG: --log_rotate_max_age="30"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164231Z  info    FLAG: --log_rotate_max_backups="1000"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164232Z  info    FLAG: --log_rotate_max_size="104857600"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164233Z  info    FLAG: --log_stacktrace_level="default:none"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164235Z  info    FLAG: --log_target="[stdout]"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164236Z  info    FLAG: --meshConfig="./etc/istio/config/mesh"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164237Z  info    FLAG: --outlierLogPath=""
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164239Z  info    FLAG: --proxyComponentLogLevel="misc:error"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164240Z  info    FLAG: --proxyLogLevel="warning"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164241Z  info    FLAG: --serviceCluster="istio-proxy"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164242Z  info    FLAG: --stsPort="0"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164243Z  info    FLAG: --templateFile=""
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164244Z  info    FLAG: --tokenManagerPlugin="GoogleTokenExchange"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164245Z  info    FLAG: --vklog="0"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.164246Z  info    Version 1.17.8-a781f9ee6c511d8f22140d8990c31e577b2a9676-Clean
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.165342Z  info    Maximum file descriptors (ulimit -n): 1048576
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.165476Z  info    Proxy role      ips=[10.10.0.14] type=sidecar id=catalog-6cf4b97d-5hwg7.istioinaction domain=istioinaction.svc.cluster.local
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.165524Z  info    Apply proxy config from env {}
catalog-6cf4b97d-5hwg7 istio-proxy 
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.166553Z  info    Effective config: binaryPath: /usr/local/bin/envoy
catalog-6cf4b97d-5hwg7 istio-proxy concurrency: 2
catalog-6cf4b97d-5hwg7 istio-proxy configPath: ./etc/istio/proxy
catalog-6cf4b97d-5hwg7 istio-proxy controlPlaneAuthPolicy: MUTUAL_TLS
catalog-6cf4b97d-5hwg7 istio-proxy discoveryAddress: istiod.istio-system.svc:15012
catalog-6cf4b97d-5hwg7 istio-proxy drainDuration: 45s
catalog-6cf4b97d-5hwg7 istio-proxy proxyAdminPort: 15000
catalog-6cf4b97d-5hwg7 istio-proxy serviceCluster: istio-proxy
catalog-6cf4b97d-5hwg7 istio-proxy statNameLength: 189
catalog-6cf4b97d-5hwg7 istio-proxy statusPort: 15020
catalog-6cf4b97d-5hwg7 istio-proxy terminationDrainDuration: 5s
catalog-6cf4b97d-5hwg7 istio-proxy tracing:
catalog-6cf4b97d-5hwg7 istio-proxy   zipkin:
catalog-6cf4b97d-5hwg7 istio-proxy     address: zipkin.istio-system:9411
catalog-6cf4b97d-5hwg7 istio-proxy 
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:40.997431Z   info    Istio iptables environment:
catalog-6cf4b97d-5hwg7 istio-init ENVOY_PORT=
catalog-6cf4b97d-5hwg7 istio-init INBOUND_CAPTURE_PORT=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_INBOUND_INTERCEPTION_MODE=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_INBOUND_TPROXY_ROUTE_TABLE=
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.166563Z  info    JWT policy is third-party-jwt
catalog-6cf4b97d-5hwg7 istio-init ISTIO_INBOUND_PORTS=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_OUTBOUND_PORTS=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_LOCAL_EXCLUDE_PORTS=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_EXCLUDE_INTERFACES=
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.166565Z  info    using credential fetcher of JWT type in cluster.local trust domain
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.367954Z  info    Workload SDS socket not found. Starting Istio SDS Server
catalog-6cf4b97d-5hwg7 istio-init ISTIO_SERVICE_CIDR=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_SERVICE_EXCLUDE_CIDR=
catalog-6cf4b97d-5hwg7 istio-init ISTIO_META_DNS_CAPTURE=
catalog-6cf4b97d-5hwg7 istio-init INVALID_DROP=
catalog-6cf4b97d-5hwg7 istio-init 
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.367993Z  info    CA Endpoint istiod.istio-system.svc:15012, provider Citadel
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.368006Z  info    Using CA istiod.istio-system.svc:15012 cert with certs: var/run/secrets/istio/root-cert.pem
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.367939Z  info    Opening status port 15020
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.376814Z  info    ads     All caches have been synced up in 215.203667ms, marking server ready
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.377027Z  info    xdsproxy        Initializing with upstream address "istiod.istio-system.svc:15012" and cluster "Kubernetes"
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.377246Z  info    sds     Starting SDS grpc server
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.378197Z  info    Pilot SAN: [istiod.istio-system.svc]
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.378238Z  info    starting Http service at 127.0.0.1:15004
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.378816Z  info    Starting proxy agent
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.378840Z  info    starting
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.378852Z  info    Envoy command: [-c etc/istio/proxy/envoy-rev.json --drain-time-s 45 --drain-strategy immediate --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --allow-unknown-static-fields --log-format %Y-%m-%dT%T.%fZ %l      envoy %n %g:%#  %v      thread=%t -l warning --component-log-level misc:error --concurrency 2]
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.423014Z  info    xdsproxy        connected to upstream XDS server: istiod.istio-system.svc:15012
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.433838Z  info    ads     ADS: new connection for node:catalog-6cf4b97d-5hwg7.istioinaction-1
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.433916Z  info    ads     ADS: new connection for node:catalog-6cf4b97d-5hwg7.istioinaction-2
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444446Z  info    cache   generated new workload certificate      latency=67.201709ms ttl=23h59m59.555560656s
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444462Z  info    cache   Root cert has changed, start rotating root cert
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:40.997477Z   info    Istio iptables variables:
catalog-6cf4b97d-5hwg7 istio-init PROXY_PORT=15001
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444469Z  info    ads     XDS: Incremental Pushing:0 ConnectedEndpoints:2 Version:
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444490Z  info    cache   returned workload trust anchor from cache       ttl=23h59m59.555511031s
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444508Z  info    cache   returned workload trust anchor from cache       ttl=23h59m59.555491864s
catalog-6cf4b97d-5hwg7 istio-init PROXY_INBOUND_CAPTURE_PORT=15006
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444656Z  info    ads     SDS: PUSH request for node:catalog-6cf4b97d-5hwg7.istioinaction resources:1 size:1.1kB resource:ROOTCA
catalog-6cf4b97d-5hwg7 istio-init PROXY_TUNNEL_PORT=15008
catalog-6cf4b97d-5hwg7 istio-init PROXY_UID=1337
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444682Z  info    cache   returned workload trust anchor from cache       ttl=23h59m59.555318822s
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444700Z  info    cache   returned workload certificate from cache        ttl=23h59m59.555300739s
catalog-6cf4b97d-5hwg7 istio-init PROXY_GID=1337
catalog-6cf4b97d-5hwg7 istio-init INBOUND_INTERCEPTION_MODE=REDIRECT
catalog-6cf4b97d-5hwg7 istio-init INBOUND_TPROXY_MARK=1337
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:53.444741Z  info    ads     SDS: PUSH request for node:catalog-6cf4b97d-5hwg7.istioinaction resources:1 size:4.0kB resource:default
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:54.857115Z  info    Readiness succeeded in 1.699475209s
catalog-6cf4b97d-5hwg7 istio-init INBOUND_TPROXY_ROUTE_TABLE=133
catalog-6cf4b97d-5hwg7 istio-proxy 2025-04-26T08:21:54.857713Z  info    Envoy proxy is ready
catalog-6cf4b97d-5hwg7 istio-init INBOUND_PORTS_INCLUDE=*
catalog-6cf4b97d-5hwg7 istio-init INBOUND_PORTS_EXCLUDE=15090,15021,15020
catalog-6cf4b97d-5hwg7 istio-init OUTBOUND_OWNER_GROUPS_INCLUDE=*
catalog-6cf4b97d-5hwg7 istio-init OUTBOUND_OWNER_GROUPS_EXCLUDE=
catalog-6cf4b97d-5hwg7 istio-init OUTBOUND_IP_RANGES_INCLUDE=*
catalog-6cf4b97d-5hwg7 istio-init OUTBOUND_IP_RANGES_EXCLUDE=
catalog-6cf4b97d-5hwg7 istio-init OUTBOUND_PORTS_INCLUDE=
catalog-6cf4b97d-5hwg7 istio-init OUTBOUND_PORTS_EXCLUDE=
catalog-6cf4b97d-5hwg7 istio-init KUBE_VIRT_INTERFACES=
catalog-6cf4b97d-5hwg7 istio-init ENABLE_INBOUND_IPV6=false
catalog-6cf4b97d-5hwg7 istio-init DNS_CAPTURE=false
catalog-6cf4b97d-5hwg7 istio-init DROP_INVALID=false
catalog-6cf4b97d-5hwg7 istio-init CAPTURE_ALL_DNS=false
catalog-6cf4b97d-5hwg7 istio-init DNS_SERVERS=[],[]
catalog-6cf4b97d-5hwg7 istio-init NETWORK_NAMESPACE=
catalog-6cf4b97d-5hwg7 istio-init CNI_MODE=false
catalog-6cf4b97d-5hwg7 istio-init HOST_NSENTER_EXEC=false
catalog-6cf4b97d-5hwg7 istio-init EXCLUDE_INTERFACES=
catalog-6cf4b97d-5hwg7 istio-init 
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:40.997520Z   info    Running iptables-restore with the following input:
catalog-6cf4b97d-5hwg7 istio-init * nat
catalog-6cf4b97d-5hwg7 istio-init -N ISTIO_INBOUND
catalog-6cf4b97d-5hwg7 istio-init -N ISTIO_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -N ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -N ISTIO_OUTPUT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp --dport 15008 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006
catalog-6cf4b97d-5hwg7 istio-init -A PREROUTING -p tcp -j ISTIO_INBOUND
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp --dport 15090 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp --dport 15021 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp --dport 15020 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A OUTPUT -p tcp -j ISTIO_OUTPUT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo -s 127.0.0.6/32 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo ! -d 127.0.0.1/32 -m owner --uid-owner 1337 -j ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo -m owner ! --uid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo ! -d 127.0.0.1/32 -m owner --gid-owner 1337 -j ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo -m owner ! --gid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -j ISTIO_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init COMMIT
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:40.997525Z   info    Running command: iptables-restore --noflush
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:41.001598Z   info    Running ip6tables-restore with the following input:
catalog-6cf4b97d-5hwg7 istio-init 
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:41.001611Z   info    Running command: ip6tables-restore --noflush
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:41.001979Z   info    Running command: iptables-save 
catalog-6cf4b97d-5hwg7 istio-init 2025-04-26T08:21:41.002598Z   info    Command output: 
catalog-6cf4b97d-5hwg7 istio-init # Generated by iptables-save v1.8.7 on Sat Apr 26 08:21:41 2025
catalog-6cf4b97d-5hwg7 istio-init *nat
catalog-6cf4b97d-5hwg7 istio-init :PREROUTING ACCEPT [0:0]
catalog-6cf4b97d-5hwg7 istio-init :INPUT ACCEPT [0:0]
catalog-6cf4b97d-5hwg7 istio-init :OUTPUT ACCEPT [0:0]
catalog-6cf4b97d-5hwg7 istio-init :POSTROUTING ACCEPT [0:0]
catalog-6cf4b97d-5hwg7 istio-init :ISTIO_INBOUND - [0:0]
catalog-6cf4b97d-5hwg7 istio-init :ISTIO_IN_REDIRECT - [0:0]
catalog-6cf4b97d-5hwg7 istio-init :ISTIO_OUTPUT - [0:0]
catalog-6cf4b97d-5hwg7 istio-init :ISTIO_REDIRECT - [0:0]
catalog-6cf4b97d-5hwg7 istio-init -A PREROUTING -p tcp -j ISTIO_INBOUND
catalog-6cf4b97d-5hwg7 istio-init -A OUTPUT -p tcp -j ISTIO_OUTPUT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp -m tcp --dport 15008 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp -m tcp --dport 15090 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp -m tcp --dport 15021 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp -m tcp --dport 15020 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --uid-owner 1337 -j ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo -m owner ! --uid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --gid-owner 1337 -j ISTIO_IN_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -o lo -m owner ! --gid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_OUTPUT -j ISTIO_REDIRECT
catalog-6cf4b97d-5hwg7 istio-init -A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001
catalog-6cf4b97d-5hwg7 istio-init COMMIT
catalog-6cf4b97d-5hwg7 istio-init # Completed on Sat Apr 26 08:21:41 2025
catalog-6cf4b97d-5hwg7 istio-init 
- catalog-6cf4b97d-5hwg7 › istio-init

open http://localhost:30000  ⛔️ 접속 불가
open http://catalog.istioinaction.io:30000
open http://catalog.istioinaction.io:30000/items

# 신규 터미널 : 반복 접속 실행 해두기
while true; do curl -s http://catalog.istioinaction.io:30000/items/ ; sleep 1; echo; done
while true; do curl -s http://catalog.istioinaction.io:30000/items/ -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
while true; do curl -s http://catalog.istioinaction.io:30000/items/ -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 0.5; echo; done

  • 상세 정보 확인

#
docker exec -it myk8s-control-plane istioctl proxy-status
NAME                                                  CLUSTER        CDS        LDS        EDS        RDS        ECDS         ISTIOD                      VERSION
catalog-6cf4b97d-5hwg7.istioinaction                  Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-7df6ffc78d-fhwmc     1.17.8
istio-ingressgateway-996bc6bb6-n6trq.istio-system     Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-7df6ffc78d-fhwmc     1.17.8

# istio-ingressgateway
## LDS - Listener Discovery Service
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway.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*

docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway.istio-system --port 8080
ADDRESS PORT MATCH DESTINATION
0.0.0.0 8080 ALL   Route: http.8080

docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway.istio-system --port 8080 -o json
[
    {
        "name": "0.0.0.0_8080",
        "address": {
            "socketAddress": {
                "address": "0.0.0.0",
                "portValue": 8080
            }
        },
        "filterChains": [
            {
                "filters": [
                    {
                        "name": "istio_authn",
                        "typedConfig": {
                            "@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
                            "typeUrl": "type.googleapis.com/io.istio.network.authn.Config"
                        }
                    },
                    {
                        "name": "envoy.filters.network.http_connection_manager",
                        "typedConfig": {
                            "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
                            "statPrefix": "outbound_0.0.0.0_8080",
                            "rds": {
                                "configSource": {
                                    "ads": {},
                                    "initialFetchTimeout": "0s",
                                    "resourceApiVersion": "V3"
                                },
                                "routeConfigName": "http.8080"
                            },
                            "httpFilters": [
                                {
                                    "name": "istio.metadata_exchange",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm",
                                        "config": {
                                            "vmConfig": {
                                                "runtime": "envoy.wasm.runtime.null",
                                                "code": {
                                                    "local": {
                                                        "inlineString": "envoy.wasm.metadata_exchange"
                                                    }
                                                }
                                            },
                                            "configuration": {
                                                "@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange"
                                            }
                                        }
                                    }
                                },
                                {
                                    "name": "envoy.filters.http.grpc_stats",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig",
                                        "emitFilterState": true,
                                        "statsForAllMethods": false
                                    }
                                },
                                {
                                    "name": "istio.alpn",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/istio.envoy.config.filter.http.alpn.v2alpha1.FilterConfig",
                                        "alpnOverride": [
                                            {
                                                "alpnOverride": [
                                                    "istio-http/1.0",
                                                    "istio",
                                                    "http/1.0"
                                                ]
                                            },
                                            {
                                                "upstreamProtocol": "HTTP11",
                                                "alpnOverride": [
                                                    "istio-http/1.1",
                                                    "istio",
                                                    "http/1.1"
                                                ]
                                            },
                                            {
                                                "upstreamProtocol": "HTTP2",
                                                "alpnOverride": [
                                                    "istio-h2",
                                                    "istio",
                                                    "h2"
                                                ]
                                            }
                                        ]
                                    }
                                },
                                {
                                    "name": "envoy.filters.http.fault",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault"
                                    }
                                },
                                {
                                    "name": "envoy.filters.http.cors",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors"
                                    }
                                },
                                {
                                    "name": "istio.stats",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/udpa.type.v1.TypedStruct",
                                        "typeUrl": "type.googleapis.com/stats.PluginConfig",
                                        "value": {
                                            "disable_host_header_fallback": true
                                        }
                                    }
                                },
                                {
                                    "name": "envoy.filters.http.router",
                                    "typedConfig": {
                                        "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
                                    }
                                }
                            ],
                            "tracing": {
                                "clientSampling": {
                                    "value": 100
                                },
                                "randomSampling": {
                                    "value": 1
                                },
                                "overallSampling": {
                                    "value": 100
                                },
                                "customTags": [
                                    {
                                        "tag": "istio.authorization.dry_run.allow_policy.name",
                                        "metadata": {
                                            "kind": {
                                                "request": {}
                                            },
                                            "metadataKey": {
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
                                                        "key": "istio_dry_run_allow_shadow_effective_policy_id"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
                                        "tag": "istio.authorization.dry_run.allow_policy.result",
                                        "metadata": {
                                            "kind": {
                                                "request": {}
                                            },
                                            "metadataKey": {
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
                                                        "key": "istio_dry_run_allow_shadow_engine_result"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
                                        "tag": "istio.authorization.dry_run.deny_policy.name",
                                        "metadata": {
                                            "kind": {
                                                "request": {}
                                            },
                                            "metadataKey": {
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
                                                        "key": "istio_dry_run_deny_shadow_effective_policy_id"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
                                        "tag": "istio.authorization.dry_run.deny_policy.result",
                                        "metadata": {
                                            "kind": {
                                                "request": {}
                                            },
                                            "metadataKey": {
                                                "key": "envoy.filters.http.rbac",
                                                "path": [
                                                    {
                                                        "key": "istio_dry_run_deny_shadow_engine_result"
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    {
                                        "tag": "istio.canonical_revision",
                                        "literal": {
                                            "value": "latest"
                                        }
                                    },
                                    {
                                        "tag": "istio.canonical_service",
                                        "literal": {
                                            "value": "istio-ingressgateway"
                                        }
                                    },
                                    {
                                        "tag": "istio.mesh_id",
                                        "literal": {
                                            "value": "cluster.local"
                                        }
                                    },
                                    {
                                        "tag": "istio.namespace",
                                        "literal": {
                                            "value": "istio-system"
                                        }
                                    }
                                ]
                            },
                            "httpProtocolOptions": {},
                            "serverName": "istio-envoy",
                            "streamIdleTimeout": "0s",
                            "useRemoteAddress": true,
                            "forwardClientCertDetails": "SANITIZE_SET",
                            "setCurrentClientCertDetails": {
                                "subject": true,
                                "cert": true,
                                "dns": true,
                                "uri": true
                            },
                            "upgradeConfigs": [
                                {
                                    "upgradeType": "websocket"
                                }
                            ],
                            "normalizePath": true,
                            "pathWithEscapedSlashesAction": "KEEP_UNCHANGED",
                            "requestIdExtension": {
                                "typedConfig": {
                                    "@type": "type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfig",
                                    "useRequestIdForTraceSampling": true
                                }
                            }
                        }
                    }
                ]
            }
        ],
        "trafficDirection": "OUTBOUND"
    }
]

## RDS - Route Discovery Service
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system
NAME          DOMAINS                      MATCH                  VIRTUAL SERVICE
http.8080     catalog.istioinaction.io     /*                     catalog-vs-from-gw.istioinaction
              *                            /healthz/ready*        
              *                            /stats/prometheus*
              
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080
NAME          DOMAINS                      MATCH     VIRTUAL SERVICE
http.8080     catalog.istioinaction.io     /*        catalog-vs-from-gw.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 -o json
[
    {
        "name": "http.8080",
        "virtualHosts": [
            {
                "name": "catalog.istioinaction.io:80",
                "domains": [
                    "catalog.istioinaction.io"
                ],
                "routes": [
                    {
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "cluster": "outbound|80||catalog.istioinaction.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                                "numRetries": 2,
                                "retryHostPredicate": [
                                    {
                                        "name": "envoy.retry_host_predicates.previous_hosts",
                                        "typedConfig": {
                                            "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
                                        }
                                    }
                                ],
                                "hostSelectionRetryMaxAttempts": "5",
                                "retriableStatusCodes": [
                                    503
                                ]
                            },
                            "maxGrpcTimeout": "0s"
                        },
                        "metadata": {
                            "filterMetadata": {
                                "istio": {
                                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/istioinaction/virtual-service/catalog-vs-from-gw"
                                }
                            }
                        },
                        "decorator": {
                            "operation": "catalog.istioinaction.svc.cluster.local:80/*"
                        }
                    }
                ],
                "includeRequestAttemptCount": true
            }
        ],
        "validateClusters": false,
        "ignorePortInHostMatching": true
    }
]

## CDS - Cluseter Discovery Service
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system
SERVICE FQDN                                            PORT      SUBSET     DIRECTION     TYPE           DESTINATION RULE
BlackHoleCluster                                        -         -          -             STATIC         
agent                                                   -         -          -             STATIC         
catalog.istioinaction.svc.cluster.local                 80        -          outbound      EDS            
grafana.istio-system.svc.cluster.local                  3000      -          outbound      EDS            
istio-ingressgateway.istio-system.svc.cluster.local     80        -          outbound      EDS            
istio-ingressgateway.istio-system.svc.cluster.local     443       -          outbound      EDS            
istio-ingressgateway.istio-system.svc.cluster.local     15021     -          outbound      EDS            
istiod.istio-system.svc.cluster.local                   443       -          outbound      EDS            
istiod.istio-system.svc.cluster.local                   15010     -          outbound      EDS            
istiod.istio-system.svc.cluster.local                   15012     -          outbound      EDS            
istiod.istio-system.svc.cluster.local                   15014     -          outbound      EDS            
jaeger-collector.istio-system.svc.cluster.local         9411      -          outbound      EDS            
jaeger-collector.istio-system.svc.cluster.local         14250     -          outbound      EDS            
jaeger-collector.istio-system.svc.cluster.local         14268     -          outbound      EDS            
kiali.istio-system.svc.cluster.local                    9090      -          outbound      EDS            
kiali.istio-system.svc.cluster.local                    20001     -          outbound      EDS            
kube-dns.kube-system.svc.cluster.local                  53        -          outbound      EDS            
kube-dns.kube-system.svc.cluster.local                  9153      -          outbound      EDS            
kube-ops-view.kube-system.svc.cluster.local             8080      -          outbound      EDS            
kubernetes.default.svc.cluster.local                    443       -          outbound      EDS            
metrics-server.kube-system.svc.cluster.local            443       -          outbound      EDS            
prometheus.istio-system.svc.cluster.local               9090      -          outbound      EDS            
prometheus_stats                                        -         -          -             STATIC         
sds-grpc                                                -         -          -             STATIC         
tracing.istio-system.svc.cluster.local                  80        -          outbound      EDS            
tracing.istio-system.svc.cluster.local                  16685     -          outbound      EDS            
xds-grpc                                                -         -          -             STATIC         
zipkin                                                  -         -          -             STRICT_DNS     
zipkin.istio-system.svc.cluster.local                   9411      -          outbound      EDS 

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN                                PORT     SUBSET     DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       -          outbound      EDS      

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local -o json
[
    {
        "transportSocketMatches": [
            {
                "name": "tlsMode-istio",
                "match": {
                    "tlsMode": "istio"
                },
                "transportSocket": {
                    "name": "envoy.transport_sockets.tls",
                    "typedConfig": {
                        "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                        "commonTlsContext": {
                            "tlsParams": {
                                "tlsMinimumProtocolVersion": "TLSv1_2",
                                "tlsMaximumProtocolVersion": "TLSv1_3"
                            },
                            "tlsCertificateSdsSecretConfigs": [
                                {
                                    "name": "default",
                                    "sdsConfig": {
                                        "apiConfigSource": {
                                            "apiType": "GRPC",
                                            "transportApiVersion": "V3",
                                            "grpcServices": [
                                                {
                                                    "envoyGrpc": {
                                                        "clusterName": "sds-grpc"
                                                    }
                                                }
                                            ],
                                            "setNodeOnFirstMessageOnly": true
                                        },
                                        "initialFetchTimeout": "0s",
                                        "resourceApiVersion": "V3"
                                    }
                                }
                            ],
                            "combinedValidationContext": {
                                "defaultValidationContext": {
                                    "matchSubjectAltNames": [
                                        {
                                            "exact": "spiffe://cluster.local/ns/istioinaction/sa/catalog"
                                        }
                                    ]
                                },
                                "validationContextSdsSecretConfig": {
                                    "name": "ROOTCA",
                                    "sdsConfig": {
                                        "apiConfigSource": {
                                            "apiType": "GRPC",
                                            "transportApiVersion": "V3",
                                            "grpcServices": [
                                                {
                                                    "envoyGrpc": {
                                                        "clusterName": "sds-grpc"
                                                    }
                                                }
                                            ],
                                            "setNodeOnFirstMessageOnly": true
                                        },
                                        "initialFetchTimeout": "0s",
                                        "resourceApiVersion": "V3"
                                    }
                                }
                            },
                            "alpnProtocols": [
                                "istio-peer-exchange",
                                "istio"
                            ]
                        },
                        "sni": "outbound_.80_._.catalog.istioinaction.svc.cluster.local"
                    }
                }
            },
            {
                "name": "tlsMode-disabled",
                "match": {},
                "transportSocket": {
                    "name": "envoy.transport_sockets.raw_buffer",
                    "typedConfig": {
                        "@type": "type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer"
                    }
                }
            }
        ],
        "name": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|80||catalog.istioinaction.svc.cluster.local"
        },
        "connectTimeout": "10s",
        "lbPolicy": "LEAST_REQUEST",
        "circuitBreakers": {
            "thresholds": [
                {
                    "maxConnections": 4294967295,
                    "maxPendingRequests": 4294967295,
                    "maxRequests": 4294967295,
                    "maxRetries": 4294967295,
                    "trackRemaining": true
                }
            ]
        },
        "commonLbConfig": {
            "localityWeightedLbConfig": {}
        },
        "metadata": {
            "filterMetadata": {
                "istio": {
                    "default_original_port": 80,
                    "services": [
                        {
                            "host": "catalog.istioinaction.svc.cluster.local",
                            "name": "catalog",
                            "namespace": "istioinaction"
                        }
                    ]
                }
            }
        },
        "filters": [
            {
                "name": "istio.metadata_exchange",
                "typedConfig": {
                    "@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
                    "protocol": "istio-peer-exchange"
                }
            }
        ]
    }
]

## EDS - Endpoint Discovery Service
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.10:53                                           HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.10:9153                                         HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.11:8080                                         HEALTHY     OK                outbound|8080||kube-ops-view.kube-system.svc.cluster.local
10.10.0.12:9090                                         HEALTHY     OK                outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.13:8080                                         HEALTHY     OK                outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:8443                                         HEALTHY     OK                outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:15021                                        HEALTHY     OK                outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.2:53                                            HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.2:9153                                          HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.3:3000                                          HEALTHY     OK                outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.4:14250                                         HEALTHY     OK                outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:14268                                         HEALTHY     OK                outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:16685                                         HEALTHY     OK                outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.4:16686                                         HEALTHY     OK                outbound|80||tracing.istio-system.svc.cluster.local
10.10.0.6:10250                                         HEALTHY     OK                outbound|443||metrics-server.kube-system.svc.cluster.local
10.10.0.8:15010                                         HEALTHY     OK                outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.8:15012                                         HEALTHY     OK                outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.8:15014                                         HEALTHY     OK                outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.8:15017                                         HEALTHY     OK                outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.9:9090                                          HEALTHY     OK                outbound|9090||kiali.istio-system.svc.cluster.local
10.10.0.9:20001                                         HEALTHY     OK                outbound|20001||kiali.istio-system.svc.cluster.local
10.200.1.6:9411                                         HEALTHY     OK                zipkin
127.0.0.1:15000                                         HEALTHY     OK                prometheus_stats
127.0.0.1:15020                                         HEALTHY     OK                agent
172.19.0.2:6443                                         HEALTHY     OK                outbound|443||kubernetes.default.svc.cluster.local
unix://./etc/istio/proxy/XDS                            HEALTHY     OK                xds-grpc
unix://./var/run/secrets/workload-spiffe-uds/socket     HEALTHY     OK                sds-grpc

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000     HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local' -o json
[
    {
        "name": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "addedViaApi": true,
        "hostStatuses": [
            {
                "address": {
                    "socketAddress": {
                        "address": "10.10.0.14",
                        "portValue": 3000
                    }
                },
                "stats": [
                    {
                        "name": "cx_connect_fail"
                    },
                    {
                        "value": "13",
                        "name": "cx_total"
                    },
                    {
                        "name": "rq_error"
                    },
                    {
                        "value": "9737",
                        "name": "rq_success"
                    },
                    {
                        "name": "rq_timeout"
                    },
                    {
                        "value": "9737",
                        "name": "rq_total"
                    },
                    {
                        "type": "GAUGE",
                        "value": "13",
                        "name": "cx_active"
                    },
                    {
                        "type": "GAUGE",
                        "name": "rq_active"
                    }
                ],
                "healthStatus": {
                    "edsHealthStatus": "HEALTHY"
                },
                "weight": 1,
                "locality": {}
            }
        ],
        "circuitBreakers": {
            "thresholds": [
                {
                    "maxConnections": 4294967295,
                    "maxPendingRequests": 4294967295,
                    "maxRequests": 4294967295,
                    "maxRetries": 4294967295
                },
                {
                    "priority": "HIGH",
                    "maxConnections": 1024,
                    "maxPendingRequests": 1024,
                    "maxRequests": 1024,
                    "maxRetries": 3
                }
            ]
        },
        "observabilityName": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "edsServiceName": "outbound|80||catalog.istioinaction.svc.cluster.local"
    }
]

# catalog
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
ADDRESS      PORT  MATCH                                                                                           DESTINATION
10.200.1.10  53    ALL                                                                                             Cluster: outbound|53||kube-dns.kube-system.svc.cluster.local
0.0.0.0      80    Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 80
0.0.0.0      80    ALL                                                                                             PassthroughCluster
10.200.1.1   443   ALL                                                                                             Cluster: outbound|443||kubernetes.default.svc.cluster.local
10.200.1.17  443   ALL                                                                                             Cluster: outbound|443||metrics-server.kube-system.svc.cluster.local
10.200.1.172 443   ALL                                                                                             Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.182 443   ALL                                                                                             Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.190 3000  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.190 3000  ALL                                                                                             Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
0.0.0.0      8080  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 8080
0.0.0.0      8080  ALL                                                                                             PassthroughCluster
0.0.0.0      9090  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 9090
0.0.0.0      9090  ALL                                                                                             PassthroughCluster
10.200.1.10  9153  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: kube-dns.kube-system.svc.cluster.local:9153
10.200.1.10  9153  ALL                                                                                             Cluster: outbound|9153||kube-dns.kube-system.svc.cluster.local
0.0.0.0      9411  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 9411
0.0.0.0      9411  ALL                                                                                             PassthroughCluster
10.200.1.53  14250 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.53  14250 ALL                                                                                             Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.53  14268 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.53  14268 ALL                                                                                             Cluster: outbound|14268||jaeger-collector.istio-system.svc.cluster.local
0.0.0.0      15001 ALL                                                                                             PassthroughCluster
0.0.0.0      15001 Addr: *:15001                                                                                   Non-HTTP/Non-TCP
0.0.0.0      15006 Addr: *:15006                                                                                   Non-HTTP/Non-TCP
0.0.0.0      15006 Trans: tls; App: istio-http/1.0,istio-http/1.1,istio-h2; Addr: 0.0.0.0/0                        InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: raw_buffer; App: http/1.1,h2c; Addr: 0.0.0.0/0                                           InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; App: TCP TLS; Addr: 0.0.0.0/0                                                       InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: raw_buffer; Addr: 0.0.0.0/0                                                              InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; Addr: 0.0.0.0/0                                                                     InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; App: istio,istio-peer-exchange,istio-http/1.0,istio-http/1.1,istio-h2; Addr: *:3000 Cluster: inbound|3000||
0.0.0.0      15006 Trans: raw_buffer; Addr: *:3000                                                                 Cluster: inbound|3000||
0.0.0.0      15010 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 15010
0.0.0.0      15010 ALL                                                                                             PassthroughCluster
10.200.1.182 15012 ALL                                                                                             Cluster: outbound|15012||istiod.istio-system.svc.cluster.local
0.0.0.0      15014 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 15014
0.0.0.0      15014 ALL                                                                                             PassthroughCluster
0.0.0.0      15021 ALL                                                                                             Inline Route: /healthz/ready*
10.200.1.172 15021 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.172 15021 ALL                                                                                             Cluster: outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
0.0.0.0      15090 ALL                                                                                             Inline Route: /stats/prometheus*
0.0.0.0      16685 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 16685
0.0.0.0      16685 ALL                                                                                             PassthroughCluster
0.0.0.0      20001 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 20001
0.0.0.0      20001 ALL                                                                                             PassthroughCluster

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction
routes deploy/catalog.istioinaction
NAME                                                          DOMAINS                                             MATCH                  VIRTUAL SERVICE
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     
80                                                            istio-ingressgateway.istio-system, 10.200.1.172     /*                     
80                                                            tracing.istio-system, 10.200.1.164                  /*                     
8080                                                          kube-ops-view.kube-system, 10.200.1.144             /*                     
9090                                                          kiali.istio-system, 10.200.1.26                     /*                     
9090                                                          prometheus.istio-system, 10.200.1.104               /*                     
9411                                                          jaeger-collector.istio-system, 10.200.1.53          /*                     
9411                                                          zipkin.istio-system, 10.200.1.6                     /*                     
15010                                                         istiod.istio-system, 10.200.1.182                   /*                     
15014                                                         istiod.istio-system, 10.200.1.182                   /*                     
istio-ingressgateway.istio-system.svc.cluster.local:15021     *                                                   /*                     
jaeger-collector.istio-system.svc.cluster.local:14268         *                                                   /*                     
20001                                                         kiali.istio-system, 10.200.1.26                     /*                     
16685                                                         tracing.istio-system, 10.200.1.164                  /*                     
jaeger-collector.istio-system.svc.cluster.local:14250         *                                                   /*                     
kube-dns.kube-system.svc.cluster.local:9153                   *                                                   /*                     
grafana.istio-system.svc.cluster.local:3000                   *                                                   /*                     
InboundPassthroughClusterIpv4                                 *                                                   /*                     
                                                              *                                                   /stats/prometheus*     
InboundPassthroughClusterIpv4                                 *                                                   /*                     
                                                              *                                                   /healthz/ready*        
inbound|3000||                                                *                                                   /*                     
inbound|3000||                                                *                                                   /*    

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
SERVICE FQDN                                            PORT      SUBSET     DIRECTION     TYPE             DESTINATION RULE
                                                        3000      -          inbound       ORIGINAL_DST     
BlackHoleCluster                                        -         -          -             STATIC           
InboundPassthroughClusterIpv4                           -         -          -             ORIGINAL_DST     
PassthroughCluster                                      -         -          -             ORIGINAL_DST     
agent                                                   -         -          -             STATIC           
catalog.istioinaction.svc.cluster.local                 80        -          outbound      EDS              
grafana.istio-system.svc.cluster.local                  3000      -          outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     80        -          outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     443       -          outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     15021     -          outbound      EDS              
istiod.istio-system.svc.cluster.local                   443       -          outbound      EDS              
istiod.istio-system.svc.cluster.local                   15010     -          outbound      EDS              
istiod.istio-system.svc.cluster.local                   15012     -          outbound      EDS              
istiod.istio-system.svc.cluster.local                   15014     -          outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         9411      -          outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         14250     -          outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         14268     -          outbound      EDS              
kiali.istio-system.svc.cluster.local                    9090      -          outbound      EDS              
kiali.istio-system.svc.cluster.local                    20001     -          outbound      EDS              
kube-dns.kube-system.svc.cluster.local                  53        -          outbound      EDS              
kube-dns.kube-system.svc.cluster.local                  9153      -          outbound      EDS              
kube-ops-view.kube-system.svc.cluster.local             8080      -          outbound      EDS              
kubernetes.default.svc.cluster.local                    443       -          outbound      EDS              
metrics-server.kube-system.svc.cluster.local            443       -          outbound      EDS              
prometheus.istio-system.svc.cluster.local               9090      -          outbound      EDS              
prometheus_stats                                        -         -          -             STATIC           
sds-grpc                                                -         -          -             STATIC           
tracing.istio-system.svc.cluster.local                  80        -          outbound      EDS              
tracing.istio-system.svc.cluster.local                  16685     -          outbound      EDS              
xds-grpc                                                -         -          -             STATIC           
zipkin                                                  -         -          -             STRICT_DNS       
zipkin.istio-system.svc.cluster.local                   9411      -          outbound      EDS  

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.10:53                                           HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.10:9153                                         HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.11:8080                                         HEALTHY     OK                outbound|8080||kube-ops-view.kube-system.svc.cluster.local
10.10.0.12:9090                                         HEALTHY     OK                outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.13:8080                                         HEALTHY     OK                outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:8443                                         HEALTHY     OK                outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:15021                                        HEALTHY     OK                outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                inbound|3000||
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.2:53                                            HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.2:9153                                          HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.3:3000                                          HEALTHY     OK                outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.4:14250                                         HEALTHY     OK                outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:14268                                         HEALTHY     OK                outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:16685                                         HEALTHY     OK                outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.4:16686                                         HEALTHY     OK                outbound|80||tracing.istio-system.svc.cluster.local
10.10.0.6:10250                                         HEALTHY     OK                outbound|443||metrics-server.kube-system.svc.cluster.local
10.10.0.8:15010                                         HEALTHY     OK                outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.8:15012                                         HEALTHY     OK                outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.8:15014                                         HEALTHY     OK                outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.8:15017                                         HEALTHY     OK                outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.9:9090                                          HEALTHY     OK                outbound|9090||kiali.istio-system.svc.cluster.local
10.10.0.9:20001                                         HEALTHY     OK                outbound|20001||kiali.istio-system.svc.cluster.local
10.200.1.6:9411                                         HEALTHY     OK                zipkin
127.0.0.1:15000                                         HEALTHY     OK                prometheus_stats
127.0.0.1:15020                                         HEALTHY     OK                agent
172.19.0.2:6443                                         HEALTHY     OK                outbound|443||kubernetes.default.svc.cluster.local
unix://./etc/istio/proxy/XDS                            HEALTHY     OK                xds-grpc
unix://./var/run/secrets/workload-spiffe-uds/socket     HEALTHY     OK                sds-grpc
  • 특정 파드의 istio-proxy 에 Envoy 에 Admin 웹 접속
# 신규 터미널 : istio-ingressgateway 파드
kubectl port-forward deploy/istio-ingressgateway -n istio-system 15000:15000

# 
open http://127.0.0.1:15000

1.5.3 Deploying v2 of the catalog service

  • istio 트래픽 제어 기능 동작을 알아보기 위해, catalog 서비스 v2 를 배포해보자. ⇒ 버전1,2 호출 된다. v2 호출되지 않게 할 수 없을까?
# catalog 서비스 v2 를 배포 : v2에서는 imageUrl 필드가 추가
kubectl apply -f services/catalog/kubernetes/catalog-deployment-v2.yaml -n istioinaction
deployment.apps/catalog-v2 created
#
kubectl get deploy -n istioinaction --show-labels
catalog      1/1     1            1           135m   app=catalog,version=v1
catalog-v2   1/1     1            1           20s    app=catalog,version=v2

kubectl get pod -n istioinaction -o wide
NAME                          READY   STATUS    RESTARTS   AGE    IP           NODE                  NOMINATED NODE   READINESS GATES
catalog-6cf4b97d-5hwg7        2/2     Running   0          135m   10.10.0.14   myk8s-control-plane   <none>           <none>
catalog-v2-6df885b555-q7xnv   2/2     Running   0          40s    10.10.0.15   myk8s-control-plane   <none>           <none>

docker exec -it myk8s-control-plane istioctl proxy-status
NAME                                                  CLUSTER        CDS        LDS        EDS        RDS        ECDS         ISTIOD                      VERSION
catalog-6cf4b97d-5hwg7.istioinaction                  Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-7df6ffc78d-fhwmc     1.17.8
catalog-v2-6df885b555-q7xnv.istioinaction             Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-7df6ffc78d-fhwmc     1.17.8
istio-ingressgateway-996bc6bb6-n6trq.istio-system     Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-7df6ffc78d-fhwmc     1.17.8


# 호출 테스트 : v1 , v2 호출 확인
for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done


# istio-ingressgateway proxy-config 확인
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN                                PORT     SUBSET     DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       -          outbound      EDS    

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local -o json
...
        "name": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|80||catalog.istioinaction.svc.cluster.local"
        },
        "connectTimeout": "10s",
        "lbPolicy": "LEAST_REQUEST",
        "circuitBreakers": {
            "thresholds": [
                {
                    "maxConnections": 4294967295,
                    "maxPendingRequests": 4294967295,
                    "maxRequests": 4294967295,
                    "maxRetries": 4294967295,
                    "trackRemaining": true
                }
            ]
        },
        "commonLbConfig": {
            "localityWeightedLbConfig": {}
        },
...

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.16:3000     HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.17:3000     HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local' -o json
...
   {
        "name": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "addedViaApi": true,
        "hostStatuses": [
            {
                "address": {
                    "socketAddress": {
                        "address": "10.10.0.14",
                        "portValue": 3000
                    }
                },
                "stats": [
                    {
                        "name": "cx_connect_fail"
                    },
                    {
                        "value": "8",
                        "name": "cx_total"
                    },
                    {
                        "name": "rq_error"
                    },
                    {
                        "value": "315",
                        "name": "rq_success"
                    },
                    {
                        "name": "rq_timeout"
                    },
                    {
                        "value": "315",
                        "name": "rq_total"
                    },
                    {
                        "type": "GAUGE",
                        "value": "8",
                        "name": "cx_active"
                    },
                    {
                        "type": "GAUGE",
                        "name": "rq_active"
                    }
                ],
                "healthStatus": {
                    "edsHealthStatus": "HEALTHY"
                },
                "weight": 1,
                "locality": {}
            },
            {
                "address": {
                    "socketAddress": {
                        "address": "10.10.0.15",
                        "portValue": 3000
                    }
                },
                "stats": [
                    {
                        "name": "cx_connect_fail"
                    },
                    {
                        "value": "8",
                        "name": "cx_total"
                    },
                    {
                        "name": "rq_error"
                    },
                    {
                        "value": "308",
                        "name": "rq_success"
                    },
                    {
                        "name": "rq_timeout"
                    },
                    {
                        "value": "308",
                        "name": "rq_total"
                    },
                    {
                        "type": "GAUGE",
                        "value": "8",
                        "name": "cx_active"
                    },
                    {
                        "type": "GAUGE",
                        "name": "rq_active"
                    }
                ],
                "healthStatus": {
                    "edsHealthStatus": "HEALTHY"
                },
                "weight": 1,
                "locality": {}
            }
        ],
        "circuitBreakers": {
            "thresholds": [
                {
                    "maxConnections": 4294967295,
                    "maxPendingRequests": 4294967295,
                    "maxRequests": 4294967295,
                    "maxRetries": 4294967295
                },
                {
                    "priority": "HIGH",
                    "maxConnections": 1024,
                    "maxPendingRequests": 1024,
                    "maxRequests": 1024,
                    "maxRetries": 3
                }
            ]
        },
        "observabilityName": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "edsServiceName": "outbound|80||catalog.istioinaction.svc.cluster.local"
    },
...

1.5.4 Routing all traffic to v1 of the catalog service

  • 모든 트래픽을 catalog v1 으로 라우팅. 이것이 다크런치를 시작하기 전의 일반적인 트래픽 패턴이다.
  • 어느 워크로드가 v1, v2 인지 이스티오에게 힌트를 줘야한다.
  • catalog v1은 deployment 리소스에서 레이블 app:catalog, version:v1 을 사용한다.
  • catalog v2은 deployment 리소스에서 레이블 app:catalog, version:v2 을 사용한다.
  • 이스티오에게는 이렇게 다른 버전들의 부분집합 subset 으로 지정하는 DestinationRule 을 만들어준다.
#
kubectl get pod -l app=catalog -n istioinaction --show-labels
NAME                          READY   STATUS    RESTARTS   AGE    LABELS
catalog-6cf4b97d-5hwg7        2/2     Running   0          147m   app=catalog,pod-template-hash=6cf4b97d,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=catalog,service.istio.io/canonical-revision=v1,version=v1
catalog-v2-6df885b555-q7xnv   2/2     Running   0          13m    app=catalog,pod-template-hash=6df885b555,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=catalog,service.istio.io/canonical-revision=v2,version=v2

#
cat ch5/catalog-dest-rule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: catalog
spec:
  host: catalog.istioinaction.svc.cluster.local
  subsets:
  - name: version-v1
    labels:
      version: v1
  - name: version-v2
    labels:
      version: v2

kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
destinationrule.networking.istio.io/catalog created

# 확인
kubectl get destinationrule -n istioinaction
NAME      HOST                                      AGE
catalog   catalog.istioinaction.svc.cluster.local   20s

# catalog proxy-config 확인 : SUBSET(v1, v2, -) 확인
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN                                PORT     SUBSET         DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       -              outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v1     outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v2     outbound      EDS      catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v1 -o json
...
        "name": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local"
        },
        "connectTimeout": "10s",
        "lbPolicy": "LEAST_REQUEST",
...

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v2 -o json
...
        "name": "outbound|80|version-v2|catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|80|version-v2|catalog.istioinaction.svc.cluster.local"
        },
        "connectTimeout": "10s",
        "lbPolicy": "LEAST_REQUEST",
...

#
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local -o json
...
        "name": "outbound|80||catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|80||catalog.istioinaction.svc.cluster.local"
        },
...

# 
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000                                         HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80|version-v1|catalog.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000     HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80|version-v1|catalog.istioinaction.svc.cluster.local' -o json

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80|version-v2|catalog.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.15:3000     HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80|version-v2|catalog.istioinaction.svc.cluster.local' -o json

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000     HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000     HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local

# VirtualService 수정 (subset 추가)
cat ch5/catalog-vs-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: catalog-vs-from-gw
spec:
  hosts:
  - "catalog.istioinaction.io"
  gateways:
  - catalog-gateway
  http:
  - route:
    - destination:
        host: catalog
        subset: version-v1

kubectl apply -f ch5/catalog-vs-v1.yaml -n istioinaction
virtualservice.networking.istio.io/catalog-vs-from-gw configured

# 호출 테스트 : v1
for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done


# 세부 정보 확인
# routes 에 virtualHosts 항목에 routes.route 에 cluster 부분이 ...version-v1... 설정 확인
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system
NAME          DOMAINS                      MATCH                  VIRTUAL SERVICE
http.8080     catalog.istioinaction.io     /*                     catalog-vs-from-gw.istioinaction
              *                            /healthz/ready*        
              *                            /stats/prometheus*  
              
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 -o json
...
        "virtualHosts": [
            {
                "name": "catalog.istioinaction.io:80",
                "domains": [
                    "catalog.istioinaction.io"
                ],
                "routes": [
                    {
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "cluster": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
                            "timeout": "0s",
                            "retryPolicy": {
                                "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                                "numRetries": 2,
...

# cluster 
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN                                PORT     SUBSET         DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       -              outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v1     outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v2     outbound      EDS      catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v1
SERVICE FQDN                                PORT     SUBSET         DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       version-v1     outbound      EDS      catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v1 -o json
...
        "name": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
        "edsClusterConfig": {
            "edsConfig": {
                "ads": {},
                "initialFetchTimeout": "0s",
                "resourceApiVersion": "V3"
            },
            "serviceName": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local"
        },
        ...
        "metadata": {
            "filterMetadata": {
                "istio": {
                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/istioinaction/destination-rule/catalog",
                    "default_original_port": 80,
                    "services": [
                        {
                            "host": "catalog.istioinaction.svc.cluster.local",
                            "name": "catalog",
                            "namespace": "istioinaction"
                        }
                    ],
                    "subset": "version-v1"
...

# endpoint 
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000                                         HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80|version-v1|catalog.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000     HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80|version-v1|catalog.istioinaction.svc.cluster.local' -o json
...

# istio-proxy (catalog)
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction --subset version-v1 -o json
...
        "metadata": {
            "filterMetadata": {
                "istio": {
                    "config": "/apis/networking.istio.io/v1alpha3/namespaces/istioinaction/destination-rule/catalog",
                    "default_original_port": 80,
                    "services": [
                        {
                            "host": "catalog.istioinaction.svc.cluster.local",
                            "name": "catalog",
                            "namespace": "istioinaction"
                        }
                    ],
                    "subset": "version-v1"
                }
            }
        },
...


✅ 이 시점에서 모든 트래픽이 v1 라우팅 된다.
✅ 이제 특정 요청들을 통제된 방식으로 v2 라우팅하고 싶다. 다음 절에서 알아보자.

1.5.5 Routing specific requests to v2

  • HTTP 요청 헤더 x-istio-cohort: internal 을 포함한 트래픽(통제된 방식)은 catalog v2로 보내고 싶다.
#
cat ch5/catalog-vs-v2-request.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: catalog-vs-from-gw
spec:
  hosts:
  - "catalog.istioinaction.io"
  gateways:
  - catalog-gateway
  http:
  - match:
    - headers:
        x-istio-cohort:
          exact: "internal"
    route:
    - destination:
        host: catalog
        subset: version-v2
  - route:
    - destination:
        host: catalog
        subset: version-v1

kubectl apply -f ch5/catalog-vs-v2-request.yaml -n istioinaction

# 호출 테스트 : 여전히 v1
for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done

# 요청 헤더 포함 호출 테스트 : v2!
curl http://catalog.istioinaction.io:30000/items -H "x-istio-cohort: internal"

# (옵션) 신규 터미널 : v2 반복 접속
while true; do curl -s http://catalog.istioinaction.io:30000/items/ -H "x-istio-cohort: internal" -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 2; echo; done


# 상세 확인
# route 추가 : routes 에 2개의 route 확인 - 위에서 부터 적용되는 순서 중요!
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080
NAME          DOMAINS                      MATCH     VIRTUAL SERVICE
http.8080     catalog.istioinaction.io     /*        catalog-vs-from-gw.istioinaction
http.8080     catalog.istioinaction.io     /*        catalog-vs-from-gw.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 -o json
...
        "virtualHosts": [
            {
                "name": "catalog.istioinaction.io:80",
                "domains": [
                    "catalog.istioinaction.io"
                ],
                "routes": [
                    {
                        "match": {
                            "prefix": "/",
                            "caseSensitive": true,
                            "headers": [
                                {
                                    "name": "x-istio-cohort",
                                    "stringMatch": {
                                        "exact": "internal"
                                    }
                                }
                            ]
                        },
                        "route": {
                            "cluster": "outbound|80|version-v2|catalog.istioinaction.svc.cluster.local",
                            "timeout": "0s",
                ...
                   {
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "cluster": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
...

#
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'

# istio-proxy (catalog)에는 routes 정보가 아래 cluster 로 보내는 1개만 있다. 즉 istio-proxy(istio-ingressgateway)가 routes 분기 처리하는 것을 알 수 있다.
## "cluster": "outbound|80||catalog.istioinaction.svc.cluster.local"
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction --name 80 -o json
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction | grep catalog
80                                                            catalog, catalog.istioinaction + 1 more...          /*

1.5.6 Routing deep within a call graph 호출 그래프 내 깊은 위치에서 라우팅 Mesh(Gateway)

  • 지금까지 이스티오를 사용해 요청을 라우팅하는 방법을 살펴봤지만, 라우팅 수행 위치가 에지/게이트웨이뿐이었다.
  • 이런 트래픽 규칙은 호출 그래프 내 깊은 곳에서도 적용할 수 있습니다. (그림 5.9 참조).
  • 2장에서 이 작업을 수행했으므로, 프로세스를 다시 만들고 기대대로 동작하는지 확인해보자.
# 초기화
kubectl delete gateway,virtualservice,destinationrule --all -n istioinaction
serviceaccount/webapp created
service/webapp created
deployment.apps/webapp created
serviceaccount/catalog unchanged
service/catalog unchanged
deployment.apps/catalog unchanged

# webapp 기동
kubectl apply -n istioinaction -f services/webapp/kubernetes/webapp.yaml
kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction # 이미 배포 상태

kubectl apply -f services/catalog/kubernetes/catalog-deployment-v2.yaml -n istioinaction # 이미 배포 상태

# 확인
kubectl get deploy,pod,svc,ep -n istioinaction
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/catalog      1/1     1            1           3h13m
deployment.apps/catalog-v2   1/1     1            1           58m
deployment.apps/webapp       1/1     1            1           5m54s

NAME                              READY   STATUS    RESTARTS   AGE
pod/catalog-6cf4b97d-5hwg7        2/2     Running   0          3h13m
pod/catalog-v2-6df885b555-q7xnv   2/2     Running   0          58m
pod/webapp-7685bcb84-xphnb        2/2     Running   0          5m54s

NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/catalog   ClusterIP   10.200.1.174   <none>        80/TCP    3h13m
service/webapp    ClusterIP   10.200.1.206   <none>        80/TCP    5m54s

NAME                ENDPOINTS                         AGE
endpoints/catalog   10.10.0.14:3000,10.10.0.15:3000   3h13m
endpoints/webapp    10.10.0.16:8080                   5m54s
  • GW, VS 설정 후 호출 테스트 : webapp → catalog 는 k8s service(clusterIP) 라우팅 사용
# Now, set up the Istio ingress gateway to route to the webapp service
cat services/webapp/istio/webapp-catalog-gw-vs.yaml
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: coolstore-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "webapp.istioinaction.io"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: webapp-virtualservice
spec:
  hosts:
  - "webapp.istioinaction.io"
  gateways:
  - coolstore-gateway
  http:
  - route:
    - destination:
        host: webapp
        port:
          number: 80

kubectl apply -f services/webapp/istio/webapp-catalog-gw-vs.yaml -n istioinaction
gateway.networking.istio.io/coolstore-gateway created
virtualservice.networking.istio.io/webapp-virtualservice created

# 확인
kubectl get gw,vs -n istioinaction
NAME                                            AGE
gateway.networking.istio.io/catalog-gateway     3h15m
gateway.networking.istio.io/coolstore-gateway   3m21s

NAME                                                       GATEWAYS                HOSTS                          AGE
virtualservice.networking.istio.io/catalog-vs-from-gw      ["catalog-gateway"]     ["catalog.istioinaction.io"]   3h13m
virtualservice.networking.istio.io/webapp-virtualservice   ["coolstore-gateway"]   ["webapp.istioinaction.io"]    3m21s


# 도메인 질의를 위한 임시 설정 : 실습 완료 후에는 삭제 해둘 것
echo "127.0.0.1       webapp.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 3
127.0.0.1       catalog.istioinaction.io
127.0.0.1       webapp.istioinaction.io


# 호출테스트 : 외부(web, curl) → ingressgw → webapp → catalog (v1, v2)
curl -s http://webapp.istioinaction.io:30000/api/catalog | jq

# 반복 호출테스트 : 신규터미널 2개에 아래 각각 실행 해두기
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -H "x-istio-cohort: internal" -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 2; echo; done


# proxy-config : istio-ingressgateway
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 
NAME          DOMAINS                     MATCH     VIRTUAL SERVICE
http.8080     webapp.istioinaction.io     /*        webapp-virtualservice.istioinaction
=> route."cluster": "outbound|80||webapp.istioinaction.svc.cluster.local"

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system | egrep 'webapp|catalog'
catalog.istioinaction.svc.cluster.local                 80        -          outbound      EDS            
webapp.istioinaction.svc.cluster.local                  80        -          outbound      EDS

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn webapp.istioinaction.svc.cluster.local -o json
...
        "name": "outbound|80||webapp.istioinaction.svc.cluster.local",
        "type": "EDS",
...

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||webapp.istioinaction.svc.cluster.local'
ENDPOINT            STATUS      OUTLIER CHECK     CLUSTER
10.10.0.16:8080     HEALTHY     OK                outbound|80||webapp.istioinaction.svc.cluster.local

# proxy-config : webapp
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/webapp.istioinaction
ADDRESS      PORT  MATCH                                                                                           DESTINATION
10.200.1.10  53    ALL                                                                                             Cluster: outbound|53||kube-dns.kube-system.svc.cluster.local
0.0.0.0      80    Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 80
0.0.0.0      80    ALL                                                                                             PassthroughCluster
10.200.1.1   443   ALL                                                                                             Cluster: outbound|443||kubernetes.default.svc.cluster.local
10.200.1.17  443   ALL                                                                                             Cluster: outbound|443||metrics-server.kube-system.svc.cluster.local
10.200.1.172 443   ALL                                                                                             Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.182 443   ALL                                                                                             Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.190 3000  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.190 3000  ALL                                                                                             Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
0.0.0.0      8080  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 8080
0.0.0.0      8080  ALL                                                                                             PassthroughCluster
0.0.0.0      9090  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 9090
0.0.0.0      9090  ALL                                                                                             PassthroughCluster
10.200.1.10  9153  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: kube-dns.kube-system.svc.cluster.local:9153
10.200.1.10  9153  ALL                                                                                             Cluster: outbound|9153||kube-dns.kube-system.svc.cluster.local
0.0.0.0      9411  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 9411
0.0.0.0      9411  ALL                                                                                             PassthroughCluster
10.200.1.53  14250 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.53  14250 ALL                                                                                             Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.53  14268 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.53  14268 ALL                                                                                             Cluster: outbound|14268||jaeger-collector.istio-system.svc.cluster.local
0.0.0.0      15001 ALL                                                                                             PassthroughCluster
0.0.0.0      15001 Addr: *:15001                                                                                   Non-HTTP/Non-TCP
0.0.0.0      15006 Addr: *:15006                                                                                   Non-HTTP/Non-TCP
0.0.0.0      15006 Trans: tls; App: istio-http/1.0,istio-http/1.1,istio-h2; Addr: 0.0.0.0/0                        InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: raw_buffer; App: http/1.1,h2c; Addr: 0.0.0.0/0                                           InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; App: TCP TLS; Addr: 0.0.0.0/0                                                       InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: raw_buffer; Addr: 0.0.0.0/0                                                              InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; Addr: 0.0.0.0/0                                                                     InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; App: istio,istio-peer-exchange,istio-http/1.0,istio-http/1.1,istio-h2; Addr: *:8080 Cluster: inbound|8080||
0.0.0.0      15006 Trans: raw_buffer; Addr: *:8080                                                                 Cluster: inbound|8080||
0.0.0.0      15010 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 15010
0.0.0.0      15010 ALL                                                                                             PassthroughCluster
10.200.1.182 15012 ALL                                                                                             Cluster: outbound|15012||istiod.istio-system.svc.cluster.local
0.0.0.0      15014 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 15014
0.0.0.0      15014 ALL                                                                                             PassthroughCluster
0.0.0.0      15021 ALL                                                                                             Inline Route: /healthz/ready*
10.200.1.172 15021 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.172 15021 ALL                                                                                             Cluster: outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
0.0.0.0      15090 ALL                                                                                             Inline Route: /stats/prometheus*
0.0.0.0      16685 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 16685
0.0.0.0      16685 ALL                                                                                             PassthroughCluster
0.0.0.0      20001 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 20001
0.0.0.0      20001 ALL                                                                                             PassthroughCluster

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction
NAME                                                          DOMAINS                                             MATCH                  VIRTUAL SERVICE
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     
80                                                            istio-ingressgateway.istio-system, 10.200.1.172     /*                     
80                                                            tracing.istio-system, 10.200.1.164                  /*                     
80                                                            webapp, webapp.istioinaction + 1 more...            /*                     
8080                                                          kube-ops-view.kube-system, 10.200.1.144             /*                     
9090                                                          kiali.istio-system, 10.200.1.26                     /*                     
9090                                                          prometheus.istio-system, 10.200.1.104               /*                     
9411                                                          jaeger-collector.istio-system, 10.200.1.53          /*                     
9411                                                          zipkin.istio-system, 10.200.1.6                     /*                     
15010                                                         istiod.istio-system, 10.200.1.182                   /*                     
15014                                                         istiod.istio-system, 10.200.1.182                   /*                     
16685                                                         tracing.istio-system, 10.200.1.164                  /*                     
grafana.istio-system.svc.cluster.local:3000                   *                                                   /*                     
20001                                                         kiali.istio-system, 10.200.1.26                     /*                     
istio-ingressgateway.istio-system.svc.cluster.local:15021     *                                                   /*                     
kube-dns.kube-system.svc.cluster.local:9153                   *                                                   /*                     
jaeger-collector.istio-system.svc.cluster.local:14268         *                                                   /*                     
jaeger-collector.istio-system.svc.cluster.local:14250         *                                                   /*                     
                                                              *                                                   /healthz/ready*        
inbound|8080||                                                *                                                   /*                     
InboundPassthroughClusterIpv4                                 *                                                   /*                     
                                                              *                                                   /stats/prometheus*     
InboundPassthroughClusterIpv4                                 *                                                   /*                     
inbound|8080||                                                *                                                   /*  

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction
SERVICE FQDN                                            PORT      SUBSET         DIRECTION     TYPE             DESTINATION RULE
                                                        8080      -              inbound       ORIGINAL_DST     
BlackHoleCluster                                        -         -              -             STATIC           
InboundPassthroughClusterIpv4                           -         -              -             ORIGINAL_DST     
PassthroughCluster                                      -         -              -             ORIGINAL_DST     
agent                                                   -         -              -             STATIC           
catalog.istioinaction.svc.cluster.local                 80        -              outbound      EDS              catalog.istioinaction
catalog.istioinaction.svc.cluster.local                 80        version-v1     outbound      EDS              catalog.istioinaction
catalog.istioinaction.svc.cluster.local                 80        version-v2     outbound      EDS              catalog.istioinaction
grafana.istio-system.svc.cluster.local                  3000      -              outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     80        -              outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     443       -              outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     15021     -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   443       -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   15010     -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   15012     -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   15014     -              outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         9411      -              outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         14250     -              outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         14268     -              outbound      EDS              
kiali.istio-system.svc.cluster.local                    9090      -              outbound      EDS              
kiali.istio-system.svc.cluster.local                    20001     -              outbound      EDS              
kube-dns.kube-system.svc.cluster.local                  53        -              outbound      EDS              
kube-dns.kube-system.svc.cluster.local                  9153      -              outbound      EDS              
kube-ops-view.kube-system.svc.cluster.local             8080      -              outbound      EDS              
kubernetes.default.svc.cluster.local                    443       -              outbound      EDS              
metrics-server.kube-system.svc.cluster.local            443       -              outbound      EDS              
prometheus.istio-system.svc.cluster.local               9090      -              outbound      EDS              
prometheus_stats                                        -         -              -             STATIC           
sds-grpc                                                -         -              -             STATIC           
tracing.istio-system.svc.cluster.local                  80        -              outbound      EDS              
tracing.istio-system.svc.cluster.local                  16685     -              outbound      EDS              
webapp.istioinaction.svc.cluster.local                  80        -              outbound      EDS              
xds-grpc                                                -         -              -             STATIC           
zipkin                                                  -         -              -             STRICT_DNS       
zipkin.istio-system.svc.cluster.local                   9411      -              outbound      EDS   

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.10:53                                           HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.10:9153                                         HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.11:8080                                         HEALTHY     OK                outbound|8080||kube-ops-view.kube-system.svc.cluster.local
10.10.0.12:9090                                         HEALTHY     OK                outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.13:8080                                         HEALTHY     OK                outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:8443                                         HEALTHY     OK                outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:15021                                        HEALTHY     OK                outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.16:8080                                         HEALTHY     OK                inbound|8080||
10.10.0.16:8080                                         HEALTHY     OK                outbound|80||webapp.istioinaction.svc.cluster.local
10.10.0.2:53                                            HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.2:9153                                          HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.3:3000                                          HEALTHY     OK                outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.4:14250                                         HEALTHY     OK                outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:14268                                         HEALTHY     OK                outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:16685                                         HEALTHY     OK                outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.4:16686                                         HEALTHY     OK                outbound|80||tracing.istio-system.svc.cluster.local
10.10.0.6:10250                                         HEALTHY     OK                outbound|443||metrics-server.kube-system.svc.cluster.local
10.10.0.8:15010                                         HEALTHY     OK                outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.8:15012                                         HEALTHY     OK                outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.8:15014                                         HEALTHY     OK                outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.8:15017                                         HEALTHY     OK                outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.9:9090                                          HEALTHY     OK                outbound|9090||kiali.istio-system.svc.cluster.local
10.10.0.9:20001                                         HEALTHY     OK                outbound|20001||kiali.istio-system.svc.cluster.local
10.200.1.6:9411                                         HEALTHY     OK                zipkin
127.0.0.1:15000                                         HEALTHY     OK                prometheus_stats
127.0.0.1:15020                                         HEALTHY     OK                agent
172.19.0.2:6443                                         HEALTHY     OK                outbound|443||kubernetes.default.svc.cluster.local
unix://./etc/istio/proxy/XDS                            HEALTHY     OK                xds-grpc
unix://./var/run/secrets/workload-spiffe-uds/socket     HEALTHY     OK                sds-grpc

# proxy-config : catalog
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
ADDRESS      PORT  MATCH                                                                                           DESTINATION
10.200.1.10  53    ALL                                                                                             Cluster: outbound|53||kube-dns.kube-system.svc.cluster.local
0.0.0.0      80    Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 80
0.0.0.0      80    ALL                                                                                             PassthroughCluster
10.200.1.1   443   ALL                                                                                             Cluster: outbound|443||kubernetes.default.svc.cluster.local
10.200.1.17  443   ALL                                                                                             Cluster: outbound|443||metrics-server.kube-system.svc.cluster.local
10.200.1.172 443   ALL                                                                                             Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.182 443   ALL                                                                                             Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.190 3000  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.190 3000  ALL                                                                                             Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
0.0.0.0      8080  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 8080
0.0.0.0      8080  ALL                                                                                             PassthroughCluster
0.0.0.0      9090  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 9090
0.0.0.0      9090  ALL                                                                                             PassthroughCluster
10.200.1.10  9153  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: kube-dns.kube-system.svc.cluster.local:9153
10.200.1.10  9153  ALL                                                                                             Cluster: outbound|9153||kube-dns.kube-system.svc.cluster.local
0.0.0.0      9411  Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 9411
0.0.0.0      9411  ALL                                                                                             PassthroughCluster
10.200.1.53  14250 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.53  14250 ALL                                                                                             Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.53  14268 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.53  14268 ALL                                                                                             Cluster: outbound|14268||jaeger-collector.istio-system.svc.cluster.local
0.0.0.0      15001 ALL                                                                                             PassthroughCluster
0.0.0.0      15001 Addr: *:15001                                                                                   Non-HTTP/Non-TCP
0.0.0.0      15006 Addr: *:15006                                                                                   Non-HTTP/Non-TCP
0.0.0.0      15006 Trans: tls; App: istio-http/1.0,istio-http/1.1,istio-h2; Addr: 0.0.0.0/0                        InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: raw_buffer; App: http/1.1,h2c; Addr: 0.0.0.0/0                                           InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; App: TCP TLS; Addr: 0.0.0.0/0                                                       InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: raw_buffer; Addr: 0.0.0.0/0                                                              InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; Addr: 0.0.0.0/0                                                                     InboundPassthroughClusterIpv4
0.0.0.0      15006 Trans: tls; App: istio,istio-peer-exchange,istio-http/1.0,istio-http/1.1,istio-h2; Addr: *:3000 Cluster: inbound|3000||
0.0.0.0      15006 Trans: raw_buffer; Addr: *:3000                                                                 Cluster: inbound|3000||
0.0.0.0      15010 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 15010
0.0.0.0      15010 ALL                                                                                             PassthroughCluster
10.200.1.182 15012 ALL                                                                                             Cluster: outbound|15012||istiod.istio-system.svc.cluster.local
0.0.0.0      15014 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 15014
0.0.0.0      15014 ALL                                                                                             PassthroughCluster
0.0.0.0      15021 ALL                                                                                             Inline Route: /healthz/ready*
10.200.1.172 15021 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.172 15021 ALL                                                                                             Cluster: outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
0.0.0.0      15090 ALL                                                                                             Inline Route: /stats/prometheus*
0.0.0.0      16685 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 16685
0.0.0.0      16685 ALL                                                                                             PassthroughCluster
0.0.0.0      20001 Trans: raw_buffer; App: http/1.1,h2c                                                            Route: 20001
0.0.0.0      20001 ALL                                                                                             PassthroughCluster

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction
NAME                                                          DOMAINS                                             MATCH                  VIRTUAL SERVICE
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     
80                                                            istio-ingressgateway.istio-system, 10.200.1.172     /*                     
80                                                            tracing.istio-system, 10.200.1.164                  /*                     
80                                                            webapp, webapp.istioinaction + 1 more...            /*                     
8080                                                          kube-ops-view.kube-system, 10.200.1.144             /*                     
9090                                                          kiali.istio-system, 10.200.1.26                     /*                     
9090                                                          prometheus.istio-system, 10.200.1.104               /*                     
9411                                                          jaeger-collector.istio-system, 10.200.1.53          /*                     
9411                                                          zipkin.istio-system, 10.200.1.6                     /*                     
15010                                                         istiod.istio-system, 10.200.1.182                   /*                     
15014                                                         istiod.istio-system, 10.200.1.182                   /*                     
istio-ingressgateway.istio-system.svc.cluster.local:15021     *                                                   /*                     
jaeger-collector.istio-system.svc.cluster.local:14268         *                                                   /*                     
20001                                                         kiali.istio-system, 10.200.1.26                     /*                     
16685                                                         tracing.istio-system, 10.200.1.164                  /*                     
jaeger-collector.istio-system.svc.cluster.local:14250         *                                                   /*                     
kube-dns.kube-system.svc.cluster.local:9153                   *                                                   /*                     
grafana.istio-system.svc.cluster.local:3000                   *                                                   /*                     
InboundPassthroughClusterIpv4                                 *                                                   /*                     
                                                              *                                                   /stats/prometheus*     
InboundPassthroughClusterIpv4                                 *                                                   /*                     
                                                              *                                                   /healthz/ready*        
inbound|3000||                                                *                                                   /*                     
inbound|3000||                                                *                                                   /*  

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
SERVICE FQDN                                            PORT      SUBSET         DIRECTION     TYPE             DESTINATION RULE
                                                        3000      -              inbound       ORIGINAL_DST     
BlackHoleCluster                                        -         -              -             STATIC           
InboundPassthroughClusterIpv4                           -         -              -             ORIGINAL_DST     
PassthroughCluster                                      -         -              -             ORIGINAL_DST     
agent                                                   -         -              -             STATIC           
catalog.istioinaction.svc.cluster.local                 80        -              outbound      EDS              catalog.istioinaction
catalog.istioinaction.svc.cluster.local                 80        version-v1     outbound      EDS              catalog.istioinaction
catalog.istioinaction.svc.cluster.local                 80        version-v2     outbound      EDS              catalog.istioinaction
grafana.istio-system.svc.cluster.local                  3000      -              outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     80        -              outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     443       -              outbound      EDS              
istio-ingressgateway.istio-system.svc.cluster.local     15021     -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   443       -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   15010     -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   15012     -              outbound      EDS              
istiod.istio-system.svc.cluster.local                   15014     -              outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         9411      -              outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         14250     -              outbound      EDS              
jaeger-collector.istio-system.svc.cluster.local         14268     -              outbound      EDS              
kiali.istio-system.svc.cluster.local                    9090      -              outbound      EDS              
kiali.istio-system.svc.cluster.local                    20001     -              outbound      EDS              
kube-dns.kube-system.svc.cluster.local                  53        -              outbound      EDS              
kube-dns.kube-system.svc.cluster.local                  9153      -              outbound      EDS              
kube-ops-view.kube-system.svc.cluster.local             8080      -              outbound      EDS              
kubernetes.default.svc.cluster.local                    443       -              outbound      EDS              
metrics-server.kube-system.svc.cluster.local            443       -              outbound      EDS              
prometheus.istio-system.svc.cluster.local               9090      -              outbound      EDS              
prometheus_stats                                        -         -              -             STATIC           
sds-grpc                                                -         -              -             STATIC           
tracing.istio-system.svc.cluster.local                  80        -              outbound      EDS              
tracing.istio-system.svc.cluster.local                  16685     -              outbound      EDS              
webapp.istioinaction.svc.cluster.local                  80        -              outbound      EDS              
xds-grpc                                                -         -              -             STATIC           
zipkin                                                  -         -              -             STRICT_DNS       
zipkin.istio-system.svc.cluster.local                   9411      -              outbound      EDS   

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.10:53                                           HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.10:9153                                         HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.11:8080                                         HEALTHY     OK                outbound|8080||kube-ops-view.kube-system.svc.cluster.local
10.10.0.12:9090                                         HEALTHY     OK                outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.13:8080                                         HEALTHY     OK                outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:8443                                         HEALTHY     OK                outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.13:15021                                        HEALTHY     OK                outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                inbound|3000||
10.10.0.14:3000                                         HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.16:8080                                         HEALTHY     OK                outbound|80||webapp.istioinaction.svc.cluster.local
10.10.0.2:53                                            HEALTHY     OK                outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.2:9153                                          HEALTHY     OK                outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.3:3000                                          HEALTHY     OK                outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:9411                                          HEALTHY     OK                outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.4:14250                                         HEALTHY     OK                outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:14268                                         HEALTHY     OK                outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.4:16685                                         HEALTHY     OK                outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.4:16686                                         HEALTHY     OK                outbound|80||tracing.istio-system.svc.cluster.local
10.10.0.6:10250                                         HEALTHY     OK                outbound|443||metrics-server.kube-system.svc.cluster.local
10.10.0.8:15010                                         HEALTHY     OK                outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.8:15012                                         HEALTHY     OK                outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.8:15014                                         HEALTHY     OK                outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.8:15017                                         HEALTHY     OK                outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.9:9090                                          HEALTHY     OK                outbound|9090||kiali.istio-system.svc.cluster.local
10.10.0.9:20001                                         HEALTHY     OK                outbound|20001||kiali.istio-system.svc.cluster.local
10.200.1.6:9411                                         HEALTHY     OK                zipkin
127.0.0.1:15000                                         HEALTHY     OK                prometheus_stats
127.0.0.1:15020                                         HEALTHY     OK                agent
172.19.0.2:6443                                         HEALTHY     OK                outbound|443||kubernetes.default.svc.cluster.local
unix://./etc/istio/proxy/XDS                            HEALTHY     OK                xds-grpc
unix://./var/run/secrets/workload-spiffe-uds/socket     HEALTHY     OK                sds-grpc


# webapp istio-proxy 로그 활성화
# 신규 터미널
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f

# webapp istio-proxy 로그 활성화 적용
cat << EOF | kubectl apply -f -
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: webapp
  namespace: istioinaction
spec:
  selector:
    matchLabels:
      app: webapp
  accessLogging:
  - providers:
    - name: envoy #2 액세스 로그를 위한 프로바이더 설정
    disabled: false #3 disable 를 false 로 설정해 활성화한다
EOF

# webapp → catalog 는 k8s service(clusterIP) 라우팅 사용 확인!
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
[2025-04-26T11:55:50.148Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 8 7 "192.168.65.1" "curl/8.13.0" "30cebb96-305a-4764-88bc-e38d6ca72781" "webapp.istioinaction.io:30000" "10.10.0.16:8080" inbound|8080|| 127.0.0.6:41909 10.10.0.16:8080 192.168.65.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
=> 이 로그는 webapp 서비스의 사이드카 프록시가 클라이언트로부터 직접 HTTP 요청을 받은 장면이고, 이 요청을 10.10.0.16:8080 (즉, webapp 서비스의 실제 컨테이너)으로 보냄을 의미
[2025-04-26T11:55:50.973Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 698 3 2 "192.168.65.1" "beegoServer" "9f3517f7-1848-4d04-bf5b-cef53f09dd95" "catalog.istioinaction:80" "10.10.0.15:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.16:46044 10.200.1.174:80 192.168.65.1:0 - default
=>  이 로그는 webapp 서비스가 catalog 서비스로 HTTP 요청을 보낸 상황이에요. Envoy는 catalog.istioinaction이라는 Kubernetes catalog 서비스(clusterIp 10.200.1.174:80)로 라우팅하고, 실제 Pod IP는 10.10.0.15:3000으로 연결되었어요.
...


  • Let’s create VirtualService and DestinationRule resources that route all traffic to v1 of the catalog service
#
ch5/catalog-dest-rule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: catalog
spec:
  host: catalog.istioinaction.svc.cluster.local
  subsets:
  - name: version-v1
    labels:
      version: v1
  - name: version-v2
    labels:
      version: v2
      
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction

# istio-proxy
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN                                PORT     SUBSET         DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       -              outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v1     outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v2     outbound      EDS      catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000                                         HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.16:8080                                         HEALTHY     OK                outbound|80||webapp.istioinaction.svc.cluster.local

#
cat ch5/catalog-vs-v1-mesh.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: catalog
spec:
  hosts:
  - catalog
  gateways: # 만약, gateways 부분을 제외하고 배포하면 암묵적으로 mesh gateways가 적용됨.
    - mesh  # VirtualService는 메시 내의 모든 사이드카(현재 webapp, catalog)에 적용된다. edge는 제외.
  http:
  - route:
    - destination:
        host: catalog
        subset: version-v1

kubectl apply -f ch5/catalog-vs-v1-mesh.yaml -n istioinaction
virtualservice.networking.istio.io/catalog created

# VirtualService 확인 : GATEWAYS 에 mesh 확인
kubectl get vs -n istioinaction
NAME                    GATEWAYS                HOSTS                          AGE
catalog                 ["mesh"]                ["catalog"]                    6m44s
catalog-vs-from-gw      ["catalog-gateway"]     ["catalog.istioinaction.io"]   4h39m
webapp-virtualservice   ["coolstore-gateway"]   ["webapp.istioinaction.io"]    88m


# 반복 호출테스트 : 신규터미널 2개에 아래 각각 실행 해두기 >> 현재는 v1만 라우팅 처리
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -H "x-istio-cohort: internal" -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 2; echo; done


# webapp → catalog 호출도 istio 의 DestinationRule 라우팅 전달 처리! : 신규터미널
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
[2025-04-26T13:09:36.374Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "192.168.65.1" "beegoServer" "92af0393-d73f-4731-8c9a-1e8fb43b428e" "catalog.istioinaction:80" "10.10.0.14:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.16:45786 10.200.1.174:80 192.168.65.1:0 - -
=> 이 로그는 webapp이 내부적으로 catalog 서비스를 호출하는 로그이고, version-v1이라는 **서브셋(subset)**으로 요청이 라우팅되었어요. 이는 DestinationRule에서 subset: version-v1으로 정의된 엔드포인트로 라우팅이 잘 되었다는 뜻이에요. 


# proxy-config (webapp) : 기존에 webapp 에서 catalog 로 VirtualService 정보는 없었는데, 추가됨을 확인
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction | egrep 'NAME|catalog'
NAME                                                          DOMAINS                                             MATCH                  VIRTUAL SERVICE
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction --name 80 -o json > webapp-routes.json
cat webapp-routes.json | jq
...
    "virtualHosts": [
      {
        "name": "catalog.istioinaction.svc.cluster.local:80",
        "domains": [
          "catalog.istioinaction.svc.cluster.local",
          "catalog",
          "catalog.istioinaction.svc",
          "catalog.istioinaction",
          "10.200.1.174" # 해당 IP는 catalog service(clusterIP)
        ],
        "routes": [
          {
            "match": {
              "prefix": "/"
            },
            "route": {
              "cluster": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
              "timeout": "0s",
...


docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN                                PORT     SUBSET         DIRECTION     TYPE     DESTINATION RULE
catalog.istioinaction.svc.cluster.local     80       -              outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v1     outbound      EDS      catalog.istioinaction
catalog.istioinaction.svc.cluster.local     80       version-v2     outbound      EDS      catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --subset version-v1 -o json
...
        "name": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
        "type": "EDS",
...

docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction | egrep 'ENDPOINT|catalog'
ENDPOINT                                                STATUS      OUTLIER CHECK     CLUSTER
10.10.0.14:3000                                         HEALTHY     OK                outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.14:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.15:3000                                         HEALTHY     OK                outbound|80||catalog.istioinaction.svc.cluster.local

# proxy-config (catalog) : gateway.mesh 이므로, 메시 내에 모든 사이드카에 VirtualService 적용됨을 확인. 아래 routes 부분
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction | egrep 'NAME|catalog'
NAME                                                          DOMAINS                                             MATCH                  VIRTUAL SERVICE
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction

#
cat ch5/catalog-vs-v2-request-mesh.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: catalog
spec:
  hosts:
  - catalog
  gateways:
    - mesh
  http:
  - match:
    - headers:
        x-istio-cohort:
          exact: "internal"
    route:
    - destination:
        host: catalog
        subset: version-v2
  - route:
    - destination:
        host: catalog
        subset: version-v1

kubectl apply -f ch5/catalog-vs-v2-request-mesh.yaml -n istioinaction
virtualservice.networking.istio.io/catalog configured

# 반복 호출테스트 : 신규터미널 2개에 아래 각각 실행 >> v1, v2 각기 라우팅 확인
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -H "x-istio-cohort: internal" -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 2; echo; done


# proxy-config (webapp) : 기존에 webapp 에서 catalog 로 VirtualService 추가된 2개 항목 확인
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction | egrep 'NAME|catalog'
NAME                                                          DOMAINS                                             MATCH                  VIRTUAL SERVICE
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     catalog.istioinaction
80                                                            catalog, catalog.istioinaction + 1 more...          /*                     catalog.istioinaction

docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction --name 80 -o json > webapp-routes.json
cat webapp-routes.json | jq
...
        "virtualHosts": [
            {
                "name": "catalog.istioinaction.svc.cluster.local:80",
                "domains": [
                    "catalog.istioinaction.svc.cluster.local",
                    "catalog",
                    "catalog.istioinaction.svc",
                    "catalog.istioinaction",
                    "10.200.1.206"
                ],
                "routes": [
                    {
                        "match": {
                            "prefix": "/",
                            "caseSensitive": true,
                            "headers": [
                                {
                                    "name": "x-istio-cohort",
                                    "stringMatch": {
                                        "exact": "internal"
                                    }
                                }
                            ]
                        },
                        "route": {
                            "cluster": "outbound|80|version-v2|catalog.istioinaction.svc.cluster.local",
                     ....
                    {
                        "match": {
                            "prefix": "/"
                        },
                        "route": {
                            "cluster": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
...


docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn catalog.istioinaction.svc.cluster.local
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction | egrep 'ENDPOINT|catalog'

# proxy-config (catalog) : mesh 이므로 VS가 아래 routes(catalog)에도 적용됨
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction

1.5.7 Traffic shifting

💘 Manual Canary Release: 가중치로 트래픽을 천천히 넘기는 방법

서비스를 점진적으로 릴리스하는 또 다른 방법,
가중치 기반 카나리 배포에 대해 알아보겠습니다.

이전에는 헤더 기반 라우팅을 이용해 특정 사용자 그룹(예: 내부 직원)에게만
새 버전을 다크 런치하는 방법을 살펴봤는데요,
이번에는 실제 라이브 트래픽을 버전별로 가중치를 나누어 배포하는 방식을 소개하려 합니다.

🤔 왜 가중치 기반 카나리 배포를 할까?

예를 들어, 우리가 catalog 서비스의 새로운 버전인 v2를 다크 런치한 상태라고 해봅시다.
이제 이 v2 버전을 모든 사용자에게 조금씩 노출시키고 싶다면,
v2에 10% 트래픽만 보내도록 설정할 수 있습니다.

  • 전체 트래픽의 90%는 여전히 안정적인 v1으로,
  • 나머지 10%는 새로 출시한 v2로 가는 거죠.

이렇게 하면, 새 버전이 시스템 전체에 미치는 영향을 점진적으로 확인할 수 있어
릴리스로 인한 위험을 크게 줄일 수 있습니다.

😂 문제가 생기면?

다크 런치 때와 마찬가지로, 새 버전에서 에러나 장애가 발생하는지 모니터링합니다.
문제가 발견되면?
롤백은 아주 간단합니다.
그냥 v2로 향하는 트래픽 가중치를 줄이면 됩니다.
필요하면 0%로 만들어서 v2 트래픽을 아예 차단할 수도 있죠.

✅ 이스티오로 어떻게 할까?

Istio 같은 서비스 메시는 이런 가중치 기반 트래픽 분배를 아주 쉽게 설정할 수 있습니다.
Istio를 이용해 실제로 가중치 조정하는 방법을 구체적으로 알아볼게요!

✅ Istio로 가중치 기반 카나리 배포하기

앞서 가중치로 트래픽을 나누는 개념을 살펴봤죠?
이번에는 Istio를 사용해 실제로 catalog 서비스의 트래픽을 v1과 v2로 분배하는 방법을 알아보겠습니다.

Istio에서는 VirtualService 리소스를 이용해 트래픽 분배를 설정할 수 있습니다.
아래는 예시 YAML입니다:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: catalog
spec:
  hosts:
  - catalog.default.svc.cluster.local
  http:
  - route:
    - destination:
        host: catalog
        subset: v1
      weight: 90
    - destination:
        host: catalog
        subset: v2
      weight: 10

✅ 이 설정이 의미하는 것

  • catalog 서비스로 들어오는 모든 요청은
    90%는 v1, 10%는 v2로 라우팅됩니다.
  • subsetDestinationRule에서 정의하는 버전 구분입니다.
    (예를 들어, v1v2는 각각의 레이블을 가진 버전)

그래서 이 설정을 적용하면, 사용자는 특별히 인식하지 못한 채 자연스럽게 일부만 새 버전(v2)을 사용하게 됩니다.

✅ 추가로 필요한 설정: DestinationRule

아까 subset: v1, subset: v2 얘기가 나왔죠?
이걸 사용하려면 DestinationRule도 미리 정의해줘야 합니다.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: catalog
spec:
  host: catalog.default.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

여기서는

  • version: v1 레이블을 가진 pod는 v1 subset으로,
  • version: v2 레이블을 가진 pod는 v2 subset으로 매칭됩니다.
    (※ 따라서 catalog 서비스 뒤에 v1, v2 버전 pod들이 각각 떠 있어야 해요!)

✅ 트래픽 가중치 조정은?

  • 문제없이 운영된다면 v2의 weight를 점진적으로 늘려가면서 트래픽을 30%, 50%, 70%, 마지막엔 100%까지 늘리는 식으로 롤아웃을 완료할 수 있습니다.

  • 반대로 문제가 생기면? v2의 weight를 0으로 줄이고,
    모든 트래픽을 다시 v1으로 보내면 됩니다.

🎯 이렇게 Istio를 이용하면 복잡한 코드 수정 없이 트래픽만 제어해서 안전하게 카나리 배포를 진행할 수 있습니다. 실제 운영 환경에서는 모니터링과 함께 이 방법을 꼭 병행하는 걸 추천합니다.

1.5.8 Reducing risk even further: Traffic mirroring

앞서 요청 수준 라우팅트래픽 가중치 전환을 이용해 새 버전을 점진적으로 릴리스하면서 위험을 제어하는 방법을 알아봤습니다.

하지만 이 방법들은 모두 실제 사용자 요청을 새 버전으로 일부 보내기 때문에, 아무리 조심해도 사용자에게 일정 부분 영향이 갈 수밖에 없었습니다.

✅ 트래픽 미러링은 다른 접근이다!

Traffic Mirroring(트래픽 미러링) 은 라이브 트래픽을 진짜 서비스로 보내는 동시에, 복사본을 새 버전의 서비스로 보내는 방법입니다.

  • 사용자는 기존 서비스(v1)만 사용합니다.
  • 새 버전(v2)은 실제 트래픽을 읽기 전용으로 받아 테스트합니다.
  • 사용자에게는 전혀 영향이 가지 않습니다!

이 방식을 사용하면, 운영 환경 트래픽을 기반으로 새 버전이 실제로 어떻게 동작하는지 진짜로 테스트할 수 있습니다.

결론적으로: 트래픽 미러링은 릴리스 위험을 최소화할 수 있는 매우 안전한 전략입니다.

✅ Istio에서 트래픽 미러링 설정 예시
Istio에서는 VirtualServicemirror 필드를 추가해서 쉽게 설정할 수 있습니다.

아래는 예시 YAML입니다:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: catalog
spec:
  hosts:
  - catalog.default.svc.cluster.local
  http:
  - route:
    - destination:
        host: catalog
        subset: v1
  mirror:
    host: catalog
    subset: v2
  mirrorPercentage:
    value: 100.0

🤔 이 설정이 의미하는 것

  • 모든 트래픽은 기본적으로 v1 서비스로 정상적으로 처리됩니다.
  • 동시에, 동일한 요청이 v2 서비스로 복사(mirror) 됩니다.
  • v2는 요청을 받아서 처리하지만, 사용자에게 응답은 하지 않습니다. (완전 독립)

mirrorPercentage를 조절하면, 예를 들어 50%만 미러링하는 것도 가능합니다.

mirrorPercentage:
  value: 50.0

(=> 2개 요청 중 1개만 v2로 복사)

✍🏿 정리

방법사용자 영향주요 특징
가중치 기반 카나리 릴리스있음일부 사용자만 새 버전 사용
트래픽 미러링없음사용자 영향 없이 새 버전 검증 가능

트래픽 미러링은
배포 전 최종 점검이나
운영 환경 데이터 기반 실전 테스트를 하고 싶을 때
가장 안전한 방법입니다.

1.5.9 Routing to services outside your cluster by using Istio’s service discovery

✅ 기본 동작

  • 기본적으로, Istio는 서비스 메시 바깥으로 트래픽이 나가는 것을 허용한다.
  • 예를 들어, 애플리케이션이 외부 웹사이트나 외부 API 서버와 통신하려고 하면, Istio는 이를 막지 않고 통과시킨다.
  • 모든 트래픽은 사이드카 프록시(Envoy) 를 거치므로, Istio 정책을 통해 이 트래픽을 제어할 수 있다.

✅ 외부 트래픽 차단 설정

  • Istio 기본 정책을 변경해, 메시를 벗어나는 모든 트래픽을 차단할 수 있다.
  • 이렇게 하면, 만약 메시 내 서비스가 해킹됐을 경우, 공격자가 외부 서버(자신이 통제하는 서버)로 연결을 시도하는 것을 차단할 수 있다.
  • 이 접근은 심층 방어 전략의 일부다.

✅ 주의할 점

  • Istio만으로는 100% 방어할 수 없다.
  • 해킹된 파드가 사이드카 프록시를 우회하려는 시도를 할 수 있다.
  • 따라서, Istio 정책 외에도, 네트워크 레벨(3계층/4계층) 방화벽이나 네트워크 폴리시 같은 추가 보안이 필요하다.

✅ 보안 위협 예시

  • 만약 공격자가 서비스 취약점을 이용해 컨테이너를 장악하면, 악성 코드를 심어 자신이 제어하는 외부 서버와 통신하거나, 회사의 민감 데이터와 지적 재산권을 탈취할 수 있다.

➡️ Istio에서 외부 트래픽 제어하기

  • Istio에서는 meshConfig 설정Egress 규칙을 통해 외부로 나가는 트래픽을 제어하거나 허용할 수 있어요. 아래는 실무에서 주로 사용하는 방법입니다.

➡️ 1. 기본 정책 바꾸기: meshConfig 수정

  • Istio의 기본 설정은 "외부 트래픽 허용(ALLOW_ANY)"입니다. 이를 차단하려면 meshConfig에서 outboundTrafficPolicy를 수정해야 해요.

➡️ 수정 방법

  • Istio 설치할 때, 또는 IstioOperator를 쓸 때 이렇게 설정합니다:
meshConfig:
  outboundTrafficPolicy:
    mode: REGISTRY_ONLY
  • ALLOW_ANY (기본값): 등록되지 않은 외부 서비스로 자유롭게 나감.
  • REGISTRY_ONLY: 서비스 레지스트리에 등록된 것만 허용, 나머지는 모두 차단.

➡️ REGISTRY_ONLY로 설정하면, 명시적으로 등록한 외부 서비스만 통신할 수 있습니다.


🎯 외부 서비스 등록하기: ServiceEntry 사용

REGISTRY_ONLY 모드에서는 외부 서비스로 나가려면 ServiceEntry 리소스를 만들어야 합니다.

🎯 예시: 외부 API 서버 (https://api.example.com) 허용하기

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: allow-api-example
spec:
  hosts:
  - "api.example.com"
  location: MESH_EXTERNAL
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS

설명:

  • hosts: 접근하려는 외부 도메인
  • location: MESH_EXTERNAL: 메시 외부 서비스임을 명시
  • ports: 연결할 포트와 프로토콜 지정
  • resolution: DNS: DNS 이름으로 라우팅

이렇게 등록하면, api.example.com으로 가는 트래픽만 허용되고, 나머지는 모두 차단됩니다.


🍎 3. 실제 흐름 요약

설정 항목내용
meshConfig outboundTrafficPolicy.modeREGISTRY_ONLY로 설정해 외부 차단
ServiceEntry필요한 외부 서비스만 허용 등록

2. Resilience: Solving application networking challenges

  • 회복탄력성의 중요성 이해 Understanding the importance of resilience
  • 클라이언트 측 로드 밸런싱 활용 Leveraging client-side load balancing
  • 요청 시간 초과 및 재시도 구현 Implementing request timeouts and retries
  • 회로 차단 및 연결 풀링 Circuit breaking and connection pooling
  • 마이그레이션 Migrating from application libraries used for resilience

2.1 실습환경 구성

  • [실습 환경 구성] k8s(1.23.17) 배포 : NodePort(30000 HTTP, 30005 HTTPS)
#
git clone https://github.com/AcornPublishing/istio-in-action
cd istio-in-action/book-source-code-master
pwd # 각자 자신의 pwd 경로
code .

# 아래 extramounts 생략 시, myk8s-control-plane 컨테이너 sh/bash 진입 후 직접 git clone 가능
kind create cluster --name myk8s --image kindest/node:v1.23.17 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000 # Sample Application (istio-ingrssgateway) HTTP
    hostPort: 30000
  - containerPort: 30001 # Prometheus
    hostPort: 30001
  - containerPort: 30002 # Grafana
    hostPort: 30002
  - containerPort: 30003 # Kiali
    hostPort: 30003
  - containerPort: 30004 # Tracing
    hostPort: 30004
  - containerPort: 30005 # Sample Application (istio-ingrssgateway) HTTPS
    hostPort: 30005
  - containerPort: 30006 # TCP Route
    hostPort: 30006
  - containerPort: 30007 # kube-ops-view
    hostPort: 30007
  extraMounts: # 해당 부분 생략 가능
  - hostPath: /Users/sjkim/Labs/CloudNeta/istio/istio-in-action/book-source-code-master # 각자 자신의 pwd 경로로 설정
    containerPath: /istiobook
networking:
  podSubnet: 10.10.0.0/16
  serviceSubnet: 10.200.1.0/24
EOF

# 설치 확인
docker ps

# 노드에 기본 툴 설치
docker exec -it myk8s-control-plane sh -c 'apt update && apt install tree psmisc lsof wget bridge-utils net-tools dnsutils tcpdump ngrep iputils-ping git vim -y'

# (옵션) kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30007 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view

## kube-ops-view 접속 URL 확인
open "http://localhost:30007/#scale=1.5"
open "http://localhost:30007/#scale=1.3"

# (옵션) metrics-server
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm install metrics-server metrics-server/metrics-server --set 'args[0]=--kubelet-insecure-tls' -n kube-system
kubectl get all -n kube-system -l app.kubernetes.io/instance=metrics-server
  • [실습 환경 구성] istio 1.17.8 설치 (addon 필수, istio-proxy log 설정)
# myk8s-control-plane 진입 후 설치 진행
docker exec -it myk8s-control-plane bash
-----------------------------------
# (옵션) 코드 파일들 마운트 확인
tree /istiobook/ -L 1
혹은
git clone ... /istiobook

# istioctl 설치
export ISTIOV=1.17.8
echo 'export ISTIOV=1.17.8' >> /root/.bashrc

curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV sh -
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
istioctl version --remote=false

# default 프로파일 컨트롤 플레인 배포
istioctl install --set profile=default -y

# 설치 확인 : istiod, istio-ingressgateway, crd 등
kubectl get istiooperators -n istio-system -o yaml
kubectl get all,svc,ep,sa,cm,secret,pdb -n istio-system
kubectl get cm -n istio-system istio -o yaml
kubectl get crd | grep istio.io | sort

# 보조 도구 설치
kubectl apply -f istio-$ISTIOV/samples/addons
kubectl get pod -n istio-system

# 빠져나오기
exit
-----------------------------------

# istio-proxy 로그 출력 설정 : configmap 에 mesh 바로 아래에 accessLogFile 부분 추가
KUBE_EDITOR="nano"  kubectl edit cm -n istio-system istio
...
  mesh: |-
    accessLogFile: /dev/stdout
...

# 실습을 위한 네임스페이스 설정
kubectl create ns istioinaction
kubectl label namespace istioinaction istio-injection=enabled
kubectl get ns --show-labels

# istio-ingressgateway 서비스 : NodePort 변경 및 nodeport 지정 변경 , externalTrafficPolicy 설정 (ClientIP 수집)
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 8080, "nodePort": 30000}]}}'
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 443, "targetPort": 8443, "nodePort": 30005}]}}'
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"externalTrafficPolicy": "Local"}}'
kubectl describe svc -n istio-system istio-ingressgateway

# NodePort 변경 및 nodeport 30001~30003으로 변경 : prometheus(30001), grafana(30002), kiali(30003), tracing(30004)
kubectl patch svc -n istio-system prometheus -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 30001}]}}'
kubectl patch svc -n istio-system grafana -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "targetPort": 3000, "nodePort": 30002}]}}'
kubectl patch svc -n istio-system kiali -p '{"spec": {"type": "NodePort", "ports": [{"port": 20001, "targetPort": 20001, "nodePort": 30003}]}}'
kubectl patch svc -n istio-system tracing -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 16686, "nodePort": 30004}]}}'

# Prometheus 접속 : envoy, istio 메트릭 확인
open http://127.0.0.1:30001

# Grafana 접속
open http://127.0.0.1:30002

# Kiali 접속 1 : NodePort
open http://127.0.0.1:30003

# (옵션) Kiali 접속 2 : Port forward
kubectl port-forward deployment/kiali -n istio-system 20001:20001 &
open http://127.0.0.1:20001

# tracing 접속 : 예거 트레이싱 대시보드
open http://127.0.0.1:30004


# 접속 테스트용 netshoot 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: netshoot
spec:
  containers:
  - name: netshoot
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

2.2 Building resilience into the application

  1. [복원력 패턴 필요성]
  • 마이크로서비스는 복원력을 최우선으로 고려해 설계해야 한다.
  • "장애가 안 나게 만들면 된다"는 건 비현실적이다. 장애는 언젠가 발생하며, 분산 시스템에서는 장애 지점이 더 많아진다.
  • 장애가 발생하면 전체 서비스 중단으로 이어질 수 있다.
  • 서비스 소유자는 애플리케이션 전반에 복원력 패턴을 일관되게 적용해야 한다.
  1. [장애 상황 예시]
  • 서비스 A가 서비스 B를 호출할 때 B의 특정 엔드포인트에서 지연이 생길 수 있다.
    이때 A는 다른 엔드포인트, 가용 영역, 리전으로 자동 라우팅할 수 있어야 한다.
  • 서비스 B가 가끔 오류를 낸다면 재시도(Retry) 를 시도할 수 있다.
  • 문제가 지속되면 백오프하거나 더 이상의 요청을 중단해야 한다.
  • 무작정 재시도하면 오히려 부하를 악화시켜 연쇄 장애를 일으킬 수 있다.
  1. [해결 방향]
  • 애플리케이션은 장애를 예상하고, 재시도(Retry), 타임아웃(Timeout), 서킷 브레이커(Circuit Breaker) 같은 복원력 패턴을 자동 적용해야 한다.
  • 이스티오(Istio) 를 이용해 언어와 무관하게 복원력을 투명하게 구현한다.

2.3 로드 밸런싱

2.3.1 Client-side Load Balancing

  • 개념: 요청을 보내는 클라이언트가 여러 서버 인스턴스 중 어디로 보낼지 스스로 선택.
  • 방식:
    • 클라이언트는 서버 인스턴스 목록(Endpoint 목록)을 미리 알고 있거나,
    • 서비스 디스커버리를 통해 주기적으로 갱신함.
  • 장점:
    • 중앙 집중형 로드밸런서 없이 분산 처리 가능 → 스케일이 잘 됨.
    • 네트워크 홉(Hop)이 줄어들어 지연(latency) 을 줄일 수 있음.
  • 단점:
    • 각 클라이언트가 인스턴스 목록을 관리해야 하므로 복잡성 증가.
    • 서버 추가/삭제 이벤트를 제대로 처리하지 않으면 문제가 생길 수 있음.
  • 대표 예시:
    • Netflix Ribbon (EOL), Spring Cloud LoadBalancer
    • gRPC Client-side load balancing
    • Envoy Proxy (사이드카)

2.3.2 Server-side Load Balancing

  • 개념: 클라이언트는 그냥 요청을 하나의 로드밸런서에 보냄. 로드밸런서가 트래픽을 적절한 서버 인스턴스로 분배.
  • 방식:
    • 로드밸런서(ELB, Nginx, Istio Gateway 등)가 서버 상태와 부하를 감지해 트래픽을 분배.
  • 장점:
    • 클라이언트는 복잡한 로직이 필요 없음 → 구현이 간단.
    • 서버 인스턴스 추가/삭제에 대해 클라이언트가 몰라도 됨 → 관리 편리.
  • 단점:
    • 로드밸런서가 병목이 될 수 있음.
    • 로드밸런서 장애 시 전체 장애 위험.
    • 로드밸런서까지 한 번 더 네트워크 홉이 추가됨 → 지연 증가 가능성.
  • 대표 예시:
    • AWS Elastic Load Balancer(ELB)
    • Kubernetes Service(Type=LoadBalancer)
    • Istio Ingress Gateway + 내부 DestinationRule

2.3.3 로드밸런싱 방식별 비교

항목클라이언트 사이드서버 사이드
누가 로드밸런싱?클라이언트로드밸런서 서버
장점분산, 낮은 지연단순한 클라이언트
단점복잡성, 상태 관리 필요병목/지연 가능성
예시Ribbon, EnvoyELB, Nginx, Istio Gateway

2.3.4 요약

추가로, Istio는 사실 양쪽 모델을 모두 결합해서 사용해!
→ Envoy 사이드카가 클라이언트 사이드처럼 동작하지만, 중앙 Pilot/Control Plane이 서버사이드처럼 인스턴스 목록을 관리해줌.

2.4 Istio의 로드밸런싱 아키텍처

2.4.1 제어 플레인(Control Plane)

  • Istiod (기존에는 Pilot이라고도 불림)이
    클러스터 내 모든 서비스 인스턴스 정보(IP, 포트, 상태 등)를 주기적으로 관리해.
  • Envoy 프록시(사이드카)에게
    필요한 라우팅 테이블, 서비스 엔드포인트 목록푸시(push) 해준다.
  • 클라이언트(Envoy)가 직접 서비스 디스커버리하는 게 아니라, Istiod가 대신 해주는 것.

2.4.2 데이터 플레인(Data Plane)

  • Envoy 사이드카가 클라이언트 요청을 대신 처리.
  • 클라이언트 앱은 그냥 Envoy에 요청을 보내기만 하면 됨 → 스마트 프록시가 로드밸런싱.
  • Envoy는 내부에 받은 엔드포인트 목록을 기반으로 직접 서버 인스턴스를 선택해서 로드밸런싱함.
  • 즉, 클라이언트 사이드 로드밸런싱처럼 작동하지만, 서비스 인스턴스 정보 갱신은 서버 사이드(Istiod)에서 중앙 관리.

2.4.3 요약하면

항목설명
서비스 디스커버리Istiod가 관리 (서버사이드)
로드밸런싱 결정Envoy가 직접 (클라이언트사이드)
클라이언트 앱별다른 로드밸런싱 로직 없이 사용 가능
장점- 앱 수정 없이 고급 복원력 기능 적용 가능 - 스케일 아웃/장애 상황에 빠르게 반응 가능

2.4.4 흐름도

[서비스 인스턴스 상태 감지] → [Istiod가 Envoy에게 업데이트 전송] → [Envoy가 로컬에서 로드밸런싱 결정] → [최적의 서버로 직접 요청]

2.4.5 Retry 설정(재시도)

  • 네트워크 실패를 대비해 재시도는 필요하지만,
  • 무분별한 재시도는 오히려 시스템을 망가뜨릴 수 있다.
  • 특히, 서비스가 과부하 상태일 때는 재시도가 문제를 악화시킬 수 있다.
    Istio는 기본적으로 요청을 두 번까지 자동 재시도한다.
  • 기본 동작을 이해하고, 필요하면 VirtualService에서 retries.attempts: 0으로 설정해 재시도를 비활성화할 수 있다.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: service-b-retry
spec:
  hosts:
  - service-b.default.svc.cluster.local
  http:
  - retries:
      attempts: 3        # 최대 3번 재시도
      perTryTimeout: 2s  # 각각의 재시도는 2초 타임아웃
      retryOn: gateway-error,connect-failure,refused-stream
    route:
    - destination:
        host: service-b

설명:

  • service-b 호출이 실패(gateway-error 등)하면 2초 이내 재시도.
  • 최대 3번까지 재시도.

2.4.6 Timeout 설정(요청 제한 시간)

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: service-b-timeout
spec:
  hosts:
  - service-b.default.svc.cluster.local
  http:
  - timeout: 5s         # 요청 하나당 5초 타임아웃
    route:
    - destination:
        host: service-b

설명:

  • 요청이 5초를 넘으면 Envoy가 요청을 실패로 간주하고 끊는다.

2.4.7 Circuit Breaker 설정(서킷 브레이커)

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: service-b-circuit-breaker
spec:
  host: service-b.default.svc.cluster.local
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 50
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 50

설명:

  • 5xx 에러가 5번 연속 나오면 30초 동안 해당 인스턴스를 제외.
  • 동시에 50%까지만 인스턴스를 제외한다 (완전히 죽이지 않음).

2.4.8 Failover 설정 (다른 지역/엔드포인트로 대체)

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: service-b-failover
spec:
  host: service-b.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    outlierDetection:
      consecutive5xxErrors: 2
      interval: 5s
      baseEjectionTime: 15s
    subsets:
    - name: primary
      labels:
        version: v1
    - name: secondary
      labels:
        version: v2
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: service-b-failover-vs
spec:
  hosts:
  - service-b.default.svc.cluster.local
  http:
  - route:
    - destination:
        host: service-b
        subset: primary
      weight: 100
    - destination:
        host: service-b
        subset: secondary
      weight: 0

설명:

  • 기본은 v1(primary) 로 트래픽 보냄.
  • 문제가 생기면 v2(secondary) 로 트래픽 자동 Failover.
profile
I'm SJ

0개의 댓글