웨이포인트 프록시 구성하기
웨이포인트 프록시 구성하기 (Configure waypoint proxies)
**웨이포인트 프록시(waypoint proxy)**는 정의된 워크로드 집합에 Layer 7(L7) 처리를 추가하기 위한, Envoy 기반 프록시의 선택적 배포예요.
출처: Istio 문서
본문
웨이포인트 프록시는 애플리케이션과 독립적으로 설치·업그레이드·스케일링돼요. 애플리케이션 소유자는 그것의 존재를 몰라야 해요. 각 워크로드 옆에 Envoy 프록시 인스턴스를 실행하는 사이드카 데이터 플레인 모드와 비교하면, 필요한 프록시 수를 상당히 줄일 수 있어요.
웨이포인트 또는 웨이포인트 집합은 유사한 보안 경계를 가진 애플리케이션들 사이에서 공유될 수 있어요. 이는 특정 워크로드의 모든 인스턴스일 수도, 네임스페이스의 모든 워크로드일 수도 있어요.
사이드카 모드와 달리, 앰비언트 모드에서는 정책이 목적지 웨이포인트가 적용해요. 여러모로 웨이포인트는 리소스(네임스페이스, 서비스, 파드)에 대한 게이트웨이 역할을 해요. Istio는 리소스로 들어오는 모든 트래픽이 웨이포인트를 통과하도록 강제하고, 웨이포인트는 그 리소스의 모든 정책을 적용해요.
웨이포인트 프록시가 필요한가요? (Do you need a waypoint proxy?)
앰비언트의 계층적 접근 방식은 사용자가 Istio를 더 점진적으로 도입할 수 있게 해주며, 메시 없음 → 보안 L4 오버레이 → 완전한 L7 처리로 부드럽게 전환할 수 있어요.
앰비언트 모드의 대부분의 기능은 ztunnel 노드 프록시가 제공해요. ztunnel은 안전하게 공유 컴포넌트로 동작할 수 있도록 Layer 4(L4)에서만 트래픽을 처리하도록 범위가 한정되어 있어요.
웨이포인트로 리디렉션을 구성하면, 트래픽이 ztunnel에 의해 그 웨이포인트로 전달돼요. 애플리케이션에 다음 L7 메시 기능 중 하나라도 필요하다면 웨이포인트 프록시를 사용해야 해요:
- 트래픽 관리: HTTP 라우팅 & 로드 밸런싱, 서킷 브레이킹, 레이트 리미팅, 결함 주입, 재시도, 타임아웃
- 보안: 요청 유형이나 HTTP 헤더 같은 L7 기반 원시 요소에 대한 풍부한 인가 정책
- 가시성: HTTP 메트릭, 액세스 로깅, 트레이싱
웨이포인트 프록시 배포하기 (Deploy a waypoint proxy)
웨이포인트 프록시는 쿠버네티스 Gateway 리소스를 사용해 배포돼요.
쿠버네티스 Gateway API CRD는 대부분의 쿠버네티스 클러스터에 기본으로 설치되어 있지 않다는 점을 명심하세요. Gateway API를 사용하기 전에 설치되어 있는지 확인하세요:
$ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/experimental-install.yaml
이 리소스들을 생성, 적용, 나열하려면 istioctl waypoint 하위 명령을 사용할 수 있어요.
웨이포인트가 배포된 후, 전체 네임스페이스(또는 선택한 서비스나 파드)는 그것을 사용하도록 등록(enrolled)되어야 해요.
특정 네임스페이스에 웨이포인트 프록시를 배포하기 전에, 네임스페이스가 istio.io/dataplane-mode: ambient으로 레이블링되었는지 확인하세요:
$ kubectl get ns -L istio.io/dataplane-mode
NAME STATUS AGE DATAPLANE-MODE
istio-system Active 24h
default Active 24h ambient
istioctl은 웨이포인트 프록시용 쿠버네티스 Gateway 리소스를 생성할 수 있어요. 예를 들어, default 네임스페이스의 서비스 트래픽을 처리할 수 있는 waypoint라는 웨이포인트 프록시를 생성하려면:
$ istioctl waypoint generate --for service -n default
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
istio.io/waypoint-for: service
name: waypoint
namespace: default
spec:
gatewayClassName: istio-waypoint
listeners:
- name: mesh
port: 15008
protocol: HBONE
Gateway 리소스가 istio-waypoint라는 gatewayClassName을 가지며, 이는 Istio 관리 웨이포인트를 인스턴스화한다는 점을 명심하세요. Gateway 리소스는 istio.io/waypoint-for: service로 레이블링되어, 웨이포인트가 서비스 트래픽을 처리할 수 있음을 나타내요. 이것이 기본값이에요.
웨이포인트 프록시를 직접 배포하려면 generate 대신 apply를 사용하세요:
$ istioctl waypoint apply -n default
waypoint default/waypoint applied
또는 생성된 Gateway 리소스를 배포할 수 있어요:
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
labels:
istio.io/waypoint-for: service
name: waypoint
namespace: default
spec:
gatewayClassName: istio-waypoint
listeners:
- name: mesh
port: 15008
protocol: HBONE
EOF
Gateway 리소스가 적용된 후, Istiod가 리소스를 모니터링하고 사용자를 위해 해당 웨이포인트 배포와 서비스를 자동으로 배포·관리해요.
웨이포인트 트래픽 유형 (Waypoint traffic types)
기본적으로 웨이포인트는 그 네임스페이스의 서비스로 향하는 트래픽만 처리해요. 이 선택을 한 이유는 파드 단독으로 향하는 트래픽은 드물고, Prometheus 스크레이핑 같은 내부 목적으로 자주 사용되며, L7 처리의 추가 오버헤드가 바람직하지 않을 수 있기 때문이에요.
웨이포인트가 모든 트래픽을 처리하거나, 클러스터의 워크로드(파드 또는 VM)에 직접 보내지는 트래픽만 처리하거나, 아무 트래픽도 처리하지 않도록 하는 것도 가능해요. 웨이포인트로 리디렉션될 트래픽의 유형은 Gateway 오브젝트의 istio.io/waypoint-for 레이블로 결정돼요.
istioctl waypoint apply의 --for 인자를 사용해 웨이포인트로 리디렉션될 수 있는 트래픽의 유형을 바꿀 수 있어요:
waypoint-for 값 |
원래 목적지 유형 |
|---|---|
service |
쿠버네티스 서비스 |
workload |
파드 IP 또는 VM IP |
all |
서비스와 워크로드 트래픽 모두 |
none |
트래픽 없음 (테스트에 유용) |
웨이포인트 선택은 트래픽이 원래 주소로 지정된 목적지 유형(service 또는 workload)에 기반해 이루어져요. 웨이포인트가 없는 서비스로 주소가 지정된 트래픽은, 비록 그것이 도달하는 최종 워크로드에 웨이포인트가 부착되어 있더라도, 웨이포인트를 경유하지 않아요.
웨이포인트 프록시 사용하기 (Use a waypoint proxy)
웨이포인트 프록시가 배포되면, 명시적으로 그것을 사용하도록 리소스를 구성하기 전까지는 어떤 리소스도 사용하지 않아요.
네임스페이스, 서비스 또는 파드가 웨이포인트를 사용하도록 활성화하려면, 값이 웨이포인트 이름인 istio.io/use-waypoint 레이블을 추가하세요.
istioctl로 네임스페이스 웨이포인트를 배포한다면, --enroll-namespace 파라미터를 사용해 네임스페이스에 자동으로 레이블을 붙일 수 있어요:
$ istioctl waypoint apply -n default --enroll-namespace
waypoint default/waypoint applied
namespace default labeled with "istio.io/use-waypoint: waypoint"
또는 kubectl로 default 네임스페이스에 istio.io/use-waypoint: waypoint 레이블을 추가할 수 있어요:
$ kubectl label ns default istio.io/use-waypoint=waypoint
namespace/default labeled
네임스페이스가 웨이포인트를 사용하도록 등록된 후에는, 앰비언트 데이터 플레인 모드를 사용하는 모든 파드에서 그 네임스페이스에서 실행되는 모든 서비스로의 요청이, L7 처리와 정책 적용을 위해 웨이포인트를 통해 라우팅돼요.
전체 네임스페이스에 웨이포인트를 사용하는 것보다 더 세밀한 제어를 원한다면, 특정 서비스나 파드만 웨이포인트를 사용하도록 등록할 수 있어요. 이는 네임스페이스의 일부 서비스에만 L7 기능이 필요할 때, WasmPlugin 같은 확장을 특정 서비스에만 적용하고 싶을 때, 또는 파드 IP로 쿠버네티스 헤드리스 서비스를 호출할 때 유용할 수 있어요.
인그레스 게이트웨이와 웨이포인트 (Ingress gateways and waypoints)
istio.io/use-waypoint 레이블은 이스트-웨스트 트래픽을 관장해요. 메시 안의 다른 파드에서 레이블이 붙은 네임스페이스, 서비스, 워크로드로의 요청은 Layer 7 정책과 텔레메트리를 위해 목적지 웨이포인트를 통해 보내져요.
Istio 인그레스 게이트웨이에서 그 Service로의 트래픽은 별도로 모델링돼요. 기본적으로 인그레스에서 시작된 트래픽은, 서비스나 네임스페이스에 istio.io/use-waypoint가 설정되어 있더라도 목적지 서비스 웨이포인트를 사용하지 않아요.
인그레스 트래픽을 메시 트래픽과 같은 웨이포인트로 보내려면, 쿠버네티스 Service, 또는 해당 네임스페이스의 모든 서비스에 적용하려면 Namespace에 **istio.io/ingress-use-waypoint**를 true로 설정하세요 (Istio 1.25부터 지원). 지원되는 리소스 유형은 리소스 레이블 참조를 확인하세요.
$ kubectl label service reviews istio.io/ingress-use-waypoint=true
service/reviews labeled
컨트롤 플레인은 istiod에 대해 **ENABLE_INGRESS_WAYPOINT_ROUTING**이 활성화된 경우에만 이 동작을 적용하며, 기본값은 false예요. pilot-discovery 환경 참조에서 ENABLE_INGRESS_WAYPOINT_ROUTING을 확인하세요.
특정 웨이포인트를 사용하도록 서비스 구성하기 (Configure a service to use a specific waypoint)
샘플 bookinfo 애플리케이션의 서비스를 사용해, reviews 서비스용 reviews-svc-waypoint라는 웨이포인트를 배포할 수 있어요:
$ istioctl waypoint apply -n default --name reviews-svc-waypoint
waypoint default/reviews-svc-waypoint applied
reviews 서비스에 reviews-svc-waypoint 웨이포인트를 사용하도록 레이블을 붙이세요:
$ kubectl label service reviews istio.io/use-waypoint=reviews-svc-waypoint
service/reviews labeled
이제 메시 안의 파드에서 reviews 서비스로의 모든 요청이 reviews-svc-waypoint 웨이포인트를 통해 라우팅돼요.
특정 웨이포인트를 사용하도록 파드 구성하기 (Configure a pod to use a specific waypoint)
reviews-v2 파드용 reviews-v2-pod-waypoint라는 웨이포인트를 배포하세요.
$ istioctl waypoint apply -n default --name reviews-v2-pod-waypoint --for workload
waypoint default/reviews-v2-pod-waypoint applied
reviews-v2 파드에 reviews-v2-pod-waypoint 웨이포인트를 사용하도록 레이블을 붙이세요:
$ kubectl label pod -l version=v2,app=reviews istio.io/use-waypoint=reviews-v2-pod-waypoint
pod/reviews-v2-5b667bcbf8-spnnh labeled
이제 앰비언트 메시 안의 파드에서 reviews-v2 파드 IP로의 모든 요청이, L7 처리와 정책 적용을 위해 reviews-v2-pod-waypoint 웨이포인트를 통해 라우팅돼요.
트래픽이 웨이포인트를 통과하도록 요구하기 (Require traffic to traverse the waypoint)
istio.io/use-waypoint 레이블은 웨이포인트를 통해 트래픽을 보내려는 의도를 기록하지만, 그 자체만으로는 이것이 일어난다는 것을 보장하지 않아요. ztunnel은 다음 경우에 요청을 실패시키지 않고 트래픽을 목적지로 직접 라우팅해요:
- 이름이 지정된 웨이포인트가 존재하지 않거나 주소가 없을 때; 또는
- 트래픽 유형이 웨이포인트가 처리하는 트래픽과 일치하지 않을 때; 예를 들어 웨이포인트가 서비스 트래픽만 처리할 때(기본값) 워크로드(파드 또는 VM IP)에 직접 보내지는 요청.
어느 경우든, 웨이포인트가 적용했을 Layer 7 정책은 전혀 적용되지 않으며, 트래픽은 웨이포인트가 구성되지 않은 것처럼 흐른다.
웨이포인트의 Layer 7 정책을 적용하는 것이 보안 요구사항이라면, 웨이포인트의 신원만 허용하는 AuthorizationPolicy로 웨이포인트를 필수로 만들어라. 웨이포인트는 자기 Gateway의 이름을 딴 service account를 사용하므로, 목적지 워크로드에서 그 신원만 허용하는 정책은 웨이포인트를 먼저 통과하지 않고 도달하는 모든 클라이언트를 거부해요. 위의 reviews-svc-waypoint 웨이포인트로 계속 진행하면:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: require-waypoint
namespace: default
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/reviews-svc-waypoint
이 정책은 targetRef가 아니라 워크로드 selector를 사용하므로, ztunnel이 Layer 4에서 적용해요. 따라서 웨이포인트를 사용할 수 없을 때와 클라이언트가 워크로드를 직접 다이얼할 때 둘 다, 우회 사례 모두에서 적용돼요.
웨이포인트 사이 트래픽 이동하기 (Shift traffic between waypoints)
서비스의 istio.io/use-waypoint 레이블을 바꾸면 모든 트래픽이 한 번에 새 웨이포인트로 이동해요. 두 웨이포인트 사이에서 서비스를 점진적으로 이동하려면, 예를 들어 업그레이드 중 새 웨이포인트 리비전을 검증하려면, 주 웨이포인트 옆에 두 번째 카나리 웨이포인트를 만들고 서비스 트래픽의 일부를 그것에 주세요. 구성은 전적으로 목적지 서비스에 있어요. 클라이언트는 그것을 인지하지 못하며, 두 번째 Service도 필요 없어요.
| 이름 | 유형 | 목적 |
|---|---|---|
istio.io/use-waypoint-canary |
레이블 | 카나리 웨이포인트 Gateway의 이름. |
istio.io/use-waypoint-canary-namespace |
레이블 | 카나리 웨이포인트의 네임스페이스 (서비스의 네임스페이스가 아닌 경우). |
istio.io/use-waypoint-canary-weight |
어노테이션 | 카나리로 보내는 트래픽 비율 (0~100의 정수). 주 웨이포인트가 나머지를 받아요. 기본값 0. |
위의 reviews 서비스로 계속 진행하면서, 두 번째 웨이포인트를 배포하고 서비스 트래픽의 5%를 그것으로 보내고 나머지 95%는 reviews-svc-waypoint에 남겨 두세요:
$ istioctl waypoint apply -n default --name reviews-svc-waypoint-v2
waypoint default/reviews-svc-waypoint-v2 applied
$ kubectl label service reviews istio.io/use-waypoint-canary=reviews-svc-waypoint-v2
$ kubectl annotate service reviews istio.io/use-waypoint-canary-weight=5
카나리에 대한 신뢰가 쌓이면 weight를 높이세요. 카나리가 모든 트래픽을 처리하게 되면, 그것을 주 웨이포인트로 만들어 카나리 구성을 제거함으로써 승격하세요:
$ kubectl label service reviews istio.io/use-waypoint=reviews-svc-waypoint-v2 --overwrite
$ kubectl label service reviews istio.io/use-waypoint-canary-
$ kubectl annotate service reviews istio.io/use-waypoint-canary-weight-
언제든 롤백하려면 카나리 레이블을 제거하세요. 서비스는 모든 트래픽을 주 웨이포인트를 통해 보내는 것으로 돌아가요.
지원되는 리소스 (Supported resources)
카나리 레이블과 어노테이션은 Service, ServiceEntry, Namespace에서 지원돼요. istio.io/use-waypoint와 달리 Pod나 WorkloadEntry에서는 지원되지 않아요. 분할은 메시 트래픽과 인그레스 트래픽에 대해 동일하게 동작하도록 서비스 수준에서 정의되기 때문이에요.
네임스페이스에 구성된 카나리는, 자기의 주 웨이포인트도 그 네임스페이스에서 상속하는 서비스에만 적용돼요. 서비스가 자기 자신의 istio.io/use-waypoint를 설정하면, 자체 카나리 구성도 설정해야 해요. 그 서비스에 대해서는 네임스페이스의 카나리 레이블이 무시돼요.
두 웨이포인트 모두 서비스를 프런트할 수 있어야 해요. 각각이 준비 상태여야 하고, 서비스의 네임스페이스에서의 부착을 허용해야 하며, service 또는 all 트래픽을 처리해야 해요.
weight가 적용되는 것 (What the weight applies to)
- 메시 트래픽은 ztunnel이 연결별로 분할해요. weight는 카나리를 선택하는 새로운 연결의 비율이에요. 확립된 연결은 결코 이동되지 않으므로, 클라이언트가 수명이 긴 연결을 유지하는 서비스는 그러한 클라이언트가 재연결할 때만 구성된 weight에 가까워져요. 같은 이유로 관찰된 분할은 근사치이며, 많은 수의 연결에서만 의미가 있어요.
- 인그레스 트래픽은 인그레스 게이트웨이와 웨이포인트에서 설명한 대로
istio.io/ingress-use-waypoint로 옵트인한 서비스에 대해서만, 인그레스 게이트웨이가 요청별로 분할해요. 그 옵트인이 없으면 인그레스 트래픽은 계속 두 웨이포인트를 모두 우회해요.
메시 분할에는 Istio 1.31 이상의 ztunnel이 필요해요. 데이터 플레인이 업그레이드되는 동안, 이전 ztunnel을 실행하는 노드는 모든 연결을 주 웨이포인트로 보내므로, 모든 노드가 업그레이드될 때까지 메시 전체의 분할이 구성된 weight에 뒤처져요. 인그레스 분할은 ztunnel에 의존하지 않아요.
웨이포인트에 부착된 구성 (Configuration attached to the waypoint)
두 웨이포인트 모두 같은 서비스를 제공하므로, 전환 동안 유효해야 하는 어떤 구성도 두 곳 모두에 적용되어야 해요. Service를 대상으로 하는 정책과 라우트(SG상의 AuthorizationPolicy나 서비스를 parentRef로 하는 HTTPRoute 같은)는 트래픽을 처리하는 쪽 웨이포인트가 적용하며 중복이 필요 없어요.
웨이포인트 Gateway 자체에 부착된 구성은 다른 문제예요. 웨이포인트를 선택하는 WasmPlugin이나 targetRef가 Gateway를 지정하는 정책은 그 웨이포인트에만 적용돼요. 트래픽을 이동하기 전에 카나리에 복제하세요. 그렇지 않으면 카나리를 통과하는 트래픽은 다른 정책 집합으로 처리돼요.
잘못된 구성 (Invalid configuration)
사용할 수 없는 카나리는 치명적이지 않아요. 서비스는 주 웨이포인트만 계속 사용하고, 이유는 서비스의 istio.io/WaypointBound 조건에 보고돼요:
$ kubectl get service reviews -o jsonpath='{.status.conditions}'
이 폴백은 카나리 웨이포인트가 존재하지 않거나, 준비되지 않았거나, 서비스 네임스페이스에서의 부착을 허용하지 않거나, 서비스 트래픽을 처리할 수 없을 때; weight가 0~100의 정수가 아닐 때(CanaryInvalidWeight); 카나리가 주 웨이포인트와 같은 웨이포인트를 가리킬 때(CanarySameAsPrimary) 적용돼요.
크로스-네임스페이스 웨이포인트 사용 (Cross-namespace waypoint use)
바로 사용할 수 있고(straight out of the box), 웨이포인트 프록시는 같은 네임스페이스 안의 리소스가 사용할 수 있어요. Istio 1.23부터 서로 다른 네임스페이스의 웨이포인트를 사용할 수 있게 되었어요. 이 섹션에서는 크로스-네임스페이스 사용을 활성화하는 데 필요한 게이트웨이 구성과, 다른 네임스페이스의 웨이포인트를 사용하도록 리소스를 구성하는 방법을 살펴볼 거예요.
크로스-네임스페이스 사용을 위한 웨이포인트 구성하기 (Configure a waypoint for cross-namespace use)
웨이포인트의 크로스-네임스페이스 사용을 활성화하려면, Gateway가 다른 네임스페이스의 라우트를 허용하도록 구성되어야 해요.
다음 Gateway는 "cross-namespace-waypoint-consumer"라는 네임스페이스의 리소스가 이 egress-gateway를 사용하도록 허용해요. 웨이포인트를 이그레스 게이트웨이로 사용하는 완전한 단계별 가이드는 이그레스 게이트웨이를 참조하세요.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: egress-gateway
namespace: common-infrastructure
spec:
gatewayClassName: istio-waypoint
listeners:
- name: mesh
port: 15008
protocol: HBONE
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: cross-namespace-waypoint-consumer
크로스-네임스페이스 웨이포인트 프록시를 사용하도록 리소스 구성하기 (Configure resources to use a cross-namespace waypoint proxy)
기본적으로 Istio 컨트롤 플레인은 istio.io/use-waypoint 레이블로 지정된 웨이포인트를 레이블이 적용된 리소스와 같은 네임스페이스에서 찾아요. istio.io/use-waypoint-namespace라는 새 레이블을 추가하면 다른 네임스페이스의 웨이포인트를 사용할 수 있어요. istio.io/use-waypoint-namespace는 istio.io/use-waypoint 레이블을 지원하는 모든 리소스에서 동작해요. 두 레이블을 함께 사용해 각각 웨이포인트의 이름과 네임스페이스를 지정해요. 예를 들어 istio-site라는 ServiceEntry가 common-infrastructure라는 네임스페이스의 egress-gateway라는 웨이포인트를 사용하도록 구성하려면 다음 명령을 사용할 수 있어요:
$ kubectl label serviceentries.networking.istio.io istio-site istio.io/use-waypoint=egress-gateway
serviceentries.networking.istio.io/istio-site labeled
$ kubectl label serviceentries.networking.istio.io istio-site istio.io/use-waypoint-namespace=common-infrastructure
serviceentries.networking.istio.io/istio-site labeled
정리하기 (Cleaning up)
다음을 수행해 네임스페이스에서 모든 웨이포인트를 제거할 수 있어요:
$ istioctl waypoint delete --all -n default
$ kubectl label ns default istio.io/use-waypoint-
쿠버네티스 Gateway API CRD를 제거하세요:
$ kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/experimental-install.yaml