Istio 3주차 정리
☸️ k8s(1.23.17) 배포 : NodePort(30000 HTTP, 30005 HTTPS)
1. 소스 코드 다운로드
1
2
3
4
5
6
git clone https://github.com/AcornPublishing/istio-in-action
cd istio-in-action/book-source-code-master
pwd
# 결과
/home/devshin/workspace/istio/istio-in-action/book-source-code-master
2. Kind 클러스터 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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: /home/devshin/workspace/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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
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
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
3. 클러스터 생성 확인
1
docker ps
✅ 출력
1
2
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2af1c16eea85 kindest/node:v1.23.17 "/usr/local/bin/entr…" 46 seconds ago Up 46 seconds 0.0.0.0:30000-30007->30000-30007/tcp, 127.0.0.1:38279->6443/tcp myk8s-control-plane
4. 노드에 기본 툴 설치
1
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'
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vim (vim) in auto mode
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vimdiff (vimdiff) in auto mode
Setting up bind9-libs:amd64 (1:9.18.33-1~deb12u2) ...
Setting up openssh-client (1:9.2p1-2+deb12u5) ...
Setting up libxext6:amd64 (2:1.3.4-1+b1) ...
Setting up dbus-daemon (1.14.10-1~deb12u1) ...
Setting up libnet1:amd64 (1.1.6+dfsg-3.2) ...
Setting up libpcap0.8:amd64 (1.10.3-1) ...
Setting up dbus (1.14.10-1~deb12u1) ...
invoke-rc.d: policy-rc.d denied execution of start.
/usr/sbin/policy-rc.d returned 101, not running 'start dbus.service'
Setting up libgdbm-compat4:amd64 (1.23-3) ...
Setting up xauth (1:1.1.2-1) ...
Setting up bind9-host (1:9.18.33-1~deb12u2) ...
Setting up libperl5.36:amd64 (5.36.0-7+deb12u2) ...
Setting up tcpdump (4.99.3-1) ...
Setting up ngrep (1.47+ds1-5+b1) ...
Setting up perl (5.36.0-7+deb12u2) ...
Setting up bind9-dnsutils (1:9.18.33-1~deb12u2) ...
Setting up dnsutils (1:9.18.33-1~deb12u2) ...
Setting up liberror-perl (0.17029-2) ...
Setting up git (1:2.39.5-0+deb12u2) ...
Processing triggers for libc-bin (2.36-9+deb12u4) ...
🛡️ Istio 1.17.8 설치 (addon 필수)
1. myk8s-control-plane 진입
1
2
docker exec -it myk8s-control-plane bash
root@myk8s-control-plane:/#
2. (옵션) 코드 파일 마운트 확인
1
root@myk8s-control-plane:/# tree /istiobook/ -L 1
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/istiobook/
|-- README.md
|-- appendices
|-- bin
|-- ch10
|-- ch11
|-- ch12
|-- ch13
|-- ch14
|-- ch2
|-- ch3
|-- ch4
|-- ch5
|-- ch6
|-- ch7
|-- ch8
|-- ch9
`-- services
17 directories, 1 file
3. istioctl 설치
1
2
3
4
5
6
root@myk8s-control-plane:/# 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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Downloading istio-1.17.8 from https://github.com/istio/istio/releases/download/1.17.8/istio-1.17.8-linux-amd64.tar.gz ...
Istio 1.17.8 download complete!
The Istio release archive has been downloaded to the istio-1.17.8 directory.
To configure the istioctl client tool for your workstation,
add the /istio-1.17.8/bin directory to your environment path variable with:
export PATH="$PATH:/istio-1.17.8/bin"
Begin the Istio pre-installation check by running:
istioctl x precheck
Try Istio in ambient mode
https://istio.io/latest/docs/ambient/getting-started/
Try Istio in sidecar mode
https://istio.io/latest/docs/setup/getting-started/
Install guides for ambient mode
https://istio.io/latest/docs/ambient/install/
Install guides for sidecar mode
https://istio.io/latest/docs/setup/install/
Need more information? Visit https://istio.io/latest/docs/
1.17.8
4. default 프로파일로 Istio 컨트롤 플레인 배포
1
2
3
4
5
6
7
8
9
root@myk8s-control-plane:/# istioctl install --set profile=default -y
# 결과
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete Making this installation the default for injection and validation.
Thank you for installing Istio 1.17. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/hMHGiwZHPU7UQRWe9
5. IstioOperator 리소스 확인
1
root@myk8s-control-plane:/# kubectl get istiooperators -n istio-system -o yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
apiVersion: v1
items:
- apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
annotations:
install.istio.io/ignoreReconcile: "true"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"install.istio.io/v1alpha1","kind":"IstioOperator","metadata":{"annotations":{"install.istio.io/ignoreReconcile":"true"},"creationTimestamp":null,"name":"installed-state","namespace":"istio-system"},"spec":{"components":{"base":{"enabled":true},"cni":{"enabled":false},"egressGateways":[{"enabled":false,"name":"istio-egressgateway"}],"ingressGateways":[{"enabled":true,"name":"istio-ingressgateway"}],"istiodRemote":{"enabled":false},"pilot":{"enabled":true}},"hub":"docker.io/istio","meshConfig":{"defaultConfig":{"proxyMetadata":{}},"enablePrometheusMerge":true},"profile":"default","tag":"1.17.8","values":{"base":{"enableCRDTemplates":false,"validationURL":""},"defaultRevision":"","gateways":{"istio-egressgateway":{"autoscaleEnabled":true,"env":{},"name":"istio-egressgateway","secretVolumes":[{"mountPath":"/etc/istio/egressgateway-certs","name":"egressgateway-certs","secretName":"istio-egressgateway-certs"},{"mountPath":"/etc/istio/egressgateway-ca-certs","name":"egressgateway-ca-certs","secretName":"istio-egressgateway-ca-certs"}],"type":"ClusterIP"},"istio-ingressgateway":{"autoscaleEnabled":true,"env":{},"name":"istio-ingressgateway","secretVolumes":[{"mountPath":"/etc/istio/ingressgateway-certs","name":"ingressgateway-certs","secretName":"istio-ingressgateway-certs"},{"mountPath":"/etc/istio/ingressgateway-ca-certs","name":"ingressgateway-ca-certs","secretName":"istio-ingressgateway-ca-certs"}],"type":"LoadBalancer"}},"global":{"configValidation":true,"defaultNodeSelector":{},"defaultPodDisruptionBudget":{"enabled":true},"defaultResources":{"requests":{"cpu":"10m"}},"imagePullPolicy":"","imagePullSecrets":[],"istioNamespace":"istio-system","istiod":{"enableAnalysis":false},"jwtPolicy":"third-party-jwt","logAsJson":false,"logging":{"level":"default:info"},"meshNetworks":{},"mountMtlsCerts":false,"multiCluster":{"clusterName":"","enabled":false},"network":"","omitSidecarInjectorConfigMap":false,"oneNamespace":false,"operatorManageWebhooks":false,"pilotCertProvider":"istiod","priorityClassName":"","proxy":{"autoInject":"enabled","clusterDomain":"cluster.local","componentLogLevel":"misc:error","enableCoreDump":false,"excludeIPRanges":"","excludeInboundPorts":"","excludeOutboundPorts":"","image":"proxyv2","includeIPRanges":"*","logLevel":"warning","privileged":false,"readinessFailureThreshold":30,"readinessInitialDelaySeconds":1,"readinessPeriodSeconds":2,"resources":{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"statusPort":15020,"tracer":"zipkin"},"proxy_init":{"image":"proxyv2","resources":{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"10m","memory":"10Mi"}}},"sds":{"token":{"aud":"istio-ca"}},"sts":{"servicePort":0},"tracer":{"datadog":{},"lightstep":{},"stackdriver":{},"zipkin":{}},"useMCP":false},"istiodRemote":{"injectionURL":""},"pilot":{"autoscaleEnabled":true,"autoscaleMax":5,"autoscaleMin":1,"configMap":true,"cpu":{"targetAverageUtilization":80},"deploymentLabels":null,"enableProtocolSniffingForInbound":true,"enableProtocolSniffingForOutbound":true,"env":{},"image":"pilot","keepaliveMaxServerConnectionAge":"30m","nodeSelector":{},"podLabels":{},"replicaCount":1,"traceSampling":1},"telemetry":{"enabled":true,"v2":{"enabled":true,"metadataExchange":{"wasmEnabled":false},"prometheus":{"enabled":true,"wasmEnabled":false},"stackdriver":{"configOverride":{},"enabled":false,"logging":false,"monitoring":false,"topology":false}}}}}}
creationTimestamp: "2025-04-24T13:23:10Z"
generation: 1
name: installed-state
namespace: istio-system
resourceVersion: "990"
uid: 1c9b06cc-480a-4177-9a32-c6ed4bf8a8aa
spec:
components:
base:
enabled: true
cni:
enabled: false
egressGateways:
- enabled: false
name: istio-egressgateway
ingressGateways:
- enabled: true
name: istio-ingressgateway
istiodRemote:
enabled: false
pilot:
enabled: true
hub: docker.io/istio
meshConfig:
defaultConfig:
proxyMetadata: {}
enablePrometheusMerge: true
profile: default
tag: 1.17.8
values:
base:
enableCRDTemplates: false
validationURL: ""
defaultRevision: ""
gateways:
istio-egressgateway:
autoscaleEnabled: true
env: {}
name: istio-egressgateway
secretVolumes:
- mountPath: /etc/istio/egressgateway-certs
name: egressgateway-certs
secretName: istio-egressgateway-certs
- mountPath: /etc/istio/egressgateway-ca-certs
name: egressgateway-ca-certs
secretName: istio-egressgateway-ca-certs
type: ClusterIP
istio-ingressgateway:
autoscaleEnabled: true
env: {}
name: istio-ingressgateway
secretVolumes:
- mountPath: /etc/istio/ingressgateway-certs
name: ingressgateway-certs
secretName: istio-ingressgateway-certs
- mountPath: /etc/istio/ingressgateway-ca-certs
name: ingressgateway-ca-certs
secretName: istio-ingressgateway-ca-certs
type: LoadBalancer
global:
configValidation: true
defaultNodeSelector: {}
defaultPodDisruptionBudget:
enabled: true
defaultResources:
requests:
cpu: 10m
imagePullPolicy: ""
imagePullSecrets: []
istioNamespace: istio-system
istiod:
enableAnalysis: false
jwtPolicy: third-party-jwt
logAsJson: false
logging:
level: default:info
meshNetworks: {}
mountMtlsCerts: false
multiCluster:
clusterName: ""
enabled: false
network: ""
omitSidecarInjectorConfigMap: false
oneNamespace: false
operatorManageWebhooks: false
pilotCertProvider: istiod
priorityClassName: ""
proxy:
autoInject: enabled
clusterDomain: cluster.local
componentLogLevel: misc:error
enableCoreDump: false
excludeIPRanges: ""
excludeInboundPorts: ""
excludeOutboundPorts: ""
image: proxyv2
includeIPRanges: '*'
logLevel: warning
privileged: false
readinessFailureThreshold: 30
readinessInitialDelaySeconds: 1
readinessPeriodSeconds: 2
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
statusPort: 15020
tracer: zipkin
proxy_init:
image: proxyv2
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 10m
memory: 10Mi
sds:
token:
aud: istio-ca
sts:
servicePort: 0
tracer:
datadog: {}
lightstep: {}
stackdriver: {}
zipkin: {}
useMCP: false
istiodRemote:
injectionURL: ""
pilot:
autoscaleEnabled: true
autoscaleMax: 5
autoscaleMin: 1
configMap: true
cpu:
targetAverageUtilization: 80
deploymentLabels: null
enableProtocolSniffingForInbound: true
enableProtocolSniffingForOutbound: true
env: {}
image: pilot
keepaliveMaxServerConnectionAge: 30m
nodeSelector: {}
podLabels: {}
replicaCount: 1
traceSampling: 1
telemetry:
enabled: true
v2:
enabled: true
metadataExchange:
wasmEnabled: false
prometheus:
enabled: true
wasmEnabled: false
stackdriver:
configOverride: {}
enabled: false
logging: false
monitoring: false
topology: false
kind: List
metadata:
resourceVersion: ""
selfLink: ""
6. istio-system 네임스페이스 리소스 확인
1
root@myk8s-control-plane:/# kubectl get all,svc,ep,sa,cm,secret,pdb -n istio-system
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
NAME READY STATUS RESTARTS AGE
pod/istio-ingressgateway-996bc6bb6-7b46k 1/1 Running 0 92s
pod/istiod-7df6ffc78d-md6kg 1/1 Running 0 104s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-ingressgateway LoadBalancer 10.200.1.165 <pending> 15021:30450/TCP,80:32649/TCP,443:32081/TCP 92s
service/istiod ClusterIP 10.200.1.135 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 104s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-ingressgateway 1/1 1 1 92s
deployment.apps/istiod 1/1 1 1 104s
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-ingressgateway-996bc6bb6 1 1 1 92s
replicaset.apps/istiod-7df6ffc78d 1 1 1 104s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/istio-ingressgateway Deployment/istio-ingressgateway <unknown>/80% 1 5 1 93s
horizontalpodautoscaler.autoscaling/istiod Deployment/istiod <unknown>/80% 1 5 1 105s
NAME ENDPOINTS AGE
endpoints/istio-ingressgateway 10.10.0.6:15021,10.10.0.6:8080,10.10.0.6:8443 93s
endpoints/istiod 10.10.0.5:15012,10.10.0.5:15010,10.10.0.5:15017 + 1 more... 105s
NAME SECRETS AGE
serviceaccount/default 1 106s
serviceaccount/istio-ingressgateway-service-account 1 93s
serviceaccount/istio-reader-service-account 1 106s
serviceaccount/istiod 1 105s
serviceaccount/istiod-service-account 1 106s
NAME DATA AGE
configmap/istio 2 105s
configmap/istio-ca-root-cert 1 94s
configmap/istio-gateway-deployment-leader 0 94s
configmap/istio-gateway-status-leader 0 94s
configmap/istio-leader 0 94s
configmap/istio-namespace-controller-election 0 94s
configmap/istio-sidecar-injector 2 105s
configmap/kube-root-ca.crt 1 106s
NAME TYPE DATA AGE
secret/default-token-6q9nj kubernetes.io/service-account-token 3 106s
secret/istio-ca-secret istio.io/ca-root 5 94s
secret/istio-ingressgateway-service-account-token-vjn55 kubernetes.io/service-account-token 3 93s
secret/istio-reader-service-account-token-2s85q kubernetes.io/service-account-token 3 106s
secret/istiod-service-account-token-s56km kubernetes.io/service-account-token 3 106s
secret/istiod-token-l8gzb kubernetes.io/service-account-token 3 105s
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
poddisruptionbudget.policy/istio-ingressgateway 1 N/A 0 93s
poddisruptionbudget.policy/istiod 1 N/A 0 105s
7. ConfigMap(istio) 설정 확인
1
root@myk8s-control-plane:/# kubectl get cm -n istio-system istio -o yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: v1
data:
mesh: |-
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
proxyMetadata: {}
tracing:
zipkin:
address: zipkin.istio-system:9411
enablePrometheusMerge: true
rootNamespace: istio-system
trustDomain: cluster.local
meshNetworks: 'networks: {}'
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"mesh":"defaultConfig:\n discoveryAddress: istiod.istio-system.svc:15012\n proxyMetadata: {}\n tracing:\n zipkin:\n address: zipkin.istio-system:9411\nenablePrometheusMerge: true\nrootNamespace: istio-system\ntrustDomain: cluster.local","meshNetworks":"networks: {}"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"install.operator.istio.io/owning-resource":"unknown","install.operator.istio.io/owning-resource-namespace":"istio-system","istio.io/rev":"default","operator.istio.io/component":"Pilot","operator.istio.io/managed":"Reconcile","operator.istio.io/version":"1.17.8","release":"istio"},"name":"istio","namespace":"istio-system"}}
creationTimestamp: "2025-04-24T13:22:47Z"
labels:
install.operator.istio.io/owning-resource: unknown
install.operator.istio.io/owning-resource-namespace: istio-system
istio.io/rev: default
operator.istio.io/component: Pilot
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.17.8
release: istio
name: istio
namespace: istio-system
resourceVersion: "861"
uid: b8eb787e-b7c7-4068-9fdd-8d01c1db0c0b
8. 보조 도구 설치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
root@myk8s-control-plane:/# 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
9. istio-system 네임스페이스의 파드 목록 조회
1
root@myk8s-control-plane:/# kubectl get pod -n istio-system
✅ 출력
1
2
3
4
5
6
7
NAME READY STATUS RESTARTS AGE
grafana-b854c6c8-m79jr 1/1 Running 0 48s
istio-ingressgateway-996bc6bb6-7b46k 1/1 Running 0 4m22s
istiod-7df6ffc78d-md6kg 1/1 Running 0 4m34s
jaeger-5556cd8fcf-ljsfm 1/1 Running 0 48s
kiali-648847c8c4-2bf4h 1/1 Running 0 48s
prometheus-7b8b9dd44c-lmzgv 2/2 Running 0 48s
10. 컨트롤 플레인 셸 종료
1
2
root@myk8s-control-plane:/# exit
exit
11. 실습용 네임스페이스 생성 및 istio-injection 활성화
1
2
3
kubectl create ns istioinaction
kubectl label namespace istioinaction istio-injection=enabled
kubectl get ns --show-labels
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
namespace/istioinaction created
namespace/istioinaction labeled
NAME STATUS AGE LABELS
default Active 10m kubernetes.io/metadata.name=default
istio-system Active 6m39s kubernetes.io/metadata.name=istio-system
istioinaction Active 39s istio-injection=enabled,kubernetes.io/metadata.name=istioinaction
kube-node-lease Active 10m kubernetes.io/metadata.name=kube-node-lease
kube-public Active 10m kubernetes.io/metadata.name=kube-public
kube-system Active 10m kubernetes.io/metadata.name=kube-system
local-path-storage Active 10m kubernetes.io/metadata.name=local-path-storage
12. istio-ingressgateway NodePort 및 트래픽 정책 수정
1
2
3
4
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
service/istio-ingressgateway patched
service/istio-ingressgateway patched
service/istio-ingressgateway patched
Name: istio-ingressgateway
Namespace: istio-system
Labels: app=istio-ingressgateway
install.operator.istio.io/owning-resource=unknown
install.operator.istio.io/owning-resource-namespace=istio-system
istio=ingressgateway
istio.io/rev=default
operator.istio.io/component=IngressGateways
operator.istio.io/managed=Reconcile
operator.istio.io/version=1.17.8
release=istio
Annotations: <none>
Selector: app=istio-ingressgateway,istio=ingressgateway
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.200.1.165
IPs: 10.200.1.165
Port: status-port 15021/TCP
TargetPort: 15021/TCP
NodePort: status-port 30450/TCP
Endpoints: 10.10.0.6:15021
Port: http2 80/TCP
TargetPort: 8080/TCP
NodePort: http2 30000/TCP
Endpoints: 10.10.0.6:8080
Port: https 443/TCP
TargetPort: 8443/TCP
NodePort: https 30005/TCP
Endpoints: 10.10.0.6:8443
Session Affinity: None
External Traffic Policy: Local
Internal Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Type 57s service-controller LoadBalancer -> NodePort
13. 각 서비스 NodePort 변경
1
2
3
4
5
6
7
8
9
10
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}]}}'
# 결과
service/prometheus patched
service/grafana patched
service/kiali patched
service/tracing patched
(1) Prometheus 접속 : http://127.0.0.1:30001
(2) Grafana 접속 : http://127.0.0.1:30002
(3) Kiali 접속 : http://127.0.0.1:30003
(4) tracing 접속 : http://127.0.0.1:30004
14. 내부 접속 테스트용 netshoot 파드 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
# 결과
pod/netshoot created
📦 Deploying v1 of the catalog service
1. Catalog 서비스 배포
1
2
3
4
5
6
kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
# 결과
serviceaccount/catalog created
service/catalog created
deployment.apps/catalog created
2. Catalog 파드 상태 확인
1
kubectl get pod -n istioinaction -owide
✅ 출력
1
2
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
catalog-6cf4b97d-68956 2/2 Running 0 15s 10.10.0.12 myk8s-control-plane <none> <non
3. 도메인 질의를 위한 임시 hosts 설정
1
2
3
4
5
6
7
8
9
echo "127.0.0.1 catalog.istioinaction.io" | sudo tee -a /etc/hosts
echo "127.0.0.1 webapp.istioinaction.io" | sudo tee -a /etc/hosts
echo "127.0.0.1 simple-web.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
127.0.0.1 simple-web.istioinaction.io
4. Netshoot 파드로 Catalog 서비스 내부 접속 확인
1
kubectl exec -it netshoot -- curl -s http://catalog.istioinaction/items | jq
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[
{
"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"
}
]
5. Catalog Gateway 리소스 생성
1
cat ch5/catalog-gateway.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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"
1
2
3
4
kubectl apply -f ch5/catalog-gateway.yaml -n istioinaction
# 결과
gateway.networking.istio.io/catalog-gateway created
6. Catalog VirtualService 리소스 생성
1
cat ch5/catalog-vs.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
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
1
2
3
4
kubectl apply -f ch5/catalog-vs.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog-vs-from-gw created
7. Gateway, VirtualService 리소스 상태 확인
1
kubectl get gw,vs -n istioinaction
✅ 출력
1
2
3
4
5
NAME AGE
gateway.networking.istio.io/catalog-gateway 3m9s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog-vs-from-gw ["catalog-gateway"] ["catalog.istioinaction.io"] 19s
8. istio-ingressgateway 포트 매핑 확인
1
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath="{.spec.ports}" | jq
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
{
"name": "status-port",
"nodePort": 30450,
"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
}
]
9. NodePort를 통해 Catalog 서비스 외부 접속 확인
1
curl -v -H "Host: catalog.istioinaction.io" http://localhost:30000
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
* Host localhost:30000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:30000...
* connect to ::1 port 30000 from ::1 port 49086 failed: Connection refused
* Trying 127.0.0.1:30000...
* Connected to localhost (127.0.0.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: Thu, 24 Apr 2025 13:55:28 GMT
< x-envoy-upstream-service-time: 15
< 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>
* Connection #0 to host localhost left intact
http://catalog.istioinaction.io:30000
http://catalog.istioinaction.io:30000/items
10. 반복 접속 스크립트 실행
1
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HTTP/1.1 200 OK
2025-04-24 23:05:31
HTTP/1.1 200 OK
2025-04-24 23:05:32
HTTP/1.1 200 OK
2025-04-24 23:05:33
HTTP/1.1 200 OK
2025-04-24 23:05:34
HTTP/1.1 200 OK
2025-04-24 23:05:35
...
11. Istio Proxy 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-status
✅ 출력
1
2
3
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
catalog-6cf4b97d-68956.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-md6kg 1.17.8
istio-ingressgateway-996bc6bb6-7b46k.istio-system Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-md6kg 1.17.8
12. LDS (Listener Discovery Service) 확인
(1) IngressGateway의 Listener 목록 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway.istio-system
✅ 출력
1
2
3
4
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*
(2) 8080 포트의 Listener 상세 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway.istio-system --port 8080
✅ 출력
1
2
ADDRESS PORT MATCH DESTINATION
0.0.0.0 8080 ALL Route: http.8080
(3) 8080 포트 Listener JSON 출력
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/istio-ingressgateway.istio-system --port 8080 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
[
{
"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"
}
]
13. RDS (Route Discovery Service) 확인
(1) IngressGateway의 Route 정보 전체 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system
✅ 출력
1
2
3
4
NAME DOMAINS MATCH VIRTUAL SERVICE
http.8080 catalog.istioinaction.io /* catalog-vs-from-gw.istioinaction
* /stats/prometheus*
* /healthz/ready*
(2) http.8080 이름으로 Route 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080
✅ 출력
1
2
NAME DOMAINS MATCH VIRTUAL SERVICE
http.8080 catalog.istioinaction.io /* catalog-vs-from-gw.istioinaction
(3) http.8080 Route JSON 출력
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
[
{
"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
}
]
14. CDS (Cluster Discovery Service) 확인
(1) IngressGateway의 Cluster 목록 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
kubernetes.default.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
(2) Catalog 서비스로 설정된 Cluster만 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
catalog.istioinaction.svc.cluster.local 80 - outbound EDS
(3) Catalog Cluster JSON 출력
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
[
{
"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"
}
}
]
}
]
15. EDS (Endpoint Discovery Service) 확인
(1) IngressGateway의 Endpoint 목록 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.10:9090 HEALTHY OK outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.3:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.3:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.4:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.4:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.5:15010 HEALTHY OK outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.5:15012 HEALTHY OK outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.5:15014 HEALTHY OK outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.5:15017 HEALTHY OK outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.6:8080 HEALTHY OK outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:8443 HEALTHY OK outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:15021 HEALTHY OK outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.7:9411 HEALTHY OK outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.7:9411 HEALTHY OK outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.7:14250 HEALTHY OK outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.7:14268 HEALTHY OK outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.7:16685 HEALTHY OK outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.7:16686 HEALTHY OK outbound|80||tracing.istio-system.svc.cluster.local
10.10.0.8:3000 HEALTHY OK outbound|3000||grafana.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.55:9411 HEALTHY OK zipkin
127.0.0.1:15000 HEALTHY OK prometheus_stats
127.0.0.1:15020 HEALTHY OK agent
172.18.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
(2) Catalog 서비스 전용 Endpoint 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local'
✅ 출력
1
2
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
(3) Catalog Endpoint JSON 출력
1
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
[
{
"name": "outbound|80||catalog.istioinaction.svc.cluster.local",
"addedViaApi": true,
"hostStatuses": [
{
"address": {
"socketAddress": {
"address": "10.10.0.12",
"portValue": 3000
}
},
"stats": [
{
"name": "cx_connect_fail"
},
{
"value": "18",
"name": "cx_total"
},
{
"name": "rq_error"
},
{
"value": "2273",
"name": "rq_success"
},
{
"name": "rq_timeout"
},
{
"value": "2273",
"name": "rq_total"
},
{
"type": "GAUGE",
"value": "18",
"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"
}
]
16. Catalog 파드 측 Envoy 설정 확인
(1) Catalog 파드 Listener 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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.135 443 ALL Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.165 443 ALL Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.171 3000 Trans: raw_buffer; App: http/1.1,h2c Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.171 3000 ALL Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
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.51 14250 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.51 14250 ALL Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.51 14268 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.51 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.135 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.165 15021 Trans: raw_buffer; App: http/1.1,h2c Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.165 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
(2) Catalog 파드 Route 정보 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
NAME DOMAINS MATCH VIRTUAL SERVICE
80 catalog, catalog.istioinaction + 1 more... /*
80 istio-ingressgateway.istio-system, 10.200.1.165 /*
80 tracing.istio-system, 10.200.1.87 /*
9090 kiali.istio-system, 10.200.1.162 /*
9090 prometheus.istio-system, 10.200.1.72 /*
9411 jaeger-collector.istio-system, 10.200.1.51 /*
9411 zipkin.istio-system, 10.200.1.55 /*
15010 istiod.istio-system, 10.200.1.135 /*
15014 istiod.istio-system, 10.200.1.135 /*
16685 tracing.istio-system, 10.200.1.87 /*
kube-dns.kube-system.svc.cluster.local:9153 * /*
istio-ingressgateway.istio-system.svc.cluster.local:15021 * /*
20001 kiali.istio-system, 10.200.1.162 /*
grafana.istio-system.svc.cluster.local:3000 * /*
jaeger-collector.istio-system.svc.cluster.local:14268 * /*
jaeger-collector.istio-system.svc.cluster.local:14250 * /*
InboundPassthroughClusterIpv4 * /*
InboundPassthroughClusterIpv4 * /*
inbound|3000|| * /*
* /stats/prometheus*
* /healthz/ready*
inbound|3000|| * /*
(3) Catalog 파드 Cluster 정보 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
kubernetes.default.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
(4) Catalog 파드 Endpoint 정보 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.10:9090 HEALTHY OK outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.12:3000 HEALTHY OK inbound|3000||
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.3:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.3:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.4:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.4:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.5:15010 HEALTHY OK outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.5:15012 HEALTHY OK outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.5:15014 HEALTHY OK outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.5:15017 HEALTHY OK outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.6:8080 HEALTHY OK outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:8443 HEALTHY OK outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:15021 HEALTHY OK outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.7:9411 HEALTHY OK outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.7:9411 HEALTHY OK outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.7:14250 HEALTHY OK outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.7:14268 HEALTHY OK outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.7:16685 HEALTHY OK outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.7:16686 HEALTHY OK outbound|80||tracing.istio-system.svc.cluster.local
10.10.0.8:3000 HEALTHY OK outbound|3000||grafana.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.55:9411 HEALTHY OK zipkin
127.0.0.1:15000 HEALTHY OK prometheus_stats
127.0.0.1:15020 HEALTHY OK agent
172.18.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
17. Envoy Admin Interface 접속
(1) IngressGateway Envoy Admin 웹 포트 포워딩
1
2
3
4
5
kubectl port-forward deploy/istio-ingressgateway -n istio-system 15000:15000
# 결과
Forwarding from 127.0.0.1:15000 -> 15000
Forwarding from [::1]:15000 -> 15000
📦 Catalog 서비스 v2 배포 정리
1. Catalog v2 배포
v2: imageUrl
필드가 추가된 버전
1
2
3
4
kubectl apply -f services/catalog/kubernetes/catalog-deployment-v2.yaml -n istioinaction
# 결과
deployment.apps/catalog-v2 created
2. 배포 및 파드 상태 확인
(1) 배포 목록 확인
1
kubectl get deploy -n istioinaction --show-labels
✅ 출력
1
2
3
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
catalog 1/1 1 1 66m app=catalog,version=v1
catalog-v2 1/1 1 1 21s app=catalog,version=v2
(2) 파드 상태 확인
1
kubectl get pod -n istioinaction -o wide
✅ 출력
1
2
3
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
catalog-6cf4b97d-68956 2/2 Running 0 67m 10.10.0.12 myk8s-control-plane <none> <none>
catalog-v2-6df885b555-hd9hb 2/2 Running 0 58s 10.10.0.13 myk8s-control-plane <none> <none>
3. Istio Proxy 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-status
✅ 출력
1
2
3
4
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
catalog-6cf4b97d-68956.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-md6kg 1.17.8
catalog-v2-6df885b555-hd9hb.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-md6kg 1.17.8
istio-ingressgateway-996bc6bb6-7b46k.istio-system Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-md6kg 1.17.8
4. 호출 테스트 (v1/v2 랜덤 호출 확인)
1
for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
[
{
"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"
}
]
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
[
{
"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"
}
]
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
[
{
"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"
}
]
5. Istio IngressGateway 설정 확인
(1) 클러스터 정보 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
catalog.istioinaction.svc.cluster.local 80 - outbound EDS
(2) 클러스터 상세 정보(JSON)
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
[
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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"
}
}
]
}
]
6. 엔드포인트 확인
(1) 엔드포인트 리스트
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local'
✅ 출력
1
2
3
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
(2) 서비스와 엔드포인트 확인
1
k get svc,ep -n istioinaction
✅ 출력
1
2
3
4
5
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/catalog ClusterIP 10.200.1.182 <none> 80/TCP 84m
NAME ENDPOINTS AGE
endpoints/catalog 10.10.0.12:3000,10.10.0.13:3000 84m
(3) 엔드포인트 상세(JSON)
1
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
[
{
"name": "outbound|80||catalog.istioinaction.svc.cluster.local",
"addedViaApi": true,
"hostStatuses": [
{
"address": {
"socketAddress": {
"address": "10.10.0.12",
"portValue": 3000
}
},
"stats": [
{
"name": "cx_connect_fail"
},
{
"value": "18",
"name": "cx_total"
},
{
"name": "rq_error"
},
{
"value": "121",
"name": "rq_success"
},
{
"name": "rq_timeout"
},
{
"value": "121",
"name": "rq_total"
},
{
"type": "GAUGE",
"value": "18",
"name": "cx_active"
},
{
"type": "GAUGE",
"name": "rq_active"
}
],
"healthStatus": {
"edsHealthStatus": "HEALTHY"
},
"weight": 1,
"locality": {}
},
{
"address": {
"socketAddress": {
"address": "10.10.0.13",
"portValue": 3000
}
},
"stats": [
{
"name": "cx_connect_fail"
},
{
"value": "18",
"name": "cx_total"
},
{
"name": "rq_error"
},
{
"value": "142",
"name": "rq_success"
},
{
"name": "rq_timeout"
},
{
"value": "142",
"name": "rq_total"
},
{
"type": "GAUGE",
"value": "18",
"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"
}
]
🔀 Routing all traffic to v1 of the catalog service
1. 현재 catalog 파드 상태 확인
1
kubectl get pod -l app=catalog -n istioinaction --show-labels
✅ 출력
1
2
3
NAME READY STATUS RESTARTS AGE LABELS
catalog-6cf4b97d-68956 2/2 Running 0 88m 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-hd9hb 2/2 Running 0 22m 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
2. DestinationRule 생성
(1) 생성 내용 확인
1
cat ch5/catalog-dest-rule.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
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
(2) catalog
DestinationRule 생성
1
2
3
4
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
# 결과
destinationrule.networking.istio.io/catalog created
(3) catalog
DestinationRule 확인
1
kubectl get destinationrule -n istioinaction
✅ 출력
1
2
NAME HOST AGE
catalog catalog.istioinaction.svc.cluster.local 21s
3. Subset이 적용된 Proxy Config 확인
(1) catalog 서비스 Cluster 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
3
4
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
(2) version-v1 Subset 상세 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v1 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
[
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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_.version-v1_.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|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",
"circuitBreakers": {
"thresholds": [
{
"maxConnections": 4294967295,
"maxPendingRequests": 4294967295,
"maxRequests": 4294967295,
"maxRetries": 4294967295,
"trackRemaining": true
}
]
},
"commonLbConfig": {
"localityWeightedLbConfig": {}
},
"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"
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
(3) version-v2 Subset 상세 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v2 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
[
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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_.version-v2_.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|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",
"circuitBreakers": {
"thresholds": [
{
"maxConnections": 4294967295,
"maxPendingRequests": 4294967295,
"maxRequests": 4294967295,
"maxRetries": 4294967295,
"trackRemaining": true
}
]
},
"commonLbConfig": {
"localityWeightedLbConfig": {}
},
"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-v2"
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
(4) 전체 Cluster 목록 (JSON 형태) 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
[
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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": {
"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"
}
]
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
},
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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_.version-v1_.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|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",
"circuitBreakers": {
"thresholds": [
{
"maxConnections": 4294967295,
"maxPendingRequests": 4294967295,
"maxRequests": 4294967295,
"maxRetries": 4294967295,
"trackRemaining": true
}
]
},
"commonLbConfig": {
"localityWeightedLbConfig": {}
},
"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"
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
},
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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_.version-v2_.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|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",
"circuitBreakers": {
"thresholds": [
{
"maxConnections": 4294967295,
"maxPendingRequests": 4294967295,
"maxRequests": 4294967295,
"maxRetries": 4294967295,
"trackRemaining": true
}
]
},
"commonLbConfig": {
"localityWeightedLbConfig": {}
},
"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-v2"
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
(5) 엔드포인트 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
✅ 출력
1
2
3
4
5
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
(6) 전체 catalog 서비스 엔드포인트 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local'
✅ 출력
1
2
3
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
4. VirtualService 수정 및 적용 (subset 추가)
1
cat ch5/catalog-vs-v1.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
1
2
3
4
kubectl apply -f ch5/catalog-vs-v1.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog-vs-from-gw configured
5. 호출 테스트 (v1만 응답 확인)
1
for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
6. Route 설정 확인
(1) 기본 Route 목록
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system
✅ 출력
1
2
3
4
NAME DOMAINS MATCH VIRTUAL SERVICE
http.8080 catalog.istioinaction.io /* catalog-vs-from-gw.istioinaction
* /stats/prometheus*
* /healthz/ready*
(2) http.8080 상세 (JSON)
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
[
{
"name": "http.8080",
"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,
"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
}
]
7. 클러스터 설정 확인
(1) 전체 클러스터
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
3
4
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
(2) version-v1만 필터링
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --subset version-v1
✅ 출력
1
2
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
catalog.istioinaction.svc.cluster.local 80 version-v1 outbound EDS catalog.istioinaction
8. 엔드포인트 상태 확인
(1) 전체 엔드포인트
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
✅ 출력
1
2
3
4
5
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
(2) version-v1만 필터링
1
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'
✅ 출력
1
2
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
9. istio-proxy (catalog) 설정 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction --subset version-v1 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
[
{
"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"
},
{
"exact": "spiffe://cluster.local/ns/istioinaction/sa/default"
}
]
},
"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_.version-v1_.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|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",
"circuitBreakers": {
"thresholds": [
{
"maxConnections": 4294967295,
"maxPendingRequests": 4294967295,
"maxRequests": 4294967295,
"maxRetries": 4294967295,
"trackRemaining": true
}
]
},
"commonLbConfig": {
"localityWeightedLbConfig": {}
},
"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"
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
🎯 Routing specific requests to v2
1. VirtualService 설정
- HTTP 요청 헤더
x-istio-cohort: internal
이 정확히 일치할 경우 catalog v2로 라우팅 - 그렇지 않은 경우 기본적으로 catalog v1으로 라우팅
(1) VirtualService 설정 파일
1
cat ch5/catalog-vs-v2-request.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
(2) 적용
1
2
3
4
kubectl apply -f ch5/catalog-vs-v2-request.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog-vs-from-gw configured
2. 기본 호출 테스트 (헤더 없이)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
[
{
"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"
}
]
3. 헤더 포함 호출 테스트 (x-istio-cohort: internal)
1
curl http://catalog.istioinaction.io:30000/items -H "x-istio-cohort: internal"
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
4. 신규 터미널: v2 요청 반복 호출 (옵션)
1
2
3
4
5
6
7
8
9
10
11
12
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
HTTP/1.1 200 OK
2025-04-25 22:16:18
HTTP/1.1 200 OK
2025-04-25 22:16:20
HTTP/1.1 200 OK
2025-04-25 22:16:22
...
5. Proxy Route 확인 (istio-ingressgateway)
(1) route 정보 조회
1
2
3
4
5
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
(2) routes 상세 정보
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
[
{
"name": "http.8080",
"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",
"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/*"
}
},
{
"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,
"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
}
]
6. 클러스터 및 엔드포인트 상태 확인
(1) 클러스터 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
3
4
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
(2) 엔드포인트 조회
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
✅ 출력
1
2
3
4
5
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.12:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.12:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
7. catalog 서비스 Proxy(Route) 내부 동작
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction | grep catalog
✅ 출력
1
80 catalog, catalog.istioinaction + 1 more... /*
- 1개의 기본 Route만 존재
- 분기 조건은 istio-ingressgateway에서 처리됨
🕸️ Routing deep within a call graph 호출 (Mesh 내부 라우팅 흐름)
1. 초기화: 기존 Istio 리소스 삭제
1
2
3
4
5
6
kubectl delete gateway,virtualservice,destinationrule --all -n istioinaction
# 결과
gateway.networking.istio.io "catalog-gateway" deleted
virtualservice.networking.istio.io "catalog-vs-from-gw" deleted
destinationrule.networking.istio.io "catalog" deleted
2. webapp 서비스 기동
1
2
3
4
5
6
kubectl apply -n istioinaction -f services/webapp/kubernetes/webapp.yaml
# 결과
serviceaccount/webapp created
service/webapp created
deployment.apps/webapp created
3. 서비스 상태 확인
1
kubectl get deploy,pod,svc,ep -n istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/catalog 1/1 1 1 14m
deployment.apps/catalog-v2 1/1 1 1 6m8s
deployment.apps/webapp 0/1 1 0 8s
NAME READY STATUS RESTARTS AGE
pod/catalog-6cf4b97d-ml4fw 2/2 Running 0 14m
pod/catalog-v2-6df885b555-xmg2x 2/2 Running 0 6m8s
pod/webapp-7685bcb84-ng9xn 0/2 PodInitializing 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/catalog ClusterIP 10.200.1.92 <none> 80/TCP 14m
service/webapp ClusterIP 10.200.1.51 <none> 80/TCP 8s
NAME ENDPOINTS AGE
endpoints/catalog 10.10.0.11:3000,10.10.0.13:3000 14m
endpoints/webapp 8s
4. Gateway 및 VirtualService 생성 (Ingress Gateway로 webapp 노출)
(1) webapp용 Gateway, VirtualService 설정
1
cat services/webapp/istio/webapp-catalog-gw-vs.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
---
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
(2) 적용
1
2
3
4
5
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
(3) 확인
1
kubectl get gw,vs -n istioinaction
✅ 출력
1
2
3
4
5
NAME AGE
gateway.networking.istio.io/coolstore-gateway 11s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 11s
5. 호출 테스트: 외부 → IngressGW → webapp → catalog
1
curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[
{
"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"
}
]
6. 반복 호출테스트: 신규터미널 2개에 각각 실행 해두기
(1) 일반 호출 (기본 트래픽)
1
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
2025-04-25 22:58:05
HTTP/1.1 200 OK
2025-04-25 22:58:06
HTTP/1.1 200 OK
2025-04-25 22:58:07
HTTP/1.1 200 OK
2025-04-25 22:58:08
....
(2) 헤더 포함 호출 (v2 트래픽)
1
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
2025-04-25 22:58:42
HTTP/1.1 200 OK
2025-04-25 22:58:44
HTTP/1.1 200 OK
2025-04-25 22:58:46
HTTP/1.1 200 OK
2025-04-25 22:58:48
...
7. IngressGateway Proxy 상태 점검
(1) Route 설정 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/istio-ingressgateway.istio-system --name http.8080
✅ 출력
1
2
NAME DOMAINS MATCH VIRTUAL SERVICE
http.8080 webapp.istioinaction.io /* webapp-virtualservice.istioinaction
(2) Cluster 설정 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system | egrep 'webapp|catalog'
✅ 출력
1
2
catalog.istioinaction.svc.cluster.local 80 - outbound EDS
webapp.istioinaction.svc.cluster.local 80 - outbound EDS
(3) Cluster 상세 정보 (json)
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn webapp.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
[
{
"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/webapp"
}
]
},
"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_._.webapp.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||webapp.istioinaction.svc.cluster.local",
"type": "EDS",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
"initialFetchTimeout": "0s",
"resourceApiVersion": "V3"
},
"serviceName": "outbound|80||webapp.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": "webapp.istioinaction.svc.cluster.local",
"name": "webapp",
"namespace": "istioinaction"
}
]
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
(4) Endpoint 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system --cluster 'outbound|80||webapp.istioinaction.svc.cluster.local'
✅ 출력
1
2
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.14:8080 HEALTHY OK outbound|80||webapp.istioinaction.svc.cluster.local
8. webapp Proxy 상태 점검
(1) Listener 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/webapp.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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.107 443 ALL Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.250 443 ALL Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.55 3000 Trans: raw_buffer; App: http/1.1,h2c Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.55 3000 ALL Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
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.208 14250 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.208 14250 ALL Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.208 14268 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.208 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.250 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.107 15021 Trans: raw_buffer; App: http/1.1,h2c Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.107 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
(2) Routes 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
NAME DOMAINS MATCH VIRTUAL SERVICE
jaeger-collector.istio-system.svc.cluster.local:14250 * /*
15010 istiod.istio-system, 10.200.1.250 /*
9411 jaeger-collector.istio-system, 10.200.1.208 /*
9411 zipkin.istio-system, 10.200.1.134 /*
istio-ingressgateway.istio-system.svc.cluster.local:15021 * /*
* /stats/prometheus*
80 catalog, catalog.istioinaction + 1 more... /*
80 istio-ingressgateway.istio-system, 10.200.1.107 /*
80 tracing.istio-system, 10.200.1.170 /*
80 webapp, webapp.istioinaction + 1 more... /*
jaeger-collector.istio-system.svc.cluster.local:14268 * /*
9090 kiali.istio-system, 10.200.1.157 /*
9090 prometheus.istio-system, 10.200.1.72 /*
* /healthz/ready*
inbound|8080|| * /*
grafana.istio-system.svc.cluster.local:3000 * /*
kube-dns.kube-system.svc.cluster.local:9153 * /*
inbound|8080|| * /*
InboundPassthroughClusterIpv4 * /*
InboundPassthroughClusterIpv4 * /*
15014 istiod.istio-system, 10.200.1.250 /*
16685 tracing.istio-system, 10.200.1.170 /*
20001 kiali.istio-system, 10.200.1.157 /*
(3) 클러스터 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
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
kubernetes.default.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
(4) 엔드포인트 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.10:9090 HEALTHY OK outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.11:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.14:8080 HEALTHY OK inbound|8080||
10.10.0.14: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:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.3:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.5:15010 HEALTHY OK outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.5:15012 HEALTHY OK outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.5:15014 HEALTHY OK outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.5:15017 HEALTHY OK outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.6:8080 HEALTHY OK outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:8443 HEALTHY OK outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:15021 HEALTHY OK outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.7:3000 HEALTHY OK outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.8:9411 HEALTHY OK outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:9411 HEALTHY OK outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.8:14250 HEALTHY OK outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:14268 HEALTHY OK outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:16685 HEALTHY OK outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.8:16686 HEALTHY OK outbound|80||tracing.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.134:9411 HEALTHY OK zipkin
127.0.0.1:15000 HEALTHY OK prometheus_stats
127.0.0.1:15020 HEALTHY OK agent
172.18.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
9. catalog Proxy 상태 점검
(1) Listener 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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.107 443 ALL Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.250 443 ALL Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.55 3000 Trans: raw_buffer; App: http/1.1,h2c Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.55 3000 ALL Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
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.208 14250 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.208 14250 ALL Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.208 14268 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.208 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.250 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.107 15021 Trans: raw_buffer; App: http/1.1,h2c Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.107 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
(2) Routes 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
NAME DOMAINS MATCH VIRTUAL SERVICE
80 catalog, catalog.istioinaction + 1 more... /*
80 istio-ingressgateway.istio-system, 10.200.1.107 /*
80 tracing.istio-system, 10.200.1.170 /*
80 webapp, webapp.istioinaction + 1 more... /*
9090 kiali.istio-system, 10.200.1.157 /*
9090 prometheus.istio-system, 10.200.1.72 /*
9411 jaeger-collector.istio-system, 10.200.1.208 /*
9411 zipkin.istio-system, 10.200.1.134 /*
15010 istiod.istio-system, 10.200.1.250 /*
15014 istiod.istio-system, 10.200.1.250 /*
16685 tracing.istio-system, 10.200.1.170 /*
jaeger-collector.istio-system.svc.cluster.local:14250 * /*
istio-ingressgateway.istio-system.svc.cluster.local:15021 * /*
kube-dns.kube-system.svc.cluster.local:9153 * /*
20001 kiali.istio-system, 10.200.1.157 /*
grafana.istio-system.svc.cluster.local:3000 * /*
jaeger-collector.istio-system.svc.cluster.local:14268 * /*
InboundPassthroughClusterIpv4 * /*
* /healthz/ready*
InboundPassthroughClusterIpv4 * /*
inbound|3000|| * /*
* /stats/prometheus*
inbound|3000|| * /*
(3) 클러스터 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
kubernetes.default.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
(4) 엔드포인트 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.10:9090 HEALTHY OK outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.11:3000 HEALTHY OK inbound|3000||
10.10.0.11:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.14: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:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.3:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.5:15010 HEALTHY OK outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.5:15012 HEALTHY OK outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.5:15014 HEALTHY OK outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.5:15017 HEALTHY OK outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.6:8080 HEALTHY OK outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:8443 HEALTHY OK outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:15021 HEALTHY OK outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.7:3000 HEALTHY OK outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.8:9411 HEALTHY OK outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:9411 HEALTHY OK outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.8:14250 HEALTHY OK outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:14268 HEALTHY OK outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:16685 HEALTHY OK outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.8:16686 HEALTHY OK outbound|80||tracing.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.134:9411 HEALTHY OK zipkin
127.0.0.1:15000 HEALTHY OK prometheus_stats
127.0.0.1:15020 HEALTHY OK agent
172.18.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
10. webapp istio-proxy 로그 활성화
(1) 기존 istio-proxy 로그 보기
1
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
✅ 출력
1
2
3
4
5
6
7
8
9
10
2025-04-25T13:55:46.777346Z info cache Root cert has changed, start rotating root cert
2025-04-25T13:55:46.777373Z info ads XDS: Incremental Pushing:0 ConnectedEndpoints:2 Version:
2025-04-25T13:55:46.777477Z info cache returned workload trust anchor from cache ttl=23h59m59.222532937s
2025-04-25T13:55:46.777619Z info cache returned workload certificate from cache ttl=23h59m59.222555666s
2025-04-25T13:55:46.777765Z info cache returned workload trust anchor from cache ttl=23h59m59.222245106s
2025-04-25T13:55:46.778092Z info ads SDS: PUSH request for node:webapp-7685bcb84-ng9xn.istioinaction resources:1 size:4.0kB resource:default
2025-04-25T13:55:46.778132Z info ads SDS: PUSH request for node:webapp-7685bcb84-ng9xn.istioinaction resources:1 size:1.1kB resource:ROOTCA
2025-04-25T13:55:46.778182Z info cache returned workload trust anchor from cache ttl=23h59m59.221820466s
2025-04-25T13:55:47.198787Z info Readiness succeeded in 794.646887ms
2025-04-25T13:55:47.199111Z info Envoy proxy is ready
(2) Telemetry 리소스 적용 (Access 로그 강제 활성화)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
# 결과
telemetry.telemetry.istio.io/webapp created
✅ 로그 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[2025-04-25T14:05:47.074Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "3e7645ae-b370-4a7e-9827-31a80a6ca775" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:54764 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:48.094Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 698 2 2 "172.18.0.1" "beegoServer" "f929a818-e747-4e24-91d2-1c3e41de1beb" "catalog.istioinaction:80" "10.10.0.13:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:34538 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:48.151Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 698 2 2 "172.18.0.1" "beegoServer" "a495d7f0-6a6d-4ff4-8fff-48e5305d1150" "catalog.istioinaction:80" "10.10.0.13:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:34538 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:49.115Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 5 4 "172.18.0.1" "beegoServer" "63199fd2-ff03-40ed-99ea-dc869049f223" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:59234 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:50.135Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 3 3 "172.18.0.1" "beegoServer" "1e0132c5-8783-4b5d-b89d-2688e9818c46" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:54764 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:50.166Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "86a50200-b19c-429c-ad0f-1f975a3c1c28" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:59234 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:51.155Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 3 2 "172.18.0.1" "beegoServer" "11ad26d3-20f7-4f43-b70b-cbd6a6e78e1e" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:59234 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:52.173Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "96bcd912-b759-4606-89cd-018a1d959c94" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:54764 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:52.179Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 1 1 "172.18.0.1" "beegoServer" "10d350d3-0d42-44e6-b19a-d2076c6edb89" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:54764 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:53.189Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "417f01a9-b9e9-4df5-bac7-a026194e66ab" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:54764 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:54.198Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 698 2 2 "172.18.0.1" "beegoServer" "6cf99386-007b-426b-a604-67f20586e379" "catalog.istioinaction:80" "10.10.0.13:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:34538 10.200.1.92:80 172.18.0.1:0 - default
[2025-04-25T14:05:54.196Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "6cf99386-007b-426b-a604-67f20586e379" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:60061 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-25T14:05:54.204Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "0837c43b-6094-4ce1-98d2-423694223705" "catalog.istioinaction:80" "10.10.0.11:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.14:59234 10.200.1.92:80 172.18.0.1:0 - default
...
11. DestinationRule 생성
1
cat ch5/catalog-dest-rule.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
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
- catalog 서비스에 대해
version-v1
,version-v2
로 서브셋 지정
1
2
3
4
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
# 결과
destinationrule.networking.istio.io/catalog created
12. Istio Ingress Gateway
(1) 클러스터 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
3
4
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
(2) 엔드포인트 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/istio-ingressgateway.istio-system | egrep 'ENDPOINT|istioinaction'
✅ 출력
1
2
3
4
5
6
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.11:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.11:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.14:8080 HEALTHY OK outbound|80||webapp.istioinaction.svc.cluster.local
13. VirtualService 설정 적용
1
cat ch5/catalog-vs-v1-mesh.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
1
2
3
4
kubectl apply -f ch5/catalog-vs-v1-mesh.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog created
14. VirtualService 적용 여부 확인
(1) VirtualService 목록 확인
1
kubectl get vs -n istioinaction
✅ 출력
1
2
3
NAME GATEWAYS HOSTS AGE
catalog ["mesh"] ["catalog"] 49s
webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 22m
(2) webapp 프록시에 VirtualService 라우팅 정보 적용 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction | egrep 'NAME|catalog'
✅ 출력
1
2
3
NAME DOMAINS MATCH VIRTUAL SERVICE
80 catalog, catalog.istioinaction + 1 more... /* catalog.istioinaction
80 catalog, catalog.istioinaction + 1 more... /* catalog.istioinaction
(3) webapp 프록시 클러스터 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn catalog.istioinaction.svc.cluster.local
✅ 출력
1
2
3
4
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
(4) webapp 프록시 엔드포인트 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction | egrep 'ENDPOINT|catalog'
✅ 출력
1
2
3
4
5
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.11:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.11:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
15. catalog 프록시에도 VirtualService 반영 여부 확인
(1) Listener 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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.107 443 ALL Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.200.1.250 443 ALL Cluster: outbound|443||istiod.istio-system.svc.cluster.local
10.200.1.55 3000 Trans: raw_buffer; App: http/1.1,h2c Route: grafana.istio-system.svc.cluster.local:3000
10.200.1.55 3000 ALL Cluster: outbound|3000||grafana.istio-system.svc.cluster.local
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.208 14250 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14250
10.200.1.208 14250 ALL Cluster: outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.200.1.208 14268 Trans: raw_buffer; App: http/1.1,h2c Route: jaeger-collector.istio-system.svc.cluster.local:14268
10.200.1.208 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.250 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.107 15021 Trans: raw_buffer; App: http/1.1,h2c Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
10.200.1.107 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
(2) Route 설정 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
NAME DOMAINS MATCH VIRTUAL SERVICE
80 catalog, catalog.istioinaction + 1 more... /* catalog.istioinaction
80 catalog, catalog.istioinaction + 1 more... /* catalog.istioinaction
80 istio-ingressgateway.istio-system, 10.200.1.107 /*
80 tracing.istio-system, 10.200.1.170 /*
80 webapp, webapp.istioinaction + 1 more... /*
9090 kiali.istio-system, 10.200.1.157 /*
9090 prometheus.istio-system, 10.200.1.72 /*
9411 jaeger-collector.istio-system, 10.200.1.208 /*
9411 zipkin.istio-system, 10.200.1.134 /*
15010 istiod.istio-system, 10.200.1.250 /*
15014 istiod.istio-system, 10.200.1.250 /*
16685 tracing.istio-system, 10.200.1.170 /*
jaeger-collector.istio-system.svc.cluster.local:14250 * /*
istio-ingressgateway.istio-system.svc.cluster.local:15021 * /*
kube-dns.kube-system.svc.cluster.local:9153 * /*
20001 kiali.istio-system, 10.200.1.157 /*
grafana.istio-system.svc.cluster.local:3000 * /*
jaeger-collector.istio-system.svc.cluster.local:14268 * /*
InboundPassthroughClusterIpv4 * /*
* /healthz/ready*
InboundPassthroughClusterIpv4 * /*
inbound|3000|| * /*
* /stats/prometheus*
inbound|3000|| * /*
(3) 클러스터 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
kubernetes.default.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
(4) 엔드포인트 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/catalog.istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
ENDPOINT STATUS OUTLIER CHECK CLUSTER
10.10.0.10:9090 HEALTHY OK outbound|9090||prometheus.istio-system.svc.cluster.local
10.10.0.11:3000 HEALTHY OK inbound|3000||
10.10.0.11:3000 HEALTHY OK outbound|80|version-v1|catalog.istioinaction.svc.cluster.local
10.10.0.11:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80|version-v2|catalog.istioinaction.svc.cluster.local
10.10.0.13:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
10.10.0.14: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:53 HEALTHY OK outbound|53||kube-dns.kube-system.svc.cluster.local
10.10.0.3:9153 HEALTHY OK outbound|9153||kube-dns.kube-system.svc.cluster.local
10.10.0.5:15010 HEALTHY OK outbound|15010||istiod.istio-system.svc.cluster.local
10.10.0.5:15012 HEALTHY OK outbound|15012||istiod.istio-system.svc.cluster.local
10.10.0.5:15014 HEALTHY OK outbound|15014||istiod.istio-system.svc.cluster.local
10.10.0.5:15017 HEALTHY OK outbound|443||istiod.istio-system.svc.cluster.local
10.10.0.6:8080 HEALTHY OK outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:8443 HEALTHY OK outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.6:15021 HEALTHY OK outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
10.10.0.7:3000 HEALTHY OK outbound|3000||grafana.istio-system.svc.cluster.local
10.10.0.8:9411 HEALTHY OK outbound|9411||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:9411 HEALTHY OK outbound|9411||zipkin.istio-system.svc.cluster.local
10.10.0.8:14250 HEALTHY OK outbound|14250||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:14268 HEALTHY OK outbound|14268||jaeger-collector.istio-system.svc.cluster.local
10.10.0.8:16685 HEALTHY OK outbound|16685||tracing.istio-system.svc.cluster.local
10.10.0.8:16686 HEALTHY OK outbound|80||tracing.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.134:9411 HEALTHY OK zipkin
127.0.0.1:15000 HEALTHY OK prometheus_stats
127.0.0.1:15020 HEALTHY OK agent
172.18.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
🔀 Traffic shifting
🐦 Manual Canary release
1. 배포 상태 확인
1
kubectl get deploy,rs,pod -n istioinaction --show-labels
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/catalog 1/1 1 1 13h app=catalog,version=v1
deployment.apps/catalog-v2 1/1 1 1 13h app=catalog,version=v2
deployment.apps/webapp 1/1 1 1 13h app=webapp
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/catalog-6cf4b97d 1 1 1 13h app=catalog,pod-template-hash=6cf4b97d,version=v1
replicaset.apps/catalog-v2-6df885b555 1 1 1 13h app=catalog,pod-template-hash=6df885b555,version=v2
replicaset.apps/webapp-7685bcb84 1 1 1 13h app=webapp,pod-template-hash=7685bcb84
NAME READY STATUS RESTARTS AGE LABELS
pod/catalog-6cf4b97d-ml4fw 2/2 Running 0 13h 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
pod/catalog-v2-6df885b555-xmg2x 2/2 Running 0 13h 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
pod/webapp-7685bcb84-ng9xn 2/2 Running 0 13h app=webapp,pod-template-hash=7685bcb84,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=webapp,service.istio.io/canonical-revision=latest
2. 반복 호출 테스트 (v1 응답 확인)
1
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[{"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"}]2025-04-26 12:29:53
[{"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"}]2025-04-26 12:29:54
[{"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"}]2025-04-26 12:29:55
[{"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"}]2025-04-26 12:29:56
[{"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"}]2025-04-26 12:29:57
[{"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"}]2025-04-26 12:29:58
[{"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"}]2025-04-26 12:29:59
[{"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"}]2025-04-26 12:30:00
[{"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"}]2025-04-26 12:30:01
...
3. 트래픽을 모두 v1으로 설정
(1) catalog-vs-v1-mesh.yaml
확인
1
cat ch5/catalog-vs-v1-mesh.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
(2) catalog-vs-v1-mesh.yaml
적용
1
2
3
4
kubectl apply -f ch5/catalog-vs-v1-mesh.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog configured
(3) 호출테스트 - catalog 요청은 모두 v1로만 라우팅
1
curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[
{
"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"
}
]
4. 트래픽 10%를 v2로 분배
(1) catalog-vs-v2-10-90-mesh.yaml
확인
1
cat ch5/catalog-vs-v2-10-90-mesh.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
weight: 90
- destination:
host: catalog
subset: version-v2
weight: 10
(2) catalog-vs-v2-10-90-mesh.yaml
적용
1
2
3
4
kubectl apply -f ch5/catalog-vs-v2-10-90-mesh.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog configured
1
2
3
4
kubectl get vs -n istioinaction catalog
NAME GATEWAYS HOSTS AGE
catalog ["mesh"] ["catalog"] 13h
(3) 호출테스트 - v2 호출 비중 확인
1
2
for i in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
✅ 출력
1
2
2
13
5. proxy-config(webapp) 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction --name 80 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
[
{
"name": "80",
"virtualHosts": [
{
"name": "catalog.istioinaction.svc.cluster.local:80",
"domains": [
"catalog.istioinaction.svc.cluster.local",
"catalog",
"catalog.istioinaction.svc",
"catalog.istioinaction",
"10.200.1.92"
],
"routes": [
{
"match": {
"prefix": "/"
},
"route": {
"weightedClusters": {
"clusters": [
{
"name": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
"weight": 90
},
{
"name": "outbound|80|version-v2|catalog.istioinaction.svc.cluster.local",
"weight": 10
}
],
"totalWeight": 100
},
"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"
}
}
},
"decorator": {
"operation": "catalog:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "istio-ingressgateway.istio-system.svc.cluster.local:80",
"domains": [
"istio-ingressgateway.istio-system.svc.cluster.local",
"istio-ingressgateway.istio-system",
"istio-ingressgateway.istio-system.svc",
"10.200.1.107"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||istio-ingressgateway.istio-system.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"
},
"decorator": {
"operation": "istio-ingressgateway.istio-system.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "tracing.istio-system.svc.cluster.local:80",
"domains": [
"tracing.istio-system.svc.cluster.local",
"tracing.istio-system",
"tracing.istio-system.svc",
"10.200.1.170"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||tracing.istio-system.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"
},
"decorator": {
"operation": "tracing.istio-system.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "webapp.istioinaction.svc.cluster.local:80",
"domains": [
"webapp.istioinaction.svc.cluster.local",
"webapp",
"webapp.istioinaction.svc",
"webapp.istioinaction",
"10.200.1.51"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||webapp.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"
},
"decorator": {
"operation": "webapp.istioinaction.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "allow_any",
"domains": [
"*"
],
"routes": [
{
"name": "allow_any",
"match": {
"prefix": "/"
},
"route": {
"cluster": "PassthroughCluster",
"timeout": "0s",
"maxGrpcTimeout": "0s"
}
}
],
"includeRequestAttemptCount": true
}
],
"validateClusters": false,
"maxDirectResponseBodySizeBytes": 1048576,
"ignorePortInHostMatching": true
}
]
6. 트래픽 50:50 분배로 수정
(1) catalog-vs-v2-50-50-mesh.yaml
확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat ch5/catalog-vs-v2-50-50-mesh.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
weight: 50
- destination:
host: catalog
subset: version-v2
weight: 50
(2) catalog-vs-v2-50-50-mesh.yaml
적용
1
2
3
4
kubectl apply -f ch5/catalog-vs-v2-50-50-mesh.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog configured
(3) 호출 테스트 : v2 호출 비중 확인
1
2
for i in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
✅ 출력
1
2
5
53
7. proxy-config(webapp) 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction --name 80 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
[
{
"name": "80",
"virtualHosts": [
{
"name": "catalog.istioinaction.svc.cluster.local:80",
"domains": [
"catalog.istioinaction.svc.cluster.local",
"catalog",
"catalog.istioinaction.svc",
"catalog.istioinaction",
"10.200.1.92"
],
"routes": [
{
"match": {
"prefix": "/"
},
"route": {
"weightedClusters": {
"clusters": [
{
"name": "outbound|80|version-v1|catalog.istioinaction.svc.cluster.local",
"weight": 50
},
{
"name": "outbound|80|version-v2|catalog.istioinaction.svc.cluster.local",
"weight": 50
}
],
"totalWeight": 100
},
"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"
}
}
},
"decorator": {
"operation": "catalog:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "istio-ingressgateway.istio-system.svc.cluster.local:80",
"domains": [
"istio-ingressgateway.istio-system.svc.cluster.local",
"istio-ingressgateway.istio-system",
"istio-ingressgateway.istio-system.svc",
"10.200.1.107"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||istio-ingressgateway.istio-system.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"
},
"decorator": {
"operation": "istio-ingressgateway.istio-system.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "tracing.istio-system.svc.cluster.local:80",
"domains": [
"tracing.istio-system.svc.cluster.local",
"tracing.istio-system",
"tracing.istio-system.svc",
"10.200.1.170"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||tracing.istio-system.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"
},
"decorator": {
"operation": "tracing.istio-system.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "webapp.istioinaction.svc.cluster.local:80",
"domains": [
"webapp.istioinaction.svc.cluster.local",
"webapp",
"webapp.istioinaction.svc",
"webapp.istioinaction",
"10.200.1.51"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||webapp.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"
},
"decorator": {
"operation": "webapp.istioinaction.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "allow_any",
"domains": [
"*"
],
"routes": [
{
"name": "allow_any",
"match": {
"prefix": "/"
},
"route": {
"cluster": "PassthroughCluster",
"timeout": "0s",
"maxGrpcTimeout": "0s"
}
}
],
"includeRequestAttemptCount": true
}
],
"validateClusters": false,
"maxDirectResponseBodySizeBytes": 1048576,
"ignorePortInHostMatching": true
}
]
🏁 (Automating) Canary releasing with Flagger
1. 기존 catalog-v2 및 트래픽 제어 리소스 삭제
1
2
3
4
5
6
7
8
9
10
kubectl delete virtualservice catalog -n istioinaction
kubectl delete deploy catalog-v2 -n istioinaction
kubectl delete service catalog -n istioinaction
kubectl delete destinationrule catalog -n istioinaction
# 결과
virtualservice.networking.istio.io "catalog" deleted
deployment.apps "catalog-v2" deleted
service "catalog" deleted
destinationrule.networking.istio.io "catalog" deleted
2. 남은 리소스 확인
(1) Deployment, Service, Endpoint
1
kubectl get deploy,svc,ep -n istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/catalog 1/1 1 1 14h
deployment.apps/webapp 1/1 1 1 13h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/webapp ClusterIP 10.200.1.51 <none> 80/TCP 13h
NAME ENDPOINTS AGE
endpoints/webapp 10.10.0.14:8080 13h
(2) Gateway, VirtualService
1
kubectl get gw,vs -n istioinaction
✅ 출력
1
2
3
4
5
NAME AGE
gateway.networking.istio.io/coolstore-gateway 13h
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 13h
3. Flagger CRD 설치
1
2
3
4
5
6
kubectl apply -f https://raw.githubusercontent.com/fluxcd/flagger/main/artifacts/flagger/crd.yaml
# 결과
customresourcedefinition.apiextensions.k8s.io/canaries.flagger.app created
customresourcedefinition.apiextensions.k8s.io/metrictemplates.flagger.app created
customresourcedefinition.apiextensions.k8s.io/alertproviders.flagger.app created
1
kubectl get crd | grep flagger
✅ 출력
1
2
3
alertproviders.flagger.app 2025-04-26T03:52:48Z
canaries.flagger.app 2025-04-26T03:52:48Z
metrictemplates.flagger.app 2025-04-26T03:52:48Z
4. Flagger Helm 설치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
helm repo add flagger https://flagger.app
helm install flagger flagger/flagger \
--namespace=istio-system \
--set crd.create=false \
--set meshProvider=istio \
--set metricServer=http://prometheus:9090
# 결과
"flagger" has been added to your repositories
NAME: flagger
LAST DEPLOYED: Sat Apr 26 12:53:52 2025
NAMESPACE: istio-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Flagger installed
5. Flagger 설치 확인
1
kubectl get pod -n istio-system -l app.kubernetes.io/name=flagger
✅ 출력
1
2
NAME READY STATUS RESTARTS AGE
flagger-6d4ffc5576-t7kzv 1/1 Running 0 50s
6. Canary 리소스 작성 및 적용
(1) catalog-release.yaml
확인
1
cat ch5/flagger/catalog-release.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: catalog-release
namespace: istioinaction
spec:
targetRef: #1 카나리 대상 디플로이먼트 https://docs.flagger.app/usage/how-it-works#canary-target
apiVersion: apps/v1
kind: Deployment
name: catalog
progressDeadlineSeconds: 60
# Service / VirtualService Config
service: #2 서비스용 설정 https://docs.flagger.app/usage/how-it-works#canary-service
name: catalog
port: 80
targetPort: 3000
gateways:
- mesh
hosts:
- catalog
analysis: #3 카니리 진행 파라미터 https://docs.flagger.app/usage/how-it-works#canary-analysis
interval: 45s
threshold: 5
maxWeight: 50
stepWeight: 10
match:
- sourceLabels:
app: webapp
metrics:
- name: request-success-rate # built-in metric 요청 성공률
thresholdRange:
min: 99
interval: 1m
- name: request-duration # built-in metric 요청 시간
thresholdRange:
max: 500
interval: 30s
(2) catalog-release.yaml
적용
1
2
3
4
kubectl apply -f ch5/flagger/catalog-release.yaml -n istioinaction
# 결과
canary.flagger.app/catalog-release created
7. Canary 리소스 확인
1
kubectl get canary -n istioinaction -w
✅ 출력
1
2
3
NAME STATUS WEIGHT LASTTRANSITIONTIME
catalog-release Initializing 0 2025-04-26T04:04:16Z
catalog-release Initialized 0 2025-04-26T04:05:03Z
- Initializing → Initialized 상태 전환
8. Flagger 적용 이후 리소스 변화 확인
(1) Deployment, Service, Endpoint 변화
1
kubectl get deploy,svc,ep -n istioinaction -o wide
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/catalog 0/0 0 0 14h catalog istioinaction/catalog:latest app=catalog,version=v1
deployment.apps/catalog-primary 1/1 1 1 2m23s catalog istioinaction/catalog:latest app=catalog-primary
deployment.apps/webapp 1/1 1 1 14h webapp istioinaction/webapp:latest app=webapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/catalog ClusterIP 10.200.1.37 <none> 80/TCP 98s app=catalog-primary
service/catalog-canary ClusterIP 10.200.1.160 <none> 80/TCP 2m23s app=catalog
service/catalog-primary ClusterIP 10.200.1.132 <none> 80/TCP 2m23s app=catalog-primary
service/webapp ClusterIP 10.200.1.51 <none> 80/TCP 14h app=webapp
NAME ENDPOINTS AGE
endpoints/catalog 10.10.0.16:3000 98s
endpoints/catalog-canary <none> 2m23s
endpoints/catalog-primary 10.10.0.16:3000 2m23s
endpoints/webapp 10.10.0.14:8080 14h
- catalog-primary, catalog-canary 서비스/디플로이 생성됨
- 기존 catalog 서비스는 primary로 변경
(2) Gateway, VirtualService 변화
1
kubectl get gw,vs -n istioinaction
✅ 출력
1
2
3
4
5
6
NAME AGE
gateway.networking.istio.io/coolstore-gateway 14h
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog ["mesh"] ["catalog"] 2m26s
virtualservice.networking.istio.io/webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 14h
- catalog용 VirtualService 생성됨
(3) VirtualService 상세 확인
1
kubectl get vs -n istioinaction catalog -o yaml | kubectl neat
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
name: catalog
namespace: istioinaction
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 100
- destination:
host: catalog-canary
weight: 0
- route:
- destination:
host: catalog-primary
weight: 100
(4) destinationrule 확인
1
kubectl get destinationrule -n istioinaction
✅ 출력
1
2
3
NAME HOST AGE
catalog-canary catalog-canary 3m58s
catalog-primary catalog-primary 3m58s
(5) 각 DestinationRule 상세 확인
catalog-primary
1
kubectl get destinationrule -n istioinaction catalog-primary -o yaml | kubectl neat
✅ 출력
1
2
3
4
5
6
7
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: catalog-primary
namespace: istioinaction
spec:
host: catalog-primary
catalog-canary
1
kubectl get destinationrule -n istioinaction catalog-canary -o yaml | kubectl neat
✅ 출력
1
2
3
4
5
6
7
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: catalog-canary
namespace: istioinaction
spec:
host: catalog-canary
9. Webapp → Catalog 라우팅 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/webapp.istioinaction --name 80 -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
[
{
"name": "80",
"virtualHosts": [
{
"name": "catalog-canary.istioinaction.svc.cluster.local:80",
"domains": [
"catalog-canary.istioinaction.svc.cluster.local",
"catalog-canary",
"catalog-canary.istioinaction.svc",
"catalog-canary.istioinaction",
"10.200.1.160"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||catalog-canary.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"
},
"decorator": {
"operation": "catalog-canary.istioinaction.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "catalog-primary.istioinaction.svc.cluster.local:80",
"domains": [
"catalog-primary.istioinaction.svc.cluster.local",
"catalog-primary",
"catalog-primary.istioinaction.svc",
"catalog-primary.istioinaction",
"10.200.1.132"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||catalog-primary.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"
},
"decorator": {
"operation": "catalog-primary.istioinaction.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "catalog.istioinaction.svc.cluster.local:80",
"domains": [
"catalog.istioinaction.svc.cluster.local",
"catalog",
"catalog.istioinaction.svc",
"catalog.istioinaction",
"10.200.1.37"
],
"routes": [
{
"match": {
"prefix": "/",
"caseSensitive": true
},
"route": {
"cluster": "outbound|80||catalog-primary.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"
}
}
},
"decorator": {
"operation": "catalog-primary.istioinaction.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "istio-ingressgateway.istio-system.svc.cluster.local:80",
"domains": [
"istio-ingressgateway.istio-system.svc.cluster.local",
"istio-ingressgateway.istio-system",
"istio-ingressgateway.istio-system.svc",
"10.200.1.107"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||istio-ingressgateway.istio-system.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"
},
"decorator": {
"operation": "istio-ingressgateway.istio-system.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "tracing.istio-system.svc.cluster.local:80",
"domains": [
"tracing.istio-system.svc.cluster.local",
"tracing.istio-system",
"tracing.istio-system.svc",
"10.200.1.170"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||tracing.istio-system.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"
},
"decorator": {
"operation": "tracing.istio-system.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "webapp.istioinaction.svc.cluster.local:80",
"domains": [
"webapp.istioinaction.svc.cluster.local",
"webapp",
"webapp.istioinaction.svc",
"webapp.istioinaction",
"10.200.1.51"
],
"routes": [
{
"name": "default",
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|80||webapp.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"
},
"decorator": {
"operation": "webapp.istioinaction.svc.cluster.local:80/*"
}
}
],
"includeRequestAttemptCount": true
},
{
"name": "allow_any",
"domains": [
"*"
],
"routes": [
{
"name": "allow_any",
"match": {
"prefix": "/"
},
"route": {
"cluster": "PassthroughCluster",
"timeout": "0s",
"maxGrpcTimeout": "0s"
}
}
],
"includeRequestAttemptCount": true
}
],
"validateClusters": false,
"maxDirectResponseBodySizeBytes": 1048576,
"ignorePortInHostMatching": true
}
]
10. Webapp의 클러스터 목록에서 catalog 관련 서비스 검색
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction | egrep 'RULE|catalog'
✅ 출력
1
2
3
4
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
catalog-canary.istioinaction.svc.cluster.local 80 - outbound EDS catalog-canary.istioinaction
catalog-primary.istioinaction.svc.cluster.local 80 - outbound EDS catalog-primary.istioinaction
catalog.istioinaction.svc.cluster.local 80 - outbound EDS
11. catalog 클러스터 세부 정보 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn catalog.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
[
{
"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"
}
}
]
}
]
12. catalog-primary Cluster 세부 정보 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn catalog-primary.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
[
{
"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-primary.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-primary.istioinaction.svc.cluster.local",
"type": "EDS",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
"initialFetchTimeout": "0s",
"resourceApiVersion": "V3"
},
"serviceName": "outbound|80||catalog-primary.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": {
"config": "/apis/networking.istio.io/v1alpha3/namespaces/istioinaction/destination-rule/catalog-primary",
"default_original_port": 80,
"services": [
{
"host": "catalog-primary.istioinaction.svc.cluster.local",
"name": "catalog-primary",
"namespace": "istioinaction"
}
]
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
13. catalog-canary Cluster 세부 정보 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn catalog-canary.istioinaction.svc.cluster.local -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
[
{
"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-canary.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-canary.istioinaction.svc.cluster.local",
"type": "EDS",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
"initialFetchTimeout": "0s",
"resourceApiVersion": "V3"
},
"serviceName": "outbound|80||catalog-canary.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": {
"config": "/apis/networking.istio.io/v1alpha3/namespaces/istioinaction/destination-rule/catalog-canary",
"default_original_port": 80,
"services": [
{
"host": "catalog-canary.istioinaction.svc.cluster.local",
"name": "catalog-canary",
"namespace": "istioinaction"
}
]
}
}
},
"filters": [
{
"name": "istio.metadata_exchange",
"typedConfig": {
"@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange",
"protocol": "istio-peer-exchange"
}
}
]
}
]
14. Webapp Envoy에 설정된 엔드포인트 (catalog 관련) 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction | grep catalog
✅ 출력
1
2
10.10.0.16:3000 HEALTHY OK outbound|80||catalog-primary.istioinaction.svc.cluster.local
10.10.0.16:3000 HEALTHY OK outbound|80||catalog.istioinaction.svc.cluster.local
15. catalog EDS Endpoint 메트릭 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction --cluster 'outbound|80||catalog.istioinaction.svc.cluster.local' -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
[
{
"name": "outbound|80||catalog.istioinaction.svc.cluster.local",
"addedViaApi": true,
"hostStatuses": [
{
"address": {
"socketAddress": {
"address": "10.10.0.16",
"portValue": 3000
}
},
"stats": [
{
"name": "cx_connect_fail"
},
{
"name": "cx_total"
},
{
"name": "rq_error"
},
{
"name": "rq_success"
},
{
"name": "rq_timeout"
},
{
"name": "rq_total"
},
{
"type": "GAUGE",
"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"
}
]
- 메트릭 통계 0 (cx_total, rq_total 등 아직 호출 없음)
16. catalog-primary EDS Endpoint 메트릭 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/webapp.istioinaction --cluster 'outbound|80||catalog-primary.istioinaction.svc.cluster.local' -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
[
{
"name": "outbound|80||catalog-primary.istioinaction.svc.cluster.local",
"addedViaApi": true,
"hostStatuses": [
{
"address": {
"socketAddress": {
"address": "10.10.0.16",
"portValue": 3000
}
},
"stats": [
{
"name": "cx_connect_fail"
},
{
"value": "2",
"name": "cx_total"
},
{
"name": "rq_error"
},
{
"value": "647",
"name": "rq_success"
},
{
"name": "rq_timeout"
},
{
"value": "647",
"name": "rq_total"
},
{
"type": "GAUGE",
"value": "2",
"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-primary.istioinaction.svc.cluster.local",
"edsServiceName": "outbound|80||catalog-primary.istioinaction.svc.cluster.local"
}
]
17. 서비스 부하 생성 (신규 터미널1)
1
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
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HTTP/1.1 200 OK
2025-04-26 13:22:53
HTTP/1.1 200 OK
2025-04-26 13:22:54
HTTP/1.1 200 OK
2025-04-26 13:22:55
HTTP/1.1 200 OK
2025-04-26 13:22:56
HTTP/1.1 200 OK
2025-04-26 13:22:57
...
18. Flagger 로그 모니터링 (신규 터미널2)
1
kubectl logs -f deploy/flagger -n istio-system
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{"level":"info","ts":"2025-04-26T03:53:58.174Z","caller":"flagger/main.go:151","msg":"Starting flagger version 1.41.0 revision 6f165a10de0172acd773f2c05fa92d49b72abafb mesh provider istio"}
{"level":"info","ts":"2025-04-26T03:53:58.174Z","caller":"clientcmd/client_config.go:667","msg":"Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work."}
{"level":"info","ts":"2025-04-26T03:53:58.175Z","caller":"clientcmd/client_config.go:667","msg":"Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work."}
{"level":"info","ts":"2025-04-26T03:53:58.183Z","caller":"flagger/main.go:449","msg":"Connected to Kubernetes API v1.23.17"}
{"level":"info","ts":"2025-04-26T03:53:58.183Z","caller":"flagger/main.go:302","msg":"Waiting for canary informer cache to sync"}
{"level":"info","ts":"2025-04-26T03:53:58.183Z","caller":"cache/shared_informer.go:313","msg":"Waiting for caches to sync for flagger"}
{"level":"info","ts":"2025-04-26T03:53:58.284Z","caller":"cache/shared_informer.go:320","msg":"Caches are synced for flagger"}
{"level":"info","ts":"2025-04-26T03:53:58.284Z","caller":"flagger/main.go:309","msg":"Waiting for metric template informer cache to sync"}
{"level":"info","ts":"2025-04-26T03:53:58.284Z","caller":"cache/shared_informer.go:313","msg":"Waiting for caches to sync for flagger"}
{"level":"info","ts":"2025-04-26T03:53:58.384Z","caller":"cache/shared_informer.go:320","msg":"Caches are synced for flagger"}
{"level":"info","ts":"2025-04-26T03:53:58.384Z","caller":"flagger/main.go:316","msg":"Waiting for alert provider informer cache to sync"}
{"level":"info","ts":"2025-04-26T03:53:58.384Z","caller":"cache/shared_informer.go:313","msg":"Waiting for caches to sync for flagger"}
{"level":"info","ts":"2025-04-26T03:53:58.485Z","caller":"cache/shared_informer.go:320","msg":"Caches are synced for flagger"}
{"level":"info","ts":"2025-04-26T03:53:58.489Z","caller":"flagger/main.go:213","msg":"Connected to metrics server http://prometheus:9090"}
{"level":"info","ts":"2025-04-26T03:53:58.489Z","caller":"server/server.go:45","msg":"Starting HTTP server on port 8080"}
{"level":"info","ts":"2025-04-26T03:53:58.490Z","caller":"controller/controller.go:195","msg":"Starting operator"}
{"level":"info","ts":"2025-04-26T03:53:58.490Z","caller":"controller/controller.go:204","msg":"Started operator workers"}
...
19. Canary 상태 모니터링 (신규 터미널3)
1
kubectl get canary -n istioinaction -w
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
NAME STATUS WEIGHT LASTTRANSITIONTIME
catalog-release Initialized 0 2025-04-26T04:05:03Z
catalog-release Progressing 0 2025-04-26T04:29:48Z
catalog-release Progressing 10 2025-04-26T04:30:33Z
catalog-release Progressing 20 2025-04-26T04:31:18Z
catalog-release Progressing 30 2025-04-26T04:32:03Z
catalog-release Progressing 40 2025-04-26T04:32:48Z
catalog-release Progressing 50 2025-04-26T04:33:33Z
catalog-release Promoting 0 2025-04-26T04:34:18Z
catalog-release Finalising 0 2025-04-26T04:35:03Z
catalog-release Succeeded 0 2025-04-26T04:35:48Z
20. catalog v2 배포 (imageUrl 포함)
1
cat ch5/flagger/catalog-deployment-v2.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: catalog
version: v1
name: catalog
spec:
replicas: 1
selector:
matchLabels:
app: catalog
version: v1
template:
metadata:
labels:
app: catalog
version: v1
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SHOW_IMAGE
value: "true"
image: istioinaction/catalog:latest
imagePullPolicy: IfNotPresent
name: catalog
ports:
- containerPort: 3000
name: http
protocol: TCP
securityContext:
privileged: false
1
2
3
4
kubectl apply -f ch5/flagger/catalog-deployment-v2.yaml -n istioinaction
# 결과
deployment.apps/catalog configured
21. VirtualService 가중치 변경 모니터링
1
kubectl get vs -n istioinaction catalog -o yaml -w
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 1
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "22932"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 100
- destination:
host: catalog-canary
weight: 0
- route:
- destination:
host: catalog-primary
weight: 100
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 2
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "25648"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 90
- destination:
host: catalog-canary
weight: 10
- route:
- destination:
host: catalog-primary
weight: 90
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 3
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "25729"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 80
- destination:
host: catalog-canary
weight: 20
- route:
- destination:
host: catalog-primary
weight: 80
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 4
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "25809"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 70
- destination:
host: catalog-canary
weight: 30
- route:
- destination:
host: catalog-primary
weight: 70
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 5
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "25890"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 60
- destination:
host: catalog-canary
weight: 40
- route:
- destination:
host: catalog-primary
weight: 60
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 6
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "25971"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 50
- destination:
host: catalog-canary
weight: 50
- route:
- destination:
host: catalog-primary
weight: 50
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
creationTimestamp: "2025-04-26T04:05:03Z"
generation: 7
name: catalog
namespace: istioinaction
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: catalog-release
uid: 71596c13-2d14-46d4-887b-4a1f806cd34c
resourceVersion: "26206"
uid: c9cfbc36-3896-47e8-b6d5-3bf4cc255dfd
spec:
gateways:
- mesh
hosts:
- catalog
http:
- match:
- sourceLabels:
app: webapp
route:
- destination:
host: catalog-primary
weight: 100
- destination:
host: catalog-canary
weight: 0
- route:
- destination:
host: catalog-primary
weight: 100
22. Canary 리소스 이벤트 확인
1
kubectl describe canary -n istioinaction catalog-release | grep Events: -A20
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Synced 33m flagger catalog-primary.istioinaction not ready: waiting for rollout to finish: observed deployment generation less than desired generation
Normal Synced 32m (x2 over 33m) flagger all the metrics providers are available!
Normal Synced 32m flagger Initialization done! catalog-release.istioinaction
Normal Synced 7m46s flagger New revision detected! Scaling up catalog.istioinaction
Normal Synced 7m1s flagger Starting canary analysis for catalog.istioinaction
Normal Synced 7m1s flagger Advance catalog-release.istioinaction canary weight 10
Normal Synced 6m16s flagger Advance catalog-release.istioinaction canary weight 20
Normal Synced 5m31s flagger Advance catalog-release.istioinaction canary weight 30
Normal Synced 4m46s flagger Advance catalog-release.istioinaction canary weight 40
Normal Synced 4m1s flagger Advance catalog-release.istioinaction canary weight 50
Normal Synced 3m16s flagger Copying catalog.istioinaction template spec to catalog-primary.istioinaction
Normal Synced 2m31s flagger Routing all traffic to primary
Normal Synced 106s flagger (combined from similar events): Promotion completed! Scaling down catalog.istioinaction
23. Flagger Canary 리소스 정리
Canary 삭제 / catalog 삭제 / Flagger 삭제
1
2
3
4
5
6
7
8
kubectl delete canary catalog-release -n istioinaction
kubectl delete deploy catalog -n istioinaction
helm uninstall flagger -n istio-system
# 결과
release "flagger" uninstall
canary.flagger.app "catalog-release" deleted
deployment.apps "catalog" deleted
🪞 Reducing risk even further: Traffic mirroring
1. 실습 환경 초기화
1
2
3
4
5
6
7
8
9
10
11
12
kubectl apply -f services/catalog/kubernetes/catalog-svc.yaml -n istioinaction
kubectl apply -f services/catalog/kubernetes/catalog-deployment.yaml -n istioinaction
kubectl apply -f services/catalog/kubernetes/catalog-deployment-v2.yaml -n istioinaction
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
kubectl apply -f ch5/catalog-vs-v1-mesh.yaml -n istioinaction
# 결과
service/catalog created
deployment.apps/catalog created
deployment.apps/catalog-v2 created
destinationrule.networking.istio.io/catalog created
virtualservice.networking.istio.io/catalog created
2. 리소스 정상 배포 확인
1
2
3
kubectl get deploy -n istioinaction -o wide
kubectl get svc,ep -n istioinaction -owide
kubectl get gw,vs -n istioinaction
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
catalog 1/1 1 1 24s catalog istioinaction/catalog:latest app=catalog,version=v1
catalog-v2 1/1 1 1 24s catalog istioinaction/catalog:latest app=catalog,version=v2
webapp 1/1 1 1 14h webapp istioinaction/webapp:latest app=webapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/catalog ClusterIP 10.200.1.47 <none> 80/TCP 24s app=catalog
service/webapp ClusterIP 10.200.1.51 <none> 80/TCP 14h app=webapp
NAME ENDPOINTS AGE
endpoints/catalog 10.10.0.19:3000,10.10.0.20:3000 24s
endpoints/webapp 10.10.0.14:8080 14h
NAME AGE
gateway.networking.istio.io/coolstore-gateway 14h
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog ["mesh"] ["catalog"] 24s
virtualservice.networking.istio.io/webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 14h
3. 부하 생성 (반복 호출)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
HTTP/1.1 200 OK
2025-04-26 13:50:49
HTTP/1.1 200 OK
2025-04-26 13:50:50
HTTP/1.1 200 OK
2025-04-26 13:50:51
HTTP/1.1 200 OK
2025-04-26 13:50:52
HTTP/1.1 200 OK
2025-04-26 13:50:53
...
4. catalog v1만 응답하는지 검증
1
2
3
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
0
5. 트래픽 미러링 설정
1
cat ch5/catalog-vs-v2-mirror.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
weight: 100
mirror:
host: catalog
subset: version-v2
- v1으로 100% 트래픽, 동시에 v2로 미러링 전송
6. 반복 접속
1
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
7. catalog istio-proxy 로그 활성화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat << EOF | kubectl apply -f -
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: catalog
namespace: istioinaction
spec:
accessLogging:
- disabled: false
providers:
- name: envoy
selector:
matchLabels:
app: catalog
EOF
# 결과
telemetry.telemetry.istio.io/catalog created
8. 신규 터미널에서 istio-proxy 로그 확인
1
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[2025-04-26T05:03:47.356Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "6ee64299-c88b-4774-9610-77560a14c58c" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56292 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:47.355Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 3 3 "172.18.0.1" "curl/8.13.0" "6ee64299-c88b-4774-9610-77560a14c58c" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:44971 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:47.597Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "32c66520-58ab-474d-9cb5-d71767e7f6f0" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56292 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:47.596Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 3 "172.18.0.1" "curl/8.13.0" "32c66520-58ab-474d-9cb5-d71767e7f6f0" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:44971 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:48.372Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "a54006da-ca18-4948-9cea-3ee410172ba5" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56278 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:48.371Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 3 3 "172.18.0.1" "curl/8.13.0" "a54006da-ca18-4948-9cea-3ee410172ba5" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56083 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:48.613Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "5f74086e-0245-4444-8371-3d0a1dd58ff2" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56278 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:48.612Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "5f74086e-0245-4444-8371-3d0a1dd58ff2" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56083 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:49.389Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "c8edd9eb-27f9-4854-8894-61714acc49ad" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56278 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:49.387Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "c8edd9eb-27f9-4854-8894-61714acc49ad" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:44971 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:49.632Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 3 2 "172.18.0.1" "beegoServer" "63b7e0b8-e924-4050-878c-c947de1207fd" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56278 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:49.630Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 5 4 "172.18.0.1" "curl/8.13.0" "63b7e0b8-e924-4050-878c-c947de1207fd" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56083 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:50.403Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "205075a8-a418-4054-ad36-f4f41db5b0cb" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56278 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:50.401Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 3 3 "172.18.0.1" "curl/8.13.0" "205075a8-a418-4054-ad36-f4f41db5b0cb" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:44971 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:50.651Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "92adf7fc-c360-41df-8186-a7b3fbd37527" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56292 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:50.650Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 3 3 "172.18.0.1" "curl/8.13.0" "92adf7fc-c360-41df-8186-a7b3fbd37527" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56083 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:51.420Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "e7386376-7f4c-4c68-8ce8-97c038fe8aa2" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56278 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:51.418Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "e7386376-7f4c-4c68-8ce8-97c038fe8aa2" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56083 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
[2025-04-26T05:03:51.670Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "4ad7b6b2-2580-4940-a24c-f50934b63533" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:56292 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T05:03:51.669Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "4ad7b6b2-2580-4940-a24c-f50934b63533" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56083 10.10.0.14:8080 172.18.0.1:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
...
9. v2 로그 확인
1
kubectl logs -n istioinaction -l app=catalog -l version=v2 -c istio-proxy -f
✅ 출력
1
2
3
4
5
6
7
8
9
10
2025-04-26T04:49:33.836541Z info cache returned workload trust anchor from cache ttl=23h59m59.163462166s
2025-04-26T04:49:33.861342Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012
2025-04-26T04:49:33.888087Z info ads ADS: new connection for node:catalog-v2-6df885b555-pc9br.istioinaction-1
2025-04-26T04:49:33.888110Z info ads ADS: new connection for node:catalog-v2-6df885b555-pc9br.istioinaction-2
2025-04-26T04:49:33.888153Z info cache returned workload certificate from cache ttl=23h59m59.1118509s
2025-04-26T04:49:33.888179Z info cache returned workload trust anchor from cache ttl=23h59m59.111825321s
2025-04-26T04:49:33.888281Z info ads SDS: PUSH request for node:catalog-v2-6df885b555-pc9br.istioinaction resources:1 size:4.0kB resource:default
2025-04-26T04:49:33.888402Z info ads SDS: PUSH request for node:catalog-v2-6df885b555-pc9br.istioinaction resources:1 size:1.1kB resource:ROOTCA
2025-04-26T04:49:34.336850Z info Readiness succeeded in 798.31849ms
2025-04-26T04:49:34.337023Z info Envoy proxy is ready
10. 미러링 VS 설정
1
2
3
4
kubectl apply -f ch5/catalog-vs-v2-mirror.yaml -n istioinaction
# 결과
virtualservice.networking.istio.io/catalog configured
11. v1 으로만 호출 확인
1
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
✅ 출력
1
0
12. v1 app 로그 확인
1
kubectl logs -n istioinaction -l app=catalog -l version=v1 -c catalog -f
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction:80 /items 200 502 - 0.384 ms
GET /items 200 0.384 ms - 502
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction:80 /items 200 502 - 0.320 ms
GET /items 200 0.320 ms - 502
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction:80 /items 200 502 - 0.362 ms
GET /items 200 0.362 ms - 502
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction:80 /items 200 502 - 0.410 ms
GET /items 200 0.410 ms - 502
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction:80 /items 200 502 - 0.352 ms
GET /items 200 0.352 ms - 502
request path: /items
blowups: {}
number of blowups: 0
...
13. v2 app 로그 확인
1
kubectl logs -n istioinaction -l app=catalog -l version=v2 -c catalog -f
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.362 ms
GET /items 200 0.362 ms - 698
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.353 ms
GET /items 200 0.353 ms - 698
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.439 ms
GET /items 200 0.439 ms - 698
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.393 ms
GET /items 200 0.393 ms - 698
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.512 ms
GET /items 200 0.512 ms - 698
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.430 ms
GET /items 200 0.430 ms - 698
request path: /items
blowups: {}
number of blowups: 0
GET catalog.istioinaction-shadow:80 /items 200 698 - 0.446 ms
GET /items 200 0.446 ms - 698
request path: /items
blowups: {}
number of blowups: 0
14. (심화) webapp 과 catalog v2 파드에서 패킷 덤프로 확인
(1) Istio 메시 내부망 mTLS 비활성화 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: DISABLE
EOF
# 결과
peerauthentication.security.istio.io/default created
(2) mTLS 모드가 DISABLE
로 설정됨
1
kubectl get PeerAuthentication -n istio-system
✅ 출력
1
2
NAME MODE AGE
default DISABLE 22s
(3) catalog v2 파드 IP 확인
1
2
C2IP=$(kubectl get pod -n istioinaction -l app=catalog -l version=v2 -o jsonpath='{.items[*].status.podIP}')
echo $C2IP
✅ 출력
1
10.10.0.20
(4) catalog v2 파드와 연결된 veth 인터페이스 이름 찾기
1
2
3
docker exec -it myk8s-control-plane ip -c route | grep $C2IP | awk '{ print $3 }'
C2VETH=$(docker exec -it myk8s-control-plane ip -c route | grep $C2IP | awk '{ print $3 }')
echo $C2VETH
✅ 출력
1
2
veth8c114630
veth8c114630
(5) catalog v2 파드로 들어오는 트래픽 패킷 캡처
1
docker exec -it myk8s-control-plane sh -c "ngrep -tW byline -d veth8c114630 '' 'tcp port 3000'"
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#
T 2025/04/26 14:03:45.381563 10.10.0.20:3000 -> 10.10.0.14:43232 [AP] #128
HTTP/1.1 200 OK.
x-powered-by: Express.
vary: Origin, Accept-Encoding.
access-control-allow-credentials: true.
cache-control: no-cache.
pragma: no-cache.
expires: -1.
content-type: application/json; charset=utf-8.
content-length: 698.
etag: W/"2ba-8igEisu4O69h8jWIFgUqgmp7D5o".
date: Sat, 26 Apr 2025 14:03:45 GMT.
x-envoy-upstream-service-time: 1.
x-envoy-peer-metadata: ChsKDkFQUF9DT05UQUlORVJTEgkaB2NhdGFsb2cKGgoKQ0xVU1RFUl9JRBIMGgpLdWJlcm5ldGVzChwKDElOU1RBTkNFX0lQUxIMGgoxMC4xMC4wLjIwChkKDUlTVElPX1ZFUlNJT04SCBoGMS4xNy44CrIBCgZMQUJFTFMSpwEqpAEKEAoDYXBwEgkaB2NhdGFsb2cKJAoZc2VjdXJpdHkuaXN0aW8uaW8vdGxzTW9kZRIHGgVpc3RpbwosCh9zZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1uYW1lEgkaB2NhdGFsb2cKKwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SBBoCdjIKDwoHdmVyc2lvbhIEGgJ2MgoaCgdNRVNIX0lEEg8aDWNsdXN0ZXIubG9jYWwKJQoETkFNRRIdGhtjYXRhbG9nLXYyLTZkZjg4NWI1NTUtcGM5YnIKHAoJTkFNRVNQQUNFEg8aDWlzdGlvaW5hY3Rpb24KVAoFT1dORVISSxpJa3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2lzdGlvaW5hY3Rpb24vZGVwbG95bWVudHMvY2F0YWxvZy12MgoXChFQTEFURk9STV9NRVRBREFUQRICKgAKHQoNV09SS0xPQURfTkFNRRIMGgpjYXRhbG9nLXYy.
x-envoy-peer-metadata-id: sidecar~10.10.0.20~catalog-v2-6df885b555-pc9br.istioinaction~istioinaction.svc.cluster.local.
server: istio-envoy.
.
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 2,
"color": "cyan",
"department": "Clothing",
"name": "Atlas Shirt",
"price": "127.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 3,
"color": "teal",
"department": "Clothing",
"name": "Small Metal Shoes",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
},
{
"id": 4,
"color": "red",
"department": "Watches",
"name": "Red Dragon Watch",
"price": "232.00",
"imageUrl": "http://lorempixel.com/640/480"
}
]
...
🛰️ Routing to services outside your cluster by using Istio’s service discovery
1. IstioOperators meshConfig 설정 확인
1
kubectl get istiooperators -n istio-system -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "install.istio.io/v1alpha1",
"kind": "IstioOperator",
"metadata": {
"annotations": {
"install.istio.io/ignoreReconcile": "true",
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"install.istio.io/v1alpha1\",\"kind\":\"IstioOperator\",\"metadata\":{\"annotations\":{\"install.istio.io/ignoreReconcile\":\"true\"},\"creationTimestamp\":null,\"name\":\"installed-state\",\"namespace\":\"istio-system\"},\"spec\":{\"components\":{\"base\":{\"enabled\":true},\"cni\":{\"enabled\":false},\"egressGateways\":[{\"enabled\":false,\"name\":\"istio-egressgateway\"}],\"ingressGateways\":[{\"enabled\":true,\"name\":\"istio-ingressgateway\"}],\"istiodRemote\":{\"enabled\":false},\"pilot\":{\"enabled\":true}},\"hub\":\"docker.io/istio\",\"meshConfig\":{\"defaultConfig\":{\"proxyMetadata\":{}},\"enablePrometheusMerge\":true},\"profile\":\"default\",\"tag\":\"1.17.8\",\"values\":{\"base\":{\"enableCRDTemplates\":false,\"validationURL\":\"\"},\"defaultRevision\":\"\",\"gateways\":{\"istio-egressgateway\":{\"autoscaleEnabled\":true,\"env\":{},\"name\":\"istio-egressgateway\",\"secretVolumes\":[{\"mountPath\":\"/etc/istio/egressgateway-certs\",\"name\":\"egressgateway-certs\",\"secretName\":\"istio-egressgateway-certs\"},{\"mountPath\":\"/etc/istio/egressgateway-ca-certs\",\"name\":\"egressgateway-ca-certs\",\"secretName\":\"istio-egressgateway-ca-certs\"}],\"type\":\"ClusterIP\"},\"istio-ingressgateway\":{\"autoscaleEnabled\":true,\"env\":{},\"name\":\"istio-ingressgateway\",\"secretVolumes\":[{\"mountPath\":\"/etc/istio/ingressgateway-certs\",\"name\":\"ingressgateway-certs\",\"secretName\":\"istio-ingressgateway-certs\"},{\"mountPath\":\"/etc/istio/ingressgateway-ca-certs\",\"name\":\"ingressgateway-ca-certs\",\"secretName\":\"istio-ingressgateway-ca-certs\"}],\"type\":\"LoadBalancer\"}},\"global\":{\"configValidation\":true,\"defaultNodeSelector\":{},\"defaultPodDisruptionBudget\":{\"enabled\":true},\"defaultResources\":{\"requests\":{\"cpu\":\"10m\"}},\"imagePullPolicy\":\"\",\"imagePullSecrets\":[],\"istioNamespace\":\"istio-system\",\"istiod\":{\"enableAnalysis\":false},\"jwtPolicy\":\"third-party-jwt\",\"logAsJson\":false,\"logging\":{\"level\":\"default:info\"},\"meshNetworks\":{},\"mountMtlsCerts\":false,\"multiCluster\":{\"clusterName\":\"\",\"enabled\":false},\"network\":\"\",\"omitSidecarInjectorConfigMap\":false,\"oneNamespace\":false,\"operatorManageWebhooks\":false,\"pilotCertProvider\":\"istiod\",\"priorityClassName\":\"\",\"proxy\":{\"autoInject\":\"enabled\",\"clusterDomain\":\"cluster.local\",\"componentLogLevel\":\"misc:error\",\"enableCoreDump\":false,\"excludeIPRanges\":\"\",\"excludeInboundPorts\":\"\",\"excludeOutboundPorts\":\"\",\"image\":\"proxyv2\",\"includeIPRanges\":\"*\",\"logLevel\":\"warning\",\"privileged\":false,\"readinessFailureThreshold\":30,\"readinessInitialDelaySeconds\":1,\"readinessPeriodSeconds\":2,\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"1024Mi\"},\"requests\":{\"cpu\":\"100m\",\"memory\":\"128Mi\"}},\"statusPort\":15020,\"tracer\":\"zipkin\"},\"proxy_init\":{\"image\":\"proxyv2\",\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"1024Mi\"},\"requests\":{\"cpu\":\"10m\",\"memory\":\"10Mi\"}}},\"sds\":{\"token\":{\"aud\":\"istio-ca\"}},\"sts\":{\"servicePort\":0},\"tracer\":{\"datadog\":{},\"lightstep\":{},\"stackdriver\":{},\"zipkin\":{}},\"useMCP\":false},\"istiodRemote\":{\"injectionURL\":\"\"},\"pilot\":{\"autoscaleEnabled\":true,\"autoscaleMax\":5,\"autoscaleMin\":1,\"configMap\":true,\"cpu\":{\"targetAverageUtilization\":80},\"deploymentLabels\":null,\"enableProtocolSniffingForInbound\":true,\"enableProtocolSniffingForOutbound\":true,\"env\":{},\"image\":\"pilot\",\"keepaliveMaxServerConnectionAge\":\"30m\",\"nodeSelector\":{},\"podLabels\":{},\"replicaCount\":1,\"traceSampling\":1},\"telemetry\":{\"enabled\":true,\"v2\":{\"enabled\":true,\"metadataExchange\":{\"wasmEnabled\":false},\"prometheus\":{\"enabled\":true,\"wasmEnabled\":false},\"stackdriver\":{\"configOverride\":{},\"enabled\":false,\"logging\":false,\"monitoring\":false,\"topology\":false}}}}}}\n"
},
"creationTimestamp": "2025-04-25T13:37:43Z",
"generation": 1,
"name": "installed-state",
"namespace": "istio-system",
"resourceVersion": "892",
"uid": "f2e1fbab-b327-43c0-8ccb-1a2bed1933df"
},
"spec": {
"components": {
"base": {
"enabled": true
},
"cni": {
"enabled": false
},
"egressGateways": [
{
"enabled": false,
"name": "istio-egressgateway"
}
],
"ingressGateways": [
{
"enabled": true,
"name": "istio-ingressgateway"
}
],
"istiodRemote": {
"enabled": false
},
"pilot": {
"enabled": true
}
},
"hub": "docker.io/istio",
"meshConfig": {
"defaultConfig": {
"proxyMetadata": {}
},
"enablePrometheusMerge": true
},
"profile": "default",
"tag": "1.17.8",
"values": {
"base": {
"enableCRDTemplates": false,
"validationURL": ""
},
"defaultRevision": "",
"gateways": {
"istio-egressgateway": {
"autoscaleEnabled": true,
"env": {},
"name": "istio-egressgateway",
"secretVolumes": [
{
"mountPath": "/etc/istio/egressgateway-certs",
"name": "egressgateway-certs",
"secretName": "istio-egressgateway-certs"
},
{
"mountPath": "/etc/istio/egressgateway-ca-certs",
"name": "egressgateway-ca-certs",
"secretName": "istio-egressgateway-ca-certs"
}
],
"type": "ClusterIP"
},
"istio-ingressgateway": {
"autoscaleEnabled": true,
"env": {},
"name": "istio-ingressgateway",
"secretVolumes": [
{
"mountPath": "/etc/istio/ingressgateway-certs",
"name": "ingressgateway-certs",
"secretName": "istio-ingressgateway-certs"
},
{
"mountPath": "/etc/istio/ingressgateway-ca-certs",
"name": "ingressgateway-ca-certs",
"secretName": "istio-ingressgateway-ca-certs"
}
],
"type": "LoadBalancer"
}
},
"global": {
"configValidation": true,
"defaultNodeSelector": {},
"defaultPodDisruptionBudget": {
"enabled": true
},
"defaultResources": {
"requests": {
"cpu": "10m"
}
},
"imagePullPolicy": "",
"imagePullSecrets": [],
"istioNamespace": "istio-system",
"istiod": {
"enableAnalysis": false
},
"jwtPolicy": "third-party-jwt",
"logAsJson": false,
"logging": {
"level": "default:info"
},
"meshNetworks": {},
"mountMtlsCerts": false,
"multiCluster": {
"clusterName": "",
"enabled": false
},
"network": "",
"omitSidecarInjectorConfigMap": false,
"oneNamespace": false,
"operatorManageWebhooks": false,
"pilotCertProvider": "istiod",
"priorityClassName": "",
"proxy": {
"autoInject": "enabled",
"clusterDomain": "cluster.local",
"componentLogLevel": "misc:error",
"enableCoreDump": false,
"excludeIPRanges": "",
"excludeInboundPorts": "",
"excludeOutboundPorts": "",
"image": "proxyv2",
"includeIPRanges": "*",
"logLevel": "warning",
"privileged": false,
"readinessFailureThreshold": 30,
"readinessInitialDelaySeconds": 1,
"readinessPeriodSeconds": 2,
"resources": {
"limits": {
"cpu": "2000m",
"memory": "1024Mi"
},
"requests": {
"cpu": "100m",
"memory": "128Mi"
}
},
"statusPort": 15020,
"tracer": "zipkin"
},
"proxy_init": {
"image": "proxyv2",
"resources": {
"limits": {
"cpu": "2000m",
"memory": "1024Mi"
},
"requests": {
"cpu": "10m",
"memory": "10Mi"
}
}
},
"sds": {
"token": {
"aud": "istio-ca"
}
},
"sts": {
"servicePort": 0
},
"tracer": {
"datadog": {},
"lightstep": {},
"stackdriver": {},
"zipkin": {}
},
"useMCP": false
},
"istiodRemote": {
"injectionURL": ""
},
"pilot": {
"autoscaleEnabled": true,
"autoscaleMax": 5,
"autoscaleMin": 1,
"configMap": true,
"cpu": {
"targetAverageUtilization": 80
},
"deploymentLabels": null,
"enableProtocolSniffingForInbound": true,
"enableProtocolSniffingForOutbound": true,
"env": {},
"image": "pilot",
"keepaliveMaxServerConnectionAge": "30m",
"nodeSelector": {},
"podLabels": {},
"replicaCount": 1,
"traceSampling": 1
},
"telemetry": {
"enabled": true,
"v2": {
"enabled": true,
"metadataExchange": {
"wasmEnabled": false
},
"prometheus": {
"enabled": true,
"wasmEnabled": false
},
"stackdriver": {
"configOverride": {},
"enabled": false,
"logging": false,
"monitoring": false,
"topology": false
}
}
}
}
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": ""
}
}
2. webapp 파드에서 외부 다운로드
1
2
3
4
5
6
7
kubectl exec -it deploy/webapp -n istioinaction -c webapp -- wget https://raw.githubusercontent.com/gasida/KANS/refs/heads/main/msa/sock-shop-demo.yaml
# 결과
Connecting to raw.githubusercontent.com (185.199.110.133:443)
saving to 'sock-shop-demo.yaml'
sock-shop-demo.yaml 100% |************************| 17782 0:00:00 ETA
'sock-shop-demo.yaml' saved
3. webapp istio-proxy 로그 확인
1
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[2025-04-26T14:11:31.987Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "38ab366b-1a3b-4189-9f21-e8818013aa45" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43626 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:11:31.985Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 5 4 "172.18.0.1" "curl/8.13.0" "38ab366b-1a3b-4189-9f21-e8818013aa45" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56173 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:11:33.003Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 1 1 "172.18.0.1" "beegoServer" "dcc597e0-587e-4c81-a4e4-50cff9d02891" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43630 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:11:33.002Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 3 3 "172.18.0.1" "curl/8.13.0" "dcc597e0-587e-4c81-a4e4-50cff9d02891" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56173 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:11:34.019Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "4068fda8-b01a-4e85-86e4-dbf0827ce2d3" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43630 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:11:34.017Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 5 4 "172.18.0.1" "curl/8.13.0" "4068fda8-b01a-4e85-86e4-dbf0827ce2d3" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:45915 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:11:35.036Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "a6b0f219-153d-4942-92a2-942a03f844a6" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43630 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:11:35.034Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "a6b0f219-153d-4942-92a2-942a03f844a6" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56173 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:11:36.055Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "d09bdf85-77b9-4f80-aa57-dcc5a17ae173" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43626 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:11:36.053Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 5 5 "172.18.0.1" "curl/8.13.0" "d09bdf85-77b9-4f80-aa57-dcc5a17ae173" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:45915 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:11:37.074Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "91d2b96b-7d7e-4818-a900-7d0709888c0e" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43630 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:11:37.073Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 3 "172.18.0.1" "curl/8.13.0" "91d2b96b-7d7e-4818-a900-7d0709888c0e" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:45915 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:11:38.091Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "150d9d66-c7f5-4156-830d-702a846cd058" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43626 10.200.1.47:80 172.18.0.1:0 - -
...
4. Istio 재설치 - REGISTRY_ONLY 적용
1
2
3
4
5
6
7
8
9
10
11
docker exec -it myk8s-control-plane bash
root@myk8s-control-plane:/# istioctl install --set profile=default --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
This will install the Istio 1.17.8 default profile with ["Istio core" "Istiod" "Ingress gateways"] components into the cluster. Proceed? (y/N) y
# 결과
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete Making this installation the default for injection and validation.
Thank you for installing Istio 1.17. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/hMHGiwZHPU7UQRWe9
5. webapp 파드에서 외부 다운로드 (재시도)
1
2
3
4
5
6
kubectl exec -it deploy/webapp -n istioinaction -c webapp -- wget https://raw.githubusercontent.com/gasida/KANS/refs/heads/main/msa/sock-shop-demo.yaml
# 결과
Connecting to raw.githubusercontent.com (185.199.108.133:443)
wget: error getting response: Connection reset by peer
command terminated with exit code 1
✅ 로그 출력
1
2
3
4
5
6
...
[2025-04-26T14:16:43.753Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 185.199.108.133:443 10.10.0.14:60640 - -
[2025-04-26T14:16:44.206Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 2 "172.18.0.1" "beegoServer" "646d19c9-5667-448f-89f4-bbbf5260df4f" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43630 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:16:44.204Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 4 "172.18.0.1" "curl/8.13.0" "646d19c9-5667-448f-89f4-bbbf5260df4f" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:45915 10.10.0.14:8080 172.18.0.1:0 - default
[2025-04-26T14:16:45.224Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 2 1 "172.18.0.1" "beegoServer" "73be1243-0c53-4aa3-8703-864ba5f15c30" "catalog.istioinaction:80" "10.10.0.19:3000" outbound|80|version-v1|catalog.istioinaction.svc.cluster.local 10.10.0.14:43630 10.200.1.47:80 172.18.0.1:0 - -
[2025-04-26T14:16:45.222Z] "HEAD /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 0 4 3 "172.18.0.1" "curl/8.13.0" "73be1243-0c53-4aa3-8703-864ba5f15c30" "webapp.istioinaction.io:30000" "10.10.0.14:8080" inbound|8080|| 127.0.0.6:56173 10.10.0.14:8080 172.18.0.1:0 - default
BlackHoleCluster
(등록되지 않은 트래픽이 자동 블랙홀로 라우팅)
6. proxy-config : webapp 클러스터 상태 확인
1
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn BlackHoleCluster -o json
✅ 출력
1
2
3
4
5
6
7
[
{
"name": "BlackHoleCluster",
"type": "STATIC",
"connectTimeout": "10s"
}
]
7. istiooperators meshConfig 설정 확인
1
kubectl get istiooperators -n istio-system -o json
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "install.istio.io/v1alpha1",
"kind": "IstioOperator",
"metadata": {
"annotations": {
"install.istio.io/ignoreReconcile": "true",
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"install.istio.io/v1alpha1\",\"kind\":\"IstioOperator\",\"metadata\":{\"annotations\":{\"install.istio.io/ignoreReconcile\":\"true\"},\"creationTimestamp\":null,\"name\":\"installed-state\",\"namespace\":\"istio-system\"},\"spec\":{\"components\":{\"base\":{\"enabled\":true},\"cni\":{\"enabled\":false},\"egressGateways\":[{\"enabled\":false,\"name\":\"istio-egressgateway\"}],\"ingressGateways\":[{\"enabled\":true,\"name\":\"istio-ingressgateway\"}],\"istiodRemote\":{\"enabled\":false},\"pilot\":{\"enabled\":true}},\"hub\":\"docker.io/istio\",\"meshConfig\":{\"defaultConfig\":{\"proxyMetadata\":{}},\"enablePrometheusMerge\":true,\"outboundTrafficPolicy\":{\"mode\":\"REGISTRY_ONLY\"}},\"profile\":\"default\",\"tag\":\"1.17.8\",\"values\":{\"base\":{\"enableCRDTemplates\":false,\"validationURL\":\"\"},\"defaultRevision\":\"\",\"gateways\":{\"istio-egressgateway\":{\"autoscaleEnabled\":true,\"env\":{},\"name\":\"istio-egressgateway\",\"secretVolumes\":[{\"mountPath\":\"/etc/istio/egressgateway-certs\",\"name\":\"egressgateway-certs\",\"secretName\":\"istio-egressgateway-certs\"},{\"mountPath\":\"/etc/istio/egressgateway-ca-certs\",\"name\":\"egressgateway-ca-certs\",\"secretName\":\"istio-egressgateway-ca-certs\"}],\"type\":\"ClusterIP\"},\"istio-ingressgateway\":{\"autoscaleEnabled\":true,\"env\":{},\"name\":\"istio-ingressgateway\",\"secretVolumes\":[{\"mountPath\":\"/etc/istio/ingressgateway-certs\",\"name\":\"ingressgateway-certs\",\"secretName\":\"istio-ingressgateway-certs\"},{\"mountPath\":\"/etc/istio/ingressgateway-ca-certs\",\"name\":\"ingressgateway-ca-certs\",\"secretName\":\"istio-ingressgateway-ca-certs\"}],\"type\":\"LoadBalancer\"}},\"global\":{\"configValidation\":true,\"defaultNodeSelector\":{},\"defaultPodDisruptionBudget\":{\"enabled\":true},\"defaultResources\":{\"requests\":{\"cpu\":\"10m\"}},\"imagePullPolicy\":\"\",\"imagePullSecrets\":[],\"istioNamespace\":\"istio-system\",\"istiod\":{\"enableAnalysis\":false},\"jwtPolicy\":\"third-party-jwt\",\"logAsJson\":false,\"logging\":{\"level\":\"default:info\"},\"meshNetworks\":{},\"mountMtlsCerts\":false,\"multiCluster\":{\"clusterName\":\"\",\"enabled\":false},\"network\":\"\",\"omitSidecarInjectorConfigMap\":false,\"oneNamespace\":false,\"operatorManageWebhooks\":false,\"pilotCertProvider\":\"istiod\",\"priorityClassName\":\"\",\"proxy\":{\"autoInject\":\"enabled\",\"clusterDomain\":\"cluster.local\",\"componentLogLevel\":\"misc:error\",\"enableCoreDump\":false,\"excludeIPRanges\":\"\",\"excludeInboundPorts\":\"\",\"excludeOutboundPorts\":\"\",\"image\":\"proxyv2\",\"includeIPRanges\":\"*\",\"logLevel\":\"warning\",\"privileged\":false,\"readinessFailureThreshold\":30,\"readinessInitialDelaySeconds\":1,\"readinessPeriodSeconds\":2,\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"1024Mi\"},\"requests\":{\"cpu\":\"100m\",\"memory\":\"128Mi\"}},\"statusPort\":15020,\"tracer\":\"zipkin\"},\"proxy_init\":{\"image\":\"proxyv2\",\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"1024Mi\"},\"requests\":{\"cpu\":\"10m\",\"memory\":\"10Mi\"}}},\"sds\":{\"token\":{\"aud\":\"istio-ca\"}},\"sts\":{\"servicePort\":0},\"tracer\":{\"datadog\":{},\"lightstep\":{},\"stackdriver\":{},\"zipkin\":{}},\"useMCP\":false},\"istiodRemote\":{\"injectionURL\":\"\"},\"pilot\":{\"autoscaleEnabled\":true,\"autoscaleMax\":5,\"autoscaleMin\":1,\"configMap\":true,\"cpu\":{\"targetAverageUtilization\":80},\"deploymentLabels\":null,\"enableProtocolSniffingForInbound\":true,\"enableProtocolSniffingForOutbound\":true,\"env\":{},\"image\":\"pilot\",\"keepaliveMaxServerConnectionAge\":\"30m\",\"nodeSelector\":{},\"podLabels\":{},\"replicaCount\":1,\"traceSampling\":1},\"telemetry\":{\"enabled\":true,\"v2\":{\"enabled\":true,\"metadataExchange\":{\"wasmEnabled\":false},\"prometheus\":{\"enabled\":true,\"wasmEnabled\":false},\"stackdriver\":{\"configOverride\":{},\"enabled\":false,\"logging\":false,\"monitoring\":false,\"topology\":false}}}}}}\n"
},
"creationTimestamp": "2025-04-25T13:37:43Z",
"generation": 2,
"name": "installed-state",
"namespace": "istio-system",
"resourceVersion": "86721",
"uid": "f2e1fbab-b327-43c0-8ccb-1a2bed1933df"
},
"spec": {
"components": {
"base": {
"enabled": true
},
"cni": {
"enabled": false
},
"egressGateways": [
{
"enabled": false,
"name": "istio-egressgateway"
}
],
"ingressGateways": [
{
"enabled": true,
"name": "istio-ingressgateway"
}
],
"istiodRemote": {
"enabled": false
},
"pilot": {
"enabled": true
}
},
"hub": "docker.io/istio",
"meshConfig": {
"defaultConfig": {
"proxyMetadata": {}
},
"enablePrometheusMerge": true,
"outboundTrafficPolicy": {
"mode": "REGISTRY_ONLY"
}
},
"profile": "default",
"tag": "1.17.8",
"values": {
"base": {
"enableCRDTemplates": false,
"validationURL": ""
},
"defaultRevision": "",
"gateways": {
"istio-egressgateway": {
"autoscaleEnabled": true,
"env": {},
"name": "istio-egressgateway",
"secretVolumes": [
{
"mountPath": "/etc/istio/egressgateway-certs",
"name": "egressgateway-certs",
"secretName": "istio-egressgateway-certs"
},
{
"mountPath": "/etc/istio/egressgateway-ca-certs",
"name": "egressgateway-ca-certs",
"secretName": "istio-egressgateway-ca-certs"
}
],
"type": "ClusterIP"
},
"istio-ingressgateway": {
"autoscaleEnabled": true,
"env": {},
"name": "istio-ingressgateway",
"secretVolumes": [
{
"mountPath": "/etc/istio/ingressgateway-certs",
"name": "ingressgateway-certs",
"secretName": "istio-ingressgateway-certs"
},
{
"mountPath": "/etc/istio/ingressgateway-ca-certs",
"name": "ingressgateway-ca-certs",
"secretName": "istio-ingressgateway-ca-certs"
}
],
"type": "LoadBalancer"
}
},
"global": {
"configValidation": true,
"defaultNodeSelector": {},
"defaultPodDisruptionBudget": {
"enabled": true
},
"defaultResources": {
"requests": {
"cpu": "10m"
}
},
"imagePullPolicy": "",
"imagePullSecrets": [],
"istioNamespace": "istio-system",
"istiod": {
"enableAnalysis": false
},
"jwtPolicy": "third-party-jwt",
"logAsJson": false,
"logging": {
"level": "default:info"
},
"meshNetworks": {},
"mountMtlsCerts": false,
"multiCluster": {
"clusterName": "",
"enabled": false
},
"network": "",
"omitSidecarInjectorConfigMap": false,
"oneNamespace": false,
"operatorManageWebhooks": false,
"pilotCertProvider": "istiod",
"priorityClassName": "",
"proxy": {
"autoInject": "enabled",
"clusterDomain": "cluster.local",
"componentLogLevel": "misc:error",
"enableCoreDump": false,
"excludeIPRanges": "",
"excludeInboundPorts": "",
"excludeOutboundPorts": "",
"image": "proxyv2",
"includeIPRanges": "*",
"logLevel": "warning",
"privileged": false,
"readinessFailureThreshold": 30,
"readinessInitialDelaySeconds": 1,
"readinessPeriodSeconds": 2,
"resources": {
"limits": {
"cpu": "2000m",
"memory": "1024Mi"
},
"requests": {
"cpu": "100m",
"memory": "128Mi"
}
},
"statusPort": 15020,
"tracer": "zipkin"
},
"proxy_init": {
"image": "proxyv2",
"resources": {
"limits": {
"cpu": "2000m",
"memory": "1024Mi"
},
"requests": {
"cpu": "10m",
"memory": "10Mi"
}
}
},
"sds": {
"token": {
"aud": "istio-ca"
}
},
"sts": {
"servicePort": 0
},
"tracer": {
"datadog": {},
"lightstep": {},
"stackdriver": {},
"zipkin": {}
},
"useMCP": false
},
"istiodRemote": {
"injectionURL": ""
},
"pilot": {
"autoscaleEnabled": true,
"autoscaleMax": 5,
"autoscaleMin": 1,
"configMap": true,
"cpu": {
"targetAverageUtilization": 80
},
"enableProtocolSniffingForInbound": true,
"enableProtocolSniffingForOutbound": true,
"env": {},
"image": "pilot",
"keepaliveMaxServerConnectionAge": "30m",
"nodeSelector": {},
"podLabels": {},
"replicaCount": 1,
"traceSampling": 1
},
"telemetry": {
"enabled": true,
"v2": {
"enabled": true,
"metadataExchange": {
"wasmEnabled": false
},
"prometheus": {
"enabled": true,
"wasmEnabled": false
},
"stackdriver": {
"configOverride": {},
"enabled": false,
"logging": false,
"monitoring": false,
"topology": false
}
}
}
}
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": ""
}
}
🌍 ServiceEntry
1. ServiceEntry 리소스 정의
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat ch5/forum-serviceentry.yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: jsonplaceholder
spec:
hosts:
- jsonplaceholder.typicode.com
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
- 외부 서비스(jsonplaceholder.typicode.com)를 서비스 메시 안에 등록하는 리소스 생성
2. forum 서비스 배포
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
cat services/forum/kubernetes/forum-all.yaml
---
apiVersion: v1
kind: Service
metadata:
labels:
app: forum
name: forum
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: forum
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: forum
version: v1
name: forum
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
app: forum
version: v1
template:
metadata:
labels:
app: forum
version: v1
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: istioinaction/forum:latest
imagePullPolicy: IfNotPresent
name: forum
ports:
- containerPort: 8080
name: http
protocol: TCP
securityContext:
privileged: false
1
2
3
4
5
kubectl apply -f services/forum/kubernetes/forum-all.yaml -n istioinaction
# 결과
service/forum created
deployment.apps/forum created
3. 배포 및 서비스 상태 확인
1
kubectl get deploy,svc -n istioinaction -l app=webapp
✅ 출력
1
2
3
4
5
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/webapp 1/1 1 1 24h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/webapp ClusterIP 10.200.1.51 <none> 80/TCP 24h
1
docker exec -it myk8s-control-plane istioctl proxy-status
✅ 출력
1
2
3
4
5
6
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
catalog-6d5b9bbb66-69m8j.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-qt4cj 1.17.8
catalog-v2-6df885b555-pc9br.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-qt4cj 1.17.8
forum-8667b65dcf-6knmz.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-qt4cj 1.17.8
istio-ingressgateway-996bc6bb6-w94xn.istio-system Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-qt4cj 1.17.8
webapp-7685bcb84-ng9xn.istioinaction Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-7df6ffc78d-qt4cj 1.17.8
4. webapp → forum 호출 시도
외부 서비스(jsonplaceholder.typicode.com
)에 대한 접근이 막혀 있음
1
curl -s http://webapp.istioinaction.io:30000/api/users
✅ 출력
1
error calling Forum service
5. ServiceEntry 리소스 생성
외부 서비스 호출 허용을 위해 ServiceEntry
생성
1
cat ch5/forum-serviceentry.yaml
✅ 출력
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: jsonplaceholder
spec:
hosts:
- jsonplaceholder.typicode.com
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
1
2
3
4
kubectl apply -f ch5/forum-serviceentry.yaml -n istioinaction
# 결과
serviceentry.networking.istio.io/jsonplaceholder created
6. 호출 결과 확인
1
2
3
curl -s http://webapp.istioinaction.io:30000/api/users
[{"id":1,"name":"Leanne Graham","username":"Bret","email":"Sincere@april.biz","address":{"street":"Kulas Light","suite":"Apt. 556","city":"Gwenborough","zipcode":"92998-3874"},"phone":"1-770-736-8031 x56442","website":"hildegard.org","company":{"name":"Romaguera-Crona","catchPhrase":"Multi-layered client-server neural-net","bs":"harness real-time e-markets"}},{"id":2,"name":"Ervin Howell","username":"Antonette","email":"Shanna@melissa.tv","address":{"street":"Victor Plains","suite":"Suite 879","city":"Wisokyburgh","zipcode":"90566-7771"},"phone":"010-692-6593 x09125","website":"anastasia.net","company":{"name":"Deckow-Crist","catchPhrase":"Proactive didactic contingency","bs":"synergize scalable supply-chains"}},{"id":3,"name":"Clementine Bauch","username":"Samantha","email":"Nathan@yesenia.net","address":{"street":"Douglas Extension","suite":"Suite 847","city":"McKenziehaven","zipcode":"59590-4157"},"phone":"1-463-123-4447","website":"ramiro.info","company":{"name":"Romaguera-Jacobson","catchPhrase":"Face to face bifurcated interface","bs":"e-enable strategic applications"}},{"id":4,"name":"Patricia Lebsack","username":"Karianne","email":"Julianne.OConner@kory.org","address":{"street":"Hoeger Mall","suite":"Apt. 692","city":"South Elvis","zipcode":"53919-4257"},"phone":"493-170-9623 x156","website":"kale.biz","company":{"name":"Robel-Corkery","catchPhrase":"Multi-tiered zero tolerance productivity","bs":"transition cutting-edge web services"}},{"id":5,"name":"Chelsey Dietrich","username":"Kamren","email":"Lucio_Hettinger@annie.ca","address":{"street":"Skiles Walks","suite":"Suite 351","city":"Roscoeview","zipcode":"33263"},"phone":"(254)954-1289","website":"demarco.info","company":{"name":"Keebler LLC","catchPhrase":"User-centric fault-tolerant solution","bs":"revolutionize end-to-end systems"}},{"id":6,"name":"Mrs. Dennis Schulist","username":"Leopoldo_Corkery","email":"Karley_Dach@jasper.info","address":{"street":"Norberto Crossing","suite":"Apt. 950","city":"South Christy","zipcode":"23505-1337"},"phone":"1-477-935-8478 x6430","website":"ola.org","company":{"name":"Considine-Lockman","catchPhrase":"Synchronised bottom-line interface","bs":"e-enable innovative applications"}},{"id":7,"name":"Kurtis Weissnat","username":"Elwyn.Skiles","email":"Telly.Hoeger@billy.biz","address":{"street":"Rex Trail","suite":"Suite 280","city":"Howemouth","zipcode":"58804-1099"},"phone":"210.067.6132","website":"elvis.io","company":{"name":"Johns Group","catchPhrase":"Configurable multimedia task-force","bs":"generate enterprise e-tailers"}},{"id":8,"name":"Nicholas Runolfsdottir V","username":"Maxime_Nienow","email":"Sherwood@rosamond.me","address":{"street":"Ellsworth Summit","suite":"Suite 729","city":"Aliyaview","zipcode":"45169"},"phone":"586.493.6943 x140","website":"jacynthe.com","company":{"name":"Abernathy Group","catchPhrase":"Implemented secondary concept","bs":"e-enable extensible e-tailers"}},{"id":9,"name":"Glenna Reichert","username":"Delphine","email":"Chaim_McDermott@dana.io","address":{"street":"Dayna Park","suite":"Suite 449","city":"Bartholomebury","zipcode":"76495-3109"},"phone":"(775)976-6794 x41206","website":"conrad.com","company":{"name":"Yost and Sons","catchPhrase":"Switchable contextually-based project","bs":"aggregate real-time technologies"}},{"id":10,"name":"Clementina DuBuque","username":"Moriah.Stanton","email":"Rey.Padberg@karina.biz","address":{"street":"Kattie Turnpike","suite":"Suite 198","city":"Lebsackbury","zipcode":"31428-2261"},"phone":"024-648-3804","website":"ambrose.net","company":{"name":"Hoeger LLC","catchPhrase":"Centralized empowering task-force","bs":"target end-to-end models"}}]
🗑️ 실습 후 삭제
1
2
3
4
5
kind delete cluster --name myk8s
# 결과
Deleting cluster "myk8s" ...
Deleted nodes: ["myk8s-control-plane"]