LabHub
배우기 러닝패스 코스

Istio 서비스 메시 · 확장 지점의 값과 대가 · 이론

확장 지점의 값과 대가

LabHub 에서 이어서 보기

한 줄 요약

EnvoyFilter 는 Istio 의 추상이 아니라 Envoy 의 내부 구조를 직접 건드리는 탈출구라서 판올림에 약하고,
WasmPlugin 은 같은 요구를 버전에 덜 묶인 모양으로 적게 해 주지만 모든 경우를 대신하지는 못한다.

왜 탈출구가 필요했나

Istio 의 트래픽 API 는 잘 고른 추상이다. 어디로 보낼지, 얼마나 기다릴지, 몇 번 다시 시도할지 —
대부분의 요구는 이 언어로 표현된다. 그런데 메시를 오래 쓰면 이 언어에 없는 요구가 반드시 온다.
"모든 응답에 사내 추적 헤더를 붙여 달라", "이 워크로드 앞에만 속도 제한을 걸어 달라",
"액세스 로그에 업무 필드를 하나 더 넣어 달라" 같은 것들이다.

프록시 자체(Envoy)는 이런 일을 다 할 수 있다. 모자란 것은 Istio 의 언어다. EnvoyFilter 는 그
간극을 메우려고 열어 둔 문이다 — Istio 가 만들어 낸 Envoy 설정에 덧칠할 자리와 내용을 직접 적는다.

어떻게 동작하나

EnvoyFilter 하나는 패치 목록이고, 패치마다 네 가지를 정한다.

| 자리 | 무엇을 정하나 | 값의 예 |
| --- | --- | --- |
| applyTo | 어떤 종류의 Envoy 설정을 건드리나 | HTTP_FILTER, NETWORK_FILTER, CLUSTER, LISTENER |
| match.context | 어느 방향의 설정인가 | SIDECAR_INBOUND, SIDECAR_OUTBOUND, GATEWAY, ANY |
| patch.operation | 어떻게 덧칠하나 | MERGE, ADD, REMOVE, INSERT_BEFORE, INSERT_FIRST |
| priority | 여러 패치의 적용 순서 | 정수. 작을수록 먼저 |

네 값은 모두 열거형이라 API 서버가 강제한다. 틀린 값을 넣으면 오브젝트가 만들어지지 않고 허용 값
목록이 그대로 돌아온다 — 이건 좋은 소식이다. 나쁜 소식은 **값이 다 맞아도 설정이 적용된다는 보장은
없다**는 것이다. match 는 Envoy 설정 안에서 대상을 찾아내는 조건인데, 찾지 못하면 그냥 아무 일도
일어나지 않는다. 오류도 이벤트도 없다. 판올림으로 필터 이름이나 체인 구조가 바뀌면 바로 이 상태가 된다.

여기에 한 겹이 더 있다. INSERT_BEFORE 처럼 다른 패치를 기준으로 삼는 연산은 순서가 정해져야
의미가 있는데, priority 를 적지 않으면 순서가 보장되지 않는다. istioctl analyze 가 이 경우를
IST0151 로 잡아 준다. 같은 도구가 typed_config 없이 필터 이름만 적은 경우도 지적한다 —
이름만 쓰는 방식은 오래된 표기라 앞으로 바뀔 자리다.

범위도 중요하다. EnvoyFilter 는 놓인 네임스페이스에만 걸리는데, 루트 네임스페이스
(기본값 istio-system)에 두면 메시 전체에 걸린다. 거기에 workloadSelector 를 붙이면 라벨이 맞는
워크로드로 좁혀진다. 사고의 크기는 이 선택 하나로 정해진다.

WasmPlugin 은 같은 요구를 다르게 적는다. Envoy 내부 구조 대신 어느 단계에 무엇을 끼울지
말한다 — phaseAUTHN, AUTHZ, STATS, UNSPECIFIED_PHASE 네 가지뿐이고, 코드는 OCI 이미지로
따로 배포한다. 내부 구조를 참조하지 않으니 판올림에 훨씬 강하다. 대신 못 하는 것도 있다 —
클러스터 설정이나 리스너 자체를 바꾸는 일은 여전히 EnvoyFilter 의 자리다.

현장에서 만나는 모습

가장 흔한 사고는 "작년에 넣은 EnvoyFilter 가 언제부턴가 안 먹는다" 이다. 누구도 지우지 않았고
오브젝트도 그대로 있다. 판올림 어느 시점에 매치 조건이 빗나가기 시작했을 뿐이다. 이걸 미리 잡는
방법은 두 가지뿐이다 — 판올림 전에 목록을 훑는 점검표를 두거나, 판올림 뒤 실제 프록시 설정을 받아
확인하는 절차를 두거나. 둘 다 없으면 다음 장애 때 원인 후보 목록의 맨 아래에서 발견된다.

두 번째는 범위를 넓게 잡아 생긴 사고다. 한 팀이 자기 서비스에 헤더를 붙이려고 만든 EnvoyFilter 가
루트 네임스페이스에 들어가 메시 전체 프록시에 걸린 일이 있다. 리뷰에서 눈에 띄지 않는 이유는
매니페스트가 짧고 멀쩡해 보이기 때문이다. 네임스페이스 한 줄이 곧 폭발 반경이다.

이 실습 환경의 한계

실습 파드에는 istiod 도 진짜 사이드카도 없다. 그래서 EnvoyFilter 가 **실제 Envoy 설정에 반영되는
모습은 볼 수 없다** — istioctl proxy-config 로 패치 전후를 비교하는 일은 이 환경에서 할 수 없다.
대신 진짜 API 서버가 있어서 스키마 강제는 실제로 확인할 수 있고, istioctl analyze 도 클러스터의
오브젝트를 읽어 같은 판정을 내려 준다. "선언이 받아들여지는가" 와 "선언이 실제로 먹히는가" 는 다른
질문이고, 이 실습은 앞의 질문과 그 앞의 위험 점검까지를 다룬다.

다음 실습에서 할 것

열거형 세 개를 한꺼번에 틀려 API 서버가 무엇을 돌려주는지 보고, 고쳐서 실제로 올린다. 메시 전체에
걸리는 자리와 워크로드 하나에 걸리는 자리를 나란히 만들어 범위를 비교하고, 우선순위 없는 상대 위치
패치가 분석기에 어떻게 잡히는지 본다. 같은 요구를 WasmPlugin 으로 적어 보고, 마지막에는 클러스터의
모든 EnvoyFilter 를 훑어 판올림 위험을 코드로 찍어 주는 점검 스크립트를 만든다.