Istio 심화 — 왜 그렇게 흐르는가 · 사이드카 주입과 가로채기 번호표 · 实验
주입 산출물의 번호를 읽고 두 입구를 세운다
목표
오프라인으로 사이드카 주입 산출물을 만들고, 가로채기 번호가 적힌 자리를 찾아, 그 번호가 Envoy 의 어느 리스너와 클러스터가 되는지 손으로 세워 확인한다.
왜 중요한가
사이드카가 이상하게 굴 때 가장 먼저 보는 것이 주입 산출물이다. 번호 하나가 어긋나면 프록시가 자기 요청을 다시 받거나(UID), 헬스체크가 라우팅을 타거나(-d), 외부 호출이 전부 503 이 된다(BlackHoleCluster). 번호표를 읽을 줄 알면 이 셋을 증상만 보고 가를 수 있다.
단계
1. /root/ist2-inject 를 만들고 그 안에서 istioctl kube-inject 로 /opt/lab/fixtures/istio/inject-target.yaml 에 사이드카를 넣어 /root/ist2-inject/inject.yaml 로 저장하세요(주입 설정 세 파일 /opt/istio/inject-config.yaml·mesh-config.yaml·values-config.yaml 을 모두 넘깁니다). 그다음 /root/ist2-inject/01-containers.txt 에 세 줄을 적으세요 — containers=(주입 뒤 컨테이너 이름을 순서대로 쉼표로), init=(초기화 컨테이너 이름), proxy_image=(istio-proxy 컨테이너의 이미지).
2. /root/ist2-inject/inject.yaml 의 istio-init 컨테이너 args 를 읽어 /root/ist2-inject/02-redirect.txt 에 다섯 줄을 적으세요 — outbound_port=(-p 의 값), inbound_port=(-z), proxy_uid=(-u), mode=(-m), excluded_inbound_ports=(-d, 쉼표로 이어진 그대로).
3. /root/ist2-inject/inject.yaml 에서 세 포트를 찾아 /root/ist2-inject/03-ports.txt 에 적으세요 — readiness_port=(istio-proxy 의 readinessProbe.httpGet.port), merged_metrics_port=(파드 템플릿 애너테이션 prometheus.io/port), envoy_prom_port=(istio-proxy 의 포트 중 이름이 http-envoy-prom 인 것). 마지막 줄 all_excluded= 에는 세 포트가 모두 istio-init 의 -d 목록에 들어 있으면 yes, 아니면 no 를 적으세요.
4. /root/ist2-inject/inject.yaml 의 securityContext 를 읽어 /root/ist2-inject/04-uid.txt 에 다섯 줄을 적으세요 — proxy_uid=(istio-proxy 의 runAsUser), proxy_run_as_non_root=(같은 컨테이너의 runAsNonRoot), proxy_caps_drop=(capabilities.drop 을 쉼표로), init_run_as_user=(istio-init 의 runAsUser), init_caps_add=(istio-init 의 capabilities.add 를 쉼표로, 매니페스트 순서대로).
5. /root/ist2-inject/mesh.yaml 에 Envoy 설정을 쓰세요 — 관리 포트 9981, 리스너 이름 virtualInbound 가 127.0.0.1:15006 에서 traffic_direction: INBOUND 로 듣고, 모든 경로를 클러스터 inbound|8101||(앱 역할, 127.0.0.1:8101)로 보냅니다. 업스트림을 8101 에 ok 로 띄우고 Envoy 를 띄운 뒤 curl localhost:15006/orders 의 결과를 /root/ist2-inject/05-inbound.txt 에 status=(HTTP 코드)와 body=(응답 본문 한 줄) 두 줄로 적으세요.
6. /root/ist2-inject/mesh.yaml 에 두 번째 리스너를 더하세요(앞의 virtualInbound 는 그대로) — 이름 virtualOutbound, 127.0.0.1:10081, traffic_direction: OUTBOUND, 모든 경로를 클러스터 BlackHoleCluster 로 보냅니다. BlackHoleCluster 는 type: STATIC 이고 엔드포인트가 하나도 없는 클러스터입니다. 다시 띄운 뒤 curl localhost:10081/ 의 결과를 /root/ist2-inject/06-outbound.txt 에 status=, body=, cluster=(이 리스너의 라우트가 가리키는 클러스터 이름) 세 줄로 적으세요.
7. 떠 있는 Envoy 의 localhost:9981/config_dump?resource=static_listeners 에서 리스너마다 이름 방향 포트 를 공백으로 나눠 한 줄씩 뽑아 /root/ist2-inject/07-listeners.txt 에 저장하세요(두 줄, 순서는 상관없습니다).
8. /root/ist2-inject/08-report.md 에 outbound_capture=, inbound_capture=, proxy_uid=, unknown_destination= 네 줄을 적고(각각 나가는 쪽을 꺾어 넣는 포트, 들어오는 쪽 포트, 가로채기에서 빠지는 사용자 ID, 6단계에서 목적지를 모르는 요청이 간 클러스터 이름), 그 아래 - 로 시작하는 설명을 네 줄 이상 적으세요.
참고
- 이 파드에는 진짜 istiod 도 진짜 사이드카도 없습니다. 그래서
istioctl proxy-config로 실제 생성물을 볼 수 없고, 번역 규칙을 알고 손으로 등가 Envoy 설정을 만들어 동작을 확인합니다. 같은 규칙이 운영 클러스터의proxy-config출력에 그대로 보입니다. - 주입 산출물 끝에는 빈 문서(
---와null)가 붙습니다.yq로 읽을 때는 항상select(.kind=="Deployment") | …로 거르세요.kube-inject에는-o json이 없으니 JSON 이 필요하면yq -o=json을 씁니다. - mikefarah
yq는 jq 의"\(.a)"보간을 모릅니다 —.a + " " + .b를 쓰거나jq로 넘기세요. - Envoy 를 띄울 때는
setsid --fork nohup envoy -c <파일> --log-level warn > <로그> 2>&1 </dev/null로 셸에서 완전히 떼어 놓으세요. 다시 띄우기 전에는pkill -x envoy로 정리합니다 (pkill -f 'envoy -c'는 그 문자열이 든 셸 자신까지 죽입니다). - 업스트림 흉내용 서버가 이미지에 있습니다:
python3 /opt/lab/envoy/upstream.py <포트> ok|fail|slow. 응답 본문은<모드>:<포트> <경로>입니다. - 설정을 고친 뒤에는 띄우기 전에
envoy --mode validate -c <파일>로 먼저 거르세요. 클러스터 이름에|가 들어가므로 YAML 에서는 반드시 따옴표로 감쌉니다.
8个步骤
- 주입 산출물을 만들고 무엇이 늘었는지 센다
- istio-init 의 인자에서 가로채기 설계를 읽는다
- 가로채기에서 빠진 포트가 누구를 위한 것인지 찾는다
- UID 1337 과 권한이 어디에 나뉘어 있는지 본다
- 15006 에 virtualInbound 를 세워 앱까지 보낸다
- 목적지를 모르는 요청은 BlackHoleCluster 로 간다
- config_dump 에서 두 입구의 이름·방향·포트를 되읽는다
- 가로채기 번호표로 정리한다