본문 바로가기
kubernetes

Istio ambient mode

by misankim 2025. 1. 4.

https://istio.io/latest/docs/ambient/overview/

 

Overview

An overview of Istio's ambient data plane mode.

istio.io

https://istio.io/latest/blog/2024/ambient-reaches-ga/

 

Fast, Secure, and Simple: Istio’s Ambient Mode Reaches General Availability in v1.24

Our latest release signals ambient mode – service mesh without sidecars – is ready for everyone.

istio.io

 

# 앰비언트 모드

-> 사이드카 모드(기존의 사이드카 프록시를 사용하는 방식)와 달리 사이드카 없이 L4, L7 기능에 따라 공유된 프록시를 통해 트래픽을 관리하는 모드

 

https://istio.io/latest/docs/ambient/architecture/control-plane/

 

 

ztunnel(제로 트러스트 터널) - L4, 데몬셋으로 배포
https://istio.io/latest/docs/ambient/overview/#ztunnel

waypoint proxy - L7, waypoint 역할의 gateway 배포 시 자동으로 리소스 생성
https://istio.io/latest/docs/ambient/overview/#waypoint-proxies

 

 

 

(참고) 기존의 istio proxy 를 사용하는 사이드카 모드

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

 

 

# 사이드카 모드와 앰비언트 모드 비교

https://istio.io/latest/docs/overview/dataplane-modes/

 

Sidecar or ambient?

Learn about Istio's two dataplane modes and which you should use.

istio.io

 

요점은 L4/L7을 처리하는 컴포넌트를 나누어 불필요하게 낭비되는 리소스를 없애고, 통신 특성에 맞는 공유된 프록시를 통해 istio 의 기능을 구현한다는 것

 

 

# 사전 작업

## GKE

-> istio-system 네임스페이스에 대한 ResourceQuota 생성 필요

 

apiVersion: v1
kind: ResourceQuota
metadata:
  name: gcp-critical-pods
  namespace: istio-system
spec:
  hard:
    pods: 1000
  scopeSelector:
    matchExpressions:
    - operator: In
      scopeName: PriorityClass
      values:
      - system-node-critical

 

 

## cilium

https://istio.io/latest/docs/ambient/install/platform-prerequisites/#cilium

 

Platform-Specific Prerequisites

Platform-specific prerequisites for installing Istio in ambient mode.

istio.io

 

cilium cni 를 사용하는 경우 아래 옵션을 수정

 

kubectl edit cm -n kube-system cilium-config

cni-exclusive: "true"
-> false 로 수정

kubectl rollout restart ds -n kube-system cilium

 

 

 

# 앰비언트 모드로 istio 배포

## crd 배포

helm install istio-base istio/base -n istio-system --create-namespace

 

## gateway api 배포

kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  { kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml; }

 

## istiod 배포

helm install istiod istio/istiod --namespace istio-system --set profile=ambient

 

## istio cni 및 ztunnel 배포

helm install istio-cni istio/cni -n istio-system --set profile=ambient

helm install ztunnel istio/ztunnel -n istio-system

 

## ingress gateway 배포

helm install istio-ingress istio/gateway -n istio-ingress --create-namespace

 

(참고) gke 의 경우 istio cni 차트 배포

helm install istio-cni istio/cni -n kube-system --set cni.cniBinDir=/home/kubernetes/bin --set profile=ambient

 

 

# 샘플 애플리케이션(book info) 배포

https://istio.io/latest/docs/ambient/getting-started/deploy-sample-app/

 

Deploy a sample application

Deploy the Bookinfo sample application.

istio.io

 

## 샘플 앱 배포

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/bookinfo/platform/kube/bookinfo.yaml

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/bookinfo/platform/kube/bookinfo-versions.yaml

 

## 게이트웨이 생성

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/bookinfo/gateway-api/bookinfo-gateway.yaml

kubectl annotate gateway bookinfo-gateway networking.istio.io/service-type=ClusterIP --namespace=default

 

## 접속

kubectl port-forward svc/bookinfo-gateway-istio 8080:80

접속
http://localhost:8080/productpage

 

 

# 샘플 애플리케이션을 메시에 추가

https://istio.io/latest/docs/ambient/getting-started/secure-and-visualize/#add-bookinfo-to-the-mesh

kubectl label namespace default istio.io/dataplane-mode=ambient

 

 

# 트래픽 시각화

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/prometheus.yaml

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/addons/kiali.yaml

istioctl dashboard kiali

for i in $(seq 1 100); do curl -sSI -o /dev/null http://localhost:8080/productpage; done

 

 

# waypoint proxy 사용


https://istio.io/latest/docs/ambient/usage/waypoint/

waypoint 용 게이트웨이(k8s 의 gateway api)를 목적지 서비스 네임스페이스에 배포하면 자동으로 deployment 가 생성됨

생성된 리소스에는 "gateway.networking.k8s.io/gateway-name: <gateway name>" 레이블이 추가되며 리소스 이름은 "<gateway name>" 규칙을 따름


목적지 네임스페이스 레이블 혹은 목적지 서비스 레이블에 "istio.io/use-waypoint=<waypoint name>" 추가 시 

해당 목적지 네임스페이스/서비스를 향하는 앰비언트 모드의 데이터 플레인의 트래픽이 waypoint proxy 를 향하게 됨

waypoint proxy 는 네임스페이스에 하나만 생성하여 사용할 수도 있지만 용도에 따라 특정 서비스용 waypoint 를 생성하여 분리도 가능

 

waypoint proxy 를 통해 통신하기 위해서는 출발지/목적지 네임스페이스 모두 ambient 모드를 사용하도록 "istio.io/dataplane-mode=ambient" 레이블이 설정되어 있어야함

 

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  labels:
    istio.io/waypoint-for: service
  name: waypoint
  namespace: default
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE

 

 

목적지 네임스페이스에 ambient 모드 활성화
kubectl label namespace default istio.io/dataplane-mode=ambient

목적지 네임스페이스에 waypoint 활성화 레이블 추가
kubectl label ns default istio.io/use-waypoint=waypoint

특정 목적지 서비스에 특정 waypoint 를 향하도록 레이블 추가
kubectl label service reviews istio.io/use-waypoint=reviews-svc-waypoint

 

 

## 다른 네임스페이스의 waypoint 사용

-> 특정 목적지 네임스페이스만 허용할지 모든 목적지 네임스페이스를 허용할지 설정 필요

 

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  labels:
    istio.io/waypoint-for: service
  name: waypoint
  namespace: istio-internal
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
    allowedRoutes:
      namespaces:
        from: All
        # from: Selector
        # selector:
        #   matchLabels:
        #     kubernetes.io/metadata.name: default

 

 

다른 네임스페이스(istio-internal)의 waypoint 를 사용하도록 목적지 네임스페이스 레이블 추가
kubectl label namespace istio-internal istio.io/dataplane-mode=ambient
kubectl label ns default istio.io/use-waypoint-namespace=istio-internal
kubectl label ns default istio.io/use-waypoint=waypoint

 

 

## mesh 트래픽

-> http 레벨의 mesh 트래픽 컨트롤을 위해서는 waypoint proxy 를 통해 트래픽이 전달되도록 waypoint 게이트웨이 생성 및 네임스페이스 레이블 설정 필요

-> gateway 대신 특정 서비스를 게이트웨이(parentRefs)로 하는 http route 생성하여 example 서비스를 향하는 요청에 헤더를 수정

 

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: mesh
  namespace: default
spec:
  parentRefs:
  - group: ""
    kind: Service
    name: sample
  rules:
  - filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        set:
        - name: user-agent
          value: test-agent
    backendRefs:
    - name: sample
      port: 80

 

 

# ztunnel 및 waypoint proxy 액세스 로그

-> 기존의 사이드카 모드와 동일하게 telemetry 리소스를 정의하여 액세스 로그 활성화(istio-system 네임스페이스에 배포하는 경우 전역 활성화)

 

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
spec:
  accessLogging:
    - providers:
      - name: envoy

 

 

(참고) ztunnel 의 액세스 로그

2025-01-06T04:23:00.571576Z	info	access	connection complete	src.addr=100.116.0.50:44036 src.workload="curl7" src.namespace="default" src.identity="spiffe://cluster.local/ns/default/sa/default" dst.addr=100.116.0.48:15008 dst.hbone_addr=100.66.14.35:80 dst.service="sample.default.svc.cluster.local" dst.workload="waypoint-644866d7dc-m5trv" dst.namespace="default" dst.identity="spiffe://cluster.local/ns/default/sa/waypoint" direction="outbound" bytes_sent=96 bytes_recv=927 duration="18ms"
2025-01-06T04:23:05.249303Z	info	access	connection complete	src.addr=100.116.0.50:45890 src.workload="curl7" src.namespace="default" src.identity="spiffe://cluster.local/ns/default/sa/default" dst.addr=100.116.0.48:15008 dst.hbone_addr=100.66.14.35:80 dst.service="sample.default.svc.cluster.local" dst.workload="waypoint-644866d7dc-m5trv" dst.namespace="default" dst.identity="spiffe://cluster.local/ns/default/sa/waypoint" direction="outbound" bytes_sent=96 bytes_recv=927 duration="4ms"
2025-01-06T04:24:09.952501Z	info	access	connection complete	src.addr=100.116.0.50:58624 src.workload="curl7" src.namespace="default" src.identity="spiffe://cluster.local/ns/default/sa/default" dst.addr=100.116.0.48:15008 dst.hbone_addr=100.66.14.35:80 dst.service="sample.default.svc.cluster.local" dst.workload="waypoint-644866d7dc-m5trv" dst.namespace="default" dst.identity="spiffe://cluster.local/ns/default/sa/waypoint" direction="outbound" bytes_sent=96 bytes_recv=927 duration="4ms"
2025-01-06T04:24:20.330252Z	info	access	connection complete	src.addr=100.116.0.50:44714 src.workload="curl7" src.namespace="default" src.identity="spiffe://cluster.local/ns/default/sa/default" dst.addr=100.116.0.48:15008 dst.hbone_addr=100.66.14.35:80 dst.service="sample.default.svc.cluster.local" dst.workload="waypoint-644866d7dc-m5trv" dst.namespace="default" dst.identity="spiffe://cluster.local/ns/default/sa/waypoint" direction="outbound" bytes_sent=96 bytes_recv=927 duration="5ms"

 

(참고) waypoint proxy 의 액세스 로그

[2025-01-06T04:23:00.558Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 612 6 5 "-" "curl/7.35.0" "8b3ad6cf-28a8-456b-a6c3-fedfd30c4989" "sample.default.svc.cluster.local" "envoy://connect_originate/100.116.0.45:80" inbound-vip|80|http|sample.default.svc.cluster.local envoy://internal_client_address/ 100.66.14.35:80 100.116.0.50:44138 - default
[2025-01-06T04:23:05.246Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 612 1 1 "-" "curl/7.35.0" "b0c04836-b87d-4814-8c75-51a68f66a079" "sample.default.svc.cluster.local" "envoy://connect_originate/100.116.0.45:80" inbound-vip|80|http|sample.default.svc.cluster.local envoy://internal_client_address/ 100.66.14.35:80 100.116.0.50:44138 - default
[2025-01-06T04:24:09.949Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 612 1 1 "-" "curl/7.35.0" "2f42a7e5-4026-4d68-a2c6-ea271ba4e752" "sample.default.svc.cluster.local" "envoy://connect_originate/100.116.0.45:80" inbound-vip|80|http|sample.default.svc.cluster.local envoy://internal_client_address/ 100.66.14.35:80 100.116.0.50:44138 - default
[2025-01-06T04:24:20.326Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 612 1 1 "-" "curl/7.35.0" "8b9ce465-abdf-4fad-a7f9-f6de026d91e3" "sample.default.svc.cluster.local" "envoy://connect_originate/100.116.0.45:80" inbound-vip|80|http|sample.default.svc.cluster.local envoy://internal_client_address/ 100.66.14.35:80 100.116.0.50:44138 - default