실습 환경 구성
구성 : VPC 1개(퍼블릭 서브넷 2개), EC2 인스턴스 3대 (Ubuntu 22.04 LTS, t3.xlarge - vCPU 4 , Mem 16) , testpc 1대는 t3.small
k3s-w1 54.180.9.71 running
k3s-s 43.201.45.35 running
k3s-w2 3.38.116.195 running
testpc 3.36.123.234 running
Istio란
https://istio.io/latest/docs/overview/what-is-istio/
- 등장 배경 : MSA 환경의 시스템 전체 모니터링의 어려움, 운영 시 시스템 장애나 문제 발생 시 원인과 병목 구간의 찾기 어려움
- 내부망 진입점에 역할을 하는 GW(API Gateway) 경우 모든 동작 처리에 무거워지거나, 내부망 내부 통신 제어는 어려움
- 기본 동작은 파드 간 통신 경로에 프록시를 놓고, 트래픽 모니터링이나 트래픽 컨트롤 -> 기존 어플리케이션 코드에 숮어 없이 구성 가능
1. 기존 통신 환경
2. 어플리케이션 수정 없이, 모든 어플리케이션 통신 사이에 Proxy를 두고 통신 해보자
- 파드 내에 사이드카 컨테이너로 주입되어서 동작
- Proxy 컨테이너가 Application 트리팩을 가로채야함 -> iptables rule 구현 -> 가능한 이유?
3. Proxy는 결국 DataPlane 이니, 이를 중앙에서 관리하는 CrontrolPlane을 두고 중앙에서 관리를 하자
- Proxy는 중앙에서 설정 관리가 잘되는 툴을 선택. 즉, 원격에서 동적인 설정 관리가 유연해야함 -> 풍부한 API 지원이 필요
- 중앙에서 어떤 동작 / 설정을 관리해야 될까? 라우팅, 보안 통신을 위한 mTLS관련, 동기화 상태 정보 등
- 트래픽 모니터링 : 요청의 '에러율, 레이턴시, 커넥션 개수, 요청 개수' 등 메트릭 모니터링,
특히 서비스간 혹은 특정 요청 경로로 필터링 -> 원인 파악 용이!
- 트래픽 컨트롤 : 트래픽 시프팅, 서킷 브레이커, 폴트 인젝션, 속도 제한
- 트래픽 시프팅
예시) 99% 기존앱 + 1% 신규앱, 특정 단말/사용자는 신규앱에 전달하여 단계적으로 적용하는 카나리 배포 가능
- 서킷 브레이커
목적지 마이크로서비스에 문제가 있을 시 접속을 차단하고,
출발지 마이크로서비스에 요청 에러를 반환 (연쇄 장애, 시스템 전제 장애 예방)
- 폴트 인젝션 : 의도적으로 요청을 지연 혹은 실패를 구현
- 속도 제한 : 요청 개수를 제한
- Istio 구성요소와 envoy : 컨트롤 플레인(istiod), 데이터 플레인(istio-proxy > envoy)
- istiod : Pilot(데이터 플레인과 통신하면서 라우팅 규칙을 통기화, ADS), Gally(Istio와 K8S 연동, EP 갱신 등), Citadel
- Istio Proxy : Golang으로 작성되었고, envoy 래핑한 Proxy, istiod와 통신하고 서비스 트래픽을 통제, 옵저버빌리티를 위한 메트릭 제공
- 이스티오는 각 파드 안에 사이드카로 엔보이 프록시가 들어가 있는 형태
- 모든 마이크로서비스간 통신은 엔보이를 통과하여, 메트릭을 수집하거나 트래픽 컨트롤을 할 수 있음
- 트래픽 컨트롤을 하기위해 엔보이 프록시에 전송 룰을 설정 -> 컨트롤 플레인의 이스티오가 정의된 정보를 기반으로 엔보이 설정하게 함
- 마이크로서비스 간의 통신을 mutual TLS인증으로 서로 TLS 인증으로 암호화 할 수 있음
- 각 애플리케이션은 파드 내의 엔보이 프록시에 접속하기 위해 Localhost 에 TCP 접속을 함
Envoy
- Cluste : envoy 가 트래픽을 포워드할 수 있는 논리적인 서비스 (엔드포인트 세트),
실제 요청이 처리되는 IP 또는 엔드포인트의 묶음을 의미.
- Endpoint : IP 주소, 네트워크 노드로 클러스터로 그룹핑됨, 실제 접근이 가능한 엔드포인트를 의미.
엔드포인트가 모여서 하나의 Cluster 가 된다.
- Listener: 무엇을 받을지 그리고 어떻게 처리할지 IP/Port 를 바인딩하고, 요청 처리 측면에서 다운스트림을 조정하는 역할.
- Route : Listener 로 들어온 요청을 어디로 라우팅할 것인지를 정의. 라우팅 대상은 일반적으로 Cluster 라는 것에 대해 이뤄지게 된다.
- Filter : Listener 로부터 서비스에 트래픽을 전달하기까지 요청 처리 파이프라인
- UpStream : envoy 요청을 포워딩해서 연결하는 백엔드 네트워크 노드 - 사이드카일때 application app, 아닐때 원격 백엔드
- DownStream : An entity connecting to envoy, In non-sidecar models this is a remote client
실습 시작
- TestPC에 Envoy 설치
$ wget -O- https://apt.envoyproxy.io/signing.key | sudo gpg --dearmor -o /etc/apt/keyrings/envoy-keyring.gpg
$ echo "deb [signed-by=/etc/apt/keyrings/envoy-keyring.gpg] https://apt.envoyproxy.io jammy main" | sudo tee /etc/apt/sources.list.d/envoy.list
$ sudo apt-get update && sudo apt-get install envoy -y
## 설치 확인 ##
$ envoy --version
- Envoy 데모 config 적용합니다.
적용 후에 envoy -c envoy-demo.yaml로 시작하면, 아래와 같이 로그가 표시되기 시작합니다.
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
http_filters:
- name: envoy.filters.http.router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
host_rewrite_literal: www.envoyproxy.io
cluster: service_envoyproxy_io
clusters:
- name: service_envoyproxy_io
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
connect_timeout: 5s
load_assignment:
cluster_name: service_envoyproxy_io
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: www.envoyproxy.io
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: www.envoyproxy.io
- Port Listen 시 config에 작성되어 있는 것과 같이 10000 포트가 확인되고, 이를 웹페이지에서 접속하면 아래와 같이 접속할 수 있습니다.
- admin 페이지 접속을 위해 코드를 추가하고, 접근합니다.
cat <<EOT> envoy-override.yaml
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9902
EOT
envoy -c envoy-demo.yaml --config-yaml "$(cat envoy-override.yaml)"
admin 페이지에서는 upstream의 cluster status부터, server_info까지 다양한 정보를 확인할 수 있습니다.
istio 설치 (sidecar mode)
# istioctl 설치
$ export ISTIOV=1.23.2
$ echo "export ISTIOV=1.23.2" >> /etc/profile
$ curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV TARGET_ARCH=x86_64 sh -
$ tree istio-$ISTIOV -L 2 # sample yaml 포함
$ cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
$ istioctl version --remote=false
- istio에서 제공하는 istioctl profile list 명령어는 다양한 설치 . 및구성 프로파일을 보여줍니다.
(⎈|default:N/A) root@k3s-s:~# istioctl profile list
Istio configuration profiles:
ambient
default
demo
empty
minimal
openshift
openshift-ambient
preview
remote
stable
## demo profil도 아래와 같이 확인할 수도 있고, 설치를 위해 파일로 저장합니다.
(⎈|default:N/A) root@k3s-s:~# istioctl profile dump demo > demo-profile.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
base:
enabled: true
egressGateways:
- enabled: false
name: istio-egressgateway
ingressGateways:
- enabled: true
name: istio-ingressgateway
pilot:
enabled: true
hub: docker.io/istio
profile: demo
tag: 1.23.2
values:
defaultRevision: ""
gateways:
istio-egressgateway: {}
istio-ingressgateway: {}
global:
configValidation: true
istioNamespace: istio-system
profile: demo
## 생성한 파일을 기본으로 istio를 배포합니다.
(⎈|default:N/A) root@k3s-s:~# istioctl install -f demo-profile.yaml -y
- 설치 확인 : istiod, istio-ingressgateway
|\
| \
| \
| \
/|| \
/ || \
/ || \
/ || \
/ || \
/ || \
/______||__________\
____________________
\__ _____/
\_____/
✔ Istio core installed ⛵️
✔ Istiod installed 🧠
✔ Ingress gateways installed 🛬
✔ Installation complete
Made this installation the default for cluster-wide operations.
(⎈|default:N/A) root@k3s-s:~# kubectl get all,svc,ep,sa,cm,secret,pdb -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istio-ingressgateway-5f9f654d46-kt5cm 1/1 Running 0 72s
pod/istiod-7f8b586864-4c46w 1/1 Running 0 86s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-ingressgateway LoadBalancer 10.10.200.143 192.168.10.10,192.168.10.101,192.168.10.102 15021:31481/TCP,80:32469/TCP,443:32758/TCP,31400:32504/TCP,15443:31727/TCP 72s
service/istiod ClusterIP 10.10.200.43 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 86s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-ingressgateway 1/1 1 1 72s
deployment.apps/istiod 1/1 1 1 86s
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-ingressgateway-5f9f654d46 1 1 1 72s
replicaset.apps/istiod-7f8b586864 1 1 1 86s
NAME ENDPOINTS AGE
endpoints/istio-ingressgateway 172.16.2.2:15443,172.16.2.2:15021,172.16.2.2:31400 + 2 more... 72s
endpoints/istiod 172.16.1.2:15012,172.16.1.2:15010,172.16.1.2:15017 + 1 more... 86s
NAME SECRETS AGE
serviceaccount/default 0 88s
serviceaccount/istio-ingressgateway-service-account 0 72s
serviceaccount/istio-reader-service-account 0 87s
serviceaccount/istiod 0 86s
NAME DATA AGE
configmap/istio 2 86s
configmap/istio-ca-root-cert 1 73s
configmap/istio-gateway-status-leader 0 74s
configmap/istio-leader 0 74s
configmap/istio-namespace-controller-election 0 73s
configmap/istio-sidecar-injector 2 86s
configmap/kube-root-ca.crt 1 88s
NAME TYPE DATA AGE
secret/istio-ca-secret istio.io/ca-root 5 74s
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
poddisruptionbudget.policy/istio-ingressgateway 1 N/A 0 72s
poddisruptionbudget.policy/istiod 1 N/A 0 86s
- istio-ingressgateway의 envoy version도 확인해 봅니다.
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deploy/istio-ingressgateway -n istio-system -c istio-proxy -- envoy --version
envoy version: 6c72b2179f5a58988b920a55b0be8346de3f7b35/1.31.2-dev/Clean/RELEASE/BoringSSL
- istio-ingressgateway 의 서비스 포트 정보도 확인합니다.
(⎈|default:N/A) root@k3s-s:~# kubectl get svc -n istio-system istio-ingressgateway -o jsonpath={.spec.ports[*]} | jq
{
"name": "status-port",
"nodePort": 31481,
"port": 15021,
"protocol": "TCP",
"targetPort": 15021
}
{
"name": "http2",
"nodePort": 32469,
"port": 80,
"protocol": "TCP",
"targetPort": 8080
}
{
"name": "https",
"nodePort": 32758,
"port": 443,
"protocol": "TCP",
"targetPort": 8443
}
{
"name": "tcp",
"nodePort": 32504,
"port": 31400,
"protocol": "TCP",
"targetPort": 31400
}
{
"name": "tls",
"nodePort": 31727,
"port": 15443,
"protocol": "TCP",
"targetPort": 15443
}
- istiod(컨트롤플레인) 디플로이먼트 정보 확인
## 소캣 정보
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deployment.apps/istiod -n istio-system -- ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.1:9876 0.0.0.0:* users:(("pilot-discovery",pid=1,fd=8))
LISTEN 0 4096 *:8080 *:* users:(("pilot-discovery",pid=1,fd=3))
LISTEN 0 4096 *:15010 *:* users:(("pilot-discovery",pid=1,fd=11))
LISTEN 0 4096 *:15014 *:* users:(("pilot-discovery",pid=1,fd=9))
LISTEN 0 4096 *:15012 *:* users:(("pilot-discovery",pid=1,fd=10))
LISTEN 0 4096 *:15017 *:* users:(("pilot-discovery",pid=1,fd=12))
## 프로세스 리스트
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deployment.apps/istiod -n istio-system -- ps -ef
UID PID PPID C STIME TTY TIME CMD
istio-p+ 1 0 0 15:19 ? 00:00:01 /usr/local/bin/pilot-discovery discovery --monitoringAddr=:15014 --log_output_level=default:info --domain
istio-p+ 27 0 0 15:28 pts/0 00:00:00 ps -ef
- istio-ingressgateway 디플로이먼트 정보 확인
## 소캣 정보
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.1:15004 0.0.0.0:* users:(("pilot-agent",pid=1,fd=12))
LISTEN 0 4096 127.0.0.1:15000 0.0.0.0:* users:(("envoy",pid=15,fd=18))
LISTEN 0 4096 0.0.0.0:15021 0.0.0.0:* users:(("envoy",pid=15,fd=23))
LISTEN 0 4096 0.0.0.0:15021 0.0.0.0:* users:(("envoy",pid=15,fd=22))
LISTEN 0 4096 0.0.0.0:15090 0.0.0.0:* users:(("envoy",pid=15,fd=21))
LISTEN 0 4096 0.0.0.0:15090 0.0.0.0:* users:(("envoy",pid=15,fd=20))
LISTEN 0 4096 *:15020 *:* users:(("pilot-agent",pid=1,fd=3))
## 프로세스 리스트
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ps -ef
UID PID PPID C STIME TTY TIME CMD
istio-p+ 1 0 0 15:20 ? 00:00:00 /usr/local/bin/pilot-agent p
istio-p+ 15 1 0 15:20 ? 00:00:01 /usr/local/bin/envoy -c etc/
istio-p+ 42 0 0 15:29 pts/0 00:00:00 ps -ef
- 현재 상태의 네트워크 흐름도
- Auto Injection with namespace label 설정
이 설정은 label이 설정된 namespace에 생성되는 모든 파드들에 대해 istio 사이드카가 자동으로 injection 되는 설정입니다.
(⎈|default:N/A) root@k3s-s:~# kubectl label namespace default istio-injection=enabled
namespace/default labeled
(⎈|default:N/A) root@k3s-s:~# kubectl get ns -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
default Active 148m enabled
istio-system Active 15m
kube-node-lease Active 148m
kube-public Active 148m
kube-system Active 148m
- Istio 접속 테스트를 위한 변수 지정
## istio-ingressgateway 파드가 위치된 노드의 공인 IP
k3s-w1 54.180.9.71 running
k3s-s 43.201.45.35 running
testpc 3.36.123.234 running
k3s-w2 3.38.116.195 running
#k3s-s)
# istio ingress gw NodePort(HTTP 접속용) 변수 지정 : 아래 ports[0] 은 어떤 용도의 포트일까요?
(⎈|default:N/A) root@k3s-s:~# kubectl get service -n istio-system istio-ingressgateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway NodePort 10.10.200.143 <none> 15021:31481/TCP,80:32469/TCP,443:32758/TCP,31400:32504/TCP,15443:31727/TCP 53m
(⎈|default:N/A) root@k3s-s:~# export IGWHTTP=$(kubectl get service -n istio-system istio-ingressgateway -o jsonpath='{.spec.ports[1].nodePort}')
(⎈|default:N/A) root@k3s-s:~# echo $IGWHTTP
32469
## 도메인 설정
(⎈|default:N/A) root@k3s-s:~# MYDOMAIN=www.ssungz.net
(⎈|default:N/A) root@k3s-s:~# echo -e "192.168.10.10 $MYDOMAIN" >> /etc/hosts
echo -e "export MYDOMAIN=$MYDOMAIN" >> /etc/profile
# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
(⎈|default:N/A) root@k3s-s:~# curl -v -s $MYDOMAIN:$IGWHTTP
* Trying 192.168.10.10:32469...
* connect to 192.168.10.10 port 32469 failed: Connection refused
* Failed to connect to www.ssungz.net port 32469 after 1 ms: Connection refused
* Closing connection 0
##testPC)
root@testpc:~# IGWHTTP=32469
root@testpc:~# export MYDOMAIN=www.ssungz.net
root@testpc:~# echo -e "192.168.10.10 $MYDOMAIN" >> /etc/hosts
echo -e "export MYDOMAIN=$MYDOMAIN" >> /etc/profile
root@testpc:~# curl -v -s $MYDOMAIN:$IGWHTTP
* Trying 192.168.10.10:32469...
* connect to 192.168.10.10 port 32469 failed: Connection refused
* Failed to connect to www.ssungz.net port 32469 after 1 ms: Connection refused
* Closing connection 0
##Local PC)
7w ➤ IGWHTTP=32469
7w ➤ ISTIONODEIP=43.201.45.35
7w ➤ MYDOMAIN=www.ssungz.net
7w ➤ echo "$ISTIONODEIP $MYDOMAIN" | sudo tee -a /etc/hosts
Password:
43.201.45.35 www.ssungz.net
7w ➤ curl -v -s $MYDOMAIN:$IGWHTTP
* Host www.ssungz.net:32469 was resolved.
* IPv6: (none)
* IPv4: 43.201.45.35
* Trying 43.201.45.35:32469...
* connect to 43.201.45.35 port 32469 from 192.168.219.103 port 54006 failed: Connection refused
* Failed to connect to www.ssungz.net port 32469 after 17 ms: Couldn't connect to server
* Closing connection
Istio를 통한 외부 노출
# 로그 모니터링
kubectl get pod -n istio-system -l app=istiod
kubetail -n istio-system -l app=istiod -f
kubectl get pod -n istio-system -l app=istio-ingressgateway
kubetail -n istio-system -l app=istio-ingressgateway -f
- 서비스 배포를 위한 리소스 생성, 모든 자원은 Default Namespace에 생성합니다.
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: kans-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-websrv
spec:
replicas: 1
selector:
matchLabels:
app: deploy-websrv
template:
metadata:
labels:
app: deploy-websrv
spec:
serviceAccountName: kans-nginx
terminationGracePeriodSeconds: 0
containers:
- name: deploy-websrv
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-clusterip
spec:
ports:
- name: svc-webport
port: 80
targetPort: 80
selector:
app: deploy-websrv
type: ClusterIP
EOF
- 생성 확인
(⎈|default:N/A) root@k3s-s:~# kubectl get pod,svc,ep,sa -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/deploy-websrv-778ffd6947-n2pjz 2/2 Running 0 3m1s 172.16.2.4 k3s-w1 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.10.200.1 <none> 443/TCP 3h37m <none>
service/svc-clusterip ClusterIP 10.10.200.63 <none> 80/TCP 3m1s app=deploy-websrv
NAME ENDPOINTS AGE
endpoints/kubernetes 192.168.10.10:6443 3h37m
endpoints/svc-clusterip 172.16.2.4:80 3m1s
NAME SECRETS AGE
serviceaccount/default 0 3h37m
serviceaccount/kans-nginx 0 3m2s
- describe pod로 확인해보면 Init Container가 실행되면서 Istio Proxy 이미지를 통해 IPTABLES 정책을 설정하는 것을 확인할 수 있습니다.
이 설정을 간단히 요약하면 Pod 내의 네트워크 트래픽을 Istio Sidecar로 리다이렉트해서 Istio에서 트래픽을 확인할 수 있도록 하는 정책입니다.
Init Containers:
istio-init:
Container ID: containerd://4512e3c3b98811aa6ad8573515a76c87f986a352edf86d2b680b631220f30e3a
Image: docker.io/istio/proxyv2:1.23.2
Image ID: docker.io/istio/proxyv2@sha256:2876cfc2fdf47e4b9665390ccc9ccf2bf913b71379325b8438135c9f35578e1a
Port: <none>
Host Port: <none>
Args:
istio-iptables
-p
15001
-z
15006
-u
1337
-m
REDIRECT
-i
*
-x
-b
*
-d
15090,15021,15020
--log_output_level=default:info
Main Container에도 Istio proxy 컨테이너가 생성되어 Init container의 정책을 받을 수 있도록 생성되어 있습니다.
istio-proxy:
Container ID: containerd://f83196c9450dc0a35dada4cb65e42f4ff6c506f9e068982aad24acb7154d3b0e
Image: docker.io/istio/proxyv2:1.23.2
Image ID: docker.io/istio/proxyv2@sha256:2876cfc2fdf47e4b9665390ccc9ccf2bf913b71379325b8438135c9f35578e1a
Port: 15090/TCP
Host Port: 0/TCP
Args:
proxy
sidecar
--domain
$(POD_NAMESPACE).svc.cluster.local
--proxyLogLevel=warning
--proxyComponentLogLevel=misc:error
--log_output_level=default:info
Istio Gateway/VirtualService 설정 - Host 기반 트래픽 라우팅 설정
- 사용자 접근 통신 Flow
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: test-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: nginx-service
spec:
hosts:
- "$MYDOMAIN"
gateways:
- test-gateway
http:
- route:
- destination:
host: svc-clusterip
port:
number: 80
(⎈|default:N/A) root@k3s-s:~# k get gw,vs
NAME AGE
gateway.networking.istio.io/test-gateway 2m44s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/nginx-service ["test-gateway"] ["www.ssungz.net"] 2m44s
- Istio Proxy 상태 확인
CDS : Cluster Discovery Service
LDS : Listener Discovery Service
EDS : Endpoint Discovery Service
RDS : Route Discovery Service
(⎈|default:N/A) root@k3s-s:~# istioctl proxy-status
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
deploy-websrv-778ffd6947-n2pjz.default Kubernetes SYNCED (17m) SYNCED (17m) SYNCED (17m) SYNCED (17m) IGNORED istiod-7f8b586864-4c46w 1.23.2
istio-ingressgateway-5f9f654d46-kt5cm.istio-system Kubernetes SYNCED (3m14s) SYNCED (3m14s) SYNCED (6m38s) SYNCED (3m14s) IGNORED istiod-7f8b586864-4c46w 1.23.2
- Istio를 통한 Nginx 파드 접속 테스트
- 컨테이너 로그 확인
(⎈|default:N/A) root@k3s-s:~# kubetail -n istio-system -l app=istio-ingressgateway -f
Will tail 1 logs...
istio-ingressgateway-5f9f654d46-kt5cm
[istio-ingressgateway-5f9f654d46-kt5cm] [2024-10-19T17:02:35.331Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 7 6 "172.16.0.0" "curl/8.7.1" "a8efca31-7a20-97ab-a0ed-408481ff9410" "www.ssungz.net:32469" "172.16.2.4:80" outbound|80||svc-clusterip.default.svc.cluster.local 172.16.2.2:44926 172.16.2.2:8080 172.16.0.0:19786 - -
[istio-ingressgateway-5f9f654d46-kt5cm] [2024-10-19T17:02:37.021Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 1 "172.16.0.0" "curl/7.81.0" "e36b115d-ec30-9de6-9474-75f14457d334" "www.ssungz.net:32469" "172.16.2.4:80" outbound|80||svc-clusterip.default.svc.cluster.local 172.16.2.2:44926 172.16.2.2:8080 172.16.0.0:29525 - -
- Istio Side Proxy 구성 정보 확인
## Envoy config dump : all
(⎈|default:N/A) root@k3s-s:~# istioctl proxy-status
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
deploy-websrv-778ffd6947-n2pjz.default Kubernetes SYNCED (25m) SYNCED (25m) SYNCED (25m) SYNCED (25m) IGNORED istiod-7f8b586864-4c46w 1.23.2
istio-ingressgateway-5f9f654d46-kt5cm.istio-system Kubernetes SYNCED (11m) SYNCED (11m) SYNCED (14m) SYNCED (11m) IGNORED istiod-7f8b586864-4c46w 1.23.2
(⎈|default:N/A) root@k3s-s:~# istioctl proxy-config all deploy-websrv-778ffd6947-n2pjz.default
Istio Version: 1.23.2
Istio Proxy Version: 6c72b2179f5a58988b920a55b0be8346de3f7b35
Envoy Version: 1.31.2-dev/Clean/RELEASE/BoringSSL
NAME SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
cluster/inbound|80|| 80 - inbound ORIGINAL_DST
cluster/BlackHoleCluster cluster/BlackHoleCluster - - - STATIC
cluster/InboundPassthroughCluster cluster/InboundPassthroughCluster - - - ORIGINAL_DST
cluster/PassthroughCluster cluster/PassthroughCluster - - - ORIGINAL_DST
cluster/agent cluster/agent - - - STATIC
cluster/outbound|80||istio-ingressgateway.istio-system.svc.cluster.local istio-ingressgateway.istio-system.svc.cluster.local 80 - outbound EDS
cluster/outbound|443||istio-ingressgateway.istio-system.svc.cluster.local istio-ingressgateway.istio-system.svc.cluster.local 443 - outbound EDS
cluster/outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local istio-ingressgateway.istio-system.svc.cluster.local 15021 - outbound EDS
cluster/outbound|15443||istio-ingressgateway.istio-system.svc.cluster.local istio-ingressgateway.istio-system.svc.cluster.local 15443 - outbound EDS
cluster/outbound|31400||istio-ingressgateway.istio-system.svc.cluster.local istio-ingressgateway.istio-system.svc.cluster.local 31400 - outbound EDS
cluster/outbound|443||istiod.istio-system.svc.cluster.local istiod.istio-system.svc.cluster.local 443 - outbound EDS
cluster/outbound|15010||istiod.istio-system.svc.cluster.local istiod.istio-system.svc.cluster.local 15010 - outbound EDS
cluster/outbound|15012||istiod.istio-system.svc.cluster.local istiod.istio-system.svc.cluster.local 15012 - outbound EDS
cluster/outbound|15014||istiod.istio-system.svc.cluster.local istiod.istio-system.svc.cluster.local 15014 - outbound EDS
cluster/outbound|53||kube-dns.kube-system.svc.cluster.local kube-dns.kube-system.svc.cluster.local 53 - outbound EDS
cluster/outbound|9153||kube-dns.kube-system.svc.cluster.local kube-dns.kube-system.svc.cluster.local 9153 - outbound EDS
cluster/outbound|443||kubernetes.default.svc.cluster.local kubernetes.default.svc.cluster.local 443 - outbound EDS
cluster/outbound|443||metrics-server.kube-system.svc.cluster.local metrics-server.kube-system.svc.cluster.local 443 - outbound EDS
cluster/prometheus_stats cluster/prometheus_stats - - - STATIC
cluster/sds-grpc cluster/sds-grpc - - - STATIC
cluster/outbound|80||svc-clusterip.default.svc.cluster.local svc-clusterip.default.svc.cluster.local 80 - outbound EDS
cluster/xds-grpc cluster/xds-grpc - - - STATIC
NAME ADDRESSES PORT MATCH DESTINATION
listener/10.10.200.10_53 10.10.200.10 53 ALL Cluster: outbound|53||kube-dns.kube-system.svc.cluster.local
listener/0.0.0.0_80 0.0.0.0 80 Trans: raw_buffer; App: http/1.1,h2c Route: 80
listener/0.0.0.0_80 0.0.0.0 80 ALL PassthroughCluster
listener/10.10.200.63_80 10.10.200.63 80 Trans: raw_buffer; App: http/1.1,h2c Route: svc-clusterip.default.svc.cluster.local:80
listener/10.10.200.63_80 10.10.200.63 80 ALL Cluster: outbound|80||svc-clusterip.default.svc.cluster.local
listener/10.10.200.1_443 10.10.200.1 443 ALL Cluster: outbound|443||kubernetes.default.svc.cluster.local
listener/10.10.200.143_443 10.10.200.143 443 ALL Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
listener/10.10.200.150_443 10.10.200.150 443 ALL Cluster: outbound|443||metrics-server.kube-system.svc.cluster.local
listener/10.10.200.43_443 10.10.200.43 443 ALL Cluster: outbound|443||istiod.istio-system.svc.cluster.local
listener/10.10.200.10_9153 10.10.200.10 9153 Trans: raw_buffer; App: http/1.1,h2c Route: kube-dns.kube-system.svc.cluster.local:9153
listener/10.10.200.10_9153 10.10.200.10 9153 ALL Cluster: outbound|9153||kube-dns.kube-system.svc.cluster.local
listener/virtualOutbound 0.0.0.0 15001 ALL PassthroughCluster
listener/virtualOutbound 0.0.0.0 15001 Addr: *:15001 Non-HTTP/Non-TCP
listener/virtualInbound 0.0.0.0 15006 Addr: *:15006 Non-HTTP/Non-TCP
listener/virtualInbound 0.0.0.0 15006 Trans: tls; App: istio-http/1.0,istio-http/1.1,istio-h2 InboundPassthroughCluster
listener/virtualInbound 0.0.0.0 15006 Trans: raw_buffer; App: http/1.1,h2c InboundPassthroughCluster
listener/virtualInbound 0.0.0.0 15006 Trans: tls; App: TCP TLS InboundPassthroughCluster
listener/virtualInbound 0.0.0.0 15006 Trans: raw_buffer InboundPassthroughCluster
listener/virtualInbound 0.0.0.0 15006 Trans: tls InboundPassthroughCluster
listener/virtualInbound 0.0.0.0 15006 Trans: tls; App: istio-http/1.0,istio-http/1.1,istio-h2; Addr: *:80 Cluster: inbound|80||
listener/virtualInbound 0.0.0.0 15006 Trans: raw_buffer; App: http/1.1,h2c; Addr: *:80 Cluster: inbound|80||
listener/virtualInbound 0.0.0.0 15006 Trans: tls; App: TCP TLS; Addr: *:80 Cluster: inbound|80||
listener/virtualInbound 0.0.0.0 15006 Trans: raw_buffer; Addr: *:80 Cluster: inbound|80||
listener/virtualInbound 0.0.0.0 15006 Trans: tls; Addr: *:80 Cluster: inbound|80||
listener/0.0.0.0_15010 0.0.0.0 15010 Trans: raw_buffer; App: http/1.1,h2c Route: 15010
listener/0.0.0.0_15010 0.0.0.0 15010 ALL PassthroughCluster
listener/10.10.200.43_15012 10.10.200.43 15012 ALL Cluster: outbound|15012||istiod.istio-system.svc.cluster.local
listener/0.0.0.0_15014 0.0.0.0 15014 Trans: raw_buffer; App: http/1.1,h2c Route: 15014
listener/0.0.0.0_15014 0.0.0.0 15014 ALL PassthroughCluster
listener/ 0.0.0.0 15021 ALL Inline Route: /healthz/ready*
listener/10.10.200.143_15021 10.10.200.143 15021 Trans: raw_buffer; App: http/1.1,h2c Route: istio-ingressgateway.istio-system.svc.cluster.local:15021
listener/10.10.200.143_15021 10.10.200.143 15021 ALL Cluster: outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
listener/ 0.0.0.0 15090 ALL Inline Route: /stats/prometheus*
listener/10.10.200.143_15443 10.10.200.143 15443 ALL Cluster: outbound|15443||istio-ingressgateway.istio-system.svc.cluster.local
listener/10.10.200.143_31400 10.10.200.143 31400 ALL Cluster: outbound|31400||istio-ingressgateway.istio-system.svc.cluster.local
NAME VHOST NAME DOMAINS MATCH VIRTUAL SERVICE
route/15010 istiod.istio-system.svc.cluster.local:15010 istiod.istio-system, 10.10.200.43 /*
route/svc-clusterip.default.svc.cluster.local:80 svc-clusterip.default.svc.cluster.local:80 * /*
route/80 istio-ingressgateway.istio-system.svc.cluster.local:80 istio-ingressgateway.istio-system, 10.10.200.143 /*
route/80 svc-clusterip.default.svc.cluster.local:80 svc-clusterip, svc-clusterip.default + 1 more... /*
route/kube-dns.kube-system.svc.cluster.local:9153 kube-dns.kube-system.svc.cluster.local:9153 * /*
route/istio-ingressgateway.istio-system.svc.cluster.local:15021 istio-ingressgateway.istio-system.svc.cluster.local:15021 * /*
route/15014 istiod.istio-system.svc.cluster.local:15014 istiod.istio-system, 10.10.200.43 /*
route/ backend * /healthz/ready*
route/InboundPassthroughCluster inbound|http|0 * /*
route/inbound|80|| inbound|http|80 * /*
route/inbound|80|| inbound|http|80 * /*
route/ backend * /stats/prometheus*
route/InboundPassthroughCluster inbound|http|0 * /*
RESOURCE NAME TYPE STATUS VALID CERT SERIAL NUMBER NOT AFTER NOT BEFORE
secret/default Cert Chain ACTIVE true a6e8a3fb29c823614774b593a88e7f4 2024-10-20T16:41:14Z 2024-10-19T16:39:14Z
secret/ROOTCA CA ACTIVE true 747b5c7d9e4cdaa6317de5bd0006d450 2034-10-17T15:19:51Z 2024-10-19T15:19:51Z
NAME STATUS LOCALITY CLUSTER
endpoint/172.16.2.4:80 HEALTHY inbound|80||
endpoint/127.0.0.1:15020 HEALTHY agent
endpoint/172.16.2.2:8080 HEALTHY outbound|80||istio-ingressgateway.istio-system.svc.cluster.local
endpoint/172.16.2.2:8443 HEALTHY outbound|443||istio-ingressgateway.istio-system.svc.cluster.local
endpoint/172.16.2.2:15021 HEALTHY outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local
endpoint/172.16.2.2:15443 HEALTHY outbound|15443||istio-ingressgateway.istio-system.svc.cluster.local
endpoint/172.16.2.2:31400 HEALTHY outbound|31400||istio-ingressgateway.istio-system.svc.cluster.local
endpoint/172.16.1.2:15017 HEALTHY outbound|443||istiod.istio-system.svc.cluster.local
endpoint/172.16.1.2:15010 HEALTHY outbound|15010||istiod.istio-system.svc.cluster.local
endpoint/172.16.1.2:15012 HEALTHY outbound|15012||istiod.istio-system.svc.cluster.local
endpoint/172.16.1.2:15014 HEALTHY outbound|15014||istiod.istio-system.svc.cluster.local
endpoint/172.16.0.2:53 HEALTHY outbound|53||kube-dns.kube-system.svc.cluster.local
endpoint/172.16.0.2:9153 HEALTHY outbound|9153||kube-dns.kube-system.svc.cluster.local
endpoint/192.168.10.10:6443 HEALTHY outbound|443||kubernetes.default.svc.cluster.local
endpoint/172.16.0.3:10250 HEALTHY outbound|443||metrics-server.kube-system.svc.cluster.local
endpoint/127.0.0.1:15000 HEALTHY prometheus_stats
endpoint/./var/run/secrets/workload-spiffe-uds/socket HEALTHY sds-grpc
endpoint/172.16.2.4:80 HEALTHY outbound|80||svc-clusterip.default.svc.cluster.local
endpoint/./etc/istio/proxy/XDS HEALTHY xds-grpc
- 컨테이너 내부 확인
pilot : istio-proxy 내 uds 로 envoy 와 grpc 통신, istiod 받아온 dynamic config 를 envoy 에 전달합니다.
Istio Proxy와 Pilot Agen가 서로 연결되어 있는 것을 확인할 수 있습니다.
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deploy/deploy-websrv -c istio-proxy -- ps -ef
UID PID PPID C STIME TTY TIME CMD
istio-p+ 1 0 0 16:41 ? 00:00:00 /usr/local/bin/pilot-agent proxy sidecar --domain default.svc.cluster.local --proxyLogLevel=warning --prox
istio-p+ 13 1 0 16:41 ? 00:00:04 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev.json --drain-time-s 45 --drain-strategy immediate --loca
istio-p+ 28 0 50 17:08 pts/0 00:00:00 ps -ef
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deploy/deploy-websrv -c istio-proxy -- ss -np
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
u_str ESTAB 0 0 * 92886 * 93903 users:(("envoy",pid=13,fd=19))
u_str ESTAB 0 0 etc/istio/proxy/XDS 93903 * 92886 users:(("pilot-agent",pid=1,fd=8))
u_str ESTAB 0 0 * 83131 * 85011 users:(("envoy",pid=13,fd=32))
u_str ESTAB 0 0 * 80865 * 80866
u_str ESTAB 0 0 * 80867 * 80868
u_str ESTAB 0 0 * 80870 * 80869
u_str ESTAB 0 0 * 80871 * 80872
u_str ESTAB 0 0 * 80869 * 80870
u_str ESTAB 0 0 * 80872 * 80871
u_str ESTAB 0 0 * 80866 * 80865
u_str ESTAB 0 0 * 80868 * 80867
u_str ESTAB 0 0 var/run/secrets/workload-spiffe-uds/socket 85011 * 83131 users:(("pilot-agent",pid=1,fd=15))
tcp ESTAB 0 0 172.16.2.4:60436 10.10.200.43:15012 users:(("pilot-agent",pid=1,fd=11))
tcp ESTAB 0 0 172.16.2.4:15006 172.16.2.2:45398 users:(("envoy",pid=13,fd=38))
tcp ESTAB 0 0 172.16.2.4:15006 172.16.2.2:44926 users:(("envoy",pid=13,fd=42))
tcp ESTAB 0 0 127.0.0.1:48314 127.0.0.1:15020 users:(("envoy",pid=13,fd=41))
tcp ESTAB 0 0 127.0.0.1:39004 127.0.0.1:15020 users:(("envoy",pid=13,fd=39))
tcp ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:48314 users:(("pilot-agent",pid=1,fd=18))
tcp ESTAB 0 0 [::ffff:127.0.0.1]:15020 [::ffff:127.0.0.1]:39004 users:(("pilot-agent",pid=1,fd=16))
- istiod 정보 확인
(⎈|default:N/A) root@k3s-s:~# kubectl exec -it deploy/istiod -n istio-system -- ps -ef
UID PID PPID C STIME TTY TIME CMD
istio-p+ 1 0 0 15:19 ? 00:00:13 /usr/local/bin/pilot-discovery discovery --monitoringAddr=:15014 --log_output_level=default:info --domain
istio-p+ 33 0 99 17:10 pts/0 00:00:00 ps -ef
(⎈|default:N/A) kubectl exec -it deploy/istiod -n istio-system -- netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9876 0.0.0.0:* LISTEN 1/pilot-discovery
tcp 0 0 172.16.1.2:51794 10.10.200.1:443 ESTABLISHED 1/pilot-discovery
tcp6 0 0 :::8080 :::* LISTEN 1/pilot-discovery
tcp6 0 0 :::15010 :::* LISTEN 1/pilot-discovery
tcp6 0 0 :::15014 :::* LISTEN 1/pilot-discovery
tcp6 0 0 :::15012 :::* LISTEN 1/pilot-discovery
tcp6 0 0 :::15017 :::* LISTEN 1/pilot-discovery
tcp6 0 0 172.16.1.2:8080 172.16.1.1:38360 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:41964 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:37028 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:37944 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:55418 TIME_WAIT -
tcp6 0 0 172.16.1.2:15012 172.16.2.4:44594 ESTABLISHED 1/pilot-discovery
tcp6 0 0 172.16.1.2:8080 172.16.1.1:43998 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:44020 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:44006 TIME_WAIT -
tcp6 0 0 172.16.1.2:15012 172.16.2.2:51286 ESTABLISHED 1/pilot-discovery
tcp6 0 0 172.16.1.2:15012 172.16.2.4:44578 ESTABLISHED 1/pilot-discovery
tcp6 0 0 172.16.1.2:8080 172.16.1.1:38340 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:37936 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:37960 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:40066 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:41980 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:40074 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:55420 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:55436 TIME_WAIT -
tcp6 0 0 172.16.1.2:8080 172.16.1.1:38344 TIME_WAIT -
istio-proxy, Istiod 가 각각 사용하는 포트 정보
(istio-proxy)
(istiod)
'Cloud > Kubernetes' 카테고리의 다른 글
[KANS] Istio - Traffic Management (0) | 2024.10.20 |
---|---|
[KANS] Istio example (bookinfo) (1) | 2024.10.20 |
[KANS] Gateway API (3) | 2024.10.13 |
[KANS] Ingress (0) | 2024.10.13 |
[KANS] LoadBalancer (2) | 2024.10.05 |