📌 Notice
Istio Hands-on Study (=Istio)
직접 실습을 통해 Isito를 배포 및 설정하는 내용을 정리한 블로그입니다.
CloudNet@
에서 스터디를 진행하고 있습니다.
Gasida
님께 다시한번 🙇 감사드립니다.
EKS 관련 이전 스터디 내용은 아래 링크를 통해 확인할 수 있습니다.
Istio는 원래 쿠버네티스 환경을 중심으로 설계되었지만, 가상머신(이하 VM)까지 메시에 통합할 수 있도록 기능을 확장하고 있습니다.
이번 블로그에서는 VM을 서비스 메시로 통합하는 데 필요한 핵심 개념들과 실습 과정을 중심으로 다루었습니다.
특히 Istio 1.9.0 이후 도입된 WorkloadGroup과 WorkloadEntry 리소스를 통해,
가상머신 환경에서도 쿠버네티스와 유사한 방식으로 워크로드를 관리하고 자동화할 수 있는 기반이 마련되었습니다.
또한, 사이드카 프록시 설치 및 설정, DNS 프록시를 통한 서비스 탐색,
그리고 istio-agent
동작 커스터마이징과 자동 제거 기능까지 전반적인 메시 통합 흐름을 실습 위주로 학습했습니다.
본 블로그는 실습을 중심으로 "가상머신을 메시에 어떻게 안전하고 효과적으로 통합할 수 있는가?"에 대한 실전적 인사이트를 제공합니다.
가상머신(VM)을 Istio 메시 네트워크에 통합하는 기능은 Istio의 초기 버전부터 제공되어 왔지만, 실제 운영 환경에서는 제어 평면(Control Plane) 외부에서 해결해야 할 과제들이 많았고 자동화가 미흡한 상황이었습니다.
Istio 1.9.0 버전부터는 이러한 VM 지원 기능이 핵심 기능 일부가 구현되면서 API 접근법이 안정화되어 베타(Beta) 단계로 승격되었습니다.
🔸 Istio 1.9.0에서 도입된 핵심 기능
사이드카 프록시의 설치 및 설정 자동화:
VM 환경에서도 사이드카 프록시를 손쉽게 설치하고 설정할 수 있도록 istioctl
명령어를 통해 간소화되었습니다.
가상머신의 고가용성 보장:
새로운 Istio 리소스인 WorkloadGroup
과 WorkloadEntry
를 통해 VM 환경에서도 고가용성을 지원할 수 있게 되었습니다.
메시 내 서비스에 대한 DNS 해석 지원:
VM 내 사이드카와 함께 로컬 DNS 프록시를 설정함으로써, 메시 내부의 서비스 이름을 해석할 수 있게 되었습니다.
이번 장에서는 위 기능들을 먼저 고수준에서 개념적으로 이해한 후, 실제로 가상머신을 메시 네트워크에 통합하고 작동시키는 예제를 통해 실습해볼 것입니다.
가상머신이 Istio 메시의 일부가 되기 위해서는 다음과 같은 작업이 필요합니다.
아래 그림 13.1은 이러한 작업이 성공적으로 수행되기 위해 필요한 전제 조건을 시각화한 것입니다.
쿠버네티스 환경의 워크로드도 유사한 과정을 거치지만, 자동화된 도구들이 이를 처리합니다.
webhook
이나 istioctl
을 통해 사이드카 설치 및 설정이 자동으로 이루어지고,하지만 이와 같은 편의 기능은 쿠버네티스 외부의 워크로드, 즉 가상머신에는 적용되지 않습니다.
따라서 가상머신 사용자 혹은 운영자는 사이드카를 직접 설치하고 구성해야 하며, 워크로드 ID를 위한 부트스트랩 토큰도 수작업으로 전달해야 합니다.
🔸 Single-network architecture
istio-ingressgateway
와 같은 게이트웨이로 우회시킬 수 있지만, 필수는 아닙니다.WorkloadGroup
템플릿을 기반으로 자동으로 WorkloadEntry
리소스를 생성할 수 있습니다.
출처 - https://academy.tetrate.io/courses/take/istio-fundamentals/
🔸 Multi-network architecture
VM이 쿠버네티스 클러스터와 다른 네트워크에 존재하는 경우, 클러스터의 파드는 VM의 IP에 직접 접근할 수 없습니다.
이 경우 Istio east-west gateway 또는 교차 네트워크 트래픽을 위한 Ingress/Egress gateway가 두 네트워크 간의 다리를 형성합니다.
제어 평면 통신뿐 아니라 데이터 플레인 트래픽 모두가 게이트웨이를 통해 흐르게 되며, VM은 해당 게이트웨이의 주소를 활용해 Istiod에 안전하게 연결하고 mTLS 터널을 구성해야 합니다.
출처 - https://academy.tetrate.io/courses/take/istio-fundamentals/
🔸 가상머신의 ID 프로비저닝 방식
Istio는 가상머신에 신뢰할 수 있는 ID를 제공하기 위해 쿠버네티스를 신뢰의 근원(Source of Trust) 으로 사용합니다.
쿠버네티스에서 토큰을 생성한 후, 이를 수작업으로 VM에 전달합니다.
이 토큰은 VM에 설치된 istio-agent
가 Istiod에 인증하는 데 사용되며, 결과적으로 Istiod는 SVID(Spiffe Verifiable Identity Document) 형태의 ID를 발급합니다.
쿠버네티스는 파드에 토큰을 자동 주입하지만, VM의 경우 수작업으로 안전하게 토큰을 전달해야 합니다.
이 솔루션의 단점은 서비스 메시 운영자가 수동으로 ID를 관리해야 하며, 특히 멀티 클라우드 환경에서는 운영 비용이 증가한다는 점입니다.
🔸 (참고) 플랫폼이 할당한 ID 사용
Istio 커뮤니티에서는 클라우드 플랫폼이 자동으로 할당하는 ID를 신뢰의 근원으로 사용하는 방법을 개발 중입니다.
VM이 클라우드 플랫폼으로부터 받은 ID를 기반으로 인증하고, istio-agent
가 이를 활용해 Istiod와 통신하는 구조입니다.
이 방식을 사용하면 각 VM의 ID는 해당 클라우드 플랫폼이 부여한 것으로, 인증과 ID 관리를 더 자동화할 수 있습니다.
(자세한 설계 문서는 여기 참고)
가상머신(VM) 환경에서도 서비스의 고가용성(HA, High Availability)을 보장하기 위해, Istio는 쿠버네티스에서 컨테이너 워크로드가 사용하는 접근 방식을 유사하게 모방하고 있습니다.
🔸 쿠버네티스에서의 고가용성 방식
Deployment:
고수준 리소스로, 애플리케이션의 복제본을 몇 개 만들지, 어떤 방식으로 배포할지를 설정합니다.
Pod:
Deployment 설정에 따라 생성되는 개별 실행 단위입니다.
Pod는 상태가 이상할 경우 폐기 및 재생성을 통해 손쉽게 복원할 수 있으며, 이를 통해 전체 서비스의 가용성을 유지합니다.
🔸 Istio에서의 가상머신 고가용성 구성
Istio는 쿠버네티스의 위 개념을 VM 환경에도 적용할 수 있도록 다음과 같은 두 리소스를 도입했습니다:
WorkloadGroup:
Kubernetes의 Deployment
와 유사한 리소스로, 여러 VM 워크로드에 공통으로 적용될 설정의 템플릿 역할을 합니다.
이 템플릿에는 다음과 같은 정보가 포함됩니다:
WorkloadEntry:
Kubernetes의 Pod
와 유사한 리소스로, 하나의 실제 VM 인스턴스를 나타냅니다.
이 리소스는 WorkloadGroup
에서 정의한 공통 속성 외에도:
🔸 수동 vs 자동 등록 방식
WorkloadEntry
는 수동으로 생성할 수도 있지만,
Istio에서는 워크로드 자동 등록(Workload Auto-Registration) 방식을 권장합니다.
자동 등록을 사용할 경우, 새로 프로비저닝된 VM은 시작 시점에 Istiod에 접속해
사전에 정의된 WorkloadGroup
템플릿을 기반으로 자동으로 WorkloadEntry가 생성됩니다.
이러한 구조를 통해 VM 환경에서도 Pod 기반 환경처럼 유연하게 인스턴스를 교체하거나 확장할 수 있으며,
전체 서비스의 고가용성을 확보할 수 있습니다.
워크로드 자동 등록은 가상머신이 WorkloadGroup
의 일부로 자동으로 메시 네트워크에 참여하도록 돕는 중요한 기능입니다.
WorkloadEntry
리소스를 생성합니다.🔸 WorkloadEntry로의 표현이 중요한 이유
메시 내부에서 가상머신을 WorkloadEntry
로 표현하는 것은 다양한 측면에서 중요합니다.
Kubernetes 서비스 또는 Istio의 ServiceEntry
리소스가 label selector를 통해 이 워크로드를 선택하고, 백엔드로 사용할 수 있습니다.
이 구조를 통해 클라이언트는 실제 VM의 주소를 몰라도 되고, 클러스터 내 FQDN만으로 워크로드에 트래픽을 라우팅할 수 있습니다.
결과적으로 다음과 같은 이점이 생깁니다:
🔸 레거시 → 현대화 마이그레이션 지원
이 구조는 특히 레거시 VM 기반 워크로드를 Kubernetes 기반 워크로드로 이전할 때 유용합니다.
워크로드를 병렬로 실행한 뒤, 서비스 메시의 트래픽 전환 기능(5장에서 설명됨)을 활용해 점진적으로 VM → Pod로 트래픽을 이전할 수 있습니다.
문제가 발생할 경우, 트래픽을 다시 VM으로 롤백할 수 있어 리스크 완화에 유리합니다.
서비스 메시의 일부가 된 워크로드는 클라이언트 요청을 수신할 준비가 되어 있어야 하며, Istio는 이를 확인하기 위해 헬스 체크를 수행합니다.
🔸 두 가지 헬스 체크 방식
Istio는 고가용성을 유지하기 위해 다음 두 가지 헬스 체크를 적용합니다. 이는 쿠버네티스의 방식과 유사합니다.
Readiness Probe (준비 상태 확인)
Liveness Probe (생존 상태 확인)
🔸 liveness 프로브는 메시의 역할이 아님
예시:
Deployment
리소스 내에서 정의된 liveness 프로브를 통해 워크로드 상태를 모니터링하고, 필요 시 자동 재시작합니다.🔸 주요 클라우드 제공자의 liveness & auto-healing 문서
다음은 각 클라우드 플랫폼에서 liveness 체크 및 자동 복구 기능을 구현하는 방법에 대한 공식 문서입니다.
Microsoft Azure
VM 스케일셋에 대해 자동 인스턴스 수리를 지원
👉 Azure Docs
Amazon Web Services (AWS)
오토스케일 그룹 내 인스턴스를 대상으로 헬스 체크 및 자동 대체 수행
👉 AWS Docs
정리하자면, Istio는 readiness에 집중하고, liveness는 플랫폼의 책임으로 위임함으로써 플랫폼 고유의 인프라 복구 메커니즘과 서비스 메시의 기능을 효율적으로 분리하고 있습니다.
(How Istio Performs Readiness Probes in VMs)
가상머신에서 실행 중인 애플리케이션이 트래픽을 수신할 준비가 되었는지 여부는 WorkloadGroup
리소스에 정의된 설정에 따라
istio-agent
가 주기적으로 검사합니다.
istio-agent
는 애플리케이션의 상태를 모니터링하고, 상태 변화(정상 ↔ 비정상)를 Istiod에 보고합니다.🔸 제어 플레인의 동작 방식
Istiod는 보고받은 상태 정보(health status)를 바탕으로
해당 워크로드(즉, VM)에 트래픽을 라우팅할지 여부를 결정합니다.
예시:
🔸 서비스 메시 운영자의 역할
운영자는 다음과 같은 작업을 통해 readiness와 liveness를 모두 관리해야 합니다.
WorkloadGroup
내에 readiness 프로브 설정 → Istio가 수행🔸 readiness vs liveness 설정 권장 방식
항목 | 수행 주체 | 권장 특성 | 목적 |
---|---|---|---|
Readiness Probe | Istio (istio-agent ) | 공격적 | 오류 응답을 하는 인스턴스에 트래픽 전달 방지 |
Liveness Probe | 클라우드 제공자 | 보수적 | 인스턴스가 복구할 시간을 확보 |
🔸 인스턴스를 성급하게 종료하지 말 것
이렇게 하면 시스템은 먼저 트래픽을 차단하고, 이후에도 상태가 복구되지 않을 때만 인스턴스를 종료합니다.
이는 서비스의 안정성과 사용자 경험 모두를 지키는 방식입니다.
가상머신은 쿠버네티스 클러스터 외부에 있기 때문에 클러스터 내부 DNS에 접근할 수 없습니다.
이로 인해 메시 내 서비스의 호스트네임을 해석할 수 없고, 트래픽이 프록시로 전달되지 않아 메시 통합이 불완전해집니다.
DNS 해석이 실패하므로 아웃바운드 트래픽은 절대 엔보이 프록시에 도달하지 않는다.
과거에는 프라이빗 DNS 서버를 별도로 구성하여 가상머신이 DNS 쿼리를 보내도록 설정했고, 이를 external-dns
같은 컨트롤러로 동기화했습니다. 하지만 이는 임시방편일 뿐 완전한 메시 통합 방식은 아니었습니다.
Istio 1.8 이상에서는 istio-agent
에 로컬 DNS 프록시가 추가되었고, istiod
가 메시 내 서비스 정보를 이 프록시에 자동으로 설정합니다.
DNS 쿼리는 iptables 규칙을 통해 이 프록시로 리다이렉트되며, 애플리케이션은 Kubernetes 서비스 이름을 그대로 사용할 수 있게 됩니다.
DNS 쿼리는 해석을 위해 DNS 프록시로 리다이렉트된다.
또한 Istio는 NDS(Name Discovery Service)를 도입해, 서비스가 추가되면 새로운 DNS 항목을 자동으로 동기화합니다.
이 DNS 프록시는 가상머신뿐만 아니라 클러스터 내부 워크로드에도 동일하게 활용 가능하며, DNS 기반 트래픽 제어나 가시성 개선에도 기여합니다.
이로써 가상머신도 클러스터 내부 서비스와 동일한 방식으로 FQDN 기반 통신이 가능해지며, 완전한 메시 통합이 실현됩니다.
이번 실습에서는 cool-store
애플리케이션을 구성합니다.
webapp
과 catalog
는 쿠버네티스 클러스터에, forum
은 가상머신에 배포되며, 두 환경은 서로 다른 네트워크에 위치해 있습니다.
따라서 클러스터에서 VM으로의 트래픽 전달을 위한 east-west 게이트웨이 구성이 중요합니다.
Istio 1.17.8 설치
공식 문서 및 istioctl 설치# (옵션) kube-ops-view helm repo add geek-cookbook https://geek-cookbook.github.io/charts/ helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30007 --set env.TZ="Asia/Seoul" --namespace kube-system kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view ## kube-ops-view 접속 URL 확인 echo -e "http://$(curl -s ipinfo.io/ip):30007/#scale=1.5" echo -e "http://$(curl -s ipinfo.io/ip):30007/#scale=1.3" # 소스코드 clone git clone https://github.com/AcornPublishing/istio-in-action tree istio-in-action/book-source-code-master -L 1 # istioctl 설치 export ISTIOV=1.17.8 echo 'export ISTIOV=1.17.8' >> /root/.bashrc curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV sh - cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl istioctl version --remote=false # 클러스터와 가상머신이 다른 네트워크에 있으므로, 이스티오를 설치한 네임스페이스에 네트워크 정보 레이블을 지정해야 한다. kubectl create namespace istio-system kubectl label namespace istio-system topology.istio.io/network=west-network # demo 프로파일 컨트롤 플레인 배포 cat istio-in-action/book-source-code-master/ch13/controlplane/cluster-in-west-network.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio-controlplane namespace: istio-system spec: profile: demo components: egressGateways: - name: istio-egressgateway enabled: false values: global: meshID: usmesh multiCluster: clusterName: west-cluster network: west-network istioctl install -f istio-in-action/book-source-code-master/ch13/controlplane/cluster-in-west-network.yaml --set values.global.proxy.privileged=true -y # 보조 도구 설치 kubectl apply -f istio-$ISTIOV/samples/addons kubectl apply -f istio-$ISTIOV/samples/addons # nodePort 충돌 시 한번 더 입력 # 설치 확인 : istiod, istio-ingressgateway, crd 등 kubectl get istiooperators -n istio-system -o yaml kubectl get all,svc,ep,sa,cm,secret,pdb -n istio-system kubectl get cm -n istio-system istio -o yaml kubectl get crd | grep istio.io | sort # 실습을 위한 네임스페이스 설정 kubectl create ns istioinaction kubectl label namespace istioinaction istio-injection=enabled kubectl get ns --show-labels # istio-ingressgateway 서비스 : NodePort 변경 및 nodeport 지정 변경 , externalTrafficPolicy 설정 (ClientIP 수집) kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 8080, "nodePort": 30000}]}}' kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec": {"type": "NodePort", "ports": [{"port": 443, "targetPort": 8443, "nodePort": 30005}]}}' kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"externalTrafficPolicy": "Local"}}' kc describe svc -n istio-system istio-ingressgateway # NodePort 변경 및 nodeport 30001~30003으로 변경 : prometheus(30001), grafana(30002), kiali(30003), tracing(30004) kubectl patch svc -n istio-system prometheus -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 30001}]}}' kubectl patch svc -n istio-system grafana -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "targetPort": 3000, "nodePort": 30002}]}}' kubectl patch svc -n istio-system kiali -p '{"spec": {"type": "NodePort", "ports": [{"port": 20001, "targetPort": 20001, "nodePort": 30003}]}}' kubectl patch svc -n istio-system tracing -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 16686, "nodePort": 30004}]}}' # Prometheus 접속 : envoy, istio 메트릭 확인 echo -e "http://$(curl -s ipinfo.io/ip):30001" # Grafana 접속 echo -e "http://$(curl -s ipinfo.io/ip):30002" # Kiali 접속 : NodePort echo -e "http://$(curl -s ipinfo.io/ip):30003" # tracing 접속 : 예거 트레이싱 대시보드 echo -e "http://$(curl -s ipinfo.io/ip):30004"
kiali가 ec2의 public ip를 통해 정상적으로 호스팅되는것을 확인할 수 있습니다.
cool-store 서비스/gw/vs 배포 및 http 요청 확인
# cool-store 서비스/gw/vs 배포 kubectl -n istioinaction apply -f istio-in-action/book-source-code-master/ch12/webapp-deployment-svc.yaml kubectl -n istioinaction apply -f istio-in-action/book-source-code-master/ch12/webapp-gw-vs.yaml kubectl -n istioinaction apply -f istio-in-action/book-source-code-master/ch12/catalog.yaml # 확인 kc get deploy,svc -n istioinaction kc get gw,vs -n istioinaction
http 요청확인
# k3s-s curl -s -H "Host: webapp.istioinaction.io" http://192.168.10.10:30000/api/catalog/ | jq curl -s -H "Host: webapp.istioinaction.io" http://192.168.10.10:30000/api/catalog/items/1 | jq # [forum-vm] k8s cool-store 요청 시도 확인 APP_IP=43.202.64.8 # k8s-s 의 공인 IP curl -s -H "Host: webapp.istioinaction.io" http://$APP_IP:30000/api/catalog/items/1 | jq while true; do curl -s -H "Host: webapp.istioinaction.io" http://$APP_IP:30000/api/catalog/ ; echo; date; sleep 1; done # [자신의 PC] k8s cool-store 요청 시도 확인 바로 위 [testpc]와 동일 요청 # [k8s-s] forum-vm web 요청 시도 확인 curl 192.168.10.200 curl 192.168.10.200 -I VM_IP=15.165.15.104 # testpc 의 공인 IP curl $VM_IP curl $VM_IP -I
forum
애플리케이션을 포트 8080
으로 노출 가상머신은 클러스터와 다른 네트워크에 존재하므로, 이후 단계에서는 WorkloadGroup, WorkloadEntry, DNS 프록시, east-west gateway 등을 구성하여 메시 통합을 완성합니다.
가상머신을 Istio 메시로 통합하기 위해서는 몇 가지 기능이 필요합니다.
이 기능들은 아직 베타 단계이며 기본적으로는 활성화되어 있지 않기 때문에,
이를 위해 IstioOperator 정의를 업데이트하여 기존 컨트롤 플레인을 수정해야 합니다.
기능 단계 문서 참고
이 업데이트를 통해 다음 기능들이 활성화됩니다:
이러한 기능들은 앞서 설명한 것처럼 가상머신을 메시와 통합하는 데 필수 요소입니다.
# 컨트롤 플레인 업데이트 Mesh expansion to VMs
cat istio-in-action/book-source-code-master/ch13/controlplane/cluster-in-west-network-with-vm-features.yaml
*apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-controlplane
namespace: istio-system
spec:
profile: demo
components:
egressGateways:
- name: istio-egressgateway
enabled: false
meshConfig:
defaultConfig:
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true" # DNS 쿼리가 캡처돼 DNS 프록시로 리다이렉트된다
values:
pilot:
env:
PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATION: true # 워크로드를 컨트롤 플레인에 자동 등록할 수 있다
PILOT_ENABLE_WORKLOAD_ENTRY_HEALTHCHECKS: true # 가상머신 워크로드의 상태를 검사한다
global:
meshID: usmesh
multiCluster:
clusterName: west-cluster
network: west-network*
istioctl install -f istio-in-action/book-source-code-master/ch13/controlplane/cluster-in-west-network-with-vm-features.yaml --set values.global.proxy.privileged=true -y
kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec": {"type": "NodePort"}}'
업데이트된 컨트롤 플레인은 서비스 프록시가 DNS 쿼리를 캡처하여 사이드카 내부 DNS 프록시로 리다이렉트하도록 설정합니다.
또한 워크로드는 자동 등록되고, 헬스 체크 결과를 istiod
에 주기적으로 보고할 수 있습니다.
단, 이 기능들을 사용하려면 가상머신이 istiod
에 접근 가능해야 하며, 설정과 ID 정보를 정상적으로 받아올 수 있어야 합니다.
가상머신이 메시의 일부가 되기 위해서는 istiod
와 클러스터 내부 서비스에 접근할 수 있어야 합니다.
같은 네트워크에 있다면 문제없이 동작하지만, 현재 구성처럼 별도의 네트워크에 위치한 경우에는 east-west 게이트웨이를 통해 트래픽을 프록시해야 합니다. 공식 문서 참고
먼저 east-west 게이트웨이를 설치해 봅니다:
cat istio-in-action/book-source-code-master/ch13/gateways/cluster-east-west-gw.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-eastwestgateway
namespace: istio-system
spec:
profile: empty
components:
ingressGateways:
- name: istio-eastwestgateway
label:
istio: eastwestgateway
app: istio-eastwestgateway
topology.istio.io/network: west-network
enabled: true
k8s:
env:
- name: ISTIO_META_ROUTER_MODE
value: "sni-dnat"
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
value: west-network
service:
ports:
- name: status-port
port: 15021
targetPort: 15021
- name: mtls
port: 15443
targetPort: 15443
- name: tcp-istiod
port: 15012
targetPort: 15012
- name: tcp-webhook
port: 15017
targetPort: 15017
values:
global:
meshID: usmesh
multiCluster:
clusterName: west-cluster
network: west-network
istioctl install -f istio-in-action/book-source-code-master/ch13/gateways/cluster-east-west-gw.yaml -y
게이트웨이가 설치되면 가상머신이 메시의 엔드포인트로 접근할 수 있는 포트들이 노출됩니다.
그 중 15443 포트는 가상머신에서 메시 내 서비스로 향하는 트래픽을 리버스 프록시 해주는 mTLS 포트입니다. <Image: istiod와 클러스터 서비스들은 가상머신에 노출하는 포트들>
해당 포트를 Gateway 리소스를 통해 외부로 노출합니다:
cat istio-in-action/book-source-code-master/ch13/expose-services.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: cross-network-gateway
namespace: istio-system
spec:
selector:
istio: eastwestgateway
servers:
- port:
number: 15443
name: tls
protocol: TLS
tls:
mode: AUTO_PASSTHROUGH
hosts:
- "*.local"
kubectl apply -f istio-in-action/book-source-code-master/ch13/expose-services.yaml
kubectl get gw,vs -A
다음으로는 istiod
제어 평면에 대한 포트(15012, 15017)를 노출합니다.
Gateway와 VirtualService를 함께 구성합니다:
cat istio-in-action/book-source-code-master/ch13/expose-istiod.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istiod-gateway
spec:
selector:
istio: eastwestgateway
servers:
- port:
name: tls-istiod
number: 15012
protocol: tls
tls:
mode: PASSTHROUGH
hosts:
- "*"
- port:
name: tls-istiodwebhook
number: 15017
protocol: tls
tls:
mode: PASSTHROUGH
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: istiod-vs
spec:
hosts:
- "*"
gateways:
- istiod-gateway
tls:
- match:
- port: 15012
sniHosts:
- "*"
route:
- destination:
host: istiod.istio-system.svc.cluster.local
port:
number: 15012
- match:
- port: 15017
sniHosts:
- "*"
route:
- destination:
host: istiod.istio-system.svc.cluster.local
port:
number: 443
kubectl apply -f istio-in-action/book-source-code-master/ch13/expose-istiod.yaml -n istio-system
정상적으로 적용되었는지 아래 명령어로 확인할 수 있습니다:
kc get gw,vs -A
이제 인프라와 게이트웨이 구성이 완료되었으며, 가상머신이 istiod
및 클러스터 서비스들과 통신할 준비가 마무리되었습니다.
WorkloadGroup
은 메시 외부(예: VM)에 있는 동일한 속성을 가진 워크로드 집합을 정의하는 리소스입니다.
예를 들어 forum
가상머신 워크로드의 공통 속성은 다음과 같이 정의됩니다:
cat istio-in-action/book-source-code-master/ch13/workloadgroup.yaml
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadGroup
metadata:
name: forum
namespace: forum-services
spec:
metadata:
annotations: {}
labels:
app: forum
template:
serviceAccount: forum-sa
network: vm-network
probe:
periodSeconds: 5
initialDelaySeconds: 1
httpGet:
port: 8080
path: /api/healthz
labels
: 서비스가 이 레이블을 기반으로 WorkloadEntry
를 선택할 수 있게 합니다. network
: 제어 플레인이 프록시 라우팅 시 해당 네트워크 정보로 동작하게 합니다. serviceAccount
: 가상머신 워크로드가 이 그룹의 멤버로 등록되기 위한 인증 토큰 주체입니다.이제 이 WorkloadGroup
을 클러스터에 적용해 봅니다:
kubectl create namespace forum-services
kubectl create serviceaccount forum-sa -n forum-services
kubectl apply -f istio-in-action/book-source-code-master/ch13/workloadgroup.yaml
kubectl get-all -n forum-services
kubectl get workloadgroup -n forum-services
이제 이 그룹에 속하는 가상머신이 자동 등록되고 메시의 구성원이 될 수 있도록 준비되었습니다.
이제 istioctl
명령어를 통해 해당 워크로드에 필요한 사이드카 설정을 생성합니다:
istioctl x workload entry configure -f istio-in-action/book-source-code-master/ch13/workloadgroup.yaml \
-o /tmp/my-workload-files/ \
--clusterID "west-cluster" \
--autoregister
생성된 파일들은 다음과 같습니다:
tree /tmp/my-workload-files/
/tmp/my-workload-files/
├── cluster.env
├── hosts
├── istio-token
├── mesh.yaml
└── root-cert.pem
hosts
: east-west 게이트웨이 경유로 istiod 접근 주소 root-cert.pem
: istiod 인증서 검증용 루트 인증서 istio-token
: 서비스 어카운트 인증 토큰 mesh.yaml
: 메시 설정 및 readinessProbe 정보 포함 cluster.env
: 서비스 프록시용 환경 변수 설정다음 명령어로 로컬 PC 또는 테스트 노드에서 VM으로 파일을 전송합니다:
# 로컬에서 파일 확인
openssl x509 -in ./my-workload-files/root-cert.pem -noout -text
jwt decode $(cat ./my-workload-files/istio-token)
# forum-vm으로 복사
FORUM=54.180.240.239
scp -i ~/.ssh/kp-gasida.pem ./my-workload-files/cluster.env ubuntu@$FORUM:/tmp/
scp -i ~/.ssh/kp-gasida.pem ./my-workload-files/istio-token ubuntu@$FORUM:/tmp/
scp -i ~/.ssh/kp-gasida.pem ./my-workload-files/mesh.yaml ubuntu@$FORUM:/tmp/
scp -i ~/.ssh/kp-gasida.pem ./my-workload-files/root-cert.pem ubuntu@$FORUM:/tmp/
VM 내부에서 파일이 정상적으로 존재하는지 확인합니다:
ls -l /tmp
이제 사이드카를 설치하고, 클러스터와의 보안 통신 설정을 적용할 준비가 완료되었습니다.
가상머신 forum-vm
에 Istio 사이드카인 istio-agent
를 설치하고, 메시와 통합하기 위한 설정을 진행합니다. 대부분의 설정은 VM 내 파일 복사 및 서비스 시작으로 구성되며, 각 명령은 그대로 따라 실행하면 됩니다.
# DNS 관련 설정 확인
cat /etc/resolv.conf
ss -tnlp
ss -unlp
resolvectl status
# iptables 상태 확인
iptables -t nat -L -n -v
iptables -t filter -L -n -v
iptables -t mangle -L -n -v
iptables -t raw -L -n -v
# istio-agent 다운로드 및 설치
curl -LO https://storage.googleapis.com/istio-release/releases/1.17.8/deb/istio-sidecar.deb
file istio-sidecar.deb
dpkg -i istio-sidecar.deb
which pilot-agent
pilot-agent version
which envoy
envoy --version
# 설치된 디렉터리 구조 확인
tree /etc/istio
tree /var/lib/istio/
# 설정 파일 위치에 맞게 복사
mkdir -p /etc/certs
mkdir -p /var/run/secrets/tokens
cp /tmp/root-cert.pem /etc/certs/root-cert.pem
cp /tmp/istio-token /var/run/secrets/tokens/istio-token
cp /tmp/cluster.env /var/lib/istio/envoy/cluster.env
cp /tmp/mesh.yaml /etc/istio/config/mesh
# istiod 주소를 /etc/hosts 에 등록
echo "192.168.10.10 istiod.istio-system.svc" | sudo sh -c 'cat >> /etc/hosts'
cat /etc/hosts
# istio-agent 실행 전 권한 설정
cat /etc/passwd | tail -n 3
chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem
# istio-agent 서비스 시작
systemctl start istio
systemctl enable istio
systemctl status istio
journalctl -u istio -f
# 에이전트가 사용하는 스크립트 확인
which istio-start.sh
cat /usr/local/bin/istio-start.sh
# 인증서 위치 확인
tree /etc/certs/
# 프로세스 및 iptables 상태 재확인
ps aux |grep istio
iptables -t nat -L -n -v
iptables -t filter -L -n -v
iptables -t mangle -L -n -v
iptables -t raw -L -n -v
위 작업을 완료하면
istio-agent
가 정상적으로 동작하며, 메시와 연결 준비가 완료됩니다.
에이전트가 컨트롤 플레인(istiod)에 연결됐는지 확인하려면 아래 로그를 확인합니다.
cat /var/log/istio/istio.log | grep xdsproxy
journalctl -u istio -f
워크로드가 메시에 자동 등록되면 WorkloadEntry
리소스가 생성됩니다.
kubectl get workloadentries -n forum-services
kc get workloadentries -n forum-services -o yaml
status.conditions
에Healthy
상태가False
인 경우, 헬스 체크 실패로 인한 연결 오류를 나타냅니다.
추가적으로 istioctl proxy-status
명령을 통해 메시와 싱크 상태를 확인할 수 있습니다.
istioctl proxy-status
이로써 VM이 Istio 메시의 멤버로 등록되었고, 트래픽 라우팅 전 단계까지 구성이 완료됩니다.
가상머신에서 클러스터 내 서비스(webapp)로 트래픽이 잘 전달되는지 확인하는 단계입니다. 다음과 같은 순서로 트래픽 흐름과 동작을 검증합니다.
# [forum-vm] 신규 터미널 : 패킷 모니터링 도구 termshark 실행
tcpdump -i any -w - udp port 53 | termshark
## CTRL+C 로 취소 후 수집된 패킷은 termshark UI에서 확인 가능
# [forum-vm] : 도메인 해석 정상 여부 확인
dig +short webapp.istioinaction
# 출력 예시: 10.10.200.48
# webapp 서비스로 API 요청
curl -s webapp.istioinaction/api/catalog/items/1 | jq
watch curl -s webapp.istioinaction/api/catalog/items/1
# envoy 프로세스를 통해 15443 포트로 연결되는지 확인
watch -d 'ss -tnp | grep envoy'
# 출력 예시:
# ESTAB 0 0 192.168.10.200:41238 192.168.10.10:15443 users:(("envoy",pid=3203,fd=40))
# ESTAB 0 0 192.168.10.200:41242 192.168.10.10:15443 users:(("envoy",pid=3203,fd=41))
# iptables 상태 지속 확인
watch -d iptables -t nat -L -n -v
watch -d iptables -t raw -L -n -v
# [k3s-s]에서 webapp 서비스 및 엔드포인트 확인
kubectl get svc,ep -n istioinaction webapp
# 출력 예시:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/webapp ClusterIP 10.10.200.48 <none> 80/TCP 148m
#
# NAME ENDPOINTS AGE
# endpoints/webapp 172.16.0.8:8080 148m
iptables
규칙에 의해 DNS 프록시(127.0.0.53)로 리다이렉트됩니다.이 과정을 통해 VM에서 클러스터 내부 서비스까지 트래픽이 어떻게 흘러가는지 확인할 수 있으며, DNS 해석 → 프록시 리다이렉션 → 게이트웨이 전달 → 서비스 응답의 전체 흐름을 검증하게 됩니다.
DNS 프록시 설정과 envoy의 리디렉션 동작은 서비스 메시 내에서 핵심적인 라우팅 메커니즘입니다.
클러스터 외부에서 접근 가능한 IP와 포트를 알고 있다면 아래 명령어로 반복 요청을 보내면서 응답을 관찰할 수 있습니다.
while true; do curl -s -H "Host: webapp.istioinaction.io" http://$APP_IP:30000/api/catalog/ ; echo; date; sleep 1; done
반복 요청을 통해 서비스 응답 안정성이나 로드 밸런싱 상태 등을 확인할 수 있습니다.
이번 단계에서는 클러스터 내부에서 가상머신에 존재하는 서비스(forum)로 트래픽을 라우팅하는 과정을 확인합니다. 앞 절과 반대 방향으로, 즉 클러스터 → 가상머신으로 트래픽이 흐르는 시나리오입니다.
# forum 서비스를 위한 Kubernetes 서비스 생성
cat istio-in-action/book-source-code-master/services/forum/kubernetes/forum-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: forum
name: forum
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: forum
# 서비스 적용
kubectl apply -f istio-in-action/book-source-code-master/services/forum/kubernetes/forum-svc.yaml -n forum-services
# 서비스 및 엔드포인트 확인
kubectl get svc,ep -n forum-services
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/forum ClusterIP 10.10.200.72 <none> 80/TCP 20s
#
# NAME ENDPOINTS AGE
# endpoints/forum <none> 20s
# webapp에서 forum 서비스로의 라우팅 정보 확인
istioctl proxy-config route deploy/webapp.istioinaction --name 80 -o json
# "domains": [ "forum.forum-services.svc.cluster.local", ... ]
# "cluster": "outbound|80||forum.forum-services.svc.cluster.local"
# 클러스터 정보 확인
istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn forum.forum-services.svc.cluster.local
# 아직 endpoint 정보는 없음
istioctl proxy-config endpoint deploy/webapp.istioinaction | grep forum
# eastwest gateway에서도 확인
istioctl proxy-config endpoint deploy/istio-eastwestgateway.istio-system | grep forum
# forum-vm 내부에서 istioctl 설치
export ISTIOV=1.17.8
echo 'export ISTIOV=1.17.8' >> /root/.bashrc
curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV sh -
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
# Envoy 설정 확인
curl -s localhost:15000/config_dump | istioctl proxy-config listener --file -
curl -s localhost:15000/config_dump | istioctl proxy-config route --file -
curl -s localhost:15000/config_dump | istioctl proxy-config clusters --file -
curl -s localhost:15000/config_dump | istioctl proxy-config endpoint --file -
curl -s localhost:15000/config_dump | istioctl proxy-config secret --file -
# 트래픽 요청 및 에러 로그 확인
istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn forum.forum-services.svc.cluster.local
istioctl proxy-config endpoint deploy/webapp.istioinaction | grep forum
# 로그 모니터링
kubectl logs -n istioinaction deploy/webapp -c istio-proxy -f
# [2025-05-25T04:53:18.841Z] "GET /api/users HTTP/1.1" 503 UH no_healthy_upstream ...
UH
응답은 정상적인 업스트림 엔드포인트가 없음을 의미합니다.# WorkloadEntry 상태 확인
kc get workloadentries -n forum-services -o yaml
# message: 'Get "http://192.168.10.200:8080/api/healthz": connect: connection refused'
# status: "False"
# VM에서 서비스 포트 확인
ss -tnlp | grep 8080
# 아직 서비스가 구동되지 않음
# forum-vm
wget -O forum https://git.io/J3QrT
file forum
chmod +x forum
./forum
# 실행 확인
curl http://localhost:8080/api/healthz -v
ss -tnlp | grep 8080
# LISTEN *:8080
# 다시 데이터 플레인에 엔드포인트 반영 확인
istioctl proxy-config cluster deploy/webapp.istioinaction --fqdn forum.forum-services.svc.cluster.local
istioctl proxy-config endpoint deploy/webapp.istioinaction --cluster 'outbound|80||forum.forum-services.svc.cluster.local' -o json
# 192.168.10.200:8080 HEALTHY
# WorkloadEntry 상태도 정상
kc get workloadentries -n forum-services -o yaml
# status: "True"
# type: Healthy
# 자신의 PC에서 요청
curl -s -H "Host: webapp.istioinaction.io" http://$APP_IP:30000/api/users
while true; do curl -s -H "Host: webapp.istioinaction.io" http://$APP_IP:30000/api/users ; echo; date; sleep 1; done
# 로그 모니터링
kubectl logs -n istioinaction deploy/webapp -c istio-proxy -f
# [2025-05-25T05:05:51.328Z] "GET /api/users HTTP/1.1" 200 - via_upstream ...
이 실습을 통해 다음을 확인할 수 있습니다:
이 구조는 운영 환경에서 오류 응답을 방지하고 안정적인 서비스 연속성을 보장하는 데 매우 유용합니다.
VMs are configured by the control plane: Enforcing mutual authentication
가상머신이 메시에 통합되어 사이드카 프록시가 네트워크 트래픽을 관리하게 되면, 이스티오의 다양한 기능을 그대로 가상머신에도 적용할 수 있습니다.
이번에는 트래픽 상호 인증(mTLS)을 강제하는 PeerAuthentication 리소스를 적용하여 보안을 강화해 보겠습니다.
현재는 가상머신의 8080
포트가 외부에 노출되어 있어서, 아무나(메시에 속하지 않은 사용자도) 해당 포트에 접근할 수 있는 상태입니다.
이를 테스트하기 위해 로컬 컴퓨터(메시 외부)에서 직접 요청을 보내 확인해 봅니다.
# 자신의 PC에서 요청
curl -is $FORUM:8080/api/users | grep HTTP
# HTTP/1.1 200 OK
현재는 아무 제약 없이 요청이 처리되고 있는 상태입니다.
이제부터는 메시에 속하지 않은 요청은 모두 차단되도록 설정하겠습니다.
이를 위해, 메시에 속한 트래픽만 허용하는 정책을 다음과 같이 구성합니다.
# strict-peer-auth.yaml
cat istio-in-action/book-source-code-master/ch13/strict-peer-auth.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT
# 적용
kubectl apply -f istio-in-action/book-source-code-master/ch13/strict-peer-auth.yaml
kubectl get peerauthentication -A
정책이 적용되어 데이터 플레인까지 전파되기를 잠시 기다립니다.
이후, 메시에 속하지 않은 요청이 차단되는지 다시 한 번 확인해 봅니다.
# 자신의 PC에서 요청
curl -is $FORUM:8080/api/users -v
# istio-ingressgateway 경유 요청
while true; do curl -s -H "Host: webapp.istioinaction.io" http://$APP_IP:30000/api/users ; echo; date; sleep 1; done
이제 로컬에서의 직접 요청은 실패하지만, 이스티오 메시 안의 webapp → forum 요청은 정상적으로 처리됩니다.
이는 가상머신에 대한 설정이 컨트롤 플레인에 의해 적용되고, 메시 내부에서만 허용된다는 것을 의미합니다.
이처럼 PeerAuthentication
은 하나의 예시일 뿐이며, 모든 이스티오 정책(API)을 사용하여 가상머신의 프록시 동작을 제어할 수 있습니다.
How the DNS proxy resolves cluster hostnames
이번 실습에서는 가상머신에서 webapp.istioinaction
같은 클러스터 호스트네임이 어떻게 해석되는지, DNS 프록시가 개입하는 과정을 단계별로 살펴봅니다.
webapp.istioinaction
을 해석하기 위해 DNS 쿼리를 생성합니다.systemd-resolved
이며, 127.0.0.53:53 포트에서 수신하지만,webapp.istioinaction
은 클러스터 서비스로 등록되어 있기 때문에 IP를 반환합니다.이 흐름을 검증해보겠습니다.
# [forum-vm] DNS 포트 리다이렉션 iptables 규칙 확인
iptables-save | grep 'to-ports 15053'
# -A OUTPUT -d 127.0.0.53/32 -p udp -m udp --dport 53 -j REDIRECT --to-ports 15053
# -A ISTIO_OUTPUT -d 127.0.0.53/32 -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 15053
DNS 쿼리는 실제로 Istio DNS 프록시가 리스닝 중인 127.0.0.1:15053으로 이동합니다.
해당 포트에서 어떤 프로세스가 리스닝하고 있는지 확인해보겠습니다.
# DNS 프록시 포트 확인
netstat -ltunp | egrep 'PID|15053'
# tcp 0 0 127.0.0.1:15053 0.0.0.0:* LISTEN 3195/pilot-agent
# udp 0 0 127.0.0.1:15053 0.0.0.0:* 3195/pilot-agent
Istio의 pilot-agent
가 해당 포트에서 DNS 쿼리를 처리하고 있는 것을 확인할 수 있습니다.
직접 DNS 요청을 보내보면 다음과 같이 해석됩니다.
# DNS 프록시를 통해 서비스 IP 해석
dig +short @localhost -p 15053 webapp.istioinaction
# 10.10.200.48
dig +short @localhost -p 15053 catalog.istioinaction
dig +short @localhost -p 15053 forum.forum-services
# (옵션) 외부 DNS 요청도 확인 가능
dig +short @localhost -p 15053 www.daum.net
# daum-xxxx.kgslb.com.
# 121.53.105.xxx
또한 CoreDNS 로그를 통해 DNS 요청 로그를 확인할 수도 있습니다.
# CoreDNS 로그 설정 (옵션)
KUBE_EDITOR="nano" kubectl edit cm -n kube-system coredns
# 아래 항목 추가
apiVersion: v1
data:
Corefile: |
.:53 {
log
errors
health
...
}
# 로그 출력 확인
kubectl logs -n kube-system -l k8s-app=kube-dns -f
요약하자면, 애플리케이션이 DNS 쿼리를 보낼 때,
127.0.0.53:53
으로 요청하지만,127.0.0.1:15053
의 Istio DNS 프록시(pilot-agent)로 리다이렉트합니다.Which hostnames is the DNS proxy aware of?
DNS 프록시가 실제로 어떤 호스트네임을 인식하는지는 Istiod의 디버그 엔드포인트를 통해 확인할 수 있습니다. 이 과정에서는 각 워크로드 사이드카에 전달된 NDS(NameTable Discovery Service) 정보를 쿼리하게 됩니다.
먼저 대상이 되는 워크로드(forum-vm
)를 확인해봅니다.
# 프록시 워크로드 목록 확인
istioctl proxy-status | awk '{print $1}'
# 출력 예시
catalog-77fdb4997c-f8qj4.istioinaction
istio-eastwestgateway-86f6cb4699-4xfsn.istio-system
istio-ingressgateway-7b7ccd6454-pv8zp.istio-system
forum-vm.forum-services
webapp-684c568c59-vrj97.istioinaction
그 다음, NDS 설정을 직접 조회해봅니다. forum-vm.forum-services
이름을 proxyID로 사용합니다.
# forum-vm 의 NDS(NameTable) 설정 확인
kubectl -n istio-system exec deploy/istiod -- \
curl -Ls "localhost:8080/debug/ndsz?proxyID=forum-vm.forum-services" | jq
출력 예시:
{
"resource": {
"@type": "type.googleapis.com/istio.networking.nds.v1.NameTable",
"table": {
"catalog.istioinaction.svc.cluster.local": {
"ips": [ "10.10.200.138" ],
"registry": "Kubernetes",
"shortname": "catalog",
"namespace": "istioinaction"
},
"forum.forum-services.svc.cluster.local": {
"ips": [ "10.10.200.72" ],
"registry": "Kubernetes",
"shortname": "forum",
"namespace": "forum-services"
},
"webapp.istioinaction.svc.cluster.local": {
"ips": [ "10.10.200.48" ],
"registry": "Kubernetes",
"shortname": "webapp",
"namespace": "istioinaction"
},
...
}
}
}
이 출력에서 webapp.istioinaction.svc.cluster.local 주소가 등록된 것을 확인할 수 있습니다. 하지만, 우리가 curl 등에 사용한 webapp.istioinaction 같은 짧은 도메인 형태는 직접 명시되어 있지 않습니다.
그럼에도 불구하고 왜 짧은 이름이 해석될까요?
바로 istio-agent가 이러한 짧은 형태의 변형을 자동으로 생성하기 때문입니다.
이 모든 변형은 같은 IP 주소(예: 10.10.200.48)로 해석됩니다.
이 내용을 실제 라우팅 설정을 통해서도 확인할 수 있습니다:
# webapp 사이드카에 전달된 라우팅 도메인 확인 istioctl proxy-config route deploy/webapp.istioinaction –name 80 -o json
출력 예시 중 일부:
"name": "webapp.istioinaction.svc.cluster.local:80", "domains": [ "webapp.istioinaction.svc.cluster.local", "webapp", "webapp.istioinaction.svc", "webapp.istioinaction", "10.10.200.48" ]
DNS 프록시는 Istiod가 알고 있는 서비스 목록(NDS)을 기반으로 구성됩니다.
Istio-agent는 Kubernetes 환경에서 익숙한 짧은 호스트네임 형태들을 자동 생성합니다.
이런 변형들은 모두 같은 IP로 해석되며, 클러스터 내에서 서비스 이름으로 접근할 수 있게 해줍니다.
반면, 클러스터 외부 도메인(e.g., www.google.com)은 기존에 설정된 네임서버로 쿼리됩니다.
Customizing the agent’s behavior
Istio 에이전트는 다음과 같은 다양한 설정을 통해 동작을 커스터마이징할 수 있습니다:
이번 예제에서는 두 가지 항목을 수정해보겠습니다.
이 설정은 사이드카 에이전트용 환경 설정 파일인 /var/lib/istio/envoy/sidecar.env
파일을 통해 수행할 수 있습니다.
# 기존 설정 파일 내용 확인
cat /var/lib/istio/envoy/sidecar.env
grep "^[^#]" /var/lib/istio/envoy/sidecar.env # 주석 제외한 실제 설정만 보기
# 설정 추가
echo 'ISTIO_AGENT_FLAGS="--log_output_level=dns:debug"' >> /var/lib/istio/envoy/sidecar.env
echo 'SECRET_TTL="12h0m0s"' >> /var/lib/istio/envoy/sidecar.env
# 변경된 설정 확인
grep "^[^#]" /var/lib/istio/envoy/sidecar.env
# 출력 예시
ISTIO_AGENT_FLAGS="--log_output_level=dns:debug"
SECRET_TTL="12h0m0s"
이제 변경 사항을 적용하기 위해 에이전트를 재시작합니다.
# Istio 에이전트 재시작
systemctl restart istio
디버그 로그를 확인하여 설정이 잘 적용되었는지 확인합니다. 예를 들어, 도메인 질의가 DNS 프록시에서 어떻게 처리되는지 로그에서 볼 수 있습니다.
# 로그 확인
tail -f /var/log/istio/istio.log
# 출력 예시
2025-05-25T07:23:03.660035Z debug dns response for hostname "www.daum.net." not found in dns proxy, querying upstream
2025-05-25T07:23:03.662845Z debug dns upstream response for hostname "www.daum.net." : ;; opcode: QUERY, status: NOERROR, id: 30399
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.daum.net. IN A
;; ANSWER SECTION:
www.daum.net. 77 IN CNAME daum-4vdtymgd.kgslb.com.
daum-4vdtymgd.kgslb.com. 5 IN A 121.53.105.193
로컬 DNS 프록시가 질의를 처리했는지도 직접 확인해볼 수 있습니다.
dig +short @localhost -p 15053 www.daum.net
이외에도 인증서 TTL을 변경한 설정이 적용되었는지는 /etc/certs/cert-chain.pem
경로에서 인증서 만료 시간을 확인하여 검증할 수 있습니다.
📌 더 많은 설정 옵션은 Istio 공식 문서인 pilot-agent CLI 문서를 참조하세요.
Removing a WorkloadEntry from the mesh
가상머신이 메시(Mesh)에 자동으로 등록된 것처럼, 삭제되면 WorkloadEntry도 자동으로 정리됩니다.
실습 예시
watch kubectl get workloadentries -A
kubectl get workloadentries -A
# 출력 예시
No resources found
포인트
기능별 비교 요약
기능 | 쿠버네티스 구현 | 가상머신 구현 |
---|---|---|
프록시 설치 | istioctl 주입 또는 웹훅 자동 주입 | 수동 다운로드 및 설치 |
프록시 설정 | 사이드카 주입 중 완료 | istioctl + WorkloadGroup 으로 설정 생성 및 전송 |
워크로드 ID 부트스트랩 | 쿠버네티스가 SA 토큰 자동 주입 | SA 토큰 수동 전송 필요 |
헬스 체크 | Readiness / Liveness Probe 사용 | WorkloadGroup의 Readiness 설정 사용 |
등록 처리 | 쿠버네티스가 자동 처리 | WorkloadGroup을 통한 자동 등록 |
DNS 해석 방식 | 클러스터 내 FQDN 해석 (DNS 프록시 사용은 선택) | istiod가 DNS 프록시 설정 후 FQDN 해석 수행 |
핵심 요점
리스크 예시
"새벽 3시에 가상머신을 재구성하고 메시 등록하라는 요청을 받는 상황"
권장 자동화 도구
자동화의 장점
이번 블로그에서는 가상머신(VM)을 Istio 서비스 메시로 통합하는 전체 과정을 실습을 통해 단계별로 확인해보았습니다.
WorkloadEntry를 활용한 VM 자동 등록, DNS 프록시를 통한 서비스 해석, istio-agent의 동작 커스터마이징 그리고 워크로드 자동 제거 기능까지 이어지는 흐름은 하이브리드 인프라 환경에서도 일관된 메시 정책을 적용할 수 있는 가능성을 잘 보여주었습니다.
가장 흥미로웠던 부분은 DNS 프록시의 동작 구조와 리다이렉트 메커니즘이었습니다.
로컬에서 127.0.0.53 포트로 향하는 DNS 요청을 iptables 규칙을 통해 15053 포트의 istio-agent로 리디렉션하고 이를 통해 클러스터 서비스의 다양한 호스트네임 변형(webapp, webapp.svc 등)을 자동으로 해석하는 방식은 운영자 입장에서 매우 인상 깊은 구조였습니다.
pilot-agent
의 로그 수준을 설정하거나 인증서 TTL을 조정하는 방식처럼 운영 환경에 맞게 메시 동작을 정밀하게 튜닝할 수 있는 유연성도 Istio의 강점 중 하나임을 실감할 수 있었습니다.
마지막 단계에서 WorkloadEntry가 VM이 종료됨과 동시에 자동으로 정리되는 메커니즘은 동적인 클라우드 환경에서 메시의 상태를 안정적으로 유지하기 위한 중요한 설계 포인트로서 작용할것 같습니다.