티스토리 뷰

IT/Container&k8s

K8S Service Mesh Istio

Hayley Shim 2024. 10. 20. 01:38

안녕하세요. Kubernetes Advanced Networking Study(=KANS) 3기 모임에서 스터디한 내용을 정리했습니다. 해당 글에서는 k8s중 Service Mesh인 Istio에 대해 자세히 알아보겠습니다. 

 

Service Mesh

- 마이크로서비스 아키텍처 환경의 시스템 전체 모니터링의 어려움, 운영 시 시스템 장애나 문제 발생할 때 원인과 병목 구간 찾기 어려워서 등장

- 마이크로서비스 간에 매시 형태의 통신이나 그 경로제어 - 예) 이스티오(Istio), 링커드(Linkerd) - 링크

 

기본 동작

파드 간 통신 경로에 프록시를 놓고 트래픽 모니터링이나 트래픽 컨트롤

1) 애플리케이션 수정 없이, 모든 애플리케이션 통신 사이에 Proxy 를 두고 통신

2) Proxy 는 결국 DataPlane 이니, 이를 중앙에서 관리하는 ControlPlane을 두고 중앙에서 관리

-> Proxy 는 중앙에서 설정 관리가 잘되는 툴을 선택. 원격에서 동적인 설정 관리가 유연해야함 → 풍부한 API 지원 필요 → Envoy

 

1. 트래픽 모니터링 : 요청의 '에러율, 레이턴시, 커넥션 개수, 요청 개수' 등 메트릭 모니터링, 특정 서비스간 혹은 특정 요청 경로로 필터링 → 원인 파악 용이

2. 트래픽 컨트롤 : 트래픽 시프팅(Traffic shifting), 서킷 브레이커(Circuit Breaker), 폴트 인젝션(Fault Injection), 속도 제한(Rate Limit)

- 트래픽 시프팅(Traffic shifting) : 예시) 99% 기존앱 + 1% 신규앱 , 특정 단말/사용자는 신규앱에 전달하여 단계적으로 적용하는 카니리 배포 가능

- 서킷 브레이커(Circuit Breaker) : 목적지 마이크로서비스에 문제가 있을 시 접속을 차단하고 출발지 마이크로서비스에 요청 에러를 반환 (연쇄 장애, 시스템 전제 장애 예방)

- 폴트 인젝션(Fault Injection) : 의도적으로 요청을 지연 혹은 실패를 구현

- 속도 제한(Rate Limit) : 요청 개수를 제한

 

 

Istio

 

 

Istio 구성요소와 envoy : 컨트롤 플레인(istiod) , 데이터 플레인(istio-proxy > envoy)

- Istiod : Pilot(데이터 플레인과 통신하면서 라우팅 규칙을 동기화, ADS), Gally(Istio 와 K8S 연동, Endpoint 갱신 등), Citadel(연결 암호화, 인증서 관리 등)

- Istio proxy : Golang 으로 작성되었고 envoy 래핑한 Proxy, istiod와 통신하고 서비스 트래픽을 통제, 옵저버빌리티를 위한 메트릭 제공

- 이스티오는 각 파드 안에 사이드카 엔보이 프록시가 들어가 있는 형태

- 모든 마이크로서비스간 통신은 엔보이를 통과하여, 메트릭을 수집하거나 트래픽 컨트롤을 할 수 있음

- 트래픽 컨트롤을 하기위해 엔보이 프록시에 전송 룰을 설정 → 컨트롤 플레인 이스티오가 정의된 정보를 기반으로 엔보이 설정을 하게 함

- 마이크로서비스 간의 통신을 mutual TLS 인증(mTLS)으로 서로 TLS 인증으로 암호화 할 수 있음

- 각 애플리케이션은 파드 내의 엔보이 프록시에 접속하기 위해 localhost 에 TCP 접속

 

 

실습 환경 구성

- VPC 1개(퍼블릭 서브넷 2개), EC2 인스턴스 3대 (Ubuntu 22.04 LTS, t3.xlarge - vCPU 4 , Mem 16) , testpc 1대는 t3.small

# CloudFormation 스택 배포

# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/kans/kans-7w.yaml

# CloudFormation 스택 배포
# aws cloudformation deploy --template-file kans-7w.yaml --stack-name mylab --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 --region ap-northeast-2
예시) aws cloudformation deploy --template-file kans-7w.yaml --stack-name mylab --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

## Tip. 인스턴스 타입 변경 : MyInstanceType=t3.xlarge (vCPU 4, Mem 16)
예시) aws cloudformation deploy --template-file kans-7w.yaml --stack-name mylab --parameter-overrides MyInstanceType=t3.xlarge KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

# CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력
aws cloudformation describe-stacks --stack-name mylab --query 'Stacks[*].Outputs[0].OutputValue' --output text --region ap-northeast-2

# [모니터링] CloudFormation 스택 상태 : 생성 완료 확인
while true; do 
  date
  AWS_PAGER="" aws cloudformation list-stacks \
    --stack-status-filter CREATE_IN_PROGRESS CREATE_COMPLETE CREATE_FAILED DELETE_IN_PROGRESS DELETE_FAILED \
    --query "StackSummaries[*].{StackName:StackName, StackStatus:StackStatus}" \
    --output table
  sleep 1
done

# 배포된 aws ec2 유동 공인 IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
k3s-s	3.38.151.222	running
k3s-w1	15.165.75.117	running
k3s-w2	3.39.223.99	running
testpc	54.180.243.135	running

# EC2 SSH 접속 : 바로 접속하지 말고, 3~5분 정도 후에 접속 할 것
ssh -i ~/.ssh/kp-gasida.pem ubuntu@$(aws cloudformation describe-stacks --stack-name mylab --query 'Stacks[*].Outputs[0].OutputValue' --output text --region ap-northeast-2)
...
(⎈|default:N/A) root@k3s-s:~# <- kubeps 가 나오지 않을 경우 ssh logout 후 다시 ssh 접속 할 것!

 

k3s-s , testpc 각각 접속 후 확인

실습 환경은 K3S v1.30.4 , 노드 OS(Ubuntu 22.04.5) , CNI(Flannel) , IPTABLES proxy mode , Istio v1.23.2(Envoy v1.32.2)

 

배포된 aws ec2 유동 공인 IP 확인

aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
k3s-s	3.38.151.222	running
k3s-w1	15.165.75.117	running
k3s-w2	3.39.223.99	running
testpc	54.180.243.135	running

 

k3s-s 접속 후 확인 : ssh -i <> ubuntu@3.38.151.222

kc get node -owide
NAME     STATUS   ROLES                  AGE     VERSION        INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
k3s-s    Ready    control-plane,master   8m57s   v1.30.5+k3s1   192.168.10.10    <none>        Ubuntu 22.04.5 LTS   6.8.0-1015-aws   containerd://1.7.21-k3s2
k3s-w1   Ready    <none>                 8m46s   v1.30.5+k3s1   192.168.10.101   <none>        Ubuntu 22.04.5 LTS   6.8.0-1015-aws   containerd://1.7.21-k3s2
k3s-w2   Ready    <none>                 8m45s   v1.30.5+k3s1   192.168.10.102   <none>        Ubuntu 22.04.5 LTS   6.8.0-1015-aws   containerd://1.7.21-k3s2

hostnamectl 
...
 Hardware Vendor: Amazon EC2
  Hardware Model: t3.xlarge

 

testpc 각각 접속 후 확인 : ssh -i <> ubuntu@54.180.243.135

ip -br -c addr
lo               UNKNOWN        127.0.0.1/8 ::1/128 
ens5             UP             192.168.10.200/24 metric 100 fe80::3:e9ff:fefa:85d9/64 

hostnamectl 
...
 Hardware Vendor: Amazon EC2
  Hardware Model: t3.small

 

Envoy

- L4/7 Proxy , Istio 의 Sidecar proxy 로 사용* - 링크 주요 용어

- Istio 구성요소와 envoy : 컨트롤 플레인(istiod) - ADS 를 이용한 Configuration 동기화 - 데이터 플레인(istio-proxy → envoy)

 

testps 에 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 --help

 

Envoy proxy 실습 - Link

# 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

 

# (터미널1) 데모 config 적용하여 실행
curl -O https://www.envoyproxy.io/docs/envoy/latest/_downloads/92dcb9714fb6bc288d042029b34c0de4/envoy-demo.yaml
envoy -c envoy-demo.yaml


# (터미널2) 정보 확인
ss -tnlp
State    Recv-Q  Send-Q    Local Address:Port   Peer Address:Port    Process
LISTEN   0       4096      0.0.0.0:10000        0.0.0.0:*            users:(("envoy",pid=8007,fd=18),("envoy",pid=8007,fd=16))

# 접속 테스트
curl -s http://127.0.0.1:10000 | grep -o "<title>.*</title>"

# 외부 접속 정보 출력
echo -e "http://$(curl -s ipinfo.io/ip):10000"
http://54.180.243.135:10000

--------------------
# 자신의 PC 웹브라우저에서 외부 접속 정보 접속 확인!

# k3s-s 에서 접속 테스트
curl -s http://192.168.10.200:10000 | grep -o "<title>.*</title>" 
--------------------

# 연결 정보 확인
ss -tnp

# (터미널1) envoy 실행 취소(CTRL+C) 후 (관리자페이지) 설정 덮어쓰기 - 링크
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)"

# envoy 관리페이지 외부 접속 정보 출력
echo -e "http://$(curl -s ipinfo.io/ip):9902"
http://54.180.243.135:9902

--------------------
# 자신의 PC 웹브라우저에서 관리 페이지 외부 접속 정보 접속 확인!

 

 

Istio 설치 (Sidecar mode)

Istio Sidecar mode 설치 : v1.23.2 - 버전 설치 , without GwApi - Docs

# 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

# (demo 프로파일) 컨트롤 플레인 배포 - 링크 Customizing
# The istioctl command supports the full IstioOperator API via command-line options for individual settings or for passing a yaml file containing an IstioOperator custom resource (CR).
istioctl profile list
istioctl profile dump default
istioctl profile dump --config-path components.ingressGateways
istioctl profile dump --config-path values.gateways.istio-ingressgateway
istioctl profile dump demo

istioctl profile dump demo > demo-profile.yaml
vi demo-profile.yaml # 복잡성을 줄이게 실습 시나리오 환경 맞춤
--------------------
    egressGateways:
    - enabled: false
--------------------    

istioctl install -f demo-profile.yaml -y
✔ Istio core installed ⛵️                                                                                                          
✔ Istiod installed 🧠                                                                                                              
✔ Ingress gateways installed 🛬                                                                                                    
✔ Installation complete                                                                                                            

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

# istio-ingressgateway 의 envoy 버전 확인
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 서비스 NodePort로 변경
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"type":"NodePort"}}'

# istio-ingressgateway 서비스 확인
kubectl get svc,ep -n istio-system istio-ingressgateway

## istio-ingressgateway 서비스 포트 정보 확인
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath={.spec.ports[*]} | jq

## istio-ingressgateway 디플로이먼트 파드의 포트 정보 확인 
kubectl get deploy/istio-ingressgateway -n istio-system -o jsonpath={.spec.template.spec.containers[0].ports[*]} | jq
kubectl get deploy/istio-ingressgateway -n istio-system -o jsonpath={.spec.template.spec.containers[0].readinessProbe} | jq

# istiod(컨트롤플레인) 디플로이먼트 정보 확인
kubectl exec -it deployment.apps/istiod -n istio-system -- ss -tnlp
kubectl exec -it deployment.apps/istiod -n istio-system -- ss -tnp
kubectl exec -it deployment.apps/istiod -n istio-system -- ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
istio-p+       1       0  0 05:27 ?        00:00:07 /usr/local/bin/pilot-discovery discovery --monitoringAddr=:15014 --log_output_l

# istio-ingressgateway 디플로이먼트 정보 확인
kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ss -tnlp
kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ss -tnp
kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ps -ef
istio-p+       1       0  0 05:27 ?        00:00:01 /usr/local/bin/pilot-agent proxy router --domain istio-system.svc.cluster.local
istio-p+      15       1  0 05:27 ?        00:00:11 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev.json --drain-time-s 45 --drai

kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- cat /etc/istio/proxy/envoy-rev.json
kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ss -xnlp
kubectl exec -it deployment.apps/istio-ingressgateway -n istio-system -- ss -xnp

 

Auto Injection with namespace label : 해당 네임스페이스에 생성되는 모든 파드들은 istio 사이드카가 자동으로 injection 됨

# mutating Webhook admisstion controller 사용
kubectl label namespace default istio-injection=enabled
kubectl get ns -L istio-injection
NAME              STATUS   AGE     ISTIO-INJECTION
default           Active   58m     enabled
...

 

Istio 접속 테스트를 위한 변수 지정*

mypc)
## istio-ingressgateway 파드가 배치된 노드의 유동 공인 IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
k3s-s	3.38.151.222	running
k3s-w1	15.165.75.117	running
k3s-w2	3.39.223.99	running
testpc	54.180.243.135	running


k3s-s)
# istio ingress gw NodePort(HTTP 접속용) 변수 지정 : 아래 ports[0] 은 어떤 용도의 포트일까요?
export IGWHTTP=$(kubectl get service -n istio-system istio-ingressgateway -o jsonpath='{.spec.ports[1].nodePort}')
echo $IGWHTTP
IGWHTTP=<각자 자신의 NodePort>

# /etc/hosts 파일 수정
MYDOMAIN=<각자 자신의 www 도메인> # 단, 사용하고 있지 않는 공인 도메인을 사용 할 것
MYDOMAIN=www.wellbeconnected.com
echo "<istio-ingressgateway 파드가 있는 워커 노드> $MYDOMAIN" >> /etc/hosts

MYDOMAIN=<각자 자신의 www 도메인>
export MYDOMAIN=www.wellbeconnected.com
echo -e "192.168.10.10 $MYDOMAIN" >> /etc/hosts
echo -e "export MYDOMAIN=$MYDOMAIN" >> /etc/profile

# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
curl -v -s $MYDOMAIN:$IGWHTTP

 

testpc

# 아래 변수는 각자 자신의 값을 직접 입력 할 것
IGWHTTP=<각자 출력된 NodePort>
IGWHTTP=32759
export MYDOMAIN=www.wellbeconnected.com
echo -e "192.168.10.10 $MYDOMAIN" >> /etc/hosts
echo -e "export MYDOMAIN=$MYDOMAIN" >> /etc/profile

# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
curl -v -s $MYDOMAIN:$IGWHTTP

 

PC

# 아래 변수는 각자 자신의 값을 직접 입력 할 것 : ISTIONODEIP는 3개의 노드 중 아무거나 입력
IGWHTTP=<각자 출력된 NodePort>
IGWHTTP=32759
ISTIONODEIP=<k3s-s 의 유동 공인 IP>
ISTIONODEIP=3.38.208.153

MYDOMAIN=www.wellbeconnected.com
echo "$ISTIONODEIP $MYDOMAIN" | sudo tee -a /etc/hosts

# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
curl -v -s $MYDOMAIN:$IGWHTTP

 

 

Istio 통한 외부 노출

Nginx 디플로이먼트와 서비스 배포

# 로그 모니터링
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
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

 

Istio Gateway/VirtualService 설정 - Host 기반 트래픽 라우팅 설정 - Gateway

  • 클라이언트 PC → (Service:NodePort) Istio ingressgateway 파드 → (Gateway, VirtualService, Service 는 Bypass) → Endpoint(파드 : 사이드카 - Application 컨테이너)
  • Gateway : 지정한 인그레스 게이트웨이로부터 트래픽이 인입, 프로토콜 및 포트, HOSTS, Proxy 등 설정 가능
  • VirtualService : 인입 처리할 hosts 설정, L7 PATH 별 라우팅, 목적지에 대한 정책 설정 가능 (envoy route config)
  • (참고) Introducing Istio v1 APIs - Blog
cat <<EOF | kubectl create -f -
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
EOF
# Istio Gateway(=gw)/VirtualService(=vs) 설정 정보를 확인
kc explain gateways.networking.istio.io
kc explain virtualservices.networking.istio.io
kubectl api-resources  | grep istio

# virtual service 는 다른 네임스페이스의 서비스(ex. svc-nn.<ns>)도 참조할 수 있다
kubectl get gw,vs
NAME                                       AGE
gateway.networking.istio.io/test-gateway   21s

NAME                                               GATEWAYS           HOSTS                AGE
virtualservice.networking.istio.io/nginx-service   ["test-gateway"]   ["www.wellbeconnected.com"]   4m9s

# Retrieves last sent and last acknowledged xDS sync from Istiod to each Envoy in the mesh
# istioctl proxy-status command was improved to include the time since last change, and more relevant status values.
istioctl proxy-status # 단축어 ps
istioctl ps

 

Istio 를 통한 Nginx 파드 접속 테스트

- 외부(자신의PC, testpc)에서 접속 테스트

# istio ingress gw 를 통한 접속 테스트
curl -s $MYDOMAIN:$IGWHTTP | grep -o "<title>.*</title>"
curl -v -s $MYDOMAIN:$IGWHTTP
curl -v -s <유동공인이IP>:$IGWHTTP

 

- 출력 로그 정보 확인

kubetail -n istio-system -l app=istio-ingressgateway -f
kubetail -l app=deploy-websrv

 

- istioctl 정보 확인

#
istioctl proxy-status
NAME                                                   CLUSTER        CDS                LDS                EDS                RDS                ECDS        ISTIOD                      VERSION
deploy-websrv-7d7cf8586c-l22cs.default                 Kubernetes     SYNCED (22m)       SYNCED (22m)       SYNCED (22m)       SYNCED (22m)       IGNORED     istiod-7f8b586864-mv944     1.23.2
istio-ingressgateway-5f9f654d46-c4g7s.istio-system     Kubernetes     SYNCED (5m19s)     SYNCED (5m19s)     SYNCED (5m19s)     SYNCED (5m19s)     IGNORED     istiod-7f8b586864-mv944     1.23.2

# Envoy config dump : all, cluster, endpoint, listener 등
istioctl proxy-config --help 
istioctl proxy-config all deploy-websrv-7d7cf8586c-l22cs
istioctl proxy-config all deploy-websrv-7d7cf8586c-l22cs -o json | jq
istioctl proxy-config route deploy-websrv-7d7cf8586c-l22cs -o json | jq

 

pilot : istio-proxy 내 uds 로 envoy 와 grpc 통신, istiod 받아온 dynamic config 를 envoy 에 전달

# istio-proxy 사용자 정보 확인 : uid(1337):gid(1337) 확인 -> iptables rule 에서 사용됨
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- tail -n 3 /etc/passwd
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
tcpdump:x:100:102::/nonexistent:/usr/sbin/nologin
istio-proxy:x:1337:1337::/home/istio-proxy:/bin/sh

# envoy 설정 정보 확인 : dynamic_resources , static_resources - listeners  : 출력되는 IP가 누구인지 확인 해보자
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- cat /etc/istio/proxy/envoy-rev.json
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- ss -nlp
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- ss -np
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- netstat -np
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 172.16.1.10:15021       172.16.1.1:49548        TIME_WAIT   -                   
tcp        0      0 172.16.1.10:15006       172.16.2.4:37814        ESTABLISHED 12/envoy            
tcp        0      0 172.16.1.10:15021       172.16.1.1:43138        TIME_WAIT   -                   
tcp        0      0 127.0.0.1:39158         127.0.0.1:15020         ESTABLISHED 12/envoy            
tcp        0      0 172.16.1.10:15021       172.16.1.1:42948        TIME_WAIT   -                   
tcp        0      0 172.16.1.10:51370       10.10.200.82:15012      ESTABLISHED 1/pilot-agent       
tcp        0      0 172.16.1.10:15021       172.16.1.1:39522        TIME_WAIT   -                   
tcp        0      0 172.16.1.10:51360       10.10.200.82:15012      ESTABLISHED 1/pilot-agent       
tcp        0      0 127.0.0.1:39172         127.0.0.1:15020         ESTABLISHED 12/envoy            
tcp6       0      0 127.0.0.1:15020         127.0.0.1:39158         ESTABLISHED 1/pilot-agent       
tcp6       0      0 127.0.0.1:15020         127.0.0.1:39172         ESTABLISHED 1/pilot-agent       

Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Path
unix  3      [ ]         STREAM     CONNECTED     151002   1/pilot-agent        var/run/secrets/workload-spiffe-uds/socket
unix  3      [ ]         STREAM     CONNECTED     152729   -                    
unix  3      [ ]         STREAM     CONNECTED     152723   -                    
unix  3      [ ]         STREAM     CONNECTED     152727   -                    
unix  3      [ ]         STREAM     CONNECTED     150129   12/envoy             
unix  3      [ ]         STREAM     CONNECTED     152726   -                    
unix  3      [ ]         STREAM     CONNECTED     152724   -                    
unix  3      [ ]         STREAM     CONNECTED     152722   -                    
unix  3      [ ]         STREAM     CONNECTED     150979   12/envoy             
unix  3      [ ]         STREAM     CONNECTED     152728   -                    
unix  3      [ ]         STREAM     CONNECTED     152725   -                    
unix  3      [ ]         STREAM     CONNECTED     150120   1/pilot-agent        etc/istio/proxy/XDS

#
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
istio-p+       1       0  0 07:11 ?        00:00:00 /usr/local/bin/pilot-agent proxy sidecar --domain default.svc.cluster.local --p
istio-p+      12       1  0 07:11 ?        00:00:02 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev.json --drain-time-s 45 --drai
istio-p+      91       0  0 07:21 pts/0    00:00:00 ps -ef

# 출력되는 IP가 누구인지 확인 해보자
kubectl get pod,svc -A -owide
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:15004         0.0.0.0:*               LISTEN      1/pilot-agent       
tcp        0      0 127.0.0.1:15000         0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15006           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15006           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      12/envoy            
tcp        0      0 172.16.1.10:15006       172.16.2.4:37814        ESTABLISHED 12/envoy            
tcp        0      0 172.16.1.10:15021       172.16.1.1:42632        TIME_WAIT   -                   
tcp        0      0 127.0.0.1:39158         127.0.0.1:15020         ESTABLISHED 12/envoy            
tcp        0      0 172.16.1.10:15021       172.16.1.1:55752        TIME_WAIT   -                   
tcp        0      0 172.16.1.10:51370       10.10.200.82:15012      ESTABLISHED 1/pilot-agent       
tcp        0      0 172.16.1.10:15021       172.16.1.1:50394        TIME_WAIT   -                   
tcp        0      0 172.16.1.10:51360       10.10.200.82:15012      ESTABLISHED 1/pilot-agent       
tcp        0      0 172.16.1.10:15021       172.16.1.1:49496        TIME_WAIT   -                   
tcp        0      0 127.0.0.1:39172         127.0.0.1:15020         ESTABLISHED 12/envoy            
tcp6       0      0 :::80                   :::*                    LISTEN      -                   
tcp6       0      0 :::15020                :::*                    LISTEN      1/pilot-agent       
tcp6       0      0 127.0.0.1:15020         127.0.0.1:39158         ESTABLISHED 1/pilot-agent       
tcp6       0      0 127.0.0.1:15020         127.0.0.1:39172         ESTABLISHED 1/pilot-agent  


# istiod 정보 같이 확인 : 출력되는 IP가 누구인지 확인 해보자
kubectl get pod,svc -A -owide
kubectl exec -it deploy/istiod -n istio-system -- ps -ef
kubectl exec -it deploy/istiod -n istio-system -- netstat -antp
kubectl exec -it deploy/istiod -n istio-system -- ss -nlp
kubectl exec -it deploy/istiod -n istio-system -- ss -np

 

 

Bookinfo 실습 & Istio 기능

1) Bookinfo

- Bookinfo 애플리케이션 소개 : 4개의 마이크로서비스로 구성 : Productpage, reviews, ratings, details - 링크

Bookinfo 애플리케이션 배포 - 링크

# 모니터링
watch -d 'kubectl get pod -owide;echo;kubectl get svc'

# Bookinfo 애플리케이션 배포
echo $ISTIOV
cat ~/istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f ~/istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml

# 확인
kubectl get all,sa

# product 웹 접속 확인
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

# 로그
kubetail -l app=productpage -f

 

2) Istio 를 통한 인입 기본 설정

Istio Gateway/VirtualService 설정

# Istio Gateway/VirtualService 설정
cat ~/istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f ~/istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml

# 확인
kubectl get gw,vs
istioctl proxy-status
NAME                                                   CLUSTER        CDS                LDS                EDS                RDS                ECDS        ISTIOD                      VERSION
details-v1-65cfcf56f9-4drsk.default                    Kubernetes     SYNCED (7m4s)      SYNCED (7m4s)      SYNCED (6m57s)     SYNCED (7m4s)      IGNORED     istiod-7f8b586864-mv944     1.23.2
istio-ingressgateway-5f9f654d46-c4g7s.istio-system     Kubernetes     SYNCED (3m7s)      SYNCED (3m7s)      SYNCED (6m57s)     SYNCED (3m7s)      IGNORED     istiod-7f8b586864-mv944     1.23.2
productpage-v1-d5789fdfb-5cr6m.default                 Kubernetes     SYNCED (6m59s)     SYNCED (6m59s)     SYNCED (6m57s)     SYNCED (6m59s)     IGNORED     istiod-7f8b586864-mv944     1.23.2
ratings-v1-7c9bd4b87f-9q4nv.default                    Kubernetes     SYNCED (7m3s)      SYNCED (7m3s)      SYNCED (6m57s)     SYNCED (7m3s)      IGNORED     istiod-7f8b586864-mv944     1.23.2
reviews-v1-6584ddcf65-rqgp7.default                    Kubernetes     SYNCED (7m2s)      SYNCED (7m2s)      SYNCED (6m57s)     SYNCED (7m2s)      IGNORED     istiod-7f8b586864-mv944     1.23.2
reviews-v2-6f85cb9b7c-h6m7p.default                    Kubernetes     SYNCED (7m2s)      SYNCED (7m2s)      SYNCED (6m57s)     SYNCED (7m2s)      IGNORED     istiod-7f8b586864-mv944     1.23.2
reviews-v3-6f5b775685-rprpb.default                    Kubernetes     SYNCED (6m58s)     SYNCED (6m58s)     SYNCED (6m57s)     SYNCED (6m58s)     IGNORED     istiod-7f8b586864-mv944     1.23.2

# productpage 파드의 istio-proxy 로그 확인 Access log 가 출력 - Default access log format : 링크
kubetail -l app=productpage -c istio-proxy -f

 

Istio 를 통한 productpage 접속(반복) 테스트 & 웹 브라우저 접속 테스트*

- k3s-s NodePort 접속 확인

#
export IGWHTTP=$(kubectl get service -n istio-system istio-ingressgateway -o jsonpath='{.spec.ports[1].nodePort}')
echo $IGWHTTP
32759

# 접속 확인
kubectl get svc -n istio-system istio-ingressgateway
curl -s http://localhost:$IGWHTTP/productpage
curl -s http://192.168.10.101:$IGWHTTP/productpage
curl -s http://192.168.10.102:$IGWHTTP/productpage

# 정보 확인
echo $MYDOMAIN
cat /etc/hosts

#
curl -s http://$MYDOMAIN:$IGWHTTP/productpage

 

- 자신의 PC에서 접속 확인

#
echo $MYDOMAIN $IGWHTTP
cat /etc/hosts

#
curl -v -s $MYDOMAIN:$IGWHTTP/productpage
echo -e "http://$MYDOMAIN:$IGWHTTP/productpage"

#
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text

 

- testpc 에서 접속 실행*

# istio ingress gw 를 통한 접속 테스트
curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>"
while true; do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 1; done
for i in {1..100};  do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; done

 

- http://NodeIP:NodePort/productpage 로 접속 후 새로고침 해보자 → ReviewsRatings 변경 확인!

 

3) 모니터링

- Kiali is an observability console for Istio with service mesh configuration and validation capabilities.

- Addon 설치 : Kiali (키알리) 대시보드 along with Prometheus, Grafana, and Jaeger - 링크

# Install Kiali and the other addons and wait for them to be deployed. : Kiali dashboard, along with Prometheus, Grafana, and Jaeger.
tree ~/istio-$ISTIOV/samples/addons/
kubectl apply -f ~/istio-$ISTIOV/samples/addons # 디렉터리에 있는 모든 yaml 자원을 생성
kubectl rollout status deployment/kiali -n istio-system

# 확인
kubectl get all,sa,cm -n istio-system
kubectl get svc,ep -n istio-system

# kiali 서비스 변경
kubectl patch svc -n istio-system kiali -p '{"spec":{"type":"NodePort"}}'

# kiali 웹 접속 주소 확인
KIALINodePort=$(kubectl get svc -n istio-system kiali -o jsonpath={.spec.ports[0].nodePort})
echo -e "KIALI UI URL = http://$(curl -s ipinfo.io/ip):$KIALINodePort"

# Grafana 서비스 변경
kubectl patch svc -n istio-system grafana -p '{"spec":{"type":"NodePort"}}'

# Grafana 웹 접속 주소 확인 : 7개의 대시보드
GRAFANANodePort=$(kubectl get svc -n istio-system grafana -o jsonpath={.spec.ports[0].nodePort})
echo -e "Grafana URL = http://$(curl -s ipinfo.io/ip):$GRAFANANodePort"

# Prometheus 서비스 변경
kubectl patch svc -n istio-system prometheus -p '{"spec":{"type":"NodePort"}}'

# Prometheus 웹 접속 주소 확인
PROMENodePort=$(kubectl get svc -n istio-system prometheus -o jsonpath={.spec.ports[0].nodePort})
echo -e "Prometheus URL = http://$(curl -s ipinfo.io/ip):$PROMENodePort"

 

4) Traffic Management

- Traffic Managenet : 트래픽 컨트롤은 VirtualServiceDestinationRule 설정을 통해서 동작

 

동작 소개 : 클라이언트 PC → Istio ingressgateway 파드 → (Gateway, VirtualService + DestinationRule) → Cluster(Endpoint - 파드)

 

5) Security 

- 제로 트러스트 (ZT: Zero Trust) : ‘아무것도 신뢰할 수 없다는 가정하에, 사용자 및 다양한 정보를 바탕으로 최소한의 권한과 세밀한 통제를 지속적으로 수행하는 보안 활동’ - 링크

 

 

참고) 

약식 실습 가이드(mac M 사용자의 경우)

-  kind(controlplane 1대) + istio-ingressgateway(NodePort) + Istio 통신 흐름

 

1. kind k8s 배포

#
cat <<EOF> kind-1node.yaml 
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
  - containerPort: 30001
    hostPort: 30001
  - containerPort: 30002
    hostPort: 30002
  - containerPort: 30003
    hostPort: 30003
networking:
  podSubnet: 10.10.0.0/16
  serviceSubnet: 10.200.1.0/24 
EOF
kind create cluster --config kind-1node.yaml --name myk8s --image kindest/node:v1.30.4

# 설치 확인
docker ps

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

# testpc 컨테이너 기동 : kind 도커 브리지를 지정 해서 사용
docker run -d --rm --name testpc --network kind nicolaka/netshoot sleep infinity # IP 지정 없이 실행 시
docker ps

 

2. istioctl 설치 - install , profile

# myk8s-control-plane 진입 후 설치 진행
docker exec -it myk8s-control-plane bash
-----------------------------------
# istioctl 설치
export ISTIOV=1.23.2
curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV sh -
tree istio-$ISTIOV -L 2 # sample yaml 포함
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
istioctl version --remote=false

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

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

# istio-ingressgateway 서비스 NodePort 변경 및 nodeport 30000로 지정 변경
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 8080, "nodePort": 30000}]}}'
kubectl get svc -n istio-system istio-ingressgateway

# istio-ingressgateway 서비스 externalTrafficPolicy 설정 : ClientIP 수집 확인 용도
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"externalTrafficPolicy": "Local"}}'
kubectl describe svc -n istio-system istio-ingressgateway

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

 

3. default 네임스페이스에 istio-proxy sidecar 주입 설정 - Docs

# mutating Webhook admisstion controller 사용
kubectl label namespace default istio-injection=enabled
kubectl get ns -L istio-injection

4. Istio 접속 테스트를 위한 변수 지정

mac 환경

# /etc/hosts 파일 수정
MYDOMAIN=<각자 자신의 www 도메인> # 단, 사용하고 있지 않는 공인 도메인을 사용 할 것
export MYDOMAIN=www.wellbeconnected.com # 예시 도메인
echo "127.0.0.1 $MYDOMAIN" | sudo tee -a /etc/hosts

# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
curl -v -s $MYDOMAIN:30000
curl -v -s 127.0.0.1:30000

[신규 터미널] testpc 컨테이너

# myk8s-control-plane 컨테이너 IP 확인
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myk8s-control-plane
172.18.0.2


# testpc 진입 후 설치 진행
docker exec -it testpc zsh
-----------------------------------
#
echo -e "172.18.0.2 www.wellbeconnected.com" | tee -a /etc/hosts

#
curl -v -s www.wellbeconnected.com:30000

# 이후에도 접속 테스트를 위해서 해당 터미널은 유지

 

5. Istio 를 통한 Nginx 파드 접속 테스트

Nginx 디플로이먼트와 서비스 배포

cat <<EOF | kubectl apply -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

 

Istio Gateway/VirtualService 설정 - Host 기반 트래픽 라우팅 설정 - Gateway

cat <<EOF | kubectl apply -f -
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"  # 도메인 접속이 잘 되지 않을 경우 "*" 로 변경하고 IP로 접속 할 것
  gateways:
  - test-gateway
  http:
  - route:
    - destination:
        host: svc-clusterip
        port:
          number: 80
EOF

 

리소스 생성 확인

#
kubectl get deploy,pod,svc,ep,sa
kubectl describe pod -l app=deploy-websrv
kubectl get gw,vs

# 로그 확인
kubectl logs -l app=deploy-websrv -c istio-init --tail=-1
kubectl logs -l app=deploy-websrv -c istio-proxy --tail=-1
kubectl logs -l app=deploy-websrv -c deploy-websrv --tail=-1

#
docker exec -it myk8s-control-plane istioctl proxy-status # 단축어 ps
NAME                                                   CLUSTER        CDS              LDS              EDS              RDS              ECDS        ISTIOD                      VERSION
deploy-websrv-778ffd6947-7s9fk.default                 Kubernetes     SYNCED (14m)     SYNCED (14m)     SYNCED (14m)     SYNCED (14m)     IGNORED     istiod-868cc8b7d7-l95c2     1.23.2
istio-ingressgateway-64f9774bdc-b4rzj.istio-system     Kubernetes     SYNCED (22m)     SYNCED (22m)     SYNCED (22m)     SYNCED (22m)     IGNORED     istiod-868cc8b7d7-l95c2     1.23.2

# proxy-config 단축어 pc
docker exec -it myk8s-control-plane istioctl proxy-config all deploy-websrv-778ffd6947-7s9fk
docker exec -it myk8s-control-plane istioctl proxy-config all istio-ingressgateway-64f9774bdc-b4rzj.istio-system

docker exec -it myk8s-control-plane istioctl proxy-config listener deploy-websrv-778ffd6947-7s9fk
docker exec -it myk8s-control-plane istioctl proxy-config route deploy-websrv-778ffd6947-7s9fk
docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy-websrv-778ffd6947-7s9fk
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy-websrv-778ffd6947-7s9fk
docker exec -it myk8s-control-plane istioctl proxy-config log deploy-websrv-778ffd6947-7s9fk

# envoy 가 사용하고 있는 인증서 정보 확인
docker exec -it myk8s-control-plane istioctl proxy-config secret deploy-websrv-778ffd6947-7s9fk
RESOURCE NAME     TYPE           STATUS     VALID CERT     SERIAL NUMBER                        NOT AFTER                NOT BEFORE
default           Cert Chain     ACTIVE     true           fde80f16813a7838713e9f6107679ab3     2024-10-20T07:33:16Z     2024-10-19T07:31:16Z
ROOTCA            CA             ACTIVE     true           5148b1373dbec92eb58b536d562d4976     2034-10-17T07:31:57Z     2024-10-19T07:31:57Z

 

Istio 를 통한 Nginx 파드 접속 테스트

# (참고) 출력 로그 정보 확인
kubectl logs -n istio-system -l app=istio-ingressgateway -f
kubectl logs -l app=deploy-websrv -c istio-proxy -f
kubectl logs -l app=deploy-websrv -c deploy-websrv -f

# testpc 컨테이너에서 접속 테스트
curl -v -s <각자 자신의 www 도메인>:30000
curl -v -s www.gasida.dev:30000
curl -v -s <controlplane 컨테이너IP>:30000
curl -v -s 172.18.0.2:30000

# 자신의 mac 에서 접속 테스트
curl -v -s <각자 자신의 www 도메인>:30000
curl -v -s www.gasida.dev:30000
curl -v -s 127.0.0.1:30000
open http://127.0.0.1:30000

 

(참고) 특정 파드 istio-proxy Envoy 로그 레벨 변경 : /logging 엔드포인트에 요청으로 조정 가능 - Blog , Docs

# 특정 파드에 istio-proxy 에 Envoy 로그 레벨 확인
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- curl -X POST http://localhost:15000/logging
active loggers:
  ...
  http: warning
  http2: warning
...

# 로그 레벨 : trace > debug > info > warning/warn > error > critical > off

# 특정 컴포넌트 로그만 레벨 변경 : http 만 info 변경 >> testpc에서 curl 접속 후 로그 정보 확인
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- curl -X POST http://localhost:15000/logging?http=info

# 특정 컴포넌트 로그만 레벨 변경 : http 만 debug 변경 >> testpc에서 curl 접속 후 로그 정보 확인
kubectl exec -it deploy/deploy-websrv -c istio-proxy -- curl -X POST http://localhost:15000/logging?http=debug

 

istio-ingressgateway 에 istio-proxy 에도 로깅 변경 

kubectl exec -it deploy/istio-ingressgateway -n istio-system -- curl -X POST http://localhost:15000/logging
kubectl exec -it deploy/istio-ingressgateway -n istio-system -- curl -X POST http://localhost:15000/logging?http=debug
kubectl exec -it deploy/istio-ingressgateway -n istio-system -- curl -X POST http://localhost:15000/logging?http=info

 

(참고) istio-proxy 파드에 envoy 컨테이너 admin 페이지 접속

# istio-proxy 파드에 envoy 컨테이너 admin 접속 포트 포워딩 설정
kubectl port-forward deployment/deploy-websrv 15000:15000 &

# envoy 컨테이너 admin 페이지 접속
open http://localhost:15000

 

(참고) Istiod 상세 분석을 위해, ControlZ 웹 접속 후 제공 정보 확인 : istiod 디플로이먼트에 포트 포워딩 접속 - Docs

# istiod 디플로이먼트에 포트 포워딩 설정
kubectl port-forward deploy/istiod -n istio-system 9876:9876 &

# istiod ControlZ 페이지 접속
open http://localhost:9876

 

실습 리소스 삭제

kubectl delete gw test-gateway
kubectl delete vs nginx-service
kubectl delete deploy deploy-websrv
kubectl delete svc svc-clusterip
kubectl delete sa kans-nginx

 

6. Bookinfo & Addon 설치

Bookinfo + Istio GW/VS 설정 & Addon 설치 - Link

# myk8s-control-plane 진입 후 설치 진행
docker exec -it myk8s-control-plane bash
-----------------------------------
# Bookinfo 애플리케이션 배포
export ISTIOV=1.23.2
cat /istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f /istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml

# 확인 : 서비스 어카운트(sa)는 spiffe 에 svid 에 사용됨
kubectl get all,sa

# product 웹 접속 확인
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

# productpage 파드 로그
kubectl logs -l app=productpage -c istio-proxy --tail=-1
kubectl logs -l app=productpage -c productpage -f

# Istio Gateway/VirtualService 설정
cat istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f /istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml

# Istio Gateway/VirtualService 설정 확인
kubectl get gw,vs
istioctl proxy-status

 

# productpage 파드의 istio-proxy 로그 확인 Access log 가 출력 - Default access log format : 링크
kubectl logs -l app=productpage -c istio-proxy -f


# Addon 설치
## Install Kiali and the other addons and wait for them to be deployed. : Kiali dashboard, along with Prometheus, Grafana, and Jaeger.
tree /istio-$ISTIOV/samples/addons/
kubectl apply -f /istio-$ISTIOV/samples/addons # 디렉터리에 있는 모든 yaml 자원을 생성
kubectl rollout status deployment/kiali -n istio-system

# 확인
kubectl get all,sa,cm -n istio-system
kubectl get svc,ep -n istio-system

# NodePort 변경 및 nodeport 30001~30003으로 변경 : prometheus(30001), grafana(30002), kiali(30003)
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}]}}'

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

 

 

Prometheus , Grafana , Kiali 접속

# Prometheus 접속
open http://127.0.0.1:30001

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

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

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

7. Istio 를 통한 productpage 접속(반복) 테스트 & 웹 브라우저 접속 테스트

testppc 컨테이너

# testpc 컨테이너에서 접속 테스트
curl -v -s <각자 자신의 www 도메인>:30000
curl -v -s www.gasida.dev:30000/
curl -v -s www.gasida.dev:30000/productpage
curl -v -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>"

# 반복 접속 테스트
for i in {1..10};  do curl -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>" ; done
for i in {1..100};  do curl -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>" ; done
for i in {1..1000};  do curl -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>" ; done

while true; do curl -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 1; done
while true; do curl -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 0.5; done
while true; do curl -s www.gasida.dev:30000/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 0.1; done

macOS

# 자신의 mac 에서 접속 테스트
curl -v -s <각자 자신의 www 도메인>:30000
curl -v -s www.gasida.dev:30000/productpage
curl -v -s 127.0.0.1:30000/productpage

open http://www.gasida.dev:30000/productpage
open http://127.0.0.1:30000/productpage


# (위 접속이 잘 안될 경우) productpage 파드로 직접 port-forward 로 접속
kubectl port-forward deployment/productpage-v1 9080:9080 &
open http://127.0.0.1:9080
open http://127.0.0.1:9080/productpage

Kiali (키알리) 보기 설정

Namespace  default 로 선택 후 Graph (Traffic, Versioned app graph) 에서 Display 옵션 중 ‘Traffic Distribution’ 과 ‘Traffic Animation’ 활성화! , Security 체크 해보자 (Last 1m, Evety 10s)

 

9. Bookinfo 삭제 : addon은 남겨둠!

# myk8s-control-plane 진입 후 설치 진행
docker exec -it myk8s-control-plane bash
-----------------------------------
# Bookinfo 삭제
export ISTIOV=1.23.2
cd /istio-$ISTIOV/samples/bookinfo/platform/kube
./cleanup.sh
namespace ? [default] 엔터 입력

exit
-----------------------------------

 

 

참고자료

Istio 공식 문서 - 링크

 

Documentation

Learn how to deploy, use, and operate Istio.

istio.io

 

 

'IT > Container&k8s' 카테고리의 다른 글

AWS VPC CNI  (1) 2024.11.03
K8S Cilium CNI  (4) 2024.10.27
K8s Gateway API  (0) 2024.10.13
K8s Ingress(L7)  (6) 2024.10.13
K8S IPVS Proxy 모드  (3) 2024.10.05
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/04   »
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
글 보관함