Published on

Istio Ambient Mode 기록

Authors
  • avatar
    Name
    Jiwon Jeong
    Twitter

현재 회사에서 Istio Ambient Mode를 개발 환경에서 사용 중이고, 곧 운영 환경에 적용할 예정이다. Istio 관련된 내용은 잘 정리되어 있는 것들이 너무 많아, 개인적으로 기록하고 싶은 것들만 남겨본다. 중요도 위주는 아니고, 새롭게 알게된 것이나 평소 생각해보지 못했던 방식, 한 번에 이해하기 어려웠던 내용 정도이다. 아직 ebpf는 사용하지 않아 내용에서는 빠져있지만, 추후에 리서치 후 내용을 추가할 생각이다.

1. ztunnel은 같은 노드 내에서는 Geneve 프로토콜을, 다른 노드 간에는 HBONE 프로토콜을 통해 트래픽을 주고받는다.

Geneve 프로토콜

Geneve(Generic Network Virtualization Encapsulation)는 네트워크 가상화 표준으로, VXLAN과 같은 기존의 터널링 프로토콜보다 더 많은 기능을 제공하며, 확장성이 뛰어나다. 캡슐화 데이터 포맷만 정의하는 것을 목표로 하며, 표준 UDP 패킷으로 전송된다.

같은 노드 내의 통신에서는 물리적인 네트워크를 통한 "터널"이라기보다, ztunnel 프로세스 내부에서 데이터를 효율적으로 이동시키고 Istio 관련 메타데이터를 부가하는 논리적인 "터널" 또는 "캡슐화 메커니즘"으로 이해하는 것이 더 적절하다.

HBONE 프로토콜

HBONE은 Istio Ambient Mode를 위해 고안된 전용 터널링 프로토콜로, Istio 내부(ztunnel ↔ ztunnel) 통신에만 사용된다. 애플리케이션의 순수 TCP 스트림(payload)은 HTTP CONNECT 요청의 본문으로 들어가고, 이 HTTP CONNECT 요청은 HTTP/2 프레임으로 캡슐화된다. 최종적으로는 이 모든 데이터가 mTLS로 암호화된 TCP 연결 위에서 전송된다.

2. ztunnel은 Pod의 네트워크 네임스페이스에 직접 Listener Socket을 생성한다.

ztunnel은 다른 네트워크 네임스페이스에 접근하기 위해 Linux의 NET_ADMIN capability가 필요하다.

  1. Pod의 네트워크 네임스페이스 File Descriptor(FD)는 istio CNI node agent가 ztunnel에 전달한다.
  2. ztunnel은 이 FD를 전달받은 후 setns(fd, CLONE_NEWNET) 호출을 통해 일시적으로 해당 Pod의 네트워크 네임스페이스로 진입한다.
  3. ztunnel은 Pod의 네트워크 네임스페이스 내에서 소켓을 열고 iptables 규칙을 설정하는 등의 네트워크 작업을 마친 다음, 원래의 네임스페이스로 복귀한다.

3. Ambient Mode는 기존의 CNI와의 호환성을 최대한 보장하면서, 호스트 네트워크 네임스페이스에 가해지는 변경을 최소화하는 것을 목표로 한다.

이는 Pod의 트래픽을 그 Pod의 네트워크 네임스페이스에서 직접 ztunnel로 리다이렉션하는 방식으로 달성된다.

  1. ztunnel은 Pod의 네트워크 네임스페이스의 File Descriptor(FD)를 전달받아 해당 네임스페이스로 들어가 소켓을 생성하고 리스닝한다. 이 방식으로 주요 트래픽 리다이렉션이 Pod 네임스페이스에서 이루어지며, 호스트 네임스페이스에는 Istio 관련 iptables 변경이 거의 이루어지지 않거나 아예 없다.
  2. ztunnel Pod의 네트워크 네임스페이스는 주로 ztunnel 자체의 관리 목적인 트래픽(예: Istiod와의 xDS 통신, 메트릭 전송 등)에 사용된다. 실제 서비스 트래픽은 각 Pod의 네트워크 네임스페이스에서 ztunnel로 직접 리다이렉션되거나, ztunnel이 해당 네임스페이스 내에 생성한 소켓을 통해 처리된다.

4. ztunnel 내부 트래픽 흐름 (Outbound)

ztunnel은 단일 프로세스 내에서 여러 개의 논리적인 계층을 가지고 있으며, 네트워크 스택처럼 동작한다. 파드의 outbound 트래픽 흐름은 다음과 같다.

  1. 파드에서 나가는 트래픽은 istio CNI가 구성한 iptables 규칙에 따라 같은 노드의 ztunnel로 라우팅된다. ztunnel은 L4 수준의 보안 정책(예: 통신 가능 여부)을 검증하고, 텔레메트리 데이터를 수집한다.
  2. 이후 ztunnel은 해당 트래픽의 목적지와 정책 등을 분석하고, 관련 메타데이터를 추가하기 위해 Geneve 프로토콜로 트래픽을 캡슐화한다.
  3. Geneve로 캡슐화된 트래픽은 ztunnel 내부의 가상 인터페이스인 istioout으로 전송된다. 이는 ztunnel 내부에서 다시 ztunnel로 트래픽을 보내는 구조이다.
  4. ztunnel은 istioout 인터페이스로 전달된 트래픽의 목적지를 확인한다. 만약 대상이 같은 노드의 Pod인 경우 mTLS 없이 ztunnel 내부의 다른 가상 인터페이스인 pistioout으로 전달된다. 반면, 대상이 다른 노드의 Pod인 경우에는 트래픽이 mTLS로 암호화된 후 대상 노드의 ztunnel로 전송된다.
  5. (같은 노드인 경우) pistioout 인터페이스를 통해 수신된 트래픽은 Geneve 헤더를 제거하여 원래의 IP 패킷으로 디캡슐레이션된다.
  6. 디캡슐레이션된 패킷은 목적지 Pod의 IP 주소로 전송되고, Pod의 네트워크 네임스페이스에 사전에 설정된 iptables 규칙에 따라 해당 어플리케이션으로 전달된다.