본문 바로가기
K8s/Advanced Network

[KANS3] 7. Service Mesh: Istio

by okms1017 2024. 10. 20.
728x90

✍ Posted by Immersive Builder  Seong

 

1. Service Mesh 

Service Mesh 란?

  • 등장 배경 :
    • MSA 환경에서 전체 시스템 모니터링의 어려움
    • 시스템 운영 시 발생하는 장애 또는 이슈의 원인과 병목 구간을 찾기가 어려움 
    • GW에서 내부망 통신 제어는 어려움 
  • 개념 : 마이크로서비스 간에 Mesh 형태의 통신이나 경로를 제어하기 위함 
  • 기본 동작 : 파드 간 통신 경로에 프록시를 구성하여 트래픽을 컨트롤하고 모니터링함 
    • 파드 내 사이드카 컨테이너로 주입되어 동작
    • 프록시(Data Plane)를 중앙에서 관리하는 Control Plane을 구성
    • 원격에서 동적인 설정 관리가 유연하고 고성능의 프록시를 제공하는 Envoy 사용 
    • Filter Chain(L3/L4/L7), 동적 Configuration API, API 기반 HOST Reload 제공 
    • 라우팅, mTLS, 동기화 상태 정보 등 관리 
  • 트래픽 모니터링 : 요청의 에러율, 레이턴시, 커넥션 개수, 요청 개수 등 메트릭 모니터링, 특정 서비스 간 혹은 특정 요청 경로로 필터링 
  • 트래픽 컨트롤 : Traffic Shifting, Circuit Breaker, Fault Injection, Rate Limit
    • Traffic Shifting : 특정 단말/사용자는 신규앱에 전달하여 단계적으로 적용하는 카나리 배포 
    • Circuit Breaker : 목적지 마이크로서비스에 문제가 있을 시, 접속을 차단하고 출발지 마이크로서비스에 요청 에러를 반환
    • Fault Injection : 의도적으로 요청을 지연하거나 실패를 구현
    • Rate Limit : 요청 개수의 제한 
  • 종류 : Istio/Envoy, Linkerd, Consul  

 

** Service Mesh 가 필요한가? 

- Proxy는 인프라 리소스(CPU, MEM)를 소비하고, Proxy를 사용하는 서비스 개수가 증가함에 따라 리소스 사용량이 증가한다. 

-  서비스 간에 위치한 두 개의 Proxy 자원은 네트워크 지연을 유발한다. 

- 일반 컨테이너 통신 시 커넥션 풀이 1개인 반면, Service Mesh에서는 3개의 커넥션 풀이 존재한다. 

- 커넥션 풀이 증가함에 따라 트러블 슈팅 구간(POF)이 확장된다.  

- Service Mesh를 운영하는 플랫폼 운영자는 이러한 비용을 직접적으로 감수해야 하고, 비즈니스 개발자 및 최종 사용자에게도 간접적으로 영향을 미친다. 

- 따라서 Service Mesh 도입 시에는 위와 같은 사항을 고려해야 한다. 

 

Envoy 란?

Envoy는 마이크로서비스 환경에서 사용되는 고성능 오픈 소스 프록시입니다. 특히 클라우드 네이티브 애플리케이션에서 서비스 간의 트래픽을 처리, 제어, 모니터링하는 역할을 수행합니다. 현재는 Istio를 포함한 Service Mesh, 또는 Gateway API 구현체에서 Data Plane으로 사용됩니다.

 

Components

 

  • Cluster : Envoy가 트래픽을 포워딩할 수 있는 논리적인 서비스(Endpoint set). 실제 요청이 처리되는 IP 또는 엔드포인트의 집합.
  • Endpoint : IP 주소, 네트워크 노드로 그룹핑. 실제 접근이 가능한 엔드포인트를 의미하며, 엔드포인트가 모여서 하나의 Cluster를 구성함.
  • Listener : 무엇을 받을지 그리고 어떻게 처리할지 등 IP/Port를 바인딩하고, 요청 처리 측면에서 DownStream을 조정하는 역할.
  • Route : Listener로 들어온 요청을 어디로 라우팅할 것인지를 정의. 일반적으로 Cluster가 라우팅 대상에 해당함.
  • Filter : Listener로부터 서비스에 트래픽을 전달하기까지 요청 처리 파이프라인.
  • UpStream : Envoy 요청을 포워딩해서 연결하는 백엔드 네트워크 노드. 사이드카일 때 application app에 연결하고, 아닌 경우 원격 백엔드에 연결함. 
  • DownStream : Envoy에 연결 요청을 보내는 원격 클라이언트. 

Envoy High Level Architecture

 

xDS Sync API

 

Control Plane과 Envoy 사이에서 실시간으로 데이터를 동기화하는 메커니즘입니다. Control Plane은 xDS API를 통해 Envoy에 구성 정보를 푸시하거나 Envoy가 주기적으로 요청하여 설정을 동기화합니다.

 

  • LDS : Listener Discovery Service
  • RDS : Route Discovery Service
  • CDS : Cluster Discovery Service
  • EDS : Endpoint Discovery Service
  • SDS : Secret Discovery Service
  • ADS : Aggregated Discovery Service
  • SRDS, ECDS, VHDS, RTDS etc

 

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 Proxy Hands-on

외부에서 10000/TCP로 들어오는 접속 요청을 www.envoyproxy.io:443으로 포워딩하는 정책입니다. 

 

# envoy-demo.yaml

```

  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 10000

```

clusters:
  - name: service_envoyproxy_io
    type: LOGICAL_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    load_assignment:
      cluster_name: service_envoyproxy_io
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: http://www.envoyproxy.io
                port_value: 443

 

 

설정을 반영한 후, 브라우저에서 Envoy Proxy 서버로 접속을 시도하면 Envoy 공식 홈페이지로 요청이 전달됩니다. 

 

이번에는 9902/TCP로 들어오는 접속 요청을 관리자 페이지 포워딩하도록 설정을 덮어씁니다. 

 

# envoy-override.yaml

admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9902

 

 

9902/TCP에 대한 접속 요청은 관리자 페이지로 전달됩니다. Cluster 정보를 조회하면 UpStream에 대한 상태 정보를 상세히 볼 수 있습니다. 

 

Istio 란?

Istio는 Service Mesh 솔루션으로, 클라우드 네이티브 애플리케이션에서 서비스 간 통신을 투명하게 관리하고 보안, 관찰성, 트래픽 제어 기능을 제공합니다. 주로 쿠버네티스 환경에서 많이 사용되며, 마이크로서비스 간의 복잡한 네트워크 트래픽을 프록시를 통해 관리하여 서비스 간 통신을 최적화하고 보안성을 강화하는 역할을 합니다.

 

Components

 

A. Data Plane (Envoy Proxy)

 

  • Envoy Proxy를 사용하여 서비스 트래픽을 처리 
  • 각 서비스에 사이드카로 프록시가 배포되어, 서비스가 직접 통신하는 대신 이 프록시를 통해 통신을 중계 
  • 데이터 플레인은 트래픽을 가로채고 보안, 로드 밸런싱, 트래픽 관리 등의 작업을 수행 

B. Control Plane (Istiod)

 

  • Pilot: 서비스 간의 통신 규칙 및 트래픽 라우팅 정책을 프록시에 전달하는 역할. 트래픽 관리 및 라우팅 정책을 중앙에서 설정하고, 이를 각 사이드카 프록시로 전달함
  • Citadel: 보안 기능을 담당하며, 각 서비스 간의 통신에 TLS 인증서를 발급하고 mTLS(mutual TLS)를 통해 암호화된 통신을 보장함
  • Galley: Istio의 구성 검증 및 배포를 담당하며, 잘못된 설정을 사전에 검출하여 오류를 방지함. Istio와 쿠버네티스를 연결하며 서비스 정보(Endpoint, IP, List 등)를 가져오는 역할 

Istio Architecture in sidecar mode

 

Istio 설치 (Sidecar mode)

Istio는 Sidecar mode와 ambient mode 두 가지 모드가 있으며, 설치 방법으로 Istioctl, Helm, Operator 등 다양한 툴을 제공합니다. 참고로 Operator를 이용한 설치는 Istio v1.23 이후로 지원하지 않습니다. (https://istio.io/latest/blog/2024/in-cluster-operator-deprecation-announcement/)

 

Istio 공식 홈페이지에서 요구사항에 맞게 구성 요소 및 설정을 커스터마이징한 빌트인 프로파일을 제공하고 있습니다. 

 

demo 프로파일을 이용하여 Sidecar mode로 설치를 진행합니다. 

 

# istioctl 설치
$ export ISTIOV=1.23.2
$ echo "export ISTIOV=1.23.2" >> /etc/profile
$ curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV TARGET_ARCH=x86_64 sh -
$ tree istio-$ISTIOV -L 2 
$ cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
$ istioctl version --remote=false

# Deploy Control Plane using demo profile
$ 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

 

Control Plane에 해당하는 istiod 디플로이먼트에는 pilot-discovery 프로세스가 동작 중이며 8080, 9876, 15010, 15012, 15014, 15017 포트를 리스닝하고 있습니다. 

Istiod Port/Protocol

 

istio-engressgateway 디플로이먼트에는 pilot-agent와 envoy 프로세스가 동작 중이며 15000번대의 포트를 리스닝하고 있습니다. 소켓 정보를 통해 istio-engressgateway 파드(172.16.2.4)와 istiod 서비스(10.10.200.249)가 연결이 성립된 것을 확인할 수 있습니다. 

Istio sidecar proxy Port/Protocol

 

Istio Sidecar Hands-on

Auto Injection with namespace label 

 

Annotation 또는 Label 정보를 확인하여 특정 네임스페이스에 생성되는 파드들은 istio 사이드카가 자동으로 주입되도록 하는 방법입니다. 파드를 생성할 때, Admission Controller를 호출하여 Mutating Admission Webhook을 동작시켜서 구현합니다. 

Admission controllers in Kubernetes

 

다음과 같이 디폴트 네임스페이스에 Label을 적용하면 사이드카가 주입됩니다. 

$ kubectl label namespace default istio-injection=enabled
$ kubectl get ns -L istio-injection

NAME              STATUS   AGE     ISTIO-INJECTION
default              Active      7h57m  enabled
istio-system      Active       45m

 

 

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

 

  • k3s-s

 

  • testpc

 

  • local PC

 

 

Istio를 통한 외부 노출 

 

디폴트 네임스페이스에 웹 서버용 디플로이먼트와 서비스를 하나씩 배포합니다. 

 

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

 

매니페스트 파일에 명시된 컨테이너 이미지는 1개이지만, 신규 배포한 파드의 컨테이너 개수는 2개입니다. 

 

그 이유는 파드 내에 deploy-websrv 컨테이너 외에 istio-proxy 사이드카 컨테이너가 생성되었기 때문입니다. 

 

그리고 Init Container가 istio-init 과정에서 파드 내 iptables rule을 세팅하고 종료됩니다. 이로 인해 source 컨테이너가 target 컨테이너와 통신할 때 istio-proxy 컨테이너를 거치게 됩니다. 

 

istiod 파드에서는 실시간으로 데이터를 동기화하기 위해  xDS API를 통해 istio-proxy에 구성 정보를 푸시합니다. 

 

 

Istio Gateway/VirtualService 설정 

 

클라이언트 PC → (Service:NodePort) Istio ingressgateway 파드 → (Gateway, VirtualService, Service는 Bypass) → Endpoint(파드 : 사이드카 - Application 컨테이너)

 

Dedicated application gateway

 

Gateway는 지정한 인그레스 게이트웨이로부터 트래픽이 인입될 때 Port/Protocol, Hosts, Proxy 등 공통적인 설정이 가능한 오브젝트입니다. VirtualService는 인입된 트래픽을 처리할 Hosts, PATH별 라우팅, 목적지에 대한 정책 설정이 가능한 오브젝트입니다. 

 

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

 

"test-gateway"로 인입된 트래픽 중에 Host가 "www.okms1017.name"에 해당하는 트래픽은 VirtualService가 라우팅 처리합니다. 

 

 

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

 

  • local PC

외부에서 웹 접속을 시도하면 정상적으로 연결됩니다. 웹 서버로 인입되는 패킷의 Source_IP는 deploy-websrv, istio-proxy 모두 127.0.0.6 IP 주소로 확인됩니다. 

 

  • proxy-status : CDS, LDS, EDS, RDS 동기화 상태 확인 

 

  • envoy ↔ pilot-agent uds 통신 

istio-proxy 컨테이너 내에는 envoy와 pilot-agent 2개의 프로세스가 기동 중이며, envoy와 pilot-agent 간에는 uds 통신을 합니다. 즉, istiod로부터 정보를 동기화한 pilot-agent가 다시 envoy에게 uds로 전달하는 것입니다. 

 

 

Pod Debugging

 

istio-proxy 컨테이너에 접속하여 로그를 확인하기 어려운 경우, 파드를 복제하여 디버깅하는 방법이 있습니다. 

 

$ kubectl debug deploy-websrv-778ffd6947-m2nh8 -it --image=nicolaka/netshoot -c netdebug --share-processes --copy-to=websrv-debug --profile='sysadmin' 

$ k get pod
NAME                             READY   STATUS    RESTARTS     AGE
deploy-websrv-778ffd6947-m2nh8   2/2     Running   0            132m
websrv-debug                     3/3     Running   1 (4s ago)   54s

 

Bookinfo Application Hands-on

Productpage,  Reviews, Ratings, Details 4개의 마이크로서비스로 구성된 서비스입니다.  

 

  • Productpage : 도서 리뷰를 보여주는 Reviews 서비스와 도서 상세 정보를 보여주는 Details 서비스에 접속하여 각각의 결과를 사용자에게 응답한다. 
  • Reviews : v1, v2, v3 3개의 버전이 있다. v1은 Rating이 없고, v2,v3는 Ratings 서비스에 접속하여 도서에 대한 별점을 가져온다. 

Bookinfo App Architecture

 

 

Istio Gateway/VirtualService 설정

 

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를 통한 반복 접속 테스트 

 

Reviews-v1
Reviews-v2
Reviews-v3

 

Kiali 란?

Kiali는 Istio와 같은 Service Mesh의 트래픽 흐름을 시각화하고 관리하는 모니터링 도구입니다. Kiali는 클러스터 내부에서 서비스 간의 트래픽, 라우팅 정책, 통신 상태 등을 시각적으로 제공하여 마이크로서비스 간의 복잡한 상호작용을 이해하고 관리하는데 도움을 줍니다. 

 

  • Kiali는 상세 메트릭을 제공하고, 기본적으로 Grafana와 통합이 가능합니다. 
  • Jaeger와 통합하여 분산 트레이싱을 제공합니다. 
  • Istiod 파드의 15014/TCP를 통해 Kiali가 직접 헬스체크합니다. 
  • 주 데이터소스는 Prometheus와 Jaeger 입니다. 

 

Kiali Addon 설치 및 대시보드 구성 

 

  • Prometheus: Targets - 파드별로 15020/TCP 포트에 /stats/prometheus 경로 

 

  • Grafana : Control Plane, Mesh, Performance, Service, Wasm Extension, Workload, Ztunnel Dashboard

 

  • Kiali Traffic Graph : Traffic Distribution, Traffic Rate, Traffic Animation, Security(mTLS Enabled) 

 

  • Kiali Workloads : Logs(sidecar-proxy, app), Inbound/Outbound Metrics, Envoy(Clustes, Listeners, Routes, Config) 

 

  • Kiali Istio Config : Istio 관련 설정 조회, Action을 이용한 관련 오브젝트 설정/삭제 기능 

 

Traffic Management

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

 

DestinationRule은 실제 도착지(서비스와 1:1 연결)의 정교한 정책(부하분산, 연결 옵션, 서킷 브레이크, TLS 등)을 설정하기 위한 오브젝트입니다. TrafficPolicy , Subset, ConnectionPoolSettings 등의 다양한 규칙을 제공합니다. 특히 Subset은 마이크로서비스 버전별로 라우팅할 때 사용됩니다.  

 

Request Routing

 

다음과 같이 각 파드에 subsets을 지정하여 Destination Rule을 생성합니다. 

 

# destination-rule-all.yaml

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
spec:
  host: productpage
  subsets:
  - name: v1
    labels:
      version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings
spec:
  host: ratings
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v2-mysql
    labels:
      version: v2-mysql
  - name: v2-mysql-vm
    labels:
      version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: details
spec:
  host: details
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

 

 

4개의 서비스 모두 v1의 서브셋에 전송하는 정책을 테스트합니다. 

 

# 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

 

 

이번에는 특정 사용자(jason)로 로그인 시, 신규 버전(v2)으로 전송하도록 커스터마이징합니다. 

Match 조건으로는 exact(완전일치), prefix(전방일치), regex(정규표현) 3가지 패턴을 제공합니다. 

 

# virtual-service-reviews-test-v2.yaml

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

 

Jason 사용자로 로그인하면 v2 리뷰 페이지로 접속됩니다. 

 

 

Fault Injection 

 

특정 사용자(jason)으로 로그인 시, 의도적으로 7초 간 지연을 발생시킵니다. 

 

# 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

 

7초 간 로그인 지연이 발생한 후 어플리케이션 Timeout 설정에 의해 연결이 끊어집니다. Kiali에서 에러가 발생한 구간을 분석해보면 DC Flag를 확인할 수 있으며, DC는 DownstreamConnectionTermination의 약자로 클라이언트 요청에 문제가 있었음을 알 수 있습니다. 그리고 다음 구간의 DI는 DelayInjected의 약자로 fault injection 설정에 의해 요청 처리가 일정 시간 지연되었음을 의미합니다. 

 

이번에는 7초 지연이 아닌 500 에러를 바로 리턴해보겠습니다. 

 

# 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

 

Jason 사용자로 로그인이 성공하지만 별점 정보를 불러오는데 실패(500)합니다.

Fi는 FaultInjected로 요청이 중단되었음을 의미하는 Flag입니다. 

 


2. Security 

Security 

  • 요구사항
    • 중간자 공격을 방어하기 위해 트래픽 암호화가 필요
    • 유연한 서비스 접근 제어를 위해 mTLS와 세분화된 접근 정책이 필요
    • 누가 언제 어떤 작업을 수행하였는지 확인하기 위해 감사 도구가 필요
  • 목표
    • 어플리케이션 코드 및 인프라 변경 작업 없이 보안 구현 
    • 기존 보안 시스템과 통합하여 심층 방어 제공
    • 제로트러스트 네트워크 : 신뢰할 수 없는 네트워크에 보안 솔루션 구축 
  • 구성요소
    • 키, 인증서 관리를 위한 CA
    • 인증 정책, 인가 정책, 보안 명명 정보
    • 클라이언트와 서버 간 안전한 통신을 위해 사이드카 및 경계 프록시를 정책 강화 포인트로 지정
    • Envoy Proxy Set
  • 아키텍처

Security Architecture

 

SPIFFE 

  • Secure Production Identity Framework For Everyone
  • 이기종 환경에서 서비스 ID를 발급할 수 있는 프레임워크
  • Istio와 SPIFFE는 SVID(SPIFFE Verifiable Identity Document)를 공유
  • SVID를 통해 Istio는 다른 SPIFFE 호환시스템과 연결을 설정하고 수락이 가능함 

 

Authentication/Authorization

  • Identity and certificate management
    • Istio는 X.509 인증서를 사용하여 모든 워크로드에 강력한 identities를 안전하게 프로비저닝
    • Envoy 프록시와 함께 실행되는 istio 에이전트는 istiod와 함께 작동하여 key와 certificate rotation을 대규모로 자동화  
  • Authentication
    • Peer Authentication : 서비스 간 인증에 사용되며, 서비스 코드 변경 없이 mTLS를 제공함
    • Request Authentication : Request에 첨부된 자격증명을 확인하기 위해 최종 사용자 인증에 사용함 JWT 유효성 검사를 통해 요청 수준 인증을 지원함 
  • Mutual TLS Authentication
    • 상호 TLS 인증을 통한 워크로드 요청 처리 절차 
    • PERMISSIVE(mTLS 사용/미사용 모두 허용), STRICT(mTLS 사용, 미사용 시 거부) 

 

Security Hands-on

Mutual TLS Authentication 

 

현재 PERMISSIVE 모드로 mTLS 미사용이더라도 일반 파드에서 ratings 서비스로 통신이 허용됩니다. 

 

그러나 PeerAuthentication을 STRICT 모드로 변경하면 일반 파드에서 ratings 서비스로 통신이 거부됩니다. 

 

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default-strict
spec:
  mtls:
    mode: STRICT

 

 

 

AuthoriationPolicy

 

1. allow-nothing

 

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}

 

 

2. productpage-viewer

 

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"]

 

 

3. details-viewer

 

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"]

 

 

4. reviews-viewer

 

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"]

 

 

5. ratings-viewer

 

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"]

 

 


3. Istio 트래픽 흐름 

Client (요청) → Pod (인입) 

 

  • Client PC → Istio IngressGateway Pod 
    • 외부 클라이언트 PC에서 웹 서버 파드로 접속을 시도합니다. 
  • Istio IngressGateway Pod → Node 
    • Istio IngressGateway(envoy) 파드는 클라이언트 PCIP를 HTTP XFF 헤더에 담아서 전달합니다. 
    • Istio IngressGateway(envoy) 파드 x-envoy-Y 헤더를 추가해서 전달합니다.
  • Pod 내부 IPTables 적용 → Istio-proxy 컨테이너
    • PAUSE 컨테이너가 파드 네트워크 네임스페이스를 생성하여 제공하며, Init 컨테이너는 Istio-proxy가 트래픽을 가로챌 수 있게 파드 내에 iptables rules 설정을 완료합니다. 
    • 파드 내 IPTables Chains/Rules 적용(NAT 테이블) → Istio-proxy 컨테이너인입됩니다. 
    • 포트는 15006/TCP로 리다이렉트됩니다. 
  • Pod 내부 Istio-proxy 컨테이너 → IPTables 적용
    • Istio-proxy 컨테이너는 Proxy 역할로, 출발지 IP127.0.0.6 으로 변경하여 Nginx 컨테이너와 연결합니다. 
    • 파드 내에서 출발지 IP가 127.0.0.6 으로 변경됩니다. 
    • Istio-proxy 컨테이너와 Nginx 컨테이너는 로컬 통신을 합니다. 
  • Pod 내부 IPTables 적용 → Nginx 컨테이너
    • Istio-proxy를 빠져나올 때는 출발지 IP가 127.0.0.6 이므로 ISTIO_OUTPUT 에 적용되어 리턴되어 POSTROUTING을 통해 Nginx로 도착합니다. 
    • Istio-proxy → OUTPUT → ISTIO_OUTOUT(맨 상단 Rule 매칭으로 RETURN) → POSTROUTING → NGINX 컨테이너
    • 최종적으로 nginx 컨테이너에 클라이언트의 요청 트래픽이 도착합니다. 
    • Access Log의 XFF 헤더에서 클라이언트의 출발지 IP를 확인합니다. 

 

Pod (리턴) Client 

  • Nginx 컨테이너에서 리턴 트래픽(응답, 200 OK)을 클라이언트에 전달합니다. 
  • IPTables Connection Table의 정보를 참고해서 역변환이 적용되어 전달됩니다. 

 

Pod (요청) → 외부 웹 서버 

파드에서 업데이트나 패치, 다운로드를 위해 외부 웹 서버 또는 인터넷과 연결할 때 트래픽의 흐름입니다.

  • Pod 내부 → Istio IngressGateway Pod
    • Nginx 컨테이너에서 외부 웹 서버로 요청을 합니다.
  • Pod 내부 IPTables → Istio-proxy 컨테이너 
    • 파드 내 IPTables Chains/Rules 적용(NAT 테이블) → Istio-proxy 컨테이너인입됩니다.
    • 포트는 15001/TCP로 리다이렉트됩니다.
  • Pod 내부 Istio-proxy 컨테이너 → Node의 호스트 네임스페이스
    • Istio-proxy 컨테이너는 Proxy 역할로, 출발지 포트변경한(+2) 후 외부 웹 서버와 연결합니다.
    • 여기서 포트는 15003/TCP로 리다이렉트됩니다.
    • 파드를 빠져나가기 전, 다시 한 번 IPTables가 적용됩니다. 이 때, 이전 트래픽과 매칭되는 Rule이 다른 것은 UID 1337 조건 때문입니다.
  • Node → 외부 웹 서버 
    • 노드에 SNAT 설정이 되어 있을 경우, 출발지 IP 를 노드의 IP로 변환하여 외부 웹 서버에 요청을 전달합니다.
  • 외부 웹 서버 → Pod (리턴) 
    • 파드 내로 인입 시 목적지 포트(+2) 이므로, Nginx 컨테이너로 바로 가지 않고 Istio-proxy 컨테이너로 먼저 가게 됩니다.

 

 


[출처]

1) CloudNet@, KANS 실습 스터디

2) https://www.envoyproxy.io/docs/envoy/latest/intro/what_is_envoy

 

What is Envoy — envoy 1.33.0-dev-569151 documentation

Envoy works with any application language. A single Envoy deployment can form a mesh between Java, C++, Go, PHP, Python, etc. It is becoming increasingly common for service oriented architectures to use multiple application frameworks and languages. Envoy

www.envoyproxy.io

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

 

Architecture

Describes Istio's high-level architecture and design goals.

istio.io

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

 

Security

Describes Istio's authorization and authentication functionality.

istio.io

5) https://istio.io/latest/docs/examples/bookinfo/

 

Bookinfo Application

Deploys a sample application composed of four separate microservices used to demonstrate various Istio features.

istio.io

6) https://kiali.io/

 

Kiali

Kiali Project site

kiali.io

728x90

'K8s > Advanced Network' 카테고리의 다른 글

[KANS3] 6. Ingress + Gateway API  (0) 2024.10.13
[KANS3] 5. MetalLB + IPVS  (0) 2024.10.06
[KANS3] 4. Service ClusterIP + NodePort  (3) 2024.09.29
[KANS3] 3. Calico CNI + Mode  (0) 2024.09.22
[KANS3] 2. Pause 컨테이너 + Flannel CNI  (4) 2024.09.08