LabHub
배우기 러닝패스 코스

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

확장 지점을 열었더니 판올림이 무서워졌다 — EnvoyFilter 와 WasmPlugin

LabHub 에서 이어서 보기

목표

EnvoyFilter 의 네 자리(applyTo·match.context·patch.operation·priority)를 API 서버가 어떻게 강제하는지 직접 확인하고, 같은 요구를 WasmPlugin 으로 적으면 무엇이 달라지는지 비교한다. 마지막에는 클러스터의 모든 EnvoyFilter 를 훑어 판올림 위험을 코드로 찍어 주는 점검 스크립트를 만든다.

왜 중요한가

메시를 오래 쓰면 표준 API 로 표현되지 않는 요구가 반드시 온다. 그때 EnvoyFilter 를 쓰게 되는데, 이 API 는 Istio 의 추상이 아니라 Envoy 의 내부 설정 구조를 직접 건드린다. 그래서 Istio 를 판올림하면 프록시 안의 필터 이름이나 구조가 바뀌어 패치가 조용히 적용되지 않을 수 있다 — 오류도 나지 않고, 알림도 울리지 않는다. 그렇다고 쓰지 말라는 말은 현실적이지 않다. 대신 세 가지를 습관으로 만든다. 범위를 최대한 좁히고(네임스페이스와 workloadSelector), 상대 위치 패치에는 우선순위를 적고, 어디에 무엇을 끼웠는지 기계가 읽을 수 있는 점검표로 남긴다. 그래야 판올림 전에 무엇을 다시 확인해야 하는지 사람이 기억하지 않아도 된다.

단계

1. /root/ist-envoyfilter 와 네임스페이스 ext-lab 를 만드세요. 그리고 클러스터에 등록된 확장 API 두 가지를 /root/ist-envoyfilter/ext-apis.tsv<복수형 이름>\t<API 그룹>\t<kind> 로 두 줄 적으세요 — EnvoyFilter 와 WasmPlugin 입니다. 이름 오름차순으로 정렬합니다.
2. /root/ist-envoyfilter/ef-broken.yamlext-lab 네임스페이스의 EnvoyFilter inbound-lua 를 쓰되 세 곳을 일부러 틀리세요 — applyToHTTP_FILTERS, match.contextSIDECAR_IN, patch.operationINSERT_BEFORE_ALL 입니다. workloadSelectorapp: checkout 으로 둡니다. 이 파일을 적용하지 말고 서버 쪽 시험 적용만 해서 거절 문장을 /root/ist-envoyfilter/ef-reject.txt 에 저장하세요.
3. /root/ist-envoyfilter/ef-inbound.yaml 에 고친 EnvoyFilter inbound-lua 를 쓰고 ext-lab 에 실제로 적용하세요 — applyToHTTP_FILTER, match.contextSIDECAR_INBOUND, patch.operationINSERT_BEFORE 이고, match.listener.filterChain.filter.nameenvoy.filters.network.http_connection_manager 입니다. patch.value 에는 name: envoy.filters.http.lua 만 적고 priority아직 넣지 마세요.
4. 네임스페이스 istio-system 을 만들고 그 안에 EnvoyFilter mesh-access-log 를 적용하세요 — workloadSelector두지 않고, applyToNETWORK_FILTER, match.contextANY, patch.operationMERGE 로 액세스 로그를 /dev/stdout 에 붙이는 typed_config 를 씁니다. 매니페스트는 /root/ist-envoyfilter/ef-mesh.yaml 에 두세요. 그리고 지금 클러스터의 EnvoyFilter 마다 <네임스페이스>/<이름>\t<selector 있음 yes|no>/root/ist-envoyfilter/ef-scope.tsv 에 정렬해 적으세요.
5. istioctl analyze -n ext-lab -o json 의 출력을 /root/ist-envoyfilter/analyze-before.json 에 저장하세요 — 3단계에서 올린 inbound-luaIST0151 경고가 붙어 있어야 합니다. 그다음 /root/ist-envoyfilter/ef-inbound-priority.yamlspec.priority10 으로 더한 판을 써서 다시 적용하고, 같은 명령의 출력을 /root/ist-envoyfilter/analyze-after.json 에 저장하세요. 뒤쪽에는 IST0151 이 없어야 합니다.
6. /root/ist-envoyfilter/wasm.yamlext-lab 의 WasmPlugin header-check 를 쓰고 적용하세요 — selector.matchLabelsapp: checkout, urloci://registry.lab.internal/plugins/header-check:1.0, phaseAUTHZ, priority 는 20, pluginConfig.headerx-lab-tier 입니다. 그리고 /root/ist-envoyfilter/wasm-bad.yamlheader-check-badphase: PRE_AUTHZ 로 써서 서버 시험 적용에 거절당하게 하고 그 문장을 /root/ist-envoyfilter/wasm-reject.txt 에 저장하세요.
7. istioctl analyze -n ext-lab -o json 을 다시 돌려 /root/ist-envoyfilter/findings.tsv<코드>\t<대상> 을 한 줄씩 정렬해 적으세요. 대상은 분석 결과의 origin 값을 그대로 씁니다. 그리고 /root/ist-envoyfilter/ef-inbound.yaml(3단계 파일)을 istioctl validate 로 검사한 출력을 /root/ist-envoyfilter/validate.txt 에 저장하세요 — 분석기가 잡는 것과 검증기가 잡는 것이 같지 않다는 것을 눈으로 확인합니다.
8. 네임스페이스 legacy-lab 를 만들고 EnvoyFilter legacy-ratelimit 을 적용하세요 — workloadSelector 없음, applyToHTTP_FILTER, match.contextSIDECAR_INBOUND, patch.operationINSERT_AFTER, patch.valuename: envoy.filters.http.ratelimit 만 적습니다(매니페스트는 /root/ist-envoyfilter/ef-legacy.yaml). 그다음 /root/ist-envoyfilter/ef-audit.sh 를 만들어 클러스터의 모든 EnvoyFilter 를 <네임스페이스>/<이름>\t<위험코드들> 로 정렬해 표준출력에만 찍게 하세요. 위험코드는 no-selector(workloadSelector 없음)·no-priority(상대 위치 연산인데 priority 없음)·name-only(typed_config 없이 이름만) 세 가지를 쉼표로 이어 사전순으로 쓰고, 하나도 없으면 - 를 씁니다. 출력을 /root/ist-envoyfilter/audit-result.txt 에 저장하세요.

참고

단계 8개

  1. 확장 API 두 가지가 어디에 등록돼 있는지 확인한다
  2. 열거형 세 개를 한꺼번에 틀려 본다
  3. 세 곳을 고쳐 실제로 올린다
  4. 메시 전체에 걸리는 자리와 워크로드 하나에 걸리는 자리
  5. 상대 위치 패치에 우선순위가 없으면 분석기가 경고한다
  6. 같은 일을 표준 확장 API 로 적으면 무엇이 달라지나
  7. 분석기가 이 네임스페이스에서 무엇을 잡는지 표로 굳힌다
  8. 판올림 전에 돌릴 점검표를 스크립트로 만든다