Envoy 내부 구조 · 설정이 밖에서 들어온다 · 실습
재시작 없이 설정을 갈아 끼운다
목표
정적 설정의 한계를 확인한 뒤 같은 프록시를 파일 구독 방식으로 바꾸고, 클러스터와 리스너를 재시작 없이 갈아 끼우고, 잘못된 갱신이 거절되는 것까지 본다.
왜 중요한가
서비스 메시와 인그레스 컨트롤러가 하는 일의 알맹이가 이것이다. 그런데 문서로만 읽으면 '컨트롤 플레인이 죽으면 메시가 죽는다' 같은 잘못된 문장이 머리에 남는다. 한 번 직접 거절을 만들어 보면, 거절된 뒤에도 트래픽이 흐른다는 사실과 그래서 아무도 모른 채 몇 주가 지날 수 있다는 사실이 함께 남는다. 그 둘을 아는 사람만 update_rejected 에 알림을 건다.
단계
1. 업스트림 둘을 ok 로 띄우세요(8096·8097). /root/envd-xds/static.yaml 에 / 가 static=v1 을 돌려주는 정적 설정을 두고 띄운 뒤(관리 9977, 리스너 127.0.0.1:10077), 띄운 채로 그 파일의 v1 을 v2 로 고치세요. 고치기 전과 후에 각각 요청해 /root/envd-xds/01-static.txt 에 before=·after_edit= 두 줄을 적으세요(다시 띄우지 않습니다).
2. /root/envd-xds/dyn.yaml 을 만드세요 — static_resources 없이 node(id envd-xds-1, cluster envd-xds)와 dynamic_resources 만 두고, lds_config 는 /root/envd-xds/xds/lds.yaml 을, cds_config 는 /root/envd-xds/xds/cds.yaml 을 path_config_source 로 구독합니다. 두 자원 파일도 만드세요 — 리스너는 /marker 에 lds=v1 을 돌려주고 나머지는 클러스터 pool 로 보내며, 클러스터 pool 의 엔드포인트는 8096·8097 둘입니다. 띄운 뒤 /marker 와 / 를 요청해 /root/envd-xds/02-subscribe.txt 에 marker=·upstream_ok=(/ 요청이 200 이면 yes) 두 줄을 적으세요.
3. /root/envd-xds/xds/cds.yaml 에서 엔드포인트 8097 를 빼세요(엔드포인트 하나만 남깁니다). 프록시는 그대로 둔 채 반영될 때까지 기다린 뒤 여덟 번 요청해 /root/envd-xds/03-reload.txt 에 p8096=·p8097=·total= 세 줄을 적으세요.
4. /config_dump 에서 클러스터 절만 뽑아 /root/envd-xds/04-dump.json 에 저장하고, /root/envd-xds/04-dump.txt 에 static_clusters=(정적 클러스터 수), dynamic_clusters=(동적 클러스터 수), dynamic_name=(동적 클러스터의 이름) 세 줄을 적으세요.
5. /root/envd-xds/xds/lds.yaml 의 /marker 응답을 lds=v1 에서 lds=v2 로 고치세요. 프록시는 그대로 둔 채 반영될 때까지 기다린 뒤 /root/envd-xds/05-lds.txt 에 marker_after=(/marker 응답)와 upstream_still_ok=(/ 요청이 여전히 200 이면 yes) 두 줄을 적으세요.
6. /root/envd-xds/xds/cds.yaml 에서 클러스터의 name 줄을 지워 일부러 잘못된 갱신을 보내세요(이름은 스키마가 필수로 요구합니다). 잠시 뒤 /root/envd-xds/06-rejected.txt 에 still_serving=(/ 요청이 여전히 200 이면 yes), update_rejected=(cluster_manager.cds.update_rejected 통계 값), endpoints=(/clusters 에 남아 있는 pool 엔드포인트 수) 세 줄을 적으세요.
7. /root/envd-xds/07-stats.txt 에 cds_success=·cds_rejected=·lds_success=·cds_reload= 네 줄을 적으세요 — 각각 cluster_manager.cds.update_success, cluster_manager.cds.update_rejected, listener_manager.lds.update_success, cluster_manager.cds.config_reload 통계의 값입니다.
8. /root/envd-xds/08-report.md 에 static_needs_restart=(1단계 결과가 '안 바뀐다' 면 yes), reload_count=(7단계의 cds_reload), rejected_kept_old=(6단계에서 거절 뒤에도 트래픽이 흘렀으면 yes), endpoints_after=(3단계 뒤 남은 엔드포인트 수) 네 줄을 적고, 그 아래 배운 것을 네 줄 이상 적으세요.
참고
- 이 환경에는 진짜 gRPC 컨트롤 플레인이 없어 파일 구독(
path_config_source)으로 대신합니다. 보내는 내용의 모양과 프록시의 처리 방식은 같지만, 연결이 끊겼을 때의 재구독 같은 전송 계층 동작은 여기서 볼 수 없습니다. - 파일을 고친 뒤 반영은 곧바로가 아닙니다. 고정
sleep대신 원하는 결과가 나올 때까지 도는 루프로 기다리세요(최대 마흔 번 정도). - 자원 파일은 제자리에서 덮어쓰지 말고 새 파일로 쓴 뒤
mv로 갈아 끼우세요. 파일 구독은 옮겨 놓기에서 깨어납니다 — 제자리 덮어쓰기로는 갱신이 오지 않습니다. 쿠버네티스가 ConfigMap 을 심볼릭 링크 교체로 반영하는 것과 같은 이유입니다. - Envoy 를 띄울 때는
setsid --fork nohup envoy -c <파일> --log-level warn --concurrency 1 > <로그> 2>&1 </dev/null를 쓰고, 다시 띄우기 전에는pkill -x envoy로 정리하세요. - 자원 파일의 모양은
resources:아래에"@type"을 밝힌 목록입니다. 리스너는 Listener, 클러스터는 Cluster 타입입니다. - 흔한 실수 — 3단계와 5단계에서 프록시를 다시 띄우는 것. 이 실습의 요점은 다시 띄우지 않고 바뀌는 것을 보는 데 있습니다.
단계 8개
- 정적 설정은 파일을 고쳐도 바뀌지 않는다
- 설정을 밖에서 받아 오게 바꾼다
- 파일을 고치면 다시 띄우지 않아도 반영된다
- 동적으로 받은 설정은 덤프의 다른 자리에 있다
- 리스너도 무중단으로 갈아 끼운다
- 잘못된 갱신은 거절되고 옛 설정이 남는다
- 갱신이 도착했는지는 숫자로 본다
- 동적 설정 운영 메모를 남긴다