이 페이지에서는 인그레스 트래픽의 부하 분산을 위해 단일 Google Kubernetes Engine(GKE) 클러스터에 Kubernetes 게이트웨이 리소스를 배포하는 방법을 설명합니다.
여러 클러스터(또는 Fleet)에 인그레스 트래픽을 부하 분산하기 위한 게이트웨이를 배포하려면 멀티 클러스터 게이트웨이 배포를 참조하세요.시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우
gcloud components update
를 실행하여 최신 버전을 가져옵니다.
GKE Gateway Controller 요구사항
- 표준인 경우 GKE 버전 1.24 이상
- Autopilot의 경우 GKE 버전 1.26 이상
- Google Cloud CLI 버전 407.0.0 이상
- Gateway API는 VPC 기반 클러스터에서만 지원됩니다.
- 내부 GatewayClasses를 사용하는 경우 프록시 전용 서브넷을 사용 설정해야 합니다.
- 클러스터에
HttpLoadBalancing
부가기능이 사용 설정되어 있어야 합니다. - Istio를 사용하는 경우 Istio를 다음 버전 중 하나로 업그레이드해야 합니다.
- 1.15.2 이상
- 1.14.5 이상
- 1.13.9 이상
- 공유 VPC를 사용하는 경우 호스트 프로젝트에서 서비스 프로젝트에 대해 GKE 서비스 계정에
Compute Network User
역할을 할당해야 합니다.
제한 및 한도
GKE 게이트웨이를 사용할 때는 다음과 같은 제한과 한도에 유의하세요.
최적 성능을 위해 게이트웨이 수를 최대 100으로 제한합니다. 이 한도를 초과하면 성능에 영향을 주거나 지연 시간이 늘어날 수 있습니다.
GKE GatewayClasses는 사용하는 부하 분산기에 따라 다양한 기능을 지원합니다. 각 GatewayClass에서 지원되는 다양한 기능에 대한 자세한 내용은 GatewayClass 기능을 참조하세요.
FrontendConfig 또는 BackendConfig를 사용하여 게이트웨이를 구성할 수 없습니다. 정책을 사용해야 합니다.
GKE 게이트웨이는 해당 게이트웨이가 상태 점검 매개변수를 추론하지 않는다는 점에서 인그레스와 다르게 작동합니다. 서비스가
GET /
요청에 대해 200을 반환하지 않거나 다른 조정된 포드 준비 점검이 있는 경우 서비스에 HealthCheckPolicy를 구성해야 합니다.트래픽 라우팅을 위해 호스트 이름(예: web.example.com:80)에 포트 번호를 직접 지정할 수 없습니다.
Google Cloud 콘솔에서 GKE가 게이트웨이에 대해 만드는 부하 분산기 리소스를 볼 수 있지만 이러한 리소스는 연결된 게이트웨이 또는 GKE 클러스터를 참조하지 않습니다.
- 게이트웨이를 사용하여 Google 관리형 SSL 인증서를 자동으로 생성할 수는 없지만 수동으로 Google 관리형 SSL 인증서를 만들고 참조할 수 있습니다. 자세한 내용은 게이트웨이 보안을 참조하세요.
HTTPRoute는 유일하게 지원되는 경로 유형입니다. TCPRoutes, UDPRoutes, TLSRoutes는 지원되지 않습니다. GKE Gateway Controller가 지원하는 필드 목록을 보려면 GatewayClass 기능을 참조하세요.
게이트웨이 또는 경로 리디렉션 및 URL 재작성이 포함된 커스텀 요청 및 응답 헤더는 GKE 버전 1.27 이상에서만 사용할 수 있습니다.
- 게이트웨이, 경로 리디렉션 및 URL 재작성이 포함된 커스텀 요청 및 응답 헤더의 경우 GatewayClass
gke-l7-gxlb
는 지원되지 않습니다.
HTTPRoute 커스텀 요청 및 응답 헤더를 구성할 때는 다음 Google Cloud 변수가 지원되지 않습니다.
cdn_cache_id
(Cloud CDN은 GKE 게이트웨이에서 지원되지 않음)cdn_cache_status
(Cloud CDN은 GKE 게이트웨이에서 지원되지 않음)origin_request_header
(CORS 정책은 GKE 게이트웨이에서 지원되지 않음)
GKE 게이트웨이는 Cloud CDN 부하 분산 기능을 지원하지 않습니다.
상호 TLS 커스텀 헤더는 지원되지 않습니다(GKE 게이트웨이를 사용하는 mTLS는 지원되지 않음).
Google Cloud 기본 애플리케이션 부하 분산기 제한사항은 GKE 게이트웨이에 적용되며 다음과 같은 한 가지 추가 제한사항이 있습니다.
- 백엔드 서비스에서 커스텀 호스트 응답 헤더를 구성할 수 없습니다.
경로 리디렉션과 URL 재작성은 상호 배타적이므로 동일한 규칙에서 두 필터를 동시에 사용할 수 없습니다.
Cloud Load Balancing에서는 트래픽을 다른 포트로 리디렉션할 수 없습니다. GKE Gateway Controller가 지원하는 필드 목록을 보려면 GatewayClass 기능을 참조하세요.
GKE 게이트웨이는 와일드 카드, 정규 표현식, 동적 URL을 지원하지 않습니다.
리전별 외부 게이트웨이 클래스로 게이트웨이를 지정하면 컨트롤러는 외부 주소 대신 내부 IP 주소를 프로비저닝합니다. 리전 외부 애플리케이션 부하 분산기에서 이름이 지정된 주소를 사용하는 방법은 리전 외부 게이트웨이 배포를 참조하세요.
게이트웨이는 독립형 NEG를 활용하여 네트워크 엔드포인트 그룹을 프로비저닝합니다. 게이트웨이 컨트롤러가 부하 분산기 구성을 적절히 조정해야 하므로 게이트웨이에 포함된 서비스의
cloud.google.com/neg
주석을 수정할 수는 없습니다.GKE 게이트웨이는 GKE 인그레스에서도 참조되는 서비스 참조를 지원하지 않습니다.
IP 주소를 프로비저닝하도록
Gateway
를 구성한 경우Gateway.spec.gatewayClass
변경이 지원되지 않습니다. 게이트웨이 컨트롤러가 부하 분산기를 적절히 조정할 수 있도록 기존 게이트웨이를 삭제하고gatewayClass
값을 업데이트하여 매니페스트를 다시 배포하세요.networking.gke.io/app-protocols
주석은 지원되지 않습니다. 동일한 결과를 얻으려면 대신appProtocol
필드를 사용하세요.external-dns
에 GKE 게이트웨이를 사용하고 게이트웨이 상태가 비정상이면 기본적으로 게이트웨이와 연결된 모든 DNS 레코드가 DNS 영역에서 삭제됩니다. 기존 DNS 레코드가 삭제되지 않도록 하려면external-dns
를 실행할 때--policy=upsert-only
플래그를 설정하는 것이 좋습니다.
클러스터에서 Gateway API 사용 설정
GKE에서 게이트웨이 리소스를 사용하려면 클러스터에서 Gateway API를 사용 설정해야 합니다.
Gateway API가 사용 설정된 새 클러스터 만들기
GKE는 GKE 버전 1.26부터 Autopilot 클러스터에서 Gateway API를 지원합니다. GKE 1.26 이상에서 새 Autopilot 클러스터를 만드는 경우 기본적으로 Gateway API가 사용 설정됩니다. GKE 버전 1.25 이하의 기존 클러스터의 경우 기본적으로 Gateway API가 사용 중지됩니다.
네트워크를 지정하지 않고 클러스터를 먼저 만들 경우(--network
플래그 사용), GKE가 기본 네트워크에 클러스터를 만듭니다. 이 경우에는 기본 네트워크에서 프록시 전용 서브넷 만들기도 수행해야 합니다. 클러스터 만들기 중 네트워크를 지정할 경우 동일한 네트워크에 프록시 전용 서브넷도 만들어야 합니다.
Autopilot
Gateway API가 사용 설정된 새 GKE Autopilot 클러스터 만들기:
gcloud container clusters create-auto CLUSTER_NAME \
--location=CLUSTER_LOCATION \
--release-channel=RELEASE_CHANNEL \
--cluster-version=VERSION
다음을 바꿉니다.
CLUSTER_NAME
: 클러스터의 이름CLUSTER_LOCATION
: 새 클러스터의 Compute Engine 리전 또는 영역RELEASE_CHANNEL
: 출시 채널의 이름VERSION
: GKE 버전이며 1.26 이상이어야 함.--release-channel
플래그를 사용하여 출시 채널을 선택할 수도 있습니다. 출시 채널은 기본 버전이 1.26 이상이어야 합니다.
Standard
GKE Standard를 사용하면 Gateway API는 --gateway-api
플래그로 제어됩니다. 사용 설정 시 및 사용 중지 시 가치 표준을 사용할 수 있습니다.
Gateway API가 사용 설정된 새 VPC 기반 GKE 클러스터를 만듭니다.
gcloud container clusters create CLUSTER_NAME \
--gateway-api=standard \
--cluster-version=VERSION \
--location=CLUSTER_LOCATION
다음을 바꿉니다.
RELEASE_CHANNEL
: 출시 채널의 이름CLUSTER_NAME
: 클러스터의 이름VERSION
: GKE 버전. 1.24 이상이어야 합니다.--release-channel
플래그를 사용하여 출시 채널을 선택할 수도 있습니다. 출시 채널은 기본 버전이 1.24 이상이어야 합니다.CLUSTER_LOCATION
: 새 클러스터의 Compute Engine 리전 또는 영역
--gateway-api=standard
플래그를 사용하면 GKE에서 클러스터에 v1beta1
CRD를 설치합니다.
기존 클러스터에서 Gateway API 사용 설정
Autopilot 클러스터 버전이 1.26 이상이고 Standard 클러스터 버전이 1.24 이상인지 확인합니다.
기존 GKE 클러스터(Autopilot 또는 Standard)에서 Gateway API를 사용 설정하려면 다음을 사용합니다.
gcloud container clusters update CLUSTER_NAME \
--location=CLUSTER_LOCATION\
--gateway-api=standard
다음을 바꿉니다.
CLUSTER_NAME
: 기존 클러스터의 이름CLUSTER_LOCATION
: 클러스터의 Compute Engine 리전 또는 영역
--gateway-api=standard
플래그를 사용하면 GKE에서 클러스터에 v1beta1
CRD를 설치합니다.
클러스터 확인
클러스터를 만들거나 업그레이드한 후 GKE Gateway Controller에서 GatewayClasses를 자동으로 설치합니다. 컨트롤러가 CRD를 인식하고 GatewayClasses를 설치하는 데 몇 분 정도 걸릴 수 있습니다.
Gateway API가 GKE 제어 영역에서 사용 설정되었는지 확인합니다.
gcloud container clusters describe CLUSTER_NAME \ --location=CLUSTER_LOCATION \ --format json
출력은 다음과 비슷합니다. 이 출력이 비어 있는 경우 클러스터 업데이트 명령어를 다시 실행합니다.
"networkConfig": { ... "gatewayApiConfig": { "channel": "CHANNEL_STANDARD" }, ... },
클러스터에 GatewayClasses가 설치되어 있는지 확인합니다.
kubectl get gatewayclass
출력은 다음과 비슷합니다.
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-rilb networking.gke.io/gateway True 16h
각 GatewayClass의 기능을 이해하기 위해서는 GatewayClass 기능을 참조하세요.
내부 게이트웨이 배포
내부 게이트웨이는 VPC 내에서 또는 VPC에 연결된 네트워크에서만 연결할 수 있는 애플리케이션을 노출합니다.
리전 내부 게이트웨이 배포
다음 예시에서는 특정 지역 리전 내의 서비스 간에 효율적이고 안전한 통신을 사용 설정하는 리전 내부 게이트웨이를 배포하는 방법을 보여줍니다.
프록시 전용 서브넷 구성
내부 애플리케이션 부하 분산기를 사용하는 게이트웨이를 만들기 전에 프록시 전용 서브넷을 구성해야 합니다. 내부 애플리케이션 부하 분산기를 사용하는 VPC의 각 리전에는 프록시 전용 서브넷이 있어야 합니다. 이 서브넷은 부하 분산기 프록시에 내부 IP 주소를 제공합니다.
프록시 전용 서브넷을 만듭니다.
gcloud compute networks subnets create SUBNET_NAME \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=COMPUTE_REGION \ --network=VPC_NETWORK_NAME \ --range=CIDR_RANGE
다음을 바꿉니다.
SUBNET_NAME
: 프록시 전용 서브넷의 이름입니다.COMPUTE_REGION
: 프록시 전용 서브넷의 리전입니다.VPC_NETWORK_NAME
: 이 프록시 전용 서브넷을 만드는 VPC 네트워크의 이름입니다. 이 네트워크가 GKE 클러스터가 있고 게이트웨이를 배포하는 VPC 네트워크와 동일한지 확인합니다. 이는 부하 분산기와 백엔드 서비스 사이의 원활한 통신을 위해 중요합니다.CIDR_RANGE
: 서브넷의 기본 IP 주소 범위입니다. 리전의 프록시에서 64개 이상의 IP 주소를 사용할 수 있도록/26
이하의 서브넷 마스크를 사용해야 합니다. 권장 서브넷 마스크는/23
입니다.
프록시 전용 서브넷을 확인합니다.
gcloud compute networks subnets describe SUBNET_NAME \ --region=COMPUTE_REGION
출력은 다음과 비슷합니다.
... gatewayAddress: 10.1.1.1 ipCidrRange: 10.1.1.0/24 kind: compute#subnetwork name: proxy-subnet network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default privateIpGoogleAccess: false privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS purpose: REGIONAL_MANAGED_PROXY region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION role: ACTIVE selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet state: READY
게이트웨이 만들기
게이트웨이 리소스는 Kubernetes에서 트래픽을 라우팅하는 데이터 영역을 나타냅니다. 게이트웨이는 파생된 GatewayClass에 따라 여러 종류의 부하 분산 및 라우팅을 나타낼 수 있습니다. 게이트웨이 리소스에 대한 자세한 내용은 게이트웨이 리소스 설명 또는 API 사양을 참조하세요.
여기에서는 GKE 클러스터의 관리자가 애플리케이션을 내부적으로 노출하기 위해 다른 팀에서 사용될 수 있는 게이트웨이를 만듭니다. 관리자가 게이트웨이를 배포한 후 애플리케이션 팀은 해당 경로를 독립적으로 배포하고 이를 이 게이트웨이에 연결합니다.
다음 게이트웨이 매니페스트를
gateway.yaml
이라는 파일에 저장합니다.kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80
이 매니페스트에는 다음 필드가 포함됩니다.
gatewayClassName: gke-l7-rilb
: 이 게이트웨이가 파생된 GatewayClass를 지정합니다.gke-l7-rilb
는 내부 애플리케이션 부하 분산기에 해당합니다.port: 80
: 게이트웨이가 HTTP 트래픽을 리슨하기 위해 포트 80만 노출하도록 지정합니다.
클러스터에 게이트웨이를 배포합니다.
kubectl apply -f gateway.yaml
게이트웨이가 올바르게 배포되었는지 확인합니다. 모든 리소스를 배포하려면 몇 분 정도 걸릴 수 있습니다.
kubectl describe gateways.gateway.networking.k8s.io internal-http
출력은 다음과 비슷합니다.
Name: internal-http Namespace: default Spec: Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 192.168.1.14 Conditions: Last Transition Time: 1970-01-01T00:00:00Z Message: Waiting for controller Reason: NotReconciled Status: False Type: Scheduled Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 92s networking.gke.io/gateway test/internal-http Normal UPDATE 45s (x3 over 91s) networking.gke.io/gateway test/internal-http Normal SYNC 45s networking.gke.io/gateway SYNC on test/internal-http was a success
이 시점에서는 부하 분산기 및 IP 주소를 프로비저닝한 클러스터에 게이트웨이가 배포됩니다. 게이트웨이에는 경로가 포함되지 않습니다. 하지만 따라서 백엔드에 트래픽을 전송하는 방법을 아직 알 수 없습니다. 경로가 없으면 모든 트래픽이 기본 백엔드로 이동하고, 이것이 HTTP 404를 반환합니다. 그런 후 애플리케이션 및 경로를 배포합니다. 이것은 게이트웨이에 애플리케이션 백엔드를 가져오는 방법을 알려줍니다.
데모 애플리케이션 배포
애플리케이션팀은 게이트웨이의 배포와 독립적으로 해당 애플리케이션 및 경로를 배포할 수 있습니다. 일부 경우에 애플리케이션팀은 게이트웨이도 소유하고, 애플리케이션 전용 리소스로 이를 직접 배포해야 할 수 있습니다. 게이트웨이 및 경로의 서로 다른 소유 모델은 경로 바인딩을 참조하세요. 하지만 이 예시에서 스토어팀은 이전 섹션에서 만든 internal-http
게이트웨이를 통해 앱을 노출하기 위해 해당 애플리케이션 및 수반되는 HTTPRoute를 배포합니다.
HTTPRoute 리소스에는 트래픽 일치를 위한 많은 구성 가능한 필드가 포함됩니다. HTTPRoute의 필드에 대한 설명은 API 사양을 참조하세요.
스토어 애플리케이션(store-v1, store-v2, store-german 배포)을 클러스터에 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
이렇게 하면 이름이 store-v1, store-v2, store-german인 3개 서비스와 3개 배포가 생성됩니다.
애플리케이션이 성공적으로 배포되었는지 확인합니다.
kubectl get pod
애플리케이션이 실행된 후에는 출력이 다음과 비슷합니다.
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14m
서비스도 배포되었는지 확인합니다.
kubectl get service
출력에 각 저장소 배포에 대한 서비스가 표시됩니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
HTTPRoute 배포
경로 리소스는 게이트웨이에서 Kubernetes 백엔드로 트래픽을 매핑하기 위한 프로토콜 특정 규칙을 정의합니다. HTTPRoute 리소스는 HTTP 및 HTTPS 트래픽 일치 및 필터링을 수행하며, 모든 gke-l7
GatewayClass에서 지원됩니다.
이 섹션에서는 HTTPRoute를 배포하여, 스토어 애플리케이션에 연결하기 위해 필요한 라우팅 규칙으로 게이트웨이를 프로그래밍합니다.
다음 HTTPRoute 매니페스트를
store-route.yaml
이라는 파일에 저장합니다.kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store spec: parentRefs: - kind: Gateway name: internal-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080 - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 - matches: - path: value: /de backendRefs: - name: store-german port: 8080
클러스터에 HTTProute를 배포합니다.
kubectl apply -f store-route.yaml
store
HTTPRoute는parentRefs
속성을 사용하여internal-http
게이트웨이에 바인딩됩니다. 이러한 라우팅 규칙은 다음 다이어그램과 같이 기본 부하 분산기에서 구성됩니다.이러한 라우팅 규칙은 다음과 같은 방식으로 HTTP 트래픽을 처리합니다.
store.example.com/de
에 대한 트래픽은store-german
서비스로 이동합니다.- HTTP 헤더
"env: canary"
가 있는store.example.com
에 대한 트래픽은store-v2
서비스로 이동합니다. store.example.com
에 대한 나머지 트래픽은store-v1
서비스로 이동합니다.
HTTPRoute가 배포되었는지 확인합니다.
kubectl describe httproute store
출력은 다음과 비슷합니다.
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1beta1 Kind: HTTPRoute <...> Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: Conditions: Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 24m sc-gateway-controller default/store Normal SYNC 16m (x4 over 23m) sc-gateway-controller Bind of HTTPRoute "default/store" to ParentRef {Group: gateway.networking.k8s.io", <...>
HTTPRoute가 게이트웨이에 바인딩되었는지 확인합니다.
kubectl describe gateway
출력은 다음과 비슷합니다.
Name: internal-http Namespace: default Labels: <none> <...> Status: Addresses: Type: IPAddress Value: 10.128.15.203 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute <...>
애플리케이션에 트래픽 보내기
이제 게이트웨이, 경로, 애플리케이션이 클러스터에 배포되었으므로, 트래픽을 애플리케이션에 전달할 수 있습니다.
애플리케이션에 트래픽을 전송할 수 있도록 게이트웨이에서 IP 주소를 검색합니다.
kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"
출력은 IP 주소입니다.
클러스터 연결을 사용하여 가상 머신(VM) 인스턴스에 대해 셸에서 이 IP 주소로 트래픽을 전송합니다. 이 용도로 VM을 만들 수 있습니다. 이것은 게이트웨이에 내부 IP 주소가 포함되었고 VPC 네트워크 내에서만 액세스할 수 있기 때문에 필요합니다.
internal-http
가 리전 부하 분산기이기 때문에 클라이언트 셸이 GKE 클러스터와 동일한 리전 내에 있어야 합니다.store.example.com에 요청을 수행합니다.
curl https://store.example.com" --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
GATEWAY_IP_ADDRESS
를 이전 단계의 IP 주소로 바꿉니다.데모 앱의 출력에 앱이 실행되는 위치에 대한 정보가 표시됩니다.
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:31:17", "zone": "ZONE_NAME" }
store.example.com/de
에서 스토어 서비스의 독일어 버전으로 이동하여 경로 일치를 테스트합니다.curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
요청이
store-german
포드로 제공되는 것이 출력에 확인됩니다.{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:35:37", "zone": "ZONE_NAME" }
마지막으로
env: canary
HTTP 헤더를 사용하여 스토어 서비스의 카나리아 버전으로 트래픽을 전송합니다.curl -H "env: canary" https://store.example.com" --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
요청이
store-v2
포드로 제공되는 것이 출력에 확인됩니다.{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "🦰", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:38:26", "zone": "ZONE_NAME" }
외부 게이트웨이 배포
외부 게이트웨이는 인터넷이나 VPC 외부의 네트워크에서 액세스할 수 있는 애플리케이션을 노출합니다. 게이트웨이를 공개 인터넷에서 액세스할 수 있으므로 애플리케이션을 보호해야 한다는 점을 제외하면 내부 게이트웨이 배포와 유사합니다.
외부 게이트웨이 만들기에는 외부 게이트웨이 또는 리전 외부 게이트웨이 두 가지 옵션이 있습니다.
전역 외부 게이트웨이는 전역 IP 주소(또는 Anycast IP 주소)를 모든 Google Cloud 컴퓨팅 리전에서 공지된 게이트웨이의 프런트엔드로 사용합니다. 이 Anycast IP 주소로 트래픽을 전송하는 클라이언트는 IP가 공지되는 가장 가까운 Google 위치로 라우팅됩니다. 전역 외부 게이트웨이는 프리미엄 네트워크 서비스 등급에서만 사용할 수 있습니다.
리전 외부 게이트웨이는 리전 외부 게이트웨이가 배포된 로컬 Google Cloud Compute 리전에서만 공지되는 게이트웨이의 프런트엔드로 리전 IP를 사용합니다. 이 리전 IP 주소로 트래픽을 전송하는 클라이언트는 IP가 공지된 Google 리전에 도달하기 전에 해당 로컬 ISP와 인터넷을 통해 라우팅됩니다. 리전 외부 게이트웨이는 표준 네트워크 서비스 등급에서만 사용할 수 있습니다.
전역 외부 게이트웨이 배포
다음 예시에서는 전역 외부 게이트웨이에 연결되고 인증서 관리자와 HTTPRoute를 사용하여 인증서 맵에 그룹화된 여러 인증서가 있는 스토어 애플리케이션을 노출하는 방법을 보여줍니다.
인증서 맵 만들기
게이트웨이당 15개 이상의 인증서가 필요하거나 와일드 카드 인증서를 사용해야 하는 경우 인증서 관리자를 사용하여 인증서를 관리하는 것이 좋습니다.
Kubernetes 보안 비밀 또는 Google 관리형 SSL 인증서를 사용하여 외부 게이트웨이를 보호할 수도 있습니다. 자세한 내용은 게이트웨이 보안을 참조하세요.
이 섹션에서는 인증서 관리자를 사용하여 클러스터에서 실행되는 애플리케이션을 보호하는 인증서를 만듭니다.
Certificate Manager API를 사용 설정합니다.
gcloud services enable certificatemanager.googleapis.com
인증서 맵을 만듭니다.
gcloud beta certificate-manager maps create store-example-com-map
Google 관리 인증서와 키를 인증서에 로드합니다.
gcloud beta certificate-manager certificates create store-example-com-cert \ --certificate-file="CERTIFICATE_FILE" \ --private-key-file="PRIVATE_KEY_FILE"
다음을 바꿉니다.
CERTIFICATE_FILE
: 선택한 새 파일의 이름입니다. 파일 확장자는.pem
이어야 합니다. 예를 들면cert.pem
입니다.PRIVATE_KEY_FILE
: 비공개 키 파일의 이름입니다.
자세한 내용은 비공개 키 및 인증서 만들기를 참조하세요.
인증서 맵에 인증서를 할당하는
CertificateMapEntry
를 만듭니다.gcloud beta certificate-manager maps entries create store-example-com-map-entry \ --map=store-example-com-map \ --hostname=store.example.com \ --certificates=store-example-com-cert
Kubernetes 보안 비밀 또는 SSL 인증서와 같은 다른 인증서 소스를 사용하여 게이트웨이를 보호하는 방법은 게이트웨이 보호를 참조하세요.
게이트웨이 만들기
게이트웨이 리소스는 Kubernetes에서 트래픽을 라우팅하는 데이터 영역을 나타냅니다. 게이트웨이는 사용하는 GatewayClass에 따라 다양한 종류의 부하 분산 및 라우팅을 나타낼 수 있습니다.
게이트웨이 리소스에 대한 자세한 내용은 게이트웨이 리소스 설명 또는 API 사양을 참조하세요.
이 섹션에서는 게이트웨이를 만듭니다. 애플리케이션팀은 게이트웨이를 사용하여 경로를 독립적으로 배포하고 해당 경로를 게이트웨이에 안전하게 연결하여 인터넷에 애플리케이션을 노출할 수 있습니다.
다음 매니페스트를
gateway.yaml
이라는 파일에 저장합니다.kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http annotations: networking.gke.io/certmap: store-example-com-map spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443
이 매니페스트는 다음 필드를 사용해서 게이트웨이를 기술합니다.
gatewayClassName: gke-l7-global-external-managed
: 이 게이트웨이에 GatewayClass를 지정합니다. 이 게이트웨이 클래스는 전역 외부 애플리케이션 부하 분산기를 사용합니다.protocol: HTTPS
및port: 443
: 게이트웨이가 HTTPS 트래픽에 대해 포트 443을 노출하도록 지정합니다. 이러한 필드는 TLS를 사용 설정합니다.networking.gke.io/certmap: store-example-com-map
: 인증서 관리자에서 인증서 맵 이름을 지정합니다.
TLS가
networking.gke.io/certmap
주석을 사용하여 인증서 관리자에서 구성되므로 TLS 섹션이 없습니다.매니페스트를 클러스터에 적용합니다.
kubectl apply -f gateway.yaml
GKE에서 리소스를 배포하는 데 몇 분 정도 걸릴 수 있습니다.
게이트웨이가 성공적으로 배포되었는지 확인합니다.
kubectl describe gateway
출력은 다음과 비슷합니다.
Name: external-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-global-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
이 출력은 클러스터에 배포된 게이트웨이에 부하 분산기와 공개 IP 주소가 있음을 보여줍니다. 게이트웨이에 경로가 없으므로 백엔드로 트래픽을 전송할 수 없습니다. 경로가 없으면 모든 트래픽이 기본 백엔드로 이동하고, 이것이 HTTP 404 응답을 반환합니다. 다음 섹션에서는 게이트웨이에 트래픽을 백엔드로 전송하도록 지시하는 경로를 배포합니다.
데모 애플리케이션 배포
애플리케이션팀은 게이트웨이의 배포와 독립적으로 해당 애플리케이션 및 경로를 배포할 수 있습니다. 일부 경우에 애플리케이션팀은 게이트웨이도 소유하고, 애플리케이션 전용 리소스로 이를 직접 배포해야 할 수 있습니다. 게이트웨이 및 경로의 서로 다른 소유 모델은 경로 바인딩을 참조하세요. 이 예시에서 스토어팀은 이전 섹션에서 만든 external-http
게이트웨이를 통해 앱을 노출하기 위해 해당 애플리케이션 및 수반되는 HTTPRoute를 배포합니다.
HTTPRoute 필드에 대한 자세한 내용은 API 사양을 참조하세요.
클러스터에 샘플 애플리케이션을 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
이 샘플 애플리케이션은 이름이
store-v1
,store-v2
,store-german
인 3개의 배포와 3개의 서비스를 만듭니다.애플리케이션이 성공적으로 배포되었는지 확인합니다.
kubectl get pod
출력은 다음과 비슷합니다.
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14m
서비스가 성공적으로 배포되었는지 확인합니다.
kubectl get service
출력은 다음과 비슷합니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
HTTPRoute 만들기
경로 리소스는 게이트웨이에서 Kubernetes 백엔드로 트래픽을 매핑하기 위한 프로토콜 특정 규칙을 정의합니다. HTTPRoute 리소스는 HTTP 및 HTTPS 트래픽 일치 및 필터링을 수행하며, 모든 gke-l7-*
GatewayClass에서 지원됩니다.
이 섹션에서는 샘플 애플리케이션에 도달하는 데 필요한 라우팅 규칙이 있는 게이트웨이를 구성하는 HTTPRoute를 배포합니다.
다음 매니페스트를
store-route-external.yaml
이라는 파일에 저장합니다.kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external spec: parentRefs: - kind: Gateway name: external-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080 - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 - matches: - path: value: /de backendRefs: - name: store-german port: 8080
이 매니페스트는
external-http
게이트웨이를 참조하는 HTTPRoute를 설명합니다.매니페스트를 클러스터에 적용합니다.
kubectl apply -f store-route-external.yaml
store
HTTPRoute는parentRefs
속성을 사용하여external-http
게이트웨이에 바인딩됩니다. 다음 다이어그램은 기본 부하 분산기에 구성된 라우팅 규칙을 보여줍니다.라우팅 규칙은 다음과 같이 HTTP 트래픽을 처리합니다.
store.example.com/de
에 대한 트래픽은store-german
서비스로 라우팅됩니다.- HTTP 헤더
"env: canary"
가 있는store.example.com
에 대한 트래픽은store-v2
서비스로 라우팅됩니다. store.example.com
에 대한 나머지 트래픽은store-v1
서비스로 라우팅됩니다.
HTTPRoute가 배포되었는지 확인합니다.
kubectl describe httproute store-external
출력은 다음과 비슷합니다.
Name: store-external Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1beta1 Kind: HTTPRoute <...> Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: Conditions: Last Transition Time: 2022-11-01T05:42:31Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m48s sc-gateway-controller default/store-external Normal SYNC 61s (x3 over 2m27s) sc-gateway-controller Bind of HTTPRoute "default/store-external" to ParentRef Group: "gateway.networking.k8s.io", ...
HTTPRoute가 게이트웨이에 바인딩되었는지 확인합니다.
kubectl describe gateway external-http
출력은 다음과 비슷합니다.
Name: external-http Namespace: default Labels: <none> <...> Status: Addresses: Type: IPAddress Value: 34.149.207.45 Conditions: Last Transition Time: 2022-11-01T05:37:21Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Name: https Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute <...>
애플리케이션에 트래픽 보내기
이제 게이트웨이, 경로, 애플리케이션이 클러스터에 배포되었으므로, 트래픽을 애플리케이션에 전달할 수 있습니다.
게이트웨이의 IP 주소를 가져옵니다.
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
출력은 IP 주소입니다.
VM을 만듭니다.
gcloud cloud-shell ssh
VM에서 게이트웨이 IP 주소로 트래픽을 전송합니다.
example.com
호스트 이름을 소유하지 않으므로 호스트 헤더를 수동으로 설정해야 합니다.curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
GATEWAY_IP_ADDRESS
를 이전 단계의 게이트웨이 IP 주소로 바꿉니다.출력에 앱이 실행되는 위치에 대한 데모 앱의 정보가 표시됩니다.
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:31:17", "zone": "us-central1-a" }
store.example.com/de
에서store
서비스의 독일어 버전으로 이동하여 경로 일치를 테스트합니다.curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
요청이
store-german
포드로 제공되는 것이 출력에 확인됩니다.{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:35:37", "zone": "us-central1-a" }
env: canary
HTTP 헤더를 사용하여store
서비스의 카나리아 버전으로 트래픽을 전송합니다.curl -H "env: canary" https://store.example.com"/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
요청이
store-v2
포드로 제공되는 것이 출력에 확인됩니다.{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "👩🏿", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:38:26", "zone": "us-central1-a" }
리전 외부 게이트웨이 배포
다음 예시에서는 자체 관리형 인증서 및 HTTPRoute를 사용하여 리전 외부 게이트웨이에 연결된 여러 인증서가 있는 매장 애플리케이션을 노출하는 방법을 보여줍니다.
리전 게이트웨이의 프록시 서브넷 만들기
리전 외부 애플리케이션 부하 분산기를 사용하는 게이트웨이를 만들기 전에 프록시 전용 서브넷을 구성해야 합니다. 리전 외부 애플리케이션 부하 분산기를 사용하는 VPC의 각 리전에는 external_managed_proxy
서브넷이 있어야 합니다. 이 서브넷은 부하 분산기 프록시에 내부 IP 주소를 제공합니다.
클라이언트 트래픽을 보호하기 위한 인증서 만들기
인증 기관(CA)에서 발급되고 검증된 인증서를 사용하거나 자체 서명된 인증서를 만들 수 있습니다. 인증서를 만드는 방법에 대한 자세한 내용은 Kubernetes 보안 비밀에 인증서 저장을 참조하세요.
리전 외부 HTTP(S) 게이트웨이 만들기
외부 부하 분산기의 리전 고정 IP 주소를 만듭니다.
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARD
다음을 바꿉니다.
IP_ADDRESS_NAME
: 새 고정 IP 주소의 이름COMPUTE_REGION
: 클러스터가 실행되는 Compute Engine 리전
다음과 같이 자체 관리형 인증서를 사용하여 리전 외부 애플리케이션 부하 분산기 게이트웨이를 만들고 매니페스트를
regional-gateway.yaml
로 저장합니다.kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-regional-http spec: gatewayClassName: gke-l7-regional-external-managed listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: store-example-com addresses: - type: NamedAddress value: IP_ADDRESS_NAME
regional-gateway
매니페스트를 적용합니다.kubectl apply -f regional-gateway.yaml
구성을 확인합니다.
kubectl get gateway
출력은 다음과 비슷합니다.
NAME CLASS ADDRESS READY AGE external-http gke-l7-regional-external-managed 35.118.32.224 True 49s
더 많은 세부정보를 가져오려면 describe 명령어를 사용합니다.
kubectl describe gateway
출력은 다음과 비슷합니다.
Name: external-regional-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-regional-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
데모 애플리케이션 배포
게이트웨이 배포와 독립적으로 애플리케이션 및 경로를 배포할 수 있습니다.
데모 애플리케이션을 배포하는 방법에 대한 자세한 내용은 데모 애플리케이션 배포를 참조하세요.HTTPRoute 만들기
HTTP 및 HTTPS 트래픽 일치 및 필터링을 수행하려면 HTTPRoute를 만들어야 합니다.
애플리케이션에 트래픽 보내기
애플리케이션을 배포하고 HTTPRoute를 만든 후 애플리케이션에 트래픽을 전달할 수 있습니다.
애플리케이션으로 트래픽을 보내는 방법에 대한 자세한 내용은 애플리케이션에 트래픽 전송을 참조하세요.공유 게이트웨이 사용
Gateway API에는 부하 분산기 및 라우팅 규칙을 배포하기 위해 개별 리소스, 게이트웨이, 경로 리소스가 사용됩니다. 이것은 모든 것을 하나의 리소스로 결합하는 인그레스와 다릅니다. 리소스 간 책임을 분할함으로써 게이트웨이는 부하 분산기 및 해당 라우팅 규칙이 개별적으로 배포되고 서로 다른 사용자 또는 팀에 의해 배포될 수 있게 합니다. 이렇게 해서 게이트웨이는 서로 다른 네임스페이스 간에도 독립적인 팀에 의해 완전히 소유되고 관리될 수 있는 여러 다른 경로로 연결되는 공유 게이트웨이가 될 수 있습니다.
공유 게이트웨이에 경로 배포
이 예시는 내부 게이트웨이 배포에 배포된 internal-http
게이트웨이를 기반으로 합니다.
이 예시에서 사이트팀은 게이트웨이에서 해당 서비스로 일치하는 트래픽을 선택하기 위해 자신의 애플리케이션, 서비스, HTTPRoute를 배포합니다.
예시 애플리케이션 배포:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml
다음 매니페스트를
site-route-internal.yaml
이라는 파일에 저장합니다.kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: site-internal spec: parentRefs: - kind: Gateway name: internal-http hostnames: - "site.example.com" rules: - backendRefs: - name: site-v1 port: 8080
이 매니페스트는
site.example.com
의 모든 트래픽과 일치하고site-v1
서비스로 라우팅하는 HTTPRoute를 기술합니ㅏㄷ.매니페스트를 클러스터에 적용합니다.
kubectl apply -f site-route-internal.yaml
HTTPRoute가 게이트웨이에 연결되었는지 확인합니다.
kubectl describe httproute.gateway.networking.k8s.io site-internal
출력은 다음과 비슷합니다.
Status: Parents: Conditions: Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http ...
게이트웨이의
Accepted
조건이True
이면 HTTPRoute가 게이트웨이에 성공적으로 바인딩된 것입니다. 상태 필드에 대한 자세한 내용은 경로 상태를 참조하세요.게이트웨이에 대한 트래픽이 올바르게 라우팅되는지 확인합니다.
curl -H "host: site.example.com" GATEWAY_IP_ADDRESS curl -H "host: store.example.com" GATEWAY_IP_ADDRESS
GATEWAY_IP_ADDRESS
를 게이트웨이의 IP 주소로 바꿉니다.게이트웨이와 동일한 VPC에서 가상 머신(VM)을 사용해야 합니다.
출력은 다음과 비슷합니다.
{ "cluster_name": "CLUSTER_NAME", "host_header": "site.example.com", "metadata": "site-v1", "pod_name": "site-v1-5d64fc4d7d-fz6f6", "pod_name_emoji": "👩🏼🍳", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" } ... { "cluster_name": "CLUSTER_NAME", "host_header": "store.example.com", "metadata": "store-v1", "pod_name": "store-v1-6d8d58d78-vz8pn", "pod_name_emoji": "🧝🏻♂️", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" }
게이트웨이 기본 백엔드 구성
모든 gke-l7-*
GatewayClasses는 일치하지 않는 트래픽에 HTTP 404를 반환합니다. 일치하지 않는 트래픽을 사용자가 제공한 서비스로 전송하는 명시적인 기본 경로를 사용하여 기본 백엔드를 구성할 수 있습니다.
다음 HTTPRoute는 기본 백엔드를 맞춤설정하는 방법에 대한 예시입니다. 다음과 유사한 HTTPRoute를 적용하면 암시적 기본 백엔드보다 우선 적용됩니다.
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: custom-default-backend
spec:
parentRefs:
- kind: Gateway
name: my-internal-gateway
rules:
- backendRefs:
- name: my-custom-default-backend-service
port: 8080
이 HTTPRoute는 특정 게이트웨이에서 모든 일치하는 트래픽을 선택합니다. 게이트웨이마다 이러한 규칙 하나만 포함할 수 있습니다. 그렇지 않으면 규칙이 충돌하여 우선순위 순서가 적용됩니다.
기본 백엔드를 사용하여 누군가 모든 게이트웨이 트래픽을 라우팅하는 기본 경로 백엔드를 만들지 못하게 할 수 있습니다. 명시적 HTTPRoute는 라우팅 규칙이 충돌하는 새 HTTPRoute보다 항상 우선 적용됩니다.
게이트웨이의 고정 IP 주소 구성
모든 게이트웨이에는 트래픽을 리슨하는 데 사용하는 IP 주소가 있습니다. 게이트웨이에 IP 주소를 지정하지 않으면 게이트웨이 컨트롤러가 자동으로 IP 주소를 제공합니다. 또한 IP 주소가 게이트웨이 수명 주기와 독립적으로 존재하도록 고정 IP 주소를 만들 수도 있습니다.
게이트웨이가 배포된 다음에는 해당 IP 주소가 상태 필드에 표시됩니다.
kind: Gateway
...
status:
addresses:
- value: 10.15.32.3
GatewayClass에 따라 IP 주소가 다음 서브넷에서 할당됩니다.
GatewayClasses | 기본 IP 주소 풀 |
---|---|
|
기본 노드 IPv4/IPv6 주소 범위의 리전 비공개 IP 주소 |
|
Google 리전 외부 IPv4/IPv6 범위의 리전 공개 IP 주소 |
|
Google 전역 외부 IPv4/IPv6 범위의 전역 공개 IP 주소 |
addresses.NamedAddress
필드를 사용하면 게이트웨이와 독립적으로 IP 주소를 지정할 수 있습니다. 게이트웨이 배포 전 고정 IP 주소 리소스를 만들 수 있으며, 리소스는 NamedAddress
로 참조됩니다. 게이트웨이가 삭제된 경우에도 고정 IP 주소를 다시 사용할 수 있습니다.
이름이 지정된 IP 주소 사용
NamedAddress
를 지정하여 IPv4 또는 IPv6 주소를 구성할 수 있습니다. 게이트웨이를 만들기 전에 고정 IP 주소를 프로비저닝해야 합니다.
고정 IP 주소 리소스를 만듭니다.
gcloud compute addresses create IP_ADDRESS_NAME \ --purpose=SHARED_LOADBALANCER_VIP \ --region=COMPUTE_REGION \ --subnet=SUBNET \ --project=PROJECT_ID
다음을 바꿉니다.
IP_ADDRESS_NAME
: 새 고정 IP 주소의 이름입니다.COMPUTE_REGION
: 리전 게이트웨이의 경우 클러스터가 실행되는 Compute Engine 리전입니다. 전역 외부 게이트웨이에는 이 플래그가 필요하지 않습니다.SUBNET
: IP 주소의 서브넷입니다. 전역 외부 게이트웨이에는 이 플래그가 필요하지 않습니다.PROJECT_ID
: GKE 클러스터가 실행되는 프로젝트입니다.
다음 매니페스트를
named-ip-gateway.yaml
이라는 파일에 저장합니다.kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 addresses: - type: NamedAddress value: IP_ADDRESS_NAME
이 매니페스트는 명명된 IP 주소를 참조하는 게이트웨이를 설명합니다.
매니페스트를 클러스터에 적용합니다.
kubectl apply -f named-ip-gateway.yaml
게이트웨이 IP 주소를 확인합니다.
kubectl describe gateway internal-http
출력은 다음과 비슷합니다.
Name: internal-http Namespace: default Labels: <none> ... Spec: Addresses: Type: NamedAddress Value: IP_ADDRESS_NAME Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.15.32.103
HTTP-HTTPS 간 리디렉션 구성
Cloud Load Balancing은 HTTP-HTTPS 간 리디렉션 기능을 제공합니다. 외부 애플리케이션 부하 분산기는 암호화되지 않은 HTTP 요청을 동일한 IP 주소를 사용하는 HTTPS 부하 분산기로 리디렉션할 수 있습니다. HTTP-HTTPS 간 리디렉션을 사용 설정한 게이트웨이를 만들면 두 부하 분산기 모두 자동으로 생성됩니다. 포트 80에서 게이트웨이의 외부 IP 주소에 대한 요청은 포트 443에서 동일한 외부 IP 주소로 자동 리디렉션됩니다.
기본적으로 HTTP-HTTPS 간의 리디렉션은 게이트웨이에 정의되지 않습니다.
HTTP 트래픽을 HTTPS로 리디렉션하려면 HTTP 트래픽과 HTTPS 트래픽을 모두 처리하도록 게이트웨이를 구성합니다. HTTP 또는 HTTPS를 사용 중지할 경우 게이트웨이가 트래픽을 리디렉션하지 않습니다.
다음 예시에서는 클라이언트에서 웹 애플리케이션으로 이동하는 트래픽이 항상 보안 페이지로 리디렉션되도록 하는 수단으로 HTTP-HTTPS 간 리디렉션을 사용하는 방법을 보여줍니다.
인프라 네임스페이스에서 HTTP 트래픽 리디렉션
일부 경우에는 인프라 또는 플랫폼 관리팀과 애플리케이션팀 사이에 명확한 차이가 없으므로 게이트웨이의 오용을 방지하는 것이 어려울 수 있습니다.
다음 예시에서는 애플리케이션 팀이 비보안 프로토콜을 의도치 않게 사용하는 것을 방지하기 위해 HTTP 리스너 사용을 추가로 제한합니다. 이 예시에서는 지정된 네임스페이스(http-redirect)에 경로가 있는 경우에만 HTTPRoute가 HTTP 리스너를 사용하도록 하는 한편, HTTPS 네임스페이스가 모든 네임스페이스에 열리도록 게이트웨이를 구성합니다. Kubernetes RBAC를 통해 http-redirect 네임스페이스를 제한하여 애플리케이션팀이 실수로 이 네임스페이스에 HTTPRoute를 생성하지 못하게 할 수 있습니다.
게이트웨이의 네임스페이스를 만듭니다. 매니페스트를
gateway-namespace.yaml
로 저장하세요.apiVersion: v1 kind: Namespace metadata: name: gateway-infra
매니페스트를 적용합니다.
kubectl apply -f gateway-namespace.yaml
게이트웨이의 네임스페이스를 만들고 매니페스트를
redirect-namespace.yaml
으로 저장합니다.apiVersion: v1 kind: Namespace metadata: name: http-redirect labels: otherInfra: httpToHttps
- 이 네임스페이스에는 특정 라벨이 설정되어 있습니다.
매니페스트를 적용합니다.
kubectl apply -f redirect-namespace.yaml
http 리스너 사용을 제한하려면 다음 매니페스트를 사용하여 게이트웨이를 만듭니다. 매니페스트를
external-gateway.yaml
로 저장합니다.kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http namespace: gateway-infra spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: selector selector: matchLabels: otherInfra: httpToHttps - name: https protocol: HTTPS port: 443 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-com ```
namespace
필드는 게이트웨이가gateway-infra
네임스페이스에 생성되도록 지정합니다.allowedRoutes
섹션의namespaces
필드는 http 리스너를otherInfra: httpToHttps
라벨과 일치하는 네임스페이스로 제한합니다.
매니페스트를 적용합니다.
kubectl apply -f external-gateway.yaml
HTTPS 리디렉션을 강제 적용하려면 다음 매니페스트를 사용하여 기본 HTTPRoute를 만드세요. 매니페스트를
http-redirect.yaml
로 저장합니다.kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: redirect namespace: http-redirect spec: parentRefs: - namespace: gateway-infra name: external-http sectionName: http rules: - filters: - type: RequestRedirect requestRedirect: scheme: https
sectionName
필드는 게이트웨이가 http 리스너에서만 일치하도록 지시합니다.RequestRedirect
필터는 https 리스너로 강제 리디렉션합니다.
매니페스트를 적용합니다.
kubectl apply -f http-redirect.yaml
다음 매니페스트를 사용하여 애플리케이션 서비스를 만듭니다. 매니페스트를
service-deployment.yaml
로 저장합니다.apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store version: v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store version: v1 template: metadata: labels: app: store version: v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080 env: - name: METADATA value: "store-v1"
매니페스트를 적용합니다.
kubectl apply -f service-deployment.yaml
다음 매니페스트를 사용하여 HTTPS만 허용하는 애플리케이션에 대한 HTTPRoute를 만듭니다. 매니페스트를
http-route.yaml
로 저장합니다.kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http namespace: gateway-infra sectionName: https hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
매니페스트를 적용합니다.
kubectl apply -f http-route.yaml
경로 리디렉션 및 URL 재작성 구성
경로 리디렉션에는 한 URL 경로에서 다른 URL 경로로 들어오는 요청을 리디렉션하는 작업이 포함됩니다. 경로 리디렉션을 사용하면 오래되었거나 지원 중단된 URL을 처리해야 할 때 URL 구조를 변경할 수 있습니다.
URL 재작성은 수신 URL을 서버에서 처리하기 전에 수정하는 데 도움이 됩니다. 기본 콘텐츠나 파일 구조를 실제로 변경하지 않고도 URL의 구조나 형식을 변경할 수 있습니다. URL 재작성은 기억하기 쉽고 이해하기 쉬운 사용자 친화적이고 검색엔진 최적화 친화적인 URL을 만드는 데 유용합니다. 기본적으로 경로 리디렉션 및 URL 재작성은 구성되지 않으므로 HTTPRoute의 필터를 사용하여 해당 리디렉션 또는 재작성을 명시적으로 구성해야 합니다.
GKE 게이트웨이는 경로 리디렉션 및 URL 재작성을 지원합니다. 자세한 내용은 HTTP 경로 리디렉션 및 재작성을 참조하세요.
경로 리디렉션 구성
경로 리디렉션을 구성하여 전체 경로를 바꾸거나 URL에서 프리픽스만 바꿀 수 있습니다.
전체 경로 바꾸기
전체 경로를 바꾸려면 URL 경로에 프리픽스
/any-path
가 포함된 모든 URL을 엄격한 값/new-path
로 바꾸는 HTTPRoute에서 필터를 구성합니다.다음과 같이
HTTPRoute
매니페스트를 만들고 이름을store.yaml
으로 지정합니다.apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: type: PathPrefix value: /any-path filters: - type: RequestRedirect requestRedirect: path: type: ReplaceFullPath replaceFullPath: /new-path statusCode: 302
예를 들어 이 매니페스트는 HTTPRoute에 대한 라우팅 규칙을 다음과 같이 설정합니다. URL https://store.example.com/any-path/...에 대한 모든 경로는 새 위치인 https://store.example.com/new-path/(엄격)로 리디렉션되어야 합니다.
매니페스트를 적용합니다.
kubectl apply -f store.yaml
이 라우팅 규칙은 엄격한 리디렉션 규칙을 따릅니다. 즉, 브라우저가 리디렉션을 캐시하려고 시도하지 않고 대신 최신 버전으로 리디렉션합니다.
프리픽스만 바꾸기
프리픽스만 바꾸려면 URL 경로의 프리픽스
/any-prefix
가 포함된 모든 URL을 엄격한 값/new-prefix
로 바꾸는 HTTPRoute에서 필터를 구성합니다.다음과 같이
HTTPRoute
매니페스트를 만들고 이름을store.yaml
으로 지정합니다.apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: type: PathPrefix value: /any-prefix filters: - type: RequestRedirect requestRedirect: path: type: ReplacePrefixMatch replacePrefixMatch: /new-prefix statusCode: 302
예를 들어 이 매니페스트는 HTTPRoute에 대한 라우팅 규칙을 다음과 같이 설정합니다. URL https://store.example.com/any-path/v1/...에 대한 모든 경로는 새 위치인 https://store.example.com/new-path/v1/...로 리디렉션되어야 합니다 (전용).
매니페스트를 적용합니다.
kubectl apply -f store.yaml
이 라우팅 규칙은 리디렉션 규칙만 따르므로 브라우저에서 항상 사용자를 동일한 의도된 페이지로 리디렉션합니다.
URL 재작성 구성
URL 재작성을 설정하여 사용자에게 URL이 표시되는 방식을 변경할 수 있습니다. URL 재작성을 사용하여 URL을 더 사용자 친화적으로 만들거나 검색엔진 최적화를 개선하거나 사용자를 새 페이지로 리디렉션할 수 있습니다.
전체 호스트 이름 재작성
전체 호스트 이름을 재작성하려면 다음 안내를 따르세요.
요청을 백엔드 서비스로 전달하기 전에 요청 헤더에 있는
Host
정보를 www.example.com에서 store.example.com으로 바꾸도록 게이트웨이에 지시하는 HTTPRoute에서 필터를 구성합니다.다음과 같이
HTTPRoute
매니페스트를 만들고 이름을www.yaml
로 지정합니다.apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - filters: - type: URLRewrite urlRewrite: hostname: store.example.com backendRefs: - name: store-v1 port: 8080
예를 들어 위의 구성에서 https://www.example.com에 대한 모든 요청은
Host: www.example.com
대신Host: store.example.com
헤더와 함께 백엔드 서비스로 전달됩니다.매니페스트를 적용합니다.
kubectl apply -f www.yaml
경로 수정자를 사용하여 재작성
재작성을 경로 수정자와 결합하여 백엔드 서비스에 요청을 릴레이하기 전에 고급 URL 및 경로 수정을 제공할 수 있습니다.
경로 수정자를 사용하여 재작성하려면 다음 안내를 따르세요.
요청을 백엔드 서비스로 전달하기 전에 요청 헤더에 있는 '호스트' 정보를 www.example.com에서 store.example.com으로 바꾸고
/store
값을/
로 바꾸도록 게이트웨이에 지시하는 HTTPRoute의 필터를 구성합니다.다음과 같이
HTTPRoute
매니페스트를 만들고 이름을www.yaml
로 지정합니다.apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - matches: - path: type: PathPrefix value: /store filters: - type: URLRewrite urlRewrite: hostname: store.example.com path: type: ReplacePrefixMatch replacePrefixMatch: /de backendRefs: - name: store-german port: 8080
예를 들어 위 구성을 사용하면 https://www.example.com/store/...에 대한 모든 요청은 요청 헤더(
Host: www.example.com
대신)Host: store.example.com
이 있는 백엔드 서비스로 전달되며/store
를/de
로 재작성합니다.매니페스트를 적용합니다.
kubectl apply -f www.yaml
구성을 확인합니다
URL 재작성 또는 경로 리디렉션 필터를 사용하여 HTTPRoute를 만든 후 필터가 적용되었는지 확인하려면 다음을 수행합니다.
kubectl get httproute www -o yaml
출력은 다음과 비슷합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1beta1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
creationTimestamp: "2023-06-22T01:00:42Z"
generation: 3
name: www
namespace: default
resourceVersion: "51268631"
uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
spec:
hostnames:
- www.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: external-http
rules:
- backendRefs:
- group: ""
kind: Service
name: store-german
port: 8080
weight: 1
filters:
- type: URLRewrite
urlRewrite:
hostname: store.example.com
path:
replacePrefixMatch: /de
type: ReplacePrefixMatch
matches:
- path:
type: PathPrefix
value: /store
status:
parents:
- conditions:
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: ReconciliationSucceeded
status: "True"
type: Reconciled
controllerName: networking.gke.io/gateway
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: external-http
더 많은 세부정보를 확인하려면 describe 명령어를 사용합니다.
kubectl describe httproute
커스텀 요청 및 응답 헤더 구성
커스텀 요청과 응답 헤더를 사용하면 HTTP(S) 요청 및 응답에 추가 헤더를 지정할 수 있습니다. 부하 분산기에서 감지된 정보에 따라 헤더에는 다음 정보가 포함될 수 있습니다.
- 클라이언트에 대한 지연 시간
- 클라이언트 IP 주소의 지리적 위치
- TLS 연결 매개변수
기본적으로 백엔드 서비스와 주고받는 요청에 추가된 커스텀 헤더가 없으므로 HTTPRoute의 필터를 사용하여 커스텀 헤더를 명시적으로 구성해야 합니다.
다음과 같이 HTTPRoute 규칙에 필터 섹션을 추가하여 커스텀 헤더를 구성할 수 있습니다.
커스텀 요청 헤더 구성
RequestHeaderModifier 필터로 HTTPRoute 매니페스트를 만들고 http-route-request.yaml:
로 저장합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
<...>
매니페스트를 적용합니다.
kubectl apply -f http-route-request.yaml
커스텀 응답 헤더 구성
ResponseHeaderModifier 필터를 사용하여 HTTPRoute 매니페스트를 만들고 이를 http-route-response.yaml:
로 저장합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
<...>
매니페스트를 적용합니다.
kubectl apply -f http-route-response.yaml
Gateway API 구현에 설명된 대로 헤더를 추가, 설정, 삭제할 수 있습니다. Google Cloud 지원 변수를 사용하여 커스텀 헤더로 HTTPRoute를 구성할 수 있습니다.
예시 1:
클라이언트 위치 정보를 백엔드 서비스로 보내기 전에 HTTP 요청에 추가하는 HTTPRoute를 구성하려면 HTTPRoute 매니페스트를 만들고 이름을 external-http-request.yaml
로 지정합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /fr
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Client-Geo-Location
value: "{client_region},{client_city}"
backendRefs:
- name: store-french
port: 8080
예를 들어 프랑스 스트라스부르에 있는 클라이언트의 경우 게이트웨이는 헤더를 X-Client-Geo-Location:FR,Strasbourg
로 추가합니다.
예시 2:
HTTP Strict Transport Security를 지원하도록 커스텀 응답 헤더를 추가하는 HTTPRoute를 구성하려면 HTTPRoute 매니페스트를 만들고 이름을 external-http-response.yaml
로 지정합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /de
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: Strict-Transport-Security
value: max-age=63072000
backendRefs:
- name: store-german
port: 8080
구성을 확인합니다
커스텀 요청 및 응답 헤더를 구성한 후 구성을 확인하려면 다음 안내를 따르세요.
kubectl get httproute
출력은 다음과 비슷합니다.
NAME HOSTNAMES AGE store ["store.example.com"] 4d23h
더 많은 세부정보를 확인하려면 describe 명령어를 사용합니다.
kubectl describe httproute
출력은 다음과 비슷합니다.
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1beta1 Kind: HTTPRoute Metadata: Creation Timestamp: 2023-05-27T00:51:01Z Generation: 5 Resource Version: 25418887 UID: 2e07a1b8-420b-41b4-acd1-cecbfcd39f42 Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Filters: Request Header Modifier: Add: Name: X-Client-Geo-Location Value: {client_region},{client_city} Type: RequestHeaderModifier Matches: Path: Type: PathPrefix Value: /de Status: <...>
경로 상태
HTTPRoute 리소스는 HTTPRoute가 하나 이상의 게이트웨이와 성공적으로 바인딩되었는지 또는 거부되었는지를 사용자가 이해할 수 있도록 조건 및 이벤트를 방출합니다.
HTTPRoute 조건
HTTPRoute 조건은 경로가 바인딩된 게이트웨이와 경로의 상태를 나타냅니다. 경로를 여러 게이트웨이에 바인딩할 수 있기 때문에 이것은 경로와 각 게이트웨이 사이의 개별 조건과 게이트웨이 목록입니다.
Accepted=True
는 HTTPRoute가 게이트웨이에 성공적으로 바인딩되었음을 나타냅니다.Accepted=False
는 HTTPRoute가 이 게이트웨이와의 바인딩에서 거부되었음을 나타냅니다.
Gateway bindings
제목 아래에 게이트웨이가 없으면 HTTPRoute 라벨과 게이트웨이 라벨 선택기가 일치하지 않을 수 있습니다. 이 문제는 게이트웨이에서 경로를 선택하지 않은 경우에 발생할 수 있습니다.
HTTPRoute 이벤트
HTTPRoute 이벤트는 HTTPRoute 상태에 대한 세부정보를 제공합니다. 이벤트는 다음과 같은 이유로 그룹화됩니다.
ADD
이벤트는 추가되는 리소스에 의해 트리거됩니다.UPDATE
이벤트는 업데이트되는 리소스에 의해 트리거됩니다.SYNC
이벤트는 정기적인 조정으로 트리거됩니다.
경로 병합, 우선순위, 검증
경로 우선순위
Gateway API는 겹쳐진 라우팅 규칙을 갖는 경로에서 트래픽이 선택되는 방법에 대해 엄격한 우선순위 규칙을 정의합니다. 두 가지 겹치는 HTTPRoute 사이의 우선순위는 다음과 같습니다.
- 호스트 이름 병합: 가장 길고 가장 구체적인 호스트 이름이 선택됩니다.
- 경로 병합: 가장 길고 가장 구체적인 경로가 선택됩니다.
- 헤더 병합: 일치하는 가장 큰 수의 HTTP 헤더입니다.
- 충돌: 위 3개 규칙에 따라 우선순위가 결정되지 않으면 가장 오래된 타임스탬프의 HTTPRoute 리소스가 우선 적용됩니다.
경로 병합
gke-l7
GatewayClass의 경우 지정된 게이트웨이에 대한 모든 HTTPRoute가 동일한 URL 맵 리소스에 병합됩니다. HTTPRoute가 병합되는 방법은 HTTPRoute 사이의 겹침 유형에 따라 달라집니다. 이전 예시의 HTTPRoute를 3개의 개별 HTTPRoute로 분할하여 경로 병합 및 우선순위를 나타낼 수 있습니다.
- 경로 병합: 3개 HTTPRoute 모두 동일한
internal-http
게이트웨이와 연결되어 함께 병합됩니다. - 호스트 이름 병합: 3개 경로 모두
store.example.com
과 일치하여, 해당 호스트 이름 규칙이 병합됩니다. - 경로 병합: store-german-route에 보다 구체적인 경로
/de
가 포함되므로, 이것은 추가로 병합되지 않습니다. store-v1-route 및 store-v2-route는 모두 동일한/*
경로에서 일치하므로, 해당 경로로 병합됩니다. - 헤더 병합: store-v2-route는 store-v1-route보다 더 구체적인 HTTP 헤더 일치 집합을 가지므로, 추가로 병합되지 않습니다.
- 충돌: 경로가 호스트 이름, 경로, 헤더로 병합될 수 있기 때문에 충돌이 없고, 모든 경로 규칙이 트래픽에 적용됩니다.
앞의 예시에 사용된 단일 HTTPRoute는 이러한 3개의 개별 경로와 동일합니다.
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-v1-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- kind: Service
name: store-v1
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-v2-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- headers:
- type: Exact
name: env
value: canary
backendRefs:
- kind: Service
name: store-v2
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
name: store-german-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /de
backendRefs:
- kind: Service
name: store-german
port: 8080
Kubernetes 게이트웨이 및 Istio 게이트웨이
Kubernetes Gateway API와 Istio API에는 모두 Gateway
라는 리소스가 있습니다. 비슷한 기능을 실행하지만 동일한 리소스는 아닙니다. Istio와 Gateway API를 동일한 Kubernetes 클러스터에서 사용하는 경우 이러한 이름은 명령줄에서 kubectl을 사용할 때 겹칠 수 있습니다.
kubectl get gateway
는 Istio 게이트웨이 리소스가 아닌 Kubernetes 게이트웨이 리소스를 반환할 수 있으며 그 반대의 경우도 마찬가지입니다.
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
gateways gw networking.istio.io/v1beta1 true Gateway
gateways gtw networking.k8s.io/v1beta1 true Gateway
Istio를 사용하고 GKE 1.20 이상으로 업그레이드하는 경우 게이트웨이 리소스 별칭 사용하거나 API 그룹을 지정하는 것이 좋습니다. Kubernetes 게이트웨이의 별칭은 gtw
이며 Istio 게이트웨이의 별칭은 gw
입니다. 다음 명령어는 각각 Kubernetes 게이트웨이 및 Istio 게이트웨이 리소스를 반환합니다.
# Kubernetes Gateway
$ kubectl get gtw
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
$ kubectl get gateway.networking.x-k8s.io
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
# Istio Gateway
$ kubectl get gw
NAME AGE
bookinfo-gateway 64m
$ kubectl get gateway.networking.istio.io
NAME AGE
bookinfo-gateway 64m
문제 해결
리전에서 프록시 전용 서브넷 누락
증상
리전 게이트웨이(내부 또는 외부)를 만들 때 다음 문제가 발생할 수 있습니다.
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
이유:
이 오류 메시지는 게이트웨이에 대한 리전에 프록시 전용 서브넷이 없음을 나타냅니다.
해결 방법:
이 문제를 해결하려면 프록시 전용 서브넷을 배포합니다.
프록시 전용 서브넷이 잘못된 용도로 리전에 이미 있습니다.
증상
리전 게이트웨이(내부 또는 외부)에 대한 프록시 전용 서브넷을 만들 때 다음 문제가 발생할 수 있습니다.
ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
- The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
이유:
이 오류 메시지는 프록시 전용 서브넷이 이미 있는 리전에서 리전 프록시 전용 서브넷을 만들려고 했음을 나타냅니다.
해결 방법:
이 문제를 해결하려면 다음을 단계를 사용해 보세요.
프록시 전용 서브넷이 리전에 이미 있는지 확인하고 올바른 목적을 가지고 있는지 확인합니다.
서브넷을 나열하여 해당 리전의 프록시 전용 서브넷을 찾습니다.
gcloud compute networks subnets list --regions=COMPUTE_REGION
COMPUTE_REGION
을 리전 게이트웨이를 만들려는 Compute Engine 리전으로 바꿉니다.해당 리전의 프록시 전용 서브넷을 설명하여 그 용도를 찾습니다.
gcloud compute networks subnets describe PROXY_ONLY_SUBNET \ --region COMPUTE_REGION | grep -E 'name|purpose'
PROXY_ONLY_SUBNET
을 프록시 전용 서브넷으로 바꿉니다.
GKE 게이트웨이는 리전 게이트웨이(내부 또는 리전)에 대해
REGIONAL_MANAGED_PROXY
프록시 전용 서브넷만 지원합니다.리전의 기존 프록시 전용 서브넷이
INTERNAL_HTTPS_LOAD_BALANCER
목적으로 생성된 경우 해당 목적을REGIONAL_MANAGED_PROXY
로 마이그레이션합니다.
정상 업스트림 없음
증상:
게이트웨이를 만들 때 백엔드 서비스에 액세스할 수 없는 경우 다음 문제가 발생할 수 있습니다(503 응답 코드).
no healthy upstream
이유:
이 오류 메시지는 상태 점검 프로버가 정상 백엔드 서비스를 찾을 수 없음을 나타냅니다. 백엔드 서비스가 정상일 수 있지만 상태 점검을 맞춤설정해야 할 수도 있습니다.
해결 방법:
이 문제를 해결하려면 HealthCheckPolicy
를 사용하여 애플리케이션 요구사항(예: /health
)에 따라 상태 점검을 맞춤설정합니다.
다음 단계
- 게이트웨이 컨트롤러 자세히 알아보기
- 정책을 사용한 게이트웨이 리소스 구성 방법 알아보기