home..

서비스 매시와 Istio

mont-kim Docker Container Pod Container Kubernetes Service

이번에는 서비스 매시와 ISTIO 에 대해 알아보는 시간을 갖겠습니다.

서비스 매시(Service Mesh)

등장 배경 : 마이크로서비스 아키텍처 환경의 시스템 전체 모니터링의 어려움,

운영 시 시스템 장애나 문제 발생할 때 원인과 병목 구간 찾기 어려움

image.png

클러스터의 트래픽 진입점인 Gateway 의 경우 모든 동작 처리의 비용이 크고, 통신의 제어가 어렵습니다

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

Pod 간의 통신 경로에 Proxy 를 통해 Traffic Monitoring, Traffic Control 을 가능하게 해줍니다.

기존 어플리케이션의 코드 수정없이 구성이 가능합니다.

  1. 기존 통신 환경

    1.png

  2. 애플리케이션 수정 없이, 모든 애플리케이션 통신 사이에 Proxy 를 두고 통신 해보자

    2.png

    • 파드 내에 사이드카 컨테이너로 주입되어서 동작
    • Proxy 컨테이너가 Application 트래픽을 Injection → iptables rule 구현합니다.
      • Sidecar 패턴으로 network 를 공유하여 iptables를 통해 트래픽을 가로챕니다.
  3. Proxy 는 결국 DataPlane 이니, 이를 중앙에서 관리하는 ControlPlane을 두고 중앙에서 관리를 하자

    3.png

    • Proxy 는 중앙에서 설정 관리가 잘되는 툴을 선택. 즉, 원격에서 동적인 설정 관리가 유연해야함 → 풍부한 API 지원이 필요 ⇒ Envoy
      • ‘구글 IBM 리프트(Lyft)’가 중심이 되어 개발하고 있는 오픈 소스 소프트웨어이며, C++ 로 구현된 고성능 Proxy 인 엔보이(Envoy)
      • 네트워크의 투명성을 목표, 다양한 필터체인 지원(L3/L4, HTTP L7), 동적 configuration API 제공, api 기반 hot reload 제공
    • 중앙에서 어떤 동작/설정을 관리해야 될까?
      • 라우팅, 보안 통신을 위한 mTLS 관련, 동기화 상태 정보 등
  • 트래픽 모니터링 : 요청의 ‘에러율, 레이턴시, 커넥션 개수, 요청 개수’ 등 메트릭 모니터링, 특정 서비스간 혹은 특정 요청 경로로 필터링 → 원인 파악 용이!
  • 트래픽 컨트롤 : 트래픽 시프팅(Traffic shifting), 서킷 브레이커(Circuit Breaker), 폴트 인젝션(Fault Injection), 속도 제한(Rate Limit)
    • 트래픽 시프팅(Traffic shifting) : 예시) 99% 기존앱 + 1% 신규앱 , 특정 단말/사용자는 신규앱에 전달하여 단계적으로 적용하는 카니리 배포 가능
    • 서킷 브레이커(Circuit Breaker) : 목적지 마이크로서비스에 문제가 있을 시 접속을 차단하고 출발지 마이크로서비스에 요청 에러를 반환 (연쇄 장애, 시스템 전제 장애 예방)
    • 폴트 인젝션(Fault Injection) : 의도적으로 요청을 지연 혹은 실패를 구현
    • 속도 제한(Rate Limit) : 요청 개수를 제한

About ISTIO

https://istio.io/latest/docs/ops/deployment/architecture/

  • Istio 구성요소와 envoy : 컨트롤 플레인(istiod) , 데이터 플레인(istio-proxy > envoy)
    • istiod : Pilot(데이터 플레인과 통신하면서 라우팅 규칙을 동기화, ADS), Gally(Istio 와 K8S 연동, Endpoint 갱신 등), Citadel(연결 암호화, 인증서관리 등)

      https://istio.io/latest/docs/concepts/security/

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

  • 이스티오는 각 파드 안에 사이드카엔보이 프록시가 들어가 있는 형태
  • 모든 마이크로서비스간 통신은 엔보이를 통과하여, 메트릭을 수집하거나 트래픽 컨트롤을 할 수 있음
  • 트래픽 컨트롤을 하기위해 엔보이 프록시에 전송 룰을 설정 → 컨트롤 플레인이스티오가 정의된 정보를 기반으로 엔보이 설정을 하게 함
  • 마이크로서비스 간의 통신을 mutual TLS 인증(mTLS)으로 서로 TLS 인증으로 암호화 할 수 있음
  • 각 애플리케이션은 파드 내의 엔보이 프록시에 접속하기 위해 localhost 에 TCP 접속을 함

Envoy

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

KANS(Kubernetes Advanced NeStudy) 3기 [6주차] - Envoy Proxy & Gateway API

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

[https://blog.naver.com/alice_k106/222000680202](https://blog.naver.com/alice_k106/222000680202)

https://blog.naver.com/alice_k106/222000680202

https://www.envoyproxy.io/docs/envoy/latest/intro/life_of_a_request

Envoy Components

  • Cluster: 요청을 전달할 엔드포인트들의 논리적 그룹.
  • Downstream: Envoy에 연결하는 클라이언트 또는 애플리케이션.
  • Endpoints: 클러스터 내에서 서비스를 제공하는 네트워크 노드들.
  • Filter: 요청을 처리하는 개별 모듈.
  • Filter chain: 여러 필터로 구성된 처리 체인.
  • Listeners: IP/포트에 바인딩하여 연결을 수락하고 처리하는 모듈.
  • Upstream: Envoy가 요청을 전달하는 엔드포인트, 보통 백엔드 서버.

Envoy 구성을 관리하기 위해 API 기반의 관리가 가능합니다.

image.png

  • Service Mesh 솔루션이나, Gateway API 구현체들을 Enovy를 내부적으로 사용하고 있으며, Envoy가 제공하는 동적 구성을 위한 API (xDS Sync API)를 이용하여 다양한 네트워크 정책을 구성하게 됩니다.

Envoy의 xDS Sync API는 아래와 같은 레이어에서 동작하게 됩니다.

  • LDS - Listener Discovery Service
  • RDS - Route Discovery Service
  • CDS - Cluseter Discovery Service
  • EDS - Endpoint Discovery Service

[https://blog.naver.com/yu3papa/223614975957](https://blog.naver.com/yu3papa/223614975957)

https://blog.naver.com/yu3papa/223614975957

CleanSh.png

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 focal 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 실습

Reference : 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

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

# 외부 접속 정보 출력
echo -e "http://$(curl -s ipinfo.io/ip):10000"
--------------------
# 자신의 PC 웹브라우저에서 외부 접속 정보 접속 확인!

# 연결 정보 확인
ss -tnp

# (터미널1) envoy 실행 취소(CTRL+C) 후 (관리자페이지) 설정 덮어쓰기 - [링크](https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/run-envoy#override-the-default-configuration)
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"

image.png

ISTIO Installation

Istio는 Docs 기반의 해석이 제일 정확합니다 Docs

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

https://istio.io/latest/docs/setup/install/operator/

Operator 기반의 Istio 설치는 이제 Derprecated 되었습니다. 1.23.x 버전 이상으로 업그레이드를 지원하지 않습니다

![https://istio.io/latest/docs/setup/additional-setup/config-profiles/

[config-profiles]](images/KANS/week7/part1/CleanShot_2024-10-13_at_14.23.09.png)

https://istio.io/latest/docs/setup/additional-setup/config-profiles/

# 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

# (default 프로파일) 컨트롤 플레인 배포 - [링크](https://istio.io/latest/docs/setup/additional-setup/config-profiles/) [Customizin](https://istio.io/latest/docs/setup/additional-setup/customize-installation/)g
istioctl profile dump demo > demo-profile.yaml

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

istioctl install -f demo-profile.yaml

image.png


# 설치 확인 : istiod, istio-ingressgateway
kubectl get all,svc,ep,sa,cm,secret -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

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

# istio-ingressgateway 디플로이먼트 정보 확인
kubectl exec -it deployment.apps/istiod -n istio-system -- ps -ef

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

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

image.png

설치된 istio ingress gateway들의 network 정보들을 조회해봅니다.

istio-ingressgateway 와 기존 Ingress(구현체) 혹은 GatewayAPI(구현체) 와 어떤 차이점이 있을까요?

  • 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
...

CleanSpng

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

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=31973

## 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

  • testpc
# 아래 변수는 각자 자신의 값을 직접 입력 할 것
IGWHTTP=31973
export MYDOMAIN=montkim.org
# istio ingress gw 접속 테스트 : 아직은 설정이 없어서 접속 실패가 된다
curl -v -s $MYDOMAIN:$IGWHTTP
  • 자신의 PC
# 아래 변수는 각자 자신의 값을 직접 입력 할 것 : ISTIONODEIP는 3개의 노드 중 아무거나 입력
IGWHTTP=31973
ISTIONODEIP=3.36.127.106
MYDOMAIN=www.gasida.dev
echo "$ISTIONODEIP $MYDOMAIN" | sudo tee -a /etc/hosts

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

image.png

아직은 해당 Traffic을 처리할 다른 방법들이 존재하지 않아, 처리가 불가능한 상태입니다.

timeout이 발생하네요.

그렇다면 istio를 외부노출해서 연결을 마저 진행해보도록 하겠습니다.

Istio 외부노출

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

# 로그 모니터링
kubectl get pod -n istio-system -l app=istiod
kubetail -n istio-system -l app=istiod -f
kubetail -n istio-system -l app=istio-ingressgateway -f
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-websrv
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      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
# 사이드카 컨테이너 배포 확인
kubectl get pod,svc -o wide
kc describe pod

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

  • 클라이언트 PC → Istio ingressgateway 파드 → (Gateway, VirtualService, Service 는 Bypass) → Endpoint(파드 : 사이드카 - Nginx)
  • Gateway : 지정한 인그레스 게이트웨이로부터 트래픽이 인입, 프로토콜 및 포트, HOSTS, Proxy 등 설정 가능

    https://istio.io/latest/docs/setup/additional-setup/gateway/

  • VirtualService : 인입 처리할 hosts 설정, L7 PATH 별 라우팅, 목적지에 대한 정책 설정 가능 (envoy route config)
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.gasida.dev"]   4m9s

image.png

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

  • 외부(자신의PC, testpc)에서 접속 테스트
# istio ingress gw 를 통한 접속 테스트
curl -s $MYDOMAIN:$IGWHTTP | grep -o "<title>.*</title>"
curl -v -s $MYDOMAIN:$IGWHTTP

image.png

  • 출력 로그 정보 확인

image.png

  • 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

istio-proxy

istio-proxy

Istio

Istio

(심화 옵션) debug : 파드 디버깅

#
kubectl get pod
kc describe pod

# 방안1 : 파드의 복제본을 이용
kubectl debug $(kubectl get pod -l app=deploy-websrv -oname) -it --image=nicolaka/netshoot -c netdebug --share-processes --copy-to=websrv-debug --profile='sysadmin'
-----
ip -c addr
curl localhost

ps axf

exit
-----
kubectl delete pod websrv-debug

image.png

# 방안2 : 파드 내 컨테이너 삽입
kubectl debug $(kubectl get pod -l app=deploy-websrv -oname) -it --image=nicolaka/netshoot -c netdebug --profile='netadmin'
-----
ip -c addr
curl localhost
ps axf

exit
-----

image.png

  • (심화 옵션) IPC & UDS 관련 정보 링크 - UDS 소개2 IPC방법들

    4.png

    • Istio - Envoy xDS (x Discovery Service, Dynamic API Configuration) - 링크
      • 동적으로 각 영역의 설정을 로드하는 방법
      • Management 서비스(Istiod)와 통신하면서 configuration갱신 : Istod - [Istop-proxy ↔ envoy]
      • gRPC, REST 방식 모두 지원
      • CDS(Clusters) , LDS(Listeners) , EDS(Endpoints), RDS(Routes) → Discovery Service ⇒ ADS (Aggregation Discovery Service) ↔ Istiod
        # proxy 상태 확인
        istioctl proxy-status
        NAME                                                   CLUSTER        CDS               LDS               EDS              RDS               ECDS        ISTIOD                      VERSION
        deploy-websrv-7d7cf8586c-tvzk6.default                 Kubernetes     SYNCED (55s)      SYNCED (55s)      SYNCED (55s)     SYNCED (55s)      IGNORED     istiod-7f8b586864-mv944     1.23.2
        istio-ingressgateway-5f9f654d46-c4g7s.istio-system     Kubernetes     SYNCED (4m1s)     SYNCED (4m1s)     SYNCED (55s)     SYNCED (4m1s)     IGNORED     istiod-7f8b586864-mv944     1.23.2
        ...
      
      • ADS 를 통해 다양한 타입의 리소스싱글 스트림에서 해결

      Untitled

    • Istio - Istio proxy 와 Envoy 프로세스간 ‘유닉스 도메인 소켓 통신’ 환경을 실습으로 확인

        # 파드 확인
        kubectl get pod
              
        # istio 컨테이너 접속
        kubectl exec -it deploy/deploy-websrv -c istio-proxy -- bash
        ---------------------------------------------------------------
        # ~~SDS~~, XDS 는 소켓 타입
        ls -al /etc/istio/proxy
        total 28
        drwxrwsrwt 2 root        istio-proxy   120 Dec 13 13:03 .
        drwxr-xr-x 1 root        root         4096 Dec 13 13:03 ..
        srw-rw-rw- 1 istio-proxy istio-proxy     0 Dec 13 13:03 SDS
        srw-rw-rw- 1 istio-proxy istio-proxy     0 Dec 13 13:03 XDS
        -rw-r--r-- 1 istio-proxy istio-proxy 17409 Dec 13 13:03 envoy-rev.json
        -rw-r--r-- 1 istio-proxy istio-proxy  2967 Dec 13 13:03 grpc-bootstrap.json
              
        # .json 파일 확인
        more /etc/istio/proxy/envoy-rev.json
              
        # display only Unix domain sockets : Listener 과 ESTAB 상태 정보 확인
        ss -xpl
        Netid   State    Recv-Q   Send-Q            Local Address:Port         Peer Address:Port   Process
        u_str   LISTEN   0        4096        etc/istio/proxy/SDS 446191                  * 0       users:(("pilot-agent",pid=1,fd=13))
        u_str   LISTEN   0        4096        etc/istio/proxy/XDS 446192                  * 0       users:(("pilot-agent",pid=1,fd=14))
              
        ss -xp
        Netid   State   Recv-Q   Send-Q           Local Address:Port         Peer Address:Port     Process
        u_str   ESTAB   0        0          etc/istio/proxy/XDS 446483                  * 446482    users:(("pilot-agent",pid=1,fd=16))
        u_str   ESTAB   0        0          etc/istio/proxy/SDS 446267                  * 446266    users:(("pilot-agent",pid=1,fd=18))
        u_str   ESTAB   0        0                            * 446482                  * 446483    users:(("envoy",pid=16,fd=20))
        u_str   ESTAB   0        0                            * 446266                  * 446267    users:(("envoy",pid=16,fd=19))
              
        # display only TCP sockets and display only IP version 4 sockets
        ss -4tpl
      
  • 삭제

kubectl delete gw,vs,deploy,svc --all

Bookinfo로 알아보는 Istio 기능

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

image.png

  • ProductPage 페이지에서 요청을 받으면, 도서 리뷰를 보여주는 Reviews 서비스와 도서 상세 정보를 보여주는 Details 서비스에 접속하고,
  • ProductPage 는 ReviewsDetails 결과를 사용자에게 응답한다.
  • Reviews 서비스는 v1, v2, v3 세 개의 버전이 있고 v2, v3 버전의 경우 Ratings 서비스의 도서에 대한 5단계 평가를 가져옴.
  • Reviews 서비스의 차이는, v1은 Rating 이 없고, v2는 검은색 별로 Ratings 가 표시되며, v3는 색깔이 있는 별로 Ratings 가 표시됨.
  • (도서 참고 정보) 실수연발 (셰익스피어) Wikipedia

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

[출처] [https://tisdev.tistory.com/2](https://tisdev.tistory.com/2)

[출처] https://tisdev.tistory.com/2


# 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

image.png

Network Traffic 인입 설정

Istio Gateway/VirtualService 설정

bookinfo-gateway.yaml

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  # The selector matches the ingress gateway pod labels.
  # If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 8080
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
# Istio Gateway/VirtualService 설정
kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/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 : [링크](https://istio.io/latest/docs/tasks/observability/logs/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
      31973
        
      # 접속 확인
      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 에서 웹 브라우저를 통해서 http://:NodePort/productpage 로 접속 후 새로고침 해보자 → ReviewsRatings 변경 확인!

image.png

image.png

image.png

Monitoring

Blog

Kiali

metric from Prometheus & Jaeger

  • 링크 링크2 링크3

  • Kiali is an observability console for Istio with service mesh configuration and validation capabilities. Kiali provides detailed metrics and a basic Grafana integration, which can be used for advanced queries. Distributed tracing is provided by integration with Jaeger.
    • Jaeger 와 연동을 통해서 분산 트레이싱을 제공할 수 있다
  • Monitoring port of the IstioD pod : Kiali connects directly to the IstioD pod (not the Service) to check for its health. By default, the connection is done to port 15014 which is the default monitoring port of the IstioD pod.
    • 파드의 헬스체크는 Kiali 가 직접 IstioD 파드에 TCP Port 15014 를 통해서 체크한다
  • Prometheus, Jaeger and Grafana - 링크 Prometheus and Jaeger are primary data sources for Kiali. This page describes how to configure Kiali to communicate with these dependencies. A minimalistic Grafana integration is also available.
    • 주 데이터 소스는 Prometheus and Jaeger 이며, 최소 수준의 Grafana 와 연동할 수 있다

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 $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 $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 $PROMENodePort
  • 프로메테우스 : Targets - 파드 별로 tcp 15020 에 /stats/prometheus

image.png

image.png

image.png

수집되는 관련 메트릭들을 확인 할 수 있습니다.

그라파나에서도 기본적으로 import 된 istio의 7개 대시보드가 존재합니다.

image.png

image.png

자신의 PC 에서 웹 브라우저를 통해서 KAILI 웹 접속 해보자!

image.png

Kiali (키알리) 대시보드 둘러보기 - 링크

  • Namespacedefault 로 선택 후 Graph (Traffic, Versioned app graph) 에서 Display 옵션 중 ‘Traffic Distribution’ 과 ‘Traffic Animation’ 활성화! , Security 체크 해보자 (Last 1m, Evety 10s) Last 5m
  • k8s-rtr 에서 트래픽 요청 간격을 조절해보자 (1초, 0.5초, 0.3초, 0.1초)
testpc 에서 아래 실행
# 반복 접속 테스트
while true; do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 1; done
while true; do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 0.1; done
while true; do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; echo "--------------" ; sleep 0.5; done
for i in {1..100};  do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; done
for i in {1..1000}; do curl -s $MYDOMAIN:$IGWHTTP/productpage | grep -o "<title>.*</title>" ; done
  • ApplicationsServices 측면에서의 정보를 확인해보자
  • Workloads 에서 Logs(istio-proxy, app) 를 확인할 수 있고, Envoy 관련 설정 정보(Clusters, Listeners, Routes, Config 등)를 편리하게 볼 수 있다

image.png

  • Istio Config 에서 Istio 관련 설정을 볼 수 있고, Action 으로 Istio 관련 오브젝트를 설정/삭제 할 수 있다

  • 레밍즈(Lemmings) 게임의 커스텀 맵으로 Bookinfo Kiali 대시보드 화면을 꾸며주셨네요! - 링크 레밍즈포럼 도커컴포즈배포

Traffic Management

트래픽 컨트롤은 VirtualServiceDestinationRule 설정을 통해서 동작합니다.

개념 및 Reference - Concepts 링크

https://faun.pub/on-premise-to-cloud-migration-mock-drills-using-istio-ea89aee5ea38

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

  • Gateway : 지정한 인그레스 게이트웨이로부터 트래픽이 인입, 프로토콜 및 포트, HOSTS, Proxy 등 설정 가능
  • VirtualService : 인입 처리할 hosts 설정, L7 PATH 별 라우팅, 목적지에 대한 정책 설정 가능 (envoy route config) - 링크

사용 예시 : 헤더 매칭에 따라서, 각기 다른 destination 으로 라우팅

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3
  • VirtualService 는 DestinationRule 에서 설정된 서브셋(subset)을 사용하여 트래픽 컨트롤을 할 수 있다
  • hosts 필드 : 목적지 주소 - IP address, a DNS name (FQDN), 혹은 k8s svc 이름 , wildcard (”*”) prefixes
  • Routing rules : HTTP 경우 - Match 필드(예, 헤더) , Destination(istio/envoy 에 등록된 대상, subnet 에 DestinationRule 활용)
  • HTTPRoute : redirect , rewrite , fault(장애 주입) , mirror(복제, 기본 100%) , corsPolicy(CORS 삽입) , headers(헤더 조작) 등 - 링크
  • Routing rule precedence : Routing rules are evaluated in sequential order from top to bottom - 위에서 순차적 적용
  • DestinationRule : 실제 도착지(서비스와 1:1 연결)의 정교한 정책(부하분산, 연결 옵션, 서킷 브레이크, TLS 등)을 설정 - 링크

    사용 예시 : 3개의 subsets for the my-svc destination service 에 3개의 subsets 이 있고, 이중 v1/v3 은 RAMDOM 이고 v2 는 ROUND_ROBIN

      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      metadata:
        name: my-destination-rule
      spec:
        host: my-svc
        trafficPolicy:
          loadBalancer:
            simple: RANDOM
        subsets:
        - name: v1
          labels:
            version: v1
        - name: v2
          labels:
            version: v2
          trafficPolicy:
            loadBalancer:
              simple: ROUND_ROBIN
        - name: v3
          labels:
            version: v3
    
  • Load balancing options : Round robin(기본값) , Random , Weighted , Least requests - 링크
  • Destination Rule : TrafficPolicy , Subset , ConnectionPoolSettings 등 - 링크
  • 서브셋(subsets)을 정의할 수 있어 마이크로서비스 버전별로 라우팅할 때 사용한다

Request Routing - 링크

실습 전 기본 DestinationRule 적용 : 각각의 파드에 subset 지정

# 샘플 파일들 확인
cd ~/istio-$ISTIOV/samples/bookinfo/networking
tree

# 기본 DestinationRule 적용
kubectl apply -f destination-rule-all.yaml

# DestinationRule 확인 dr(=destinationrules) : KIALI Services 확인 시 GW, VS, DR 확인

image.png

image.png

virtual-service-all-v1.yaml : 4개 서비스 모두 v1 의 서브셋(subset) 에 전송하는 정책 테스트

virtual-service-all-v1.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - route:
    - destination:
        host: details
        subset: v1
---
# istio vs(virtualservices) 확인
kubectl get vs
NAME       GATEWAYS               HOSTS   AGE
bookinfo   ["bookinfo-gateway"]   ["*"]   85m

# 모든 마이크로서비스에 대해 v1 의 서브셋(subset) 에 전송되게 virtualservices 적용
kubectl apply -f virtual-service-all-v1.yaml

# istio vs(virtualservices) 확인 >> KIALI 에서 reviews v2,v3 향하는 트래픽 경로가 사라진다!
kubectl get virtualservices
NAME          GATEWAYS               HOSTS             AGE
bookinfo      ["bookinfo-gateway"]   ["*"]             85m
details                              ["details"]       9s
productpage                          ["productpage"]   9s
ratings                              ["ratings"]       9s
reviews                              ["reviews"]       9s

image.png

image.png

  • 웹 브라우저에서 productpage 로 접속 후 새로 고침 시 v1으로만 라우팅되는것을 확인 할 수 있습니다.

virtual-service-reviews-test-v2.yaml : User Identity 기반 라우팅, end-user 커스텀 헤더에 jason 매칭 시 reviews v2 로 전달

virtual-service-reviews-test-v2.yaml : match 설정이 위에 배치되어 있다

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
  • Match 조건에는 완전 일치(exact) , 전방 일치(prefix) , 정규 표현(regex) - 3가지 패턴을 선택할 수 있다
# 모든 마이크로서비스에 대해 v1 의 서브셋(subset) 에 전송되게 virtualservices 적용
kubectl apply -f virtual-service-reviews-test-v2.yaml

# jason 로그인 시 로그 확인
kubetail -l app=productpage -f
  • 웹 브라우저에서 productpage 로 접속 후 새로 고침 해보자 → 출력 내용 확인
  • 웹 브라우저에서 productpage 오른쪽 상단에 Sign in 클릭 후 jason 과 암호(아무거나) 입력 → 새로고침 출력 내용 확인 ⇒ sign out 시 출력 내용 확인

스크린샷.png

image.png

jason으로 로그인한 트래픽이 다음과같이 라우팅 분기가 된걸 확인 할 수 있습니다.

  • 실습 완료 후 virtualservices 삭제 kubectl delete -f virtual-service-all-v1.yaml ← 아래 실습과 이어짐

Fault Injection (HTTP 결함 주입) - 의도적으로 지연(Latency)를 발생시키거나 중단 - 링크

virtual-service-ratings-test-delay.yaml : end-user 가 jason 는 ratings v1 에 7초 지연 발생, 그외 사용자는 ratings v1 정상 연결

  • virtual-service-ratings-test-delay.yaml

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: ratings
      spec:
        hosts:
        - ratings
        http:
        - match:
          - headers:
              end-user:
                exact: jason
          fault:
            delay:
              percentage:
                value: 100.0
              fixedDelay: 7s
          route:
          - destination:
              host: ratings
              subset: v1
        - route:
          - destination:
              host: ratings
              subset: v1
    
# virtualservices 적용
kubectl apply -f virtual-service-ratings-test-delay.yaml

# 로그 확인 : product 입장에서 접속 사용자(clinet) 연결을 끊어버림 0 DC downstream_remote_disconnect
kubetail -l app=productpage -f
  • 웹 브라우저에서 productpage 오른쪽 상단에 Sign in 클릭 후 jason 과 암호(아무거나) 입력 → 출력 내용 확인 ⇒ 새로 고침 ⇒ sign out 시 출력 내용 확인

image.png

Jason은 Review 조회 권한이 없어 입구컷을 당했습니다…

  • 크롬 → 개발자 도구 → Network : 새로 고침 시 아래 productpage 6초 Time 확인

image.png

  • KIALI 에서 상태 확인 , Flags (DC) - 링크

image.png

  • Flags 확인연결 링크를 클릭하자
  • Untitled

virtual-service-ratings-test-abort.yaml : end-user 가 jason 는 ratings v1 에 500 에러 리턴, 그외 사용자는 ratings v1 정상 연결

virtual-service-ratings-test-abort.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      abort:
        percentage:
          value: 100.0
        httpStatus: 500
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
# virtualservices 적용
kubectl apply -f virtual-service-ratings-test-abort.yaml

# 로그 확인
kubetail -l version=v2 -f
  • 웹 브라우저에서 productpage 오른쪽 상단에 Sign in 클릭 후 jason 과 암호(아무거나) 입력 → 출력 내용 확인 ⇒ 새로 고침 ⇒ sign out 시 출력 내용 확인

image.png

  • KIALI 에서 상태 확인 , Flags (DC) - 링크

image.png

  • 실습 완료 후 virtualservices 삭제 kubectl delete -f virtual-service-all-v1.yaml

Traffic Shifting (트래픽 전환) : 카나라 배포 전략 등 활용 - 링크

기본 virtualservices 설정 kubectl apply -f virtual-service-all-v1.yaml

virtual-service-reviews-50-v3.yaml : 가중치 (weight-based routing), reviews 에 v1(50%), v3(50%)

  • virtual-service-reviews-50-v3.yaml : 웹 브라우저 새로 고침 확인

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: reviews
      spec:
        hosts:
          - reviews
        http:
        - route:
          - destination:
              host: reviews
              subset: v1
            weight: 50
          - destination:
              host: reviews
              subset: v3
            weight: 50
    
# virtualservices 적용
kubectl apply -f virtual-service-reviews-50-v3.yaml

image.png

virtual-service-reviews-80-20.yaml : 가중치 (weight-based routing), reviews 에 v1(80%), v2(20%)

  • virtual-service-reviews-80-20.yaml : 웹 브라우저 새로 고침 확인

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: reviews
      spec:
        hosts:
          - reviews
        http:
        - route:
          - destination:
              host: reviews
              subset: v1
            weight: 80
          - destination:
              host: reviews
              subset: v2
            weight: 20
    
# virtualservices 적용
kubectl apply -f virtual-service-reviews-80-20.yaml

image.png

virtual-service-reviews-90-10.yaml : 가중치 (weight-based routing), reviews 에 v1(90%), v2(10%)

  • virtual-service-reviews-90-10.yaml : 웹 브라우저 새로 고침 확인

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: reviews
      spec:
        hosts:
          - reviews
        http:
        - route:
          - destination:
              host: reviews
              subset: v1
            weight: 90
          - destination:
              host: reviews
              subset: v2
            weight: 10
    
# virtualservices 적용
kubectl apply -f virtual-service-reviews-90-10.yaml

image.png

실습 완료 후 virtualservices 삭제 kubectl delete -f virtual-service-all-v1.yaml

Request Timeouts (타임아웃 제어) - 링크

  • 기본 virtualservices 설정

      cd ~/istio-$ISTIOV/samples/bookinfo/networking
      kubectl apply -f virtual-service-all-v1.yaml
    
  • 기본적으로 HTTP request timeout is disabled 이지만, 설정(override) 가능하다

Route requests to v2 of the reviews service Add a 2 second delay to calls to the ratings service (2초 지연 설정)

# reviews service 는 reviews v2 만 호출 설정
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
EOF

# ratings service 호출 시 2초 지연 설정 >> 가장 끝단에서 장애 상황이라고 재연 >> 앞단의 모든 서비스가 영향을 받는다
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percent: 100
        fixedDelay: 2s
    route:
    - destination:
        host: ratings
        subset: v1
EOF

2초

2초 지연 후 정상 출력 확인

Trace

Trace 에서 2초 지연 확인

  • http timeout 0.5초 설정하지만, 응답 1초 걸리는 이유는, productpage 코드에 reviews 호출 시 timeout 되면 한번 더 재시도하게끔 하드 코딩되어 있음

      # http timeout 0.5초 설정
      kubectl apply -f - <<EOF
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: reviews
      spec:
        hosts:
        - reviews
        http:
        - route:
          - destination:
              host: reviews
              subset: v2
          timeout: 0.5s
      EOF
    
    • 각각 KIALI 와 웹 브라우저 접속하여 상태를 확인해보자

    스크린샷.png

  • http timeout 제한 설정 후, 실제 timeout 시 고객측에는 별도 “페이지”를 출력해줄 수 있습니다.
  • 경로 이외에 요청별로 timeout 설정도 가능합니다
    • a per-request basis if the application adds an x-envoy-upstream-rq-timeout-ms header on outbound requests
  • 실습 완료 후 virtualservices 삭제 kubectl delete -f virtual-service-all-v1.yaml

Circuit Breaking 테스트를 위한 httpbin 배포 : A simple HTTP Request & Response Service - 링크

# httpbin 배포
kubectl apply -f ~/istio-$ISTIOV/samples/httpbin/httpbin-nodeport.yaml

# httpbin service 접속 : 마스터/워커 노드에서 시도
CIP=$(kubectl get svc httpbin -o jsonpath={.spec.clusterIP})
curl -s $CIP:8000 | grep -o "<title>.*</title>"
curl -s $CIP:8000/html
curl -s $CIP:8000/status/500 -v

time curl -s $CIP:8000/delay/5
real	0m5.013s
user	0m0.004s
sys	0m0.004s

# httpbin 웹 접속 주소 확인
HTTPBHostIP=$(kubectl get pod -l app=httpbin -o jsonpath='{.items[0].status.hostIP}')
HTTPBNodePort=$(kubectl get svc httpbin -o jsonpath={.spec.ports[0].nodePort})
echo -e "HTTPBIN UI URL = http://$HTTPBHostIP:$HTTPBNodePort"

# (옵션) 로그 확인
kubetail -l app=httpbin

Untitled

Circuit Breaking (장애로 인한 영향 확산 차단) - 링크 한글 → httpbin 동작 오류로 실습은 skip

  1. Configuring the circuit breaker (타켓 서비스 준비)
    • connectionPool : TCP 최대 연결 1개, HTTP 연결당 요청 1개(keepalive disable), 요청 대기 최대 1개
    • 1초 간격(interval: 1s) 응답 탐지하고 연속으로 1회 에러(consecutive5xxErrors: 1)가 발생하면 3분간(baseEjectionTime: 3m) Circuit break 합니다
     # Create a destination rule to apply circuit breaking settings when calling the httpbin service
     kubectl apply -f - <<EOF
     apiVersion: networking.istio.io/v1alpha3
     kind: DestinationRule
     metadata:
       name: httpbin
     spec:
       host: httpbin
       trafficPolicy:
         connectionPool:
           tcp:
             maxConnections: 1
           http:
             http1MaxPendingRequests: 1
             maxRequestsPerConnection: 1  # keepalive disable
         outlierDetection:
           consecutive5xxErrors: 1
           interval: 1s
           baseEjectionTime: 3m
           maxEjectionPercent: 100
     EOF
        
     # 확인
     kubectl get destinationrule httpbin -o yaml
    
  2. Adding a client : httpbin 서비스로 트래픽을 보낼 부하 테스트 클라이언트 배포 fortio (Istio 코인 탑승) - 링크

     # fortio 배포
     kubectl apply -f ~/istio-$ISTIO_VERSION/samples/httpbin/sample-client/fortio-deploy.yaml
     kubectl patch svc fortio -p '{"spec":{"type":"NodePort"}}'
        
     # Log in to the client pod and use the fortio tool to call httpbin. Pass in curl to indicate that you just want to make one call
     export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}')
     kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio curl -quiet http://httpbin:8000/get
        
     # (옵션) fortio control UI Web 접속 주소 확인
     FORTIOHostIP=$(kubectl get pod -l app=fortio -o jsonpath='{.items[0].status.hostIP}')
     FORTIONodePort=$(kubectl get svc fortio -o jsonpath={.spec.ports[0].nodePort})
     echo -e "FORTIO UI URL = http://$FORTIOHostIP:$FORTIONodePort/fortio"
    

    Untitled

  3. Tripping the circuit breaker
    • In the DestinationRule settings, you specified maxConnections: 1 and http1MaxPendingRequests: 1

    [http://itnp.kr/post/istio-circuit-break](http://itnp.kr/post/istio-circuit-break)

    http://itnp.kr/post/istio-circuit-break

     # Call the service with two concurrent connections (-c 2) and send 20 requests (-n 20)
     kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
     Code 200 : 13 (65.0 %)
     Code 503 : 7 (35.0 %)
        
     # Bring the number of concurrent connections up to 3 x10번 정도 반복
     kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://httpbin:8000/get
     Code 200 : 14 (46.7 %)
     Code 503 : 16 (53.3 %)
        
     # Query the istio-proxy stats to see more
     kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep httpbin | grep pending
     cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.default.remaining_pending: 1
     cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
     cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
     cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_active: 0
     cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
     cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_overflow: 75 # 서킷브레이크로 넘친것
     cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_total: 71
    

    Untitled

  4. 삭제

     kubectl delete destinationrule httpbin
     kubectl delete deploy httpbin fortio-deploy
     kubectl delete svc httpbin fortio
    

TCP Traffic Shifting : TCP 트래픽을 비중에 따라 처리 - 링크

Set up the test environment

# istio-injection 설정
kubectl create namespace istio-io-tcp-traffic-shifting
kubectl label namespace istio-io-tcp-traffic-shifting istio-injection=enabled

# 모니터링
watch -d 'kubectl get pod -owide -n istio-io-tcp-traffic-shifting;echo;kubectl get svc -n istio-io-tcp-traffic-shifting'

# (Simple sleep service - [링크](https://github.com/istio/istio/tree/release-1.13/samples/sleep)) Deploy the sleep sample app to use as a test source for sending requests.
kubectl apply -f ~/istio-$ISTIO_VERSION/samples/sleep/sleep.yaml -n istio-io-tcp-traffic-shifting

# Deploy the v1 and v2 versions of the tcp-echo microservice.
kubectl apply -f ~/istio-$ISTIO_VERSION/samples/tcp-echo/tcp-echo-services.yaml -n istio-io-tcp-traffic-shifting

Apply weight-based TCP routing

# Route all TCP traffic to the v1 version of the tcp-echo microservice.
 kubectl apply -f ~/istio-$ISTIO_VERSION/samples/tcp-echo/tcp-echo-all-v1.yaml -n istio-io-tcp-traffic-shifting

# TCP Ingress Port - [링크](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/#determining-the-ingress-ip-and-ports)
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].nodePort}')

# Confirm that the tcp-echo service is up and running by sending some TCP traffic from the sleep client.
for i in {1..20}; do \
kubectl exec "$(kubectl get pod -l app=sleep -n istio-io-tcp-traffic-shifting -o jsonpath={.items..metadata.name})" \
-c sleep -n istio-io-tcp-traffic-shifting -- sh -c "(date; sleep 1) | nc $INGRESS_HOST $TCP_INGRESS_PORT"; \
done

## 아래 그림 처럼 v1 으로 접속됨
## You should notice that all the timestamps have a prefix of one,
## which means that all traffic was routed to the v1 version of the tcp-echo service.
one Sun Feb 13 10:42:20 UTC 2022
one Sun Feb 13 10:42:22 UTC 2022
one Sun Feb 13 10:42:23 UTC 2022

kiali 에 Namespace 를 istio-io-tcp-traffic-shifting 선택

kiali 에 Namespace 를 istio-io-tcp-traffic-shifting 선택

# Transfer 20% of the traffic from tcp-echo:v1 to tcp-echo:v2 with the following command:
kubectl apply -f ~/istio-$ISTIO_VERSION/samples/tcp-echo/tcp-echo-20-v2.yaml -n istio-io-tcp-traffic-shifting
 
# 20는 v2 로 접속
# Confirm that the tcp-echo service is up and running by sending some TCP traffic from the sleep client.
for i in {1..20}; do \
kubectl exec "$(kubectl get pod -l app=sleep -n istio-io-tcp-traffic-shifting -o jsonpath={.items..metadata.name})" \
-c sleep -n istio-io-tcp-traffic-shifting -- sh -c "(date; sleep 1) | nc $INGRESS_HOST $TCP_INGRESS_PORT"; \
done
one Sun Feb 13 10:45:33 UTC 2022
two Sun Feb 13 10:45:34 UTC 2022
one Sun Feb 13 10:45:35 UTC 2022
one Sun Feb 13 10:45:36 UTC 2022
one Sun Feb 13 10:45:38 UTC 2022
one Sun Feb 13 10:45:39 UTC 2022
one Sun Feb 13 10:45:40 UTC 2022
one Sun Feb 13 10:45:41 UTC 2022
one Sun Feb 13 10:45:42 UTC 2022
one Sun Feb 13 10:45:44 UTC 2022
one Sun Feb 13 10:45:45 UTC 2022
two Sun Feb 13 10:45:46 UTC 2022
two Sun Feb 13 10:45:47 UTC 2022
one Sun Feb 13 10:45:48 UTC 2022
one Sun Feb 13 10:45:50 UTC 2022
two Sun Feb 13 10:45:51 UTC 2022
one Sun Feb 13 10:45:52 UTC 2022
one Sun Feb 13 10:45:53 UTC 2022
one Sun Feb 13 10:45:55 UTC 2022
one Sun Feb 13 10:45:56 UTC 2022

# 확인
kubectl get virtualservice tcp-echo -o yaml -n istio-io-tcp-traffic-shifting
...
spec:
  gateways:
  - tcp-echo-gateway
  hosts:
  - '*'
  tcp:
  - match:
    - port: 31400
    route:
    - destination:
        host: tcp-echo
        port:
          number: 9000
        subset: v1
      weight: 80
    - destination:
        host: tcp-echo
        port:
          number: 9000
        subset: v2
      weight: 20

# Send some more TCP traffic to the tcp-echo microservice.
for i in {1..20}; do \
kubectl exec "$(kubectl get pod -l app=sleep -n istio-io-tcp-traffic-shifting -o jsonpath={.items..metadata.name})" \
-c sleep -n istio-io-tcp-traffic-shifting -- sh -c "(date; sleep 1) | nc $INGRESS_HOST $TCP_INGRESS_PORT"; \
done

Untitled

삭제

kubectl delete -f ~/istio-$ISTIO_VERSION/samples/tcp-echo/tcp-echo-all-v1.yaml -n istio-io-tcp-traffic-shifting
kubectl delete -f ~/istio-$ISTIO_VERSION/samples/tcp-echo/tcp-echo-services.yaml -n istio-io-tcp-traffic-shifting
kubectl delete -f ~/istio-$ISTIO_VERSION/samples/sleep/sleep.yaml -n istio-io-tcp-traffic-shifting
kubectl delete namespace istio-io-tcp-traffic-shifting
  • 그외 기능 : 재시도 제어, 요청 헤더 추가, 응답 헤더 삭제, 리다이렉트(Redirect), 재작성(Rewrite)
  • Bookinfo 삭제

      # Bookinfo 삭제
      cd ~/istio-$ISTIOV/samples/bookinfo/platform/kube
      ./cleanup.sh
      namespace ? [default] 엔터 입력
      cd
    

Security with ISTIO

[링크](https://istio.io/latest/docs/concepts/security/) Task

당근 SRE 밋업 : 실전! gRPC 서비스 운영 노하우(배상익) - 링크

소개 - Docs

요구사항

  • To defend against man-in-the-middle attacks, they need traffic encryption.
  • To provide flexible service access control, they need mutual TLS and fine-grained access policies.
  • To determine who did what at what time, they need auditing tools.

목표

  • Security by default: no changes needed to application code and infrastructure
  • Defense in depth: integrate with existing security systems to provide multiple layers of defense
  • Zero-trust network: build security solutions on distrusted networks

구성요소

아키텍처

  • The control plane handles configuration from the API server and configures the PEPs in the data plane.
  • The PEPs are implemented using Envoy. The following diagram shows the architecture.

  • 제로 트러스트 (ZT: Zero Trust) : ‘아무것도 신뢰할 수 없다는 가정하에, 사용자 및 다양한 정보를 바탕으로 최소한의 권한과 세밀한 통제를 지속적으로 수행하는 보안 활동’ - 링크
  • TLS vs mTLS
  • SPIFFE : 워크로드 식별 표준 집합 https://teleport-docs.infograb.net/enroll-resources/machine-id/workload-identity/
    • 이기종 환경에서 서비스 ID를 발급할 수 있는 프레임워크
    • istio 와 SPIFFE는 SVID 공유 → 이를 통해 istio 서비스는 다른 SPIFFE 호환 시스템과 연결 설정 및 수락 가능

Authentication, Authorization (Auto mutual TLS)

Identity and certificate management

Istio securely provisions strong identities to every workload with X.509 certificates. Istio agents, running alongside each Envoy proxy, work together with istiod to automate key and certificate rotation at scale. The following diagram shows the identity provisioning flow.

Identity Provisioning Workflow

  1. istiod offers a gRPC service to take certificate signing requests (CSRs).
  2. When started, the Istio agent creates the private key and CSR, and then sends the CSR with its credentials to istiod for signing.
  3. The CA in istiod validates the credentials carried in the CSR. Upon successful validation, it signs the CSR to generate the certificate.
  4. When a workload is started, Envoy requests the certificate and key from the Istio agent in the same container via the Envoy secret discovery service (SDS) API.
  5. The Istio agent sends the certificates received from istiod and the private key to Envoy via the Envoy SDS API.
  6. Istio agent monitors the expiration of the workload certificate. The above process repeats periodically for certificate and key rotation.

dd

Authentication : 2가지 타입 인증 제공

  • Peer authentication : used for service-to-service authentication to verify the client making the connection. Istio offers mutual TLS as a full stack solution for transport authentication, which can be enabled without requiring service code changes. This solution:
    • Provides each service with a strong identity representing its role to enable interoperability across clusters and clouds.
    • Secures service-to-service communication.
    • Provides a key management system to automate key and certificate generation, distribution, and rotation.
  • Request authentication : Used for end-user authentication to verify the credential attached to the request. Istio enables request-level authentication with JSON Web Token (JWT) validation and a streamlined developer experience using a custom authentication provider or any OpenID Connect providers, for example:

Mutual TLS authentication - 링크 Permissive mode Peer authentication Secure naming SPIFFE

Istio tunnels service-to-service communication through the client- and server-side PEPs, which are implemented as Envoy proxies. When a workload sends a request to another workload using mutual TLS authentication, the request is handled as follows:

  1. Istio re-routes the outbound traffic from a client to the client’s local sidecar Envoy.
  2. The client side Envoy starts a mutual TLS handshake with the server side Envoy. During the handshake, the client side Envoy also does a secure naming check to verify that the service account presented in the server certificate is authorized to run the target service.
  3. The client side Envoy and the server side Envoy establish a mutual TLS connection, and Istio forwards the traffic from the client side Envoy to the server side Envoy.
  4. The server side Envoy authorizes the request. If authorized, it forwards the traffic to the backend service through local TCP connections.
    • The URI that represents the SPIFFE ID is formatted like this: spiffe://cluster-name/ns/namespace/sa/service-account-name
    • Peer authentication : PERMISSIVE(mTLS 사용/미사용 모두 허용) , STRICT(반드시 mTLS 사용, 미사용 시 거부) , DISABLE(mTLS 미사용)

Authentication architecture

  • You can specify authentication requirements for workloads receiving requests in an Istio mesh using peer and request authentication policies. The mesh operator uses .yaml files to specify the policies. The policies are saved in the Istio configuration storage once deployed. The Istio controller watches the configuration storage.
  • Upon any policy changes, the new policy is translated to the appropriate configuration telling the PEP how to perform the required authentication mechanisms. The control plane may fetch the public key and attach it to the configuration for JWT validation. Alternatively, Istiod provides the path to the keys and certificates the Istio system manages and installs them to the application pod for mutual TLS. You can find more info in the Identity and certificate management section.
  • Istio sends configurations to the targeted endpoints asynchronously. Once the proxy receives the configuration, the new authentication requirement takes effect immediately on that pod.
  • Client services, those that send requests, are responsible for following the necessary authentication mechanism. For request authentication, the application is responsible for acquiring and attaching the JWT credential to the request. For peer authentication, Istio automatically upgrades all traffic between two PEPs to mutual TLS. If authentication policies disable mutual TLS mode, Istio continues to use plain text between PEPs. To override this behavior explicitly disable mutual TLS mode with destination rules. You can find out more about how mutual TLS works in the Mutual TLS authentication section.

Authorization

Istio’s authorization features provide mesh-, namespace-, and workload-wide access control for your workloads in the mesh. This level of control provides the following benefits:

  • Workload-to-workload and end-user-to-workload authorization.
  • A simple API: it includes a single AuthorizationPolicy CRD, which is easy to use and maintain.
  • Flexible semantics: operators can define custom conditions on Istio attributes, and use CUSTOM, DENY and ALLOW actions.
  • High performance: Istio authorization (ALLOW and DENY) is enforced natively on Envoy.
  • High compatibility: supports gRPC, HTTP, HTTPS and HTTP/2 natively, as well as any plain TCP protocols.

Authentication (Auto mutual TLS) 실습 : mTLS - 링크 & PeerAuthentication - 링크 링크2

  • 기존 파드에 로그에서 인증서 등 보안 관련 내용 화긴

      # CA Endpoint, CA(/var/run/secret/istio/root-cert,pem), citadelclient, SDS server 등등
      k logs rating-v -c istio-proxy -
      kubetail 
        
      # envoy 에 cert 정보 확인 : istio-proxy 에 admin페이지 접속 or kaila 에서 envoy 에서 확인
        
    
  • bookinfo → kiali → product 계속 접속
  • kiali 에서 Display(Security 체크) 후 자물쇠 클릭 후 오른쪽 창에 정보 확인 : mTLS Enabled, spiffe(Secure name)

Untitled

  • test 네임스페이스 생성 후 파드 생성(sidecar 미적용) 후 ratings 접속
# 네임스페이스 생성
kubectl create ns test

# 파드 생성
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: netpod
  namespace: test
spec:
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

# 확인 : sidecar 미적용
kubectl get pod -n test

# ratings 서비스 확인
kubectl get svc ratings

# ratings 접속 시도 : 성공
kubectl exec -it -n test netpod -- curl ratings.default:9080/health ;echo
{"status":"Ratings is healthy"}

# 로그 확인
kubetail -l app=ratings -f

NS(default, test 체크) netpod 에서 접속 시 unknown 으로 표기되며, 접근 성공(녹색) 확인

NS(default, test 체크) netpod 에서 접속 시 unknown 으로 표기되며, 접근 성공(녹색) 확인

# Peer authentication 설정 변경 : PERMISSIVE(mTLS 사용/미사용 모두 허용) → STRICT(반드시 mTLS 사용, 미사용 시 거부)
cat <<EOF | kubectl create -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default-strict
spec:
  mtls:
    mode: STRICT
EOF

# ratings 접속 시도 : 실패!
kubectl exec -it -n test netpod -- curl ratings.default:9080/health ;echo
curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56

kubetail -l app=ratings -f
[ratings-v1-b6994bb9-v6grn istio-proxy] [2022-02-14T20:36:39.136Z] "- - -" 0 NR filter_chain_not_found - "-" 0 0 0 - "-" "-" "-" "-" "-" - - 172.16.184.3:9080 172.16.116.4:49054 - -
  • 실습 자원 삭제
kubectl delete PeerAuthentication default-strict
kubectl delete pod -n test netpod
kubectl delete ns test

AuthoriationPolicy & 실습 - 링크

인가 기능

  • Workload-to-workload and end-user-to-workload authorization.
  • A simple API: it includes a single AuthorizationPolicy CRD, which is easy to use and maintain.
  • Flexible semantics: operators can define custom conditions on Istio attributes, and use CUSTOM, DENY and ALLOW actions.
  • High performance: Istio authorization (ALLOW and DENY) is enforced natively on Envoy.
  • High compatibility: supports gRPC, HTTP, HTTPS and HTTP/2 natively, as well as any plain TCP protocols.

Authorization architecture - 링크

  • 서버측의 Envoy proxy 는 인바운드 트래픽에 대해서 액세스 제어

Implicit enablement

  • For workloads without authorization policies applied, Istio allows all requests ⇒ 인증 미적용 시 모든 요청이 허용
  • Authorization policies support ALLOW, DENY and CUSTOM actions ⇒ 권한 부여 정책은 ‘허용, 거부, 사용자 지정’ 동작을 한다
  • Istio checks for matching policies in layers, in this order: CUSTOM, DENY, and then ALLOW ⇒ 정책 적용 우선 순위

authz-eval.png

실습 HTTP Traffic : Configure access control for workloads using HTTP traffic - 링크

Authorization Policy

  • First, you configure a simple allow-nothing policy that rejects all requests to the workload
# The spec: field of the policy has the empty value {}. That value means that no traffic is permitted, effectively denying all requests
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}
EOF

# 확인
kubectl get AuthorizationPolicy
NAME            AGE
allow-nothing   49s

kubetail -l app=productpage
[productpage-v1-6b746f74dc-dm4j6 istio-proxy] [2022-02-14T20:57:11.113Z] "GET /productpage HTTP/1.1" 403 - rbac_access_denied_matched_policy[none] - "-" 0 19 0 - "192.168.10.254" "curl/7.68.0" "3fdcdeb7-9cdb-9a38-8867-7d114590aacb" "www.gasida.dev:30959" "-" inbound|9080|| - 172.16.184.6:9080 192.168.10.254:0 outbound_.9080_._.productpage.default.svc.cluster.local -

# productpage 의 listeners 의 pc 정보 확인 
istioctl pc listener $(kubectl get pod -l app=productpage -o jsonpath={.items[0].metadata.name}).default -o json

image.png

image.png

  • Run the following command to create a productpage-viewer policy to allow access with GET method to the productpage workload
# The policy does not set the from field in the rules which means all sources are allowed, effectively allowing all users and workloads
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "productpage-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
EOF
kubectl get AuthorizationPolicy

# 확인 : productpage 는 200 ok 이지만, reviews/details 는 403 에러
kubetail -l app=productpage

Untitled

CleanSpng

  • Run the following command to create the details-viewer policy to allow the productpage workload
# which issues requests using the cluster.local/ns/default/sa/bookinfo-productpage service account, to access the details workload through GET methods:
# Secure name(SPIFFE)에 principals 가 소스(productpage)는 details 페이지에 GET 요청 허용!
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Untitled

  • Run the following command to create a policy reviews-viewer to allow the productpage workload
# which issues requests using the cluster.local/ns/default/sa/bookinfo-productpage service account, to access the reviews workload through GET methods
# Secure name(SPIFFE)에 principals 가 소스(productpage)는 reviews 페이지에 GET 요청 허용!
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "reviews-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

# 확인
kubectl get AuthorizationPolicy
NAME                 AGE
allow-nothing        20m
details-viewer       4m3s
productpage-viewer   15m
reviews-viewer       33s

kubetail -l app=ratings
kubetail -l app=details
kubetail -l app=reviews
kubetail -l app=productpage

Untitled

  • Run the following command to create the ratings-viewer policy to allow the reviews workload
# which issues requests using the cluster.local/ns/default/sa/bookinfo-reviews service account, to access the ratings workload through GET methods
# Secure name(SPIFFE)에 principals 가 소스(ratings)는 ratings 페이지에 GET 요청 허용!
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "ratings-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: ratings
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
    to:
    - operation:
        methods: ["GET"]
EOF


# 확인
kubectl get AuthorizationPolicy
NAME                 AGE
allow-nothing        23m
details-viewer       6m31s
productpage-viewer   18m
ratings-viewer       47s
reviews-viewer       3m1s

kubetail -l app=ratings
kubetail -l app=details
kubetail -l app=reviews
kubetail -l app=productpage

# productpage 의 listeners 의 pc 정보 확인 
istioctl pc listener $(kubectl get pod -l app=ratings -o jsonpath={.items[0].metadata.name}).default -o json

Untitled

  • 리소스 삭제
kubectl delete authorizationpolicy.security.istio.io/allow-nothing
kubectl delete authorizationpolicy.security.istio.io/productpage-viewer
kubectl delete authorizationpolicy.security.istio.io/details-viewer
kubectl delete authorizationpolicy.security.istio.io/reviews-viewer
kubectl delete authorizationpolicy.security.istio.io/ratings-viewer

kubectl get authorizationpolicy.security.istio.io

JWT Token 접근 제어

JWT (JSON Web Token) - 링크 링크2

  • JWT는 X.509 Certificate와 마찬가지로 private key를 이용하여 토큰을 서명하고 public key를 이용하여 서명된 메세지를 검증합니다.
  • X.509 Certificate의 lightweight JSON 버전이라고 생각하면 편리합니다.
  • jwt는 JSON 형태로 토큰 형식을 정의한 스펙입니다. jwt는 쿠버네티스에서 뿐만 아니라 다양한 웹 사이트에서 인증, 권한 허가, 세션관리 등의 목적으로 사용합니다.
    • Header: 토큰 형식와 암호화 알고리즘을 선언합니다.
    • Payload: 전송하려는 데이터를 JSON 형식으로 기입합니다.
    • Signature: Header와 Payload의 변조 가능성을 검증합니다.
  • 각 파트는 base64 URL 인코딩이 되어서 .으로 합쳐지게 됩니다.
© 2024 mont kim   •  Powered by Soopr   •  Theme  Moonwalk