LabHub
开始
学习 学习路径 课程

Istio 实测实验室

ztunnel 只看到 L4

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

한 줄 요약

앰비언트 모드는 사이드카 대신 노드마다 하나인 ztunnel(L4: mTLS·신원·연결 단위 정책)과 필요한 곳에만 두는 waypoint(L7: HTTP 라우팅·HTTP 정책)로 일을 나눈다. 무엇을 누가 강제하는지를 모르고 정책을 쓰면, 적은 규칙이 조용히 빠지거나 멀쩡하던 트래픽이 끊긴다.

왜 이게 필요했나

사이드카 모드는 파드마다 Envoy 를 하나씩 붙인다. 파드가 천 개면 Envoy 도 천 개이고, 각각이 메모리와 CPU 를 쓰며, 사이드카를 바꾸려면 파드를 다시 만들어야 한다. 그리고 대부분의 서비스가 실제로 원하는 것은 mTLS 와 신원 기반 L4 정책뿐인데, HTTP 를 해석하는 무거운 프록시를 모두가 짊어진다.

앰비언트는 이 두 층을 떼어 냈다. mTLS 와 L4 는 노드의 ztunnel 이 맡고, HTTP 가 필요한 서비스에만 waypoint(Envoy)를 둔다. 네임스페이스에 라벨 하나(istio.io/dataplane-mode=ambient)를 붙이면 istio-cni 가 파드의 네트워크 네임스페이스 안에 가로채기 규칙을 심어 트래픽을 ztunnel 로 보낸다. 파드를 다시 만들 필요가 없다.

어떻게 동작하나

ztunnel — L4. 파드에서 나가는 연결은 그 노드의 ztunnel 이 받아, 목적지 노드의 ztunnel 과 HBONE 터널(HTTP CONNECT 위의 mTLS, 포트 15008)을 맺는다. ztunnel 은 요청 경로나 메서드를 모르지만 양쪽의 SPIFFE 신원을 알고, 접근 로그에 src.identity·dst.identity 로 남긴다. 셀렉터로 붙인 AuthorizationPolicy 는 목적지 쪽 ztunnel 이 연결을 받을 때 강제하므로, 거절은 HTTP 403 이 아니라 연결 끊김이다.

HTTP 규칙을 셀렉터 정책에 쓰면 — istiod 는 ztunnel 이 강제할 수 없는 규칙(메서드·경로 등)을 빼고 내려보내고, 정책 상태에 ZtunnelAccepted 조건으로 그 사실을 적는다. ALLOW 정책은 하나라도 맞으면 허용이라, 다른 ALLOW 정책이 이미 그 출발지를 허용하고 있으면 'GET 만 허용' 이라고 쓴 것이 아무 일도 하지 않는다.

waypoint — L7. istioctl waypoint apply 는 Gateway API 의 Gateway(gatewayClassName istio-waypoint)를 만들고, --enroll-namespace 는 네임스페이스에 istio.io/use-waypoint 라벨을 붙여 그 서비스들이 waypoint 를 쓰게 한다. 그 뒤 서비스로 가는 요청의 길은 이렇다.

client ─(ztunnel)─ HBONE ─▶ waypoint(Envoy: HTTP 라우팅·HTTP 정책) ─ HBONE ─▶ (ztunnel) web

여기서 두 가지가 바뀐다.

waypoint 전 waypoint 후
web 의 ztunnel 이 보는 출발지 client waypoint
HTTP 규칙을 강제하는 곳 없음 waypoint(targetRefs 로 붙인 정책)

그래서 client 만 허용하던 L4 정책은 waypoint 를 붙이는 순간 서비스 트래픽을 끊는다. 그리고 waypoint 는 기본으로 서비스로 가는 요청만 맡으므로(istio.io/waypoint-for: service), 파드 IP 로 직접 오는 요청은 waypoint 를 거치지 않는다 — L7 정책을 우회하는 길이다. L4 정책에서 waypoint 신원만 허용하면 두 문제가 함께 풀린다.

라우팅도 waypoint 가 한다. 메시 안 라우팅은 부모가 서비스인 HTTPRoute 로 적는다(Gateway API 의 GAMMA). 처리하는 곳이 waypoint 라서 waypoint 가 없으면 적용되지 않는다.

현장에서 만나는 모습

"waypoint 를 붙였더니 서비스가 전부 503 입니다." 목적지의 L4 정책이 원래 클라이언트만 허용하고 있던 경우다. waypoint 로그에 tunnel_response:401 이 찍힌다. waypoint 도입은 정책 검토와 함께 해야 한다.

"GET 만 허용했는데 POST 가 됩니다." HTTP 규칙을 셀렉터 정책에 썼다. kubectl get authorizationpolicy -o yaml 의 status 가 이미 말하고 있다.

"L7 정책을 걸었는데 어떤 호출은 통과합니다." 파드 IP 로 직접 부르는 클라이언트(헤드리스 서비스·StatefulSet 등)가 waypoint 를 거치지 않은 경우다.

공식 문서: Ambient mode overview · Platform prerequisites — K3s · Configure waypoint proxies · Layer 4 security policy · Layer 7 features

다음 실습에서 할 것

k3s 위에 ambient 프로파일로 설치된 진짜 ztunnel 에 라벨 하나로 네임스페이스를 넣고, 재시작 없이 편입되는 것과 ztunnel 이 남긴 두 신원을 본다. L4 정책을 걸고, HTTP 규칙이 waypoint 없이 어떻게 빠지는지 정책 상태로 확인한 뒤, waypoint 를 붙여 멀쩡하던 요청이 503 이 되는 것을 직접 겪고 고친다. 마지막으로 waypoint 에 HTTP 정책과 HTTPRoute 를 건다.