Istio 서비스 메시 · 메시 밖의 서버를 안으로 · 실습
옮기지 못한 서버를 메시 안으로 들인다 — WorkloadGroup 과 WorkloadEntry
목표
WorkloadGroup 으로 메시 밖 서버 무리의 틀을 잡고, WorkloadEntry 로 서버 한 대씩 등록하고, ServiceEntry 로 메시 안의 서비스 이름에 묶는다. 마지막에는 그 서버가 받아 갈 설정 묶음을 istioctl x workload entry configure 로 실제로 만들어 보고, 셀렉터가 무엇을 잡는지 세는 보고서를 남긴다.
왜 중요한가
메시를 도입해도 쿠버네티스로 옮기지 못한 서버는 남는다. 이들을 바깥으로 두면 메시가 주는 것들이 거기서 끊긴다 — 신원, 암호화, 접근 정책, 그리고 무엇보다 한 장의 서비스 지도. 메시 확장은 그 서버를 손님이 아니라 구성원으로 들이는 일이다. 핵심은 신원이다. 쿠버네티스 안에서는 파드가 서비스어카운트로 신원을 받지만 VM 에는 그런 것이 없다. 그래서 WorkloadGroup 에 어느 서비스어카운트를 쓸지 적어 두고, 그 서버에는 클러스터가 발급한 토큰과 루트 인증서를 미리 넣어 준다. 이 세 가지가 맞아야 VM 의 프록시가 컨트롤 플레인에 붙어 자기 신원을 증명할 수 있다. 세 오브젝트의 관계도 헷갈리기 쉬운데, 무리의 틀이 WorkloadGroup, 서버 한 대가 WorkloadEntry, 부를 이름이 ServiceEntry 라고 보면 정리된다.
단계
1. /root/ist-expansion 와 네임스페이스 expansion 를 만들고 그 안에 ServiceAccount billing-sa 를 만드세요. 그리고 이 서비스어카운트를 쓰는 워크로드가 메시에서 받게 될 신원 문자열을 /root/ist-expansion/identity.txt 에 한 줄로 적으세요 — 신뢰 도메인은 기본값 cluster.local 입니다.
2. /root/ist-expansion/wg.yaml 에 WorkloadGroup legacy-billing 을 쓰고 expansion 에 적용하세요 — spec.metadata.labels 는 app: billing, spec.template 은 serviceAccount: billing-sa, network: onprem, ports.http: 8080 이고, spec.probe 는 periodSeconds: 5 에 httpGet 으로 포트 8080 의 /healthz 를 봅니다.
3. /root/ist-expansion/wg-bad-probe.yaml 에 WorkloadGroup bad-probe 를 쓰되 spec.probe 에 httpGet 과 tcpSocket 을 둘 다 넣으세요. /root/ist-expansion/wg-no-template.yaml 에는 no-template 을 쓰되 spec.template 을 아예 빼세요. 둘 다 서버 쪽 시험 적용만 해서 거절 문장을 /root/ist-expansion/wg-reject.txt 에 순서대로 모으세요.
4. /root/ist-expansion/we.yaml 에 WorkloadEntry billing-1 을 쓰고 적용하세요 — 메타데이터 라벨 app: billing, address 는 10.20.30.41, network 는 onprem, serviceAccount 는 billing-sa, locality 는 dc1/rack2, ports.http 는 8080 입니다. 그다음 /root/ist-expansion/we-typo.yaml 에 billing-typo 를 쓰되 주소를 10.20.30 .41 처럼 띄어 써서 적용하고, istioctl analyze -n expansion -o json 의 출력을 /root/ist-expansion/analyze-address.json 에 저장하세요. 라벨은 app: billing-broken 으로 둡니다.
5. /root/ist-expansion/se.yaml 에 ServiceEntry billing-svc 를 쓰고 적용하세요 — hosts 는 billing.expansion.internal 하나, location 은 MESH_INTERNAL, resolution 은 STATIC, 포트는 번호 8080 에 이름 http, 프로토콜 HTTP 이고, workloadSelector.labels 는 app: billing 입니다.
6. 세 개의 ServiceEntry 파일을 만들어 서버 쪽 시험 적용으로 규칙을 확인하세요 — /root/ist-expansion/se-none-endpoints.yaml(resolution: NONE 인데 endpoints 가 있음), /root/ist-expansion/se-roundrobin-two.yaml(resolution: DNS_ROUND_ROBIN 에 endpoints 두 개), /root/ist-expansion/se-roundrobin-one.yaml(resolution: DNS_ROUND_ROBIN 에 endpoints 하나). 결과를 /root/ist-expansion/resolution-rules.tsv 에 <파일이름>\t<accepted|rejected> 로 위 순서대로 적고, 거절 문장들은 /root/ist-expansion/resolution-reject.txt 에 모으세요. 세 파일 모두 실제로 적용하지는 마세요.
7. 먼저 istio-system 네임스페이스를 만들고, istioctl manifest generate --set profile=minimal 렌더에서 ConfigMap istio 만 뽑아 /root/ist-expansion/istio-cm.yaml 에 저장한 뒤 적용하세요. 그다음 expansion 에 ConfigMap istio-ca-root-cert 를 만드세요 — 키 이름은 root-cert.pem 이고 값은 openssl 로 만든 자체 서명 루트 인증서입니다(/root/ist-expansion/root-cert.pem). 마지막으로 istioctl x workload entry configure -f /root/ist-expansion/wg.yaml -o /root/ist-expansion/vmcfg --clusterID lab-cluster 를 돌려 설정 묶음을 만드세요.
8. /root/ist-expansion/we2.yaml 에 두 번째 서버 billing-2 를 쓰고 적용하세요 — 라벨 app: billing, 주소 10.20.30.42, network: onprem, serviceAccount: billing-sa, locality: dc1/rack3, ports.http 8080 입니다. 그다음 /root/ist-expansion/se-match.sh 를 만들어 expansion 의 ServiceEntry 중 workloadSelector 가 있는 것마다 <ServiceEntry 이름>\t<잡힌 WorkloadEntry 수>\t<이름들 쉼표> 를 이름순으로 표준출력에만 찍게 하고, 그 출력을 /root/ist-expansion/match-result.txt 에 저장하세요.
참고
- 신원 형식은
spiffe://<신뢰도메인>/ns/<네임스페이스>/sa/<서비스어카운트>입니다. kubectl apply --dry-run=server는 만들지 않고 API 서버에게 물어만 봅니다.istioctl x workload entry configure는 클러스터의 ConfigMap 두 개와 서비스어카운트를 읽습니다.- 흔한 실수: WorkloadEntry 만 만들고 ServiceEntry 를 빠뜨립니다. 부를 이름이 없으면 아무도 못 부릅니다.
- 흔한 실수: 라벨을 WorkloadEntry 의
spec에 적습니다. 셀렉터가 보는 것은metadata.labels입니다. - 참고: https://istio.io/v1.24/docs/reference/config/networking/workload-group/
- 참고: https://istio.io/v1.24/docs/reference/config/networking/workload-entry/
- 참고: https://istio.io/v1.24/docs/ops/deployment/vm-architecture/
단계 8개
- 메시가 그 서버를 뭐라고 부를지 먼저 정한다
- VM 한 대가 아니라 VM 한 무리의 틀을 만든다
- 스키마가 거절하는 두 가지를 직접 받아 본다
- 서버 한 대를 실제로 등록하고, 오타가 어디서 잡히는지 본다
- 등록한 서버를 메시의 서비스 이름에 묶는다
- resolution 마다 endpoint 규칙이 다르다
- 그 서버가 받아 갈 설정 묶음을 실제로 만들어 본다
- 셀렉터가 실제로 무엇을 잡는지 세어 보고 보고서로 남긴다