๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ


์ด ํŽ˜์ด์ง€์—์„œ๋Š” ์—ฌ๋Ÿฌ Google Kubernetes Engine(GKE) ํด๋Ÿฌ์Šคํ„ฐ(๋˜๋Š” Fleet)์— ์ธ๊ทธ๋ ˆ์Šค ํŠธ๋ž˜ํ”ฝ์„ ๋ถ€ํ•˜ ๋ถ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด Kubernetes ๊ฒŒ์ดํŠธ์›จ์ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋ฐฐํฌํ•˜๋ ค๋ฉด ๋จผ์ € ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์‚ฌ์šฉ ์„ค์ •์„ ์ฐธ์กฐํ•˜์—ฌ ํ™˜๊ฒฝ์„ ์ค€๋น„ํ•˜์„ธ์š”.

์ธ๊ทธ๋ ˆ์Šค ํŠธ๋ž˜ํ”ฝ์„ ๋‹จ์ผ GKE ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋ถ€ํ•˜ ๋ถ„์‚ฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋ฐฐํฌํ•˜๋ ค๋ฉด ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ์—ฌ๋Ÿฌ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์„ ๋ถ€ํ•˜ ๋ถ„์‚ฐํ•˜๋Š” ๊ฒŒ์ดํŠธ์›จ์ด ๋ฆฌ์†Œ์Šค์ž…๋‹ˆ๋‹ค. GKE์—์„œ gke-l7-global-external-managed-mc, gke-l7-regional-external-managed-mc, gke-l7-rilb-mc, gke-l7-gxlb-mc GatewayClass๋Š” ์—ฌ๋Ÿฌ GKE ํด๋Ÿฌ์Šคํ„ฐ, Kubernetes ๋„ค์ž„์ŠคํŽ˜์ด์Šค, ๋ฆฌ์ „ ๊ฐ„์— HTTP ๋ผ์šฐํŒ…, ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• , ํŠธ๋ž˜ํ”ฝ ๋ฏธ๋Ÿฌ๋ง, ์ƒํƒœ ๊ธฐ๋ฐ˜ ์žฅ์•  ์กฐ์น˜ ๋“ฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ์ธํ”„๋ผ ๊ด€๋ฆฌ์ž๋ฅผ ์œ„ํ•ด ์—ฌ๋Ÿฌ ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ ํŒ€ ๊ฐ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋„คํŠธ์›Œํ‚น ๊ด€๋ฆฌ๋ฅผ ์‰ฝ๊ณ , ์•ˆ์ „ํ•˜๊ณ , ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ์—ฌ๋Ÿฌ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์„ ๋ถ€ํ•˜ ๋ถ„์‚ฐํ•˜๋Š” ๊ฒŒ์ดํŠธ์›จ์ด ๋ฆฌ์†Œ์Šค์ž…๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€์—์„œ๋Š” GKE Gateway Controller๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ์„ธ ๊ฐ€์ง€ ์˜ˆ์‹œ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

  • ์˜ˆ์‹œ 1: ์ธํ„ฐ๋„ท ํŠธ๋ž˜ํ”ฝ์„ ์œ„ํ•ด 2๊ฐœ์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์ œ๊ณตํ•˜๋Š” ์™ธ๋ถ€ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด
  • ์˜ˆ์‹œ 2: ๋‚ด๋ถ€ VPC ํŠธ๋ž˜ํ”ฝ์„ ์œ„ํ•ด 2๊ฐœ์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ ๋ธ”๋ฃจ-๊ทธ๋ฆฐ ๊ฐ€์ค‘์น˜ ๊ธฐ๋ฐ˜ ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ•  ๋ฐ ํŠธ๋ž˜ํ”ฝ ๋ฏธ๋Ÿฌ๋ง
  • ์˜ˆ์‹œ 3: ์ตœ๋Œ€ ์šฉ๋Ÿ‰์„ ๊ธฐ์ค€์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฐฑ์—”๋“œ๋กœ ์š”์ฒญ์„ ๋ถ€ํ•˜ ๋ถ„์‚ฐํ•˜๋Š” ์šฉ๋Ÿ‰ ๊ธฐ๋ฐ˜ ๊ฒŒ์ดํŠธ์›จ์ด

๊ฐ ์˜ˆ์‹œ์—์„œ๋Š” ๋™์ผํ•œ ๋งค์žฅ ๋ฐ ์‚ฌ์ดํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜จ๋ผ์ธ ์‡ผํ•‘ ์„œ๋น„์Šค์™€ ์›น์‚ฌ์ดํŠธ ์„œ๋น„์Šค๊ฐ€ ๊ฐœ๋ณ„ ํŒ€์— ์˜ํ•ด ์†Œ์œ  ๋ฐ ์šด์˜๋˜๊ณ  ๊ณต์œ ๋˜๋Š” GKE ํด๋Ÿฌ์Šคํ„ฐ์˜ Fleet ๊ฐ„์— ๋ฐฐํฌ๋˜๋Š” ์‹ค์ œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋ชจ๋ธ๋งํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์˜ˆ์‹œ์—์„œ๋Š” ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด์—์„œ ์‚ฌ์šฉ ์„ค์ •ํ•˜๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํ† ํด๋กœ์ง€์™€ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ฐ•์กฐํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋ฐฐํฌ๋˜๊ธฐ ์ „ ๋ช‡ ๊ฐ€์ง€ ํ™˜๊ฒฝ์ ์ธ ์ค€๋น„๊ฐ€ ์š”๊ตฌ๋ฉ๋‹ˆ๋‹ค. ๊ณ„์†ํ•˜๊ธฐ ์ „ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์‚ฌ์šฉ ์„ค์ •์˜ ๋‹จ๊ณ„๋ฅผ ๋‹ค๋ฅด์„ธ์š”.

  1. GKE ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

  2. Fleet์— ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

  3. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ๋ฐ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— GKE Gateway Controller ์ œํ•œ์‚ฌํ•ญ ๋ฐ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๋ฅผ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ, ๋ฉ€ํ‹ฐ ๋ฆฌ์ „, ์™ธ๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” 2๊ฐœ์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‹คํ–‰๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ„์— ์™ธ๋ถ€ ํŠธ๋ž˜ํ”ฝ์„ ์ œ๊ณตํ•˜๋Š” ์™ธ๋ถ€ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

GKE ํด๋Ÿฌ์Šคํ„ฐ 2๊ฐœ ๊ฐ„์— ๋ฐฐํฌ๋˜๊ณ  ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ํ†ตํ•ด ์ธํ„ฐ๋„ท์— ๋…ธ์ถœ๋˜๋Š” store.example.com

๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. gke-west-1 ๋ฐ gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์— ์ƒ˜ํ”Œ store ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
  2. Fleet์œผ๋กœ ๋‚ด๋ณด๋‚ผ ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์˜ ์„œ๋น„์Šค๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค(๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค).
  3. ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(gke-west-1)์— ์™ธ๋ถ€ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐ HTTPRoute๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ฐฐํฌ๋œ ํ›„ ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ 2๊ฐœ์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • /west์— ๋Œ€ํ•œ ์š”์ฒญ์€ gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ์— ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.
  • /east์— ๋Œ€ํ•œ ์š”์ฒญ์€ gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ์— ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ์š”์ฒญ์€ ์š”์ฒญ ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•œ ํ•ด๋‹น ์ƒํƒœ, ์šฉ๋Ÿ‰, ๊ทผ์ ‘์„ฑ์— ๋”ฐ๋ผ ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.

๋ฐ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ

  1. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์‚ฌ์šฉ ์„ค์ •์— ๋ฐฐํฌ๋œ ํด๋Ÿฌ์Šคํ„ฐ 3๊ฐœ ๋ชจ๋‘์— store ๋ฐฐํฌ ๋ฐ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    

    ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋‹ค์Œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

    namespace/store created
    deployment.apps/store created
    

    ์ด ํŽ˜์ด์ง€์˜ ๋ชจ๋“  ์˜ˆ์‹œ์—๋Š” ์ด ๋‹จ๊ณ„์—์„œ ๋ฐฐํฌ๋œ ์•ฑ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‚จ์€ ๋‹จ๊ณ„๋ฅผ ์‹œ๋„ํ•˜๊ธฐ ์ „ 3๊ฐœ ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘์— ์•ฑ์ด ๋ฐฐํฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1 ๋ฐ gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ๋งŒ ์‚ฌ์šฉ๋˜๊ณ  gke-west-2๋Š” ๋‹ค๋ฅธ ์˜ˆ์‹œ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค

์„œ๋น„์Šค๋Š” ํฌ๋“œ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœ๋˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. GKE Gateway Controller์— ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์ด ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํฌ๋“œ ์—ฐ๊ฒฐ์„ ์œ„ํ•ด ClusterIP ๋˜๋Š” Kubernetes ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠธ๋ž˜ํ”ฝ์€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์—์„œ ํฌ๋“œ IP ์ฃผ์†Œ๋กœ ์ง์ ‘ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์„œ๋น„์Šค๋Š” ์—ฌ์ „ํžˆ ํฌ๋“œ ๊ทธ๋ฃนํ™”์— ๋Œ€ํ•œ ๋…ผ๋ฆฌ์  ์‹๋ณ„์ž๋กœ์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค(MCS)๋Š” ํด๋Ÿฌ์Šคํ„ฐ์— ๊ฑธ์ณ์ง„ ์„œ๋น„์Šค์˜ API ํ‘œ์ค€์ด๊ธฐ๋„ ํ•˜๊ณ  GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์„œ๋น„์Šค ๊ฒ€์ƒ‰์„ ์ œ๊ณตํ•˜๋Š” GKE ์ปจํŠธ๋กค๋Ÿฌ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์ปจํŠธ๋กค๋Ÿฌ๋Š” MCS API ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์ฃผ์†Œ ์ง€์ •๋˜๊ฑฐ๋‚˜ ๊ฑธ์ณ ์žˆ๋Š” ์„œ๋น„์Šค๋กœ ํฌ๋“œ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ Services API๋Š” ๋‹ค์Œ ์ปค์Šคํ…€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

  • ServiceExports๋Š” Kubernetes ์„œ๋น„์Šค์— ๋งคํ•‘๋˜๋ฉฐ, ํ•ด๋‹น ์„œ๋น„์Šค์˜ ์—”๋“œํฌ์ธํŠธ๋ฅผ Fleet์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค. ์„œ๋น„์Šค์— ํ•ด๋‹น ServiceExport๊ฐ€ ์žˆ์œผ๋ฉด ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์„œ๋น„์Šค์— ์ฃผ์†Œ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ServiceImports๋Š” ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ServiceExport ๋ฐ ServiceImport๋Š” ์Œ์œผ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ServiceExport๊ฐ€ Fleet์— ์กด์žฌํ•  ๊ฒฝ์šฐ ServiceExport์— ๋งคํ•‘๋œ ์„œ๋น„์Šค๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์ฃผ์†Œ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋‹น ServiceImport๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์„œ๋น„์Šค ๋‚ด๋ณด๋‚ด๊ธฐ๋Š” ๋‹ค์Œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋งค์žฅ ์„œ๋น„์Šค๋Š” ํ•ด๋‹น ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ํฌ๋“œ ๊ทธ๋ฃน์„ ์„ ํƒํ•˜๋Š” gke-west-1์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ServiceExport๋Š” Fleet์˜ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ gke-west-1์˜ ํฌ๋“œ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํด๋Ÿฌ์Šคํ„ฐ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ServiceExport๋Š” ServiceExport ๋ฆฌ์†Œ์Šค์™€ ์ด๋ฆ„ ๋ฐ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ๋™์ผํ•œ ์„œ๋น„์Šค๋กœ ๋งคํ•‘๋˜๋ฉฐ ์ด๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

apiVersion: v1
kind: Service
metadata:
  name: store
  namespace: store
spec:
  selector:
    app: store
  ports:
  - port: 8080
    targetPort: 8080
---
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
  name: store
  namespace: store

๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ServiceExport๊ฐ€ ๋ฐฐํฌ๋œ ํ›„์— ๋ฐœ์ƒํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ServiceExport ๋ฐ ์„œ๋น„์Šค ์Œ์ด ์กด์žฌํ•  ๊ฒฝ์šฐ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ•ด๋‹น ServiceImport๋ฅผ Fleet์— ์žˆ๋Š” ๋ชจ๋“  GKE ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ServiceImport๋Š” ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ์— ์žˆ๋Š” store ์„œ๋น„์Šค์˜ ๋กœ์ปฌ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด gke-east-1์˜ client ํฌ๋“œ๊ฐ€ ClusterIP ๋˜๋Š” ํ—ค๋“œ๋ฆฌ์Šค ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ gke-west-1์˜ store ํฌ๋“œ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค๊ฐ€ ๋‚ด๋ถ€ LoadBalancer ์„œ๋น„์Šค ์—†์ด๋„ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— east-west ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ๊ฐ„ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์œ„ํ•ด ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ๊ตฌ์„ฑ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„ ํ†ต์‹ ์„ ํ—ˆ์šฉํ•˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์„œ๋น„์Šค๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค

๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋˜ํ•œ ServiceImports๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ„ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ์— ์žˆ๋Š” ์„œ๋น„์Šค ๋˜๋Š” ์—ฌ๋Ÿฌ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ๋ถ„์‚ฐ๋œ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ๋…ผ๋ฆฌ์  ์‹๋ณ„์ž๋กœ ServiceImports๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ HTTPRoute๋Š” ์„œ๋น„์Šค ๋ฆฌ์†Œ์Šค ๋Œ€์‹  ServiceImport๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ServiceImport๋ฅผ ์ฐธ์กฐํ•จ์œผ๋กœ์จ ํ•˜๋‚˜ ์ด์ƒ์˜ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‹คํ–‰๋˜๋Š” ๋ฐฑ์—”๋“œ ํฌ๋“œ ๊ทธ๋ฃน์œผ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store-route
  namespace: store
  labels:
    gateway: multi-cluster-gateway
spec:
  parentRefs:
  - kind: Gateway
    namespace: store
    name: external-http
  hostnames:
  - "store.example.com"
  rules:
  - backendRefs:
    - group: net.gke.io
      kind: ServiceImport
      name: store
      port: 8080

๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์€ HTTPRoute๊ฐ€ store.example.com ํŠธ๋ž˜ํ”ฝ์„ gke-west-1 ๋ฐ gke-east-1์˜ store ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋Š” ์ด๋ฅผ ๋ฐฑ์—”๋“œ ์ค‘ ํ•˜๋‚˜์˜ ํ’€๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ ์ค‘ ํ•˜๋‚˜์˜ ํฌ๋“œ๊ฐ€ ๋น„์ •์ƒ ๋˜๋Š” ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ์ƒํƒœ๊ฐ€ ๋˜๊ฑฐ๋‚˜ ํŠธ๋ž˜ํ”ฝ ์šฉ๋Ÿ‰์ด ์—†์œผ๋ฉด ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋‚จ์€ ํฌ๋“œ๋กœ ํŠธ๋ž˜ํ”ฝ ๋กœ๋“œ๊ฐ€ ๋ถ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. store ์„œ๋น„์Šค ๋ฐ ServiceExport๋กœ ์ƒˆ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ช…์‹œ์ ์ธ ๋ผ์šฐํŒ… ๊ตฌ์„ฑ ๋ณ€๊ฒฝ ์—†์ด ๋ฐฑ์—”๋“œ ํฌ๋“œ๋ฅผ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MCS ๋ฆฌ์†Œ์Šค

์„œ๋น„์Šค ๋‚ด๋ณด๋‚ด๊ธฐ

์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์„œ๋น„์Šค ๋ฐ ServiceExports๋ฅผ ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋…ธ์ถœํ•˜๊ณ  ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

  1. gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์— ๋‹ค์Œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ์ ์šฉํ•˜์—ฌ store ๋ฐ store-west-1 Service์™€ ServiceExport๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-west-1
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-west-1
      namespace: store
    EOF
    
  2. gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์— ๋‹ค์Œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ์ ์šฉํ•˜์—ฌ store ๋ฐ store-east-1 Service์™€ ServiceExport๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-east-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-east-1
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-east-1
      namespace: store
    EOF
    
  3. ํด๋Ÿฌ์Šคํ„ฐ์— ์˜ฌ๋ฐ”๋ฅธ ServiceExport๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    kubectl get serviceexports --context CLUSTER_NAME --namespace store
    

    CLUSTER_NAME์„ gke-west-1 ๋ฐ gke-east-1๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    # gke-west-1
    NAME           AGE
    store          2m40s
    store-west-1   2m40s
    
    # gke-east-1
    NAME           AGE
    store          2m25s
    store-east-1   2m25s
    

    ์ด๊ฒƒ์€ store ์„œ๋น„์Šค์— ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ store ํฌ๋“œ๊ฐ€ ํฌํ•จ๋œ ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๋ฉฐ store-west-1 ๋ฐ store-east-1 ์„œ๋น„์Šค๋Š” ํ•ด๋‹น ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ๋งŒ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒน์ณ์ง„ ์„œ๋น„์Šค๋Š” ์—ฌ๋Ÿฌ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ ํฌ๋“œ ๋˜๋Š” ๋‹จ์ผ ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  4. ๋ช‡ ๋ถ„ ํ›„ ํ•จ๊ป˜ ์ œ๊ณต๋œ ServiceImports๊ฐ€ Fleet์˜ ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    kubectl get serviceimports --context CLUSTER_NAME --namespace store
    

    CLUSTER_NAME์„ gke-west-1 ๋ฐ gke-east-1๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    # gke-west-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.112.31.15"]    6m54s
    store-east-1   ClusterSetIP   ["10.112.26.235"]   5m49s
    store-west-1   ClusterSetIP   ["10.112.16.112"]   6m54s
    
    # gke-east-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.72.28.226"]    5d10h
    store-east-1   ClusterSetIP   ["10.72.19.177"]    5d10h
    store-west-1   ClusterSetIP   ["10.72.28.68"]     4h32m
    

    ์ด๊ฒƒ์€ Fleet์˜ ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘์—์„œ 3๊ฐœ์˜ ์„œ๋น„์Šค ๋ชจ๋‘์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Fleet๋‹น ํ™œ์„ฑ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์œผ๋ฏ€๋กœ gke-west-1์—์„œ ServiceImports๋ฅผ ์ฐธ์กฐํ•˜๋Š” Gateways and HTTPRoutes๋งŒ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ์˜ HTTPRoute๊ฐ€ ์ด๋Ÿฌํ•œ ServiceImports๋ฅผ ๋ฐฑ์—”๋“œ๋กœ ์ฐธ์กฐํ•  ๋•Œ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋‚ด๋ณด๋‚ธ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๋ฌด์—‡์ด๋“  ๊ฐ„์— ์ด๋Ÿฌํ•œ ์„œ๋น„์Šค๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒŒ์ดํŠธ์›จ์ด ๋ฐ HTTPRoute ๋ฐฐํฌ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฐฐํฌ๋œ ํ›„ gke-l7-global-external-managed-mc GatewayClass๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋Œ€์ƒ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐํ•˜๋„๋ก ๊ตฌ์„ฑ๋œ ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  1. ๋‹ค์Œ Gateway ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    ์ด ๊ฒŒ์ดํŠธ์›จ์ด ๊ตฌ์„ฑ์€ gkemcg1-NAMESPACE-GATEWAY_NAME-HASH ์ด๋ฆ„ ์ง€์ • ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์—ฌ ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

    ์ด ๊ตฌ์„ฑ์œผ๋กœ ์ƒ์„ฑ๋œ ๊ธฐ๋ณธ ๋ฆฌ์†Œ์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ 1๊ฐœ: gkemcg1-store-external-http-HASH
    • ๊ณต๊ฐœ IP ์ฃผ์†Œ 1๊ฐœ: gkemcg1-store-external-http-HASH
    • ์ „๋‹ฌ ๊ทœ์น™ 1๊ฐœ: gkemcg1-store-external-http-HASH
    • ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค 2๊ฐœ:
      • ๊ธฐ๋ณธ 404 ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค: gkemcg1-store-gw-serve404-HASH
      • ๊ธฐ๋ณธ 500 ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค: gkemcg1-store-gw-serve500-HASH
    • ์ƒํƒœ ์ ๊ฒ€ 1๊ฐœ:
      • ๊ธฐ๋ณธ 404 ์ƒํƒœ ์ ๊ฒ€: gkemcg1-store-gw-serve404-HASH
    • ๋ผ์šฐํŒ… ๊ทœ์น™ 0๊ฐœ(URLmap ๋น„์–ด ์žˆ์Œ)

    ์ด ๋‹จ๊ณ„์—์„œ GATEWAY_IP:80์„ ์š”์ฒญํ•˜๋ฉด fault filter abort ๋ฉ”์‹œ์ง€๊ฐ€ ๊ธฐ๋ณธ ํŽ˜์ด์ง€์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  2. ๋‹ค์Œ HTTPRoute ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: public-store-route
      namespace: store
      labels:
        gateway: external-http
    spec:
      hostnames:
      - "store.example.com"
      parentRefs:
      - name: external-http
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /west
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
      - matches:
        - path:
            type: PathPrefix
            value: /east
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-east-1
            port: 8080
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store
          port: 8080
    EOF
    

    ์ด ๋‹จ๊ณ„์—์„œ GATEWAY_IP:80์„ ์š”์ฒญํ•˜๋ฉด fault filter abort ๋ฉ”์‹œ์ง€๊ฐ€ ๊ธฐ๋ณธ ํŽ˜์ด์ง€์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    ๋ฐฐํฌ๋œ ๋‹ค์Œ์—๋Š” ์ด HTTPRoute๊ฐ€ ๋‹ค์Œ ๋ผ์šฐํŒ… ๋™์ž‘์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • store-west-1 ServiceExport์—์„œ ์„ ํƒํ•œ ํฌ๋“œ๊ฐ€ gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์—๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ /west์— ๋Œ€ํ•œ ์š”์ฒญ์ด gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.
    • store-east-1 ServiceExport์—์„œ ์„ ํƒํ•œ ํฌ๋“œ๊ฐ€ gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์—๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ /east์— ๋Œ€ํ•œ ์š”์ฒญ์ด gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.
    • ๋‹ค๋ฅธ ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ์š”์ฒญ์€ ์š”์ฒญ ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•œ ํ•ด๋‹น ์ƒํƒœ, ์šฉ๋Ÿ‰, ๊ทผ์ ‘์„ฑ์— ๋”ฐ๋ผ ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.
    • GATEWAY_IP:80์„ ์š”์ฒญํ•˜๋ฉด ๊ธฐ๋ณธ ํŽ˜์ด์ง€์— fault filter abort ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    HTTPRoute๋Š” ๊ฒน์น˜๋Š” ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ ํ•˜์œ„ ์ง‘ํ•ฉ์œผ๋กœ ๋ผ์šฐํŒ…์„ ์‚ฌ์šฉ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    ์ง€์ •๋œ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ชจ๋“  ํฌ๋“œ๊ฐ€ ์ •์ƒ์ด ์•„๋‹ˆ๋ฉด(๋˜๋Š” ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด) ์‹ค์ œ store ํฌ๋“œ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋กœ๋งŒ store ์„œ๋น„์Šค๊ฐ€ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ์ง€์ •๋œ ํด๋Ÿฌ์Šคํ„ฐ์— ServiceExport ๋ฐ ์„œ๋น„์Šค๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ํ•ด์„œ ํŠธ๋ž˜ํ”ฝ์ด ํ•ด๋‹น ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋ฐ˜๋“œ์‹œ ์ „์†ก๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํฌ๋“œ๊ฐ€ ์กด์žฌํ•˜๊ณ  ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ ์ƒํƒœ ํ™•์ธ์— ์ ์ ˆํ•˜๊ฒŒ ๋ฐ˜์‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๊ฐ€ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ์— ์žˆ๋Š” ์ •์ƒ store ํฌ๋“œ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    ๋‹ค์Œ ๊ตฌ์„ฑ์œผ๋กœ ์ƒˆ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

    • ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค 3๊ฐœ:
      • store ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค: gkemcg1-store-store-8080-HASH
      • store-east-1 ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค: gkemcg1-store-store-east-1-8080-HASH
      • store-west-1 ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค: gkemcg1-store-store-west-1-8080-HASH
    • ์ƒํƒœ ์ ๊ฒ€ 3๊ฐœ:
      • store ์ƒํƒœ ์ ๊ฒ€: gkemcg1-store-store-8080-HASH
      • store-east-1 ์ƒํƒœ ์ ๊ฒ€: gkemcg1-store-store-east-1-8080-HASH
      • store-west-1 ์ƒํƒœ ์ ๊ฒ€: gkemcg1-store-store-west-1-8080-HASH
    • URLmap์˜ ๋ผ์šฐํŒ… ๊ทœ์น™ 1๊ฐœ:
      • store.example.com ๋ผ์šฐํŒ… ๊ทœ์น™:
      • ํ˜ธ์ŠคํŠธ 1๊ฐœ: store.example.com
      • ์ƒˆ ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๋กœ ๋ผ์šฐํŒ…ํ•˜๋Š” ์—ฌ๋Ÿฌ matchRules

๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ๋ฐฐํฌํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. gke-west-1์€ ๊ฒŒ์ดํŠธ์›จ์ด ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฒŒ์ดํŠธ์›จ์ด, HTTPRoutes, ServiceImports๊ฐ€ ๊ฒŒ์ดํŠธ์›จ์ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๊ฐ์‹œ๋˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ์ž…๋‹ˆ๋‹ค. ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์—๋Š” store ServiceImport ๋ฐ ํ•ด๋‹น ํด๋Ÿฌ์Šคํ„ฐ์™€ ๊ด€๋ จ๋œ ๋˜ ๋‹ค๋ฅธ ServiceImport๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ๋™์ผํ•œ ํฌ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด HTTPRoute๊ฐ€ ํŠน์ • ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ ๋˜๋Š” ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ store ํฌ๋“œ์™€ ๊ฐ™์€ ํŠธ๋ž˜ํ”ฝ์˜ ์ •ํ™•ํ•œ ์ „์†ก ์œ„์น˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ๋ฆฌ์†Œ์Šค ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค.

์ด๋Š” ํŠธ๋ž˜ํ”ฝ ํ๋ฆ„์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋…ผ๋ฆฌ์ ์ธ ๋ฆฌ์†Œ์Šค ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. ํŠธ๋ž˜ํ”ฝ ๊ฒฝ๋กœ๋Š” ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์—์„œ ๋ฐฑ์—”๋“œ ํฌ๋“œ๋กœ ์ง์ ‘ ์ด๋™ํ•˜๋ฉฐ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๋ฌด์—‡์ด๋“  ์ง์ ‘์ ์ธ ๊ด€๋ จ์€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ ๊ฒ€์ฆ

์ด์ œ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ ์‹คํ–‰ํ•˜๊ณ  ๋‘ GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๊ฒŒ์ดํŠธ์›จ์ด ์ƒํƒœ์™€ ์ด๋ฒคํŠธ๋ฅผ ์กฐ์‚ฌํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐ HTTPRoute๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

    kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
    

    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    Name:         external-http
    Namespace:    store
    Labels:       <none>
    Annotations:  networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4
                  networking.gke.io/backend-services:
                    /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke...
                  networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global
                  networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv
                  networking.gke.io/health-checks:
                    /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s...
                  networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z
                  networking.gke.io/ssl-certificates: 
                  networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz
                  networking.gke.io/target-https-proxies: 
                  networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz
    API Version:  gateway.networking.k8s.io/v1beta1
    Kind:         Gateway
    Metadata:
      Creation Timestamp:  2023-10-12T06:59:32Z
      Finalizers:
        gateway.finalizer.networking.gke.io
      Generation:        1
      Resource Version:  467057
      UID:               1dcb188e-2917-404f-9945-5f3c2e907b4c
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed-mc
      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:  34.36.127.249
      Conditions:
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
        Observed Generation:   1
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
        Observed Generation:   1
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2023-10-12T07:00:41Z
          Message:               
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T07:00:41Z
          Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age                    From                   Message
      ----    ------  ----                   ----                   -------
      Normal  UPDATE  35m (x4 over 10h)      mc-gateway-controller  store/external-http
      Normal  SYNC    4m22s (x216 over 10h)  mc-gateway-controller  SYNC on store/external-http was a success
    
  2. ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌ๋˜์—ˆ์œผ๋ฉด external-http ๊ฒŒ์ดํŠธ์›จ์ด์—์„œ ์™ธ๋ถ€ IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ VIP๋ฅผ ์ถœ๋ ฅ์œผ๋กœ ์ˆ˜์‹ ๋˜๋Š” IP ์ฃผ์†Œ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  3. ๋„๋ฉ”์ธ์˜ ๋ฃจํŠธ ๊ฒฝ๋กœ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด gke-west-1 ๋ฐ gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์žˆ๋Š” store ServiceImport๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ถ€ํ•˜ ๋ถ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ฆฌ์ „์œผ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•˜๋ฉฐ, ๋‹ค๋ฅธ ๋ฆฌ์ „์˜ ์‘๋‹ต์€ ํ‘œ์‹œ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    curl -H "host: store.example.com" http://VIP
    

    ์ด ์ถœ๋ ฅ์€ ์š”์ฒญ์ด gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ์—์„œ ์ œ๊ณต๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-dg22z",
      "pod_name_emoji": "โญ",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:32:51"
    }
    
  4. ๊ทธ๋Ÿฐ ํ›„ /west ๊ฒฝ๋กœ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‹คํ–‰๋˜๋Š” ํฌ๋“œ๋งŒ ์žˆ๋Š” store-west-1 ServiceImport๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค. store-west-1๊ณผ ๊ฐ™์€ ํด๋Ÿฌ์Šคํ„ฐ ํŠน์ • ServiceImport๋Š” ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๊ฐ€ ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๋Œ€์‹  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์†Œ์œ ์ž๊ฐ€ ํŠน์ • ํด๋Ÿฌ์Šคํ„ฐ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

    curl -H "host: store.example.com" http://VIP/west
    

    ์ด ์ถœ๋ ฅ์€ ์š”์ฒญ์ด gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ์—์„œ ์ œ๊ณต๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    {
      "cluster_name": "gke-west-1", 
      "zone": "us-west1-a", 
      "host_header": "store.example.com",
      "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-d25m5",
      "pod_name_emoji": "๐Ÿพ",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:39:15",
    }
    
  5. ๋งˆ์ง€๋ง‰์œผ๋กœ /east ๊ฒฝ๋กœ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    curl -H "host: store.example.com" http://VIP/east
    

    ์ด ์ถœ๋ ฅ์€ ์š”์ฒญ์ด gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ์—์„œ ์ œ๊ณต๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-hz6mw",
      "pod_name_emoji": "๐Ÿงœ๐Ÿพ",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:40:48"
    }
    

๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์‚ฌ์šฉํ•œ ๋ธ”๋ฃจ-๊ทธ๋ฆฐ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๋ผ์šฐํŒ…

gke-l7-global-external-managed-*, gke-l7-regional-external-managed-*, gke-l7-rilb-* GatewayClass์—๋Š” ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• , ํ—ค๋” ์ผ์น˜, ํ—ค๋” ์กฐ์ž‘, ํŠธ๋ž˜ํ”ฝ ๋ฏธ๋Ÿฌ๋ง ๋“ฑ์„ ํฌํ•จํ•˜์—ฌ ๋งŽ์€ ๊ณ ๊ธ‰ ํŠธ๋ž˜ํ”ฝ ๋ผ์šฐํŒ… ๊ธฐ๋Šฅ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” ๊ฐ€์ค‘์น˜์— ๊ธฐ๋ฐ˜ํ•œ ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• ์„ ์‚ฌ์šฉํ•˜์—ฌ GKE ํด๋Ÿฌ์Šคํ„ฐ 2๊ฐœ ๊ฐ„์˜ ํŠธ๋ž˜ํ”ฝ ๋น„์œจ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ œ์–ดํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ด ์˜ˆ์‹œ์—์„œ๋Š” ์„œ๋น„์Šค ์†Œ์œ ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒˆ GKE ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ํ™•์žฅํ•  ๋•Œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์‹ค์ œ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ธ”๋ฃจ-๊ทธ๋ฆฐ ๋ฐฐํฌ์˜ ๋ชฉ์ ์€ ์ƒˆ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์—ฌ๋Ÿฌ ๊ฒ€์ฆ ๋‹จ๊ณ„๋ฅผ ํ†ตํ•ด ์œ„ํ—˜์„ ์ค„์ด๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ๋Š” ๋ฐฐํฌ์˜ 4๋‹จ๊ณ„๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.

  1. 100%-ํ—ค๋” ๊ธฐ๋ฐ˜ ์นด๋‚˜๋ฆฌ์•„: HTTP ํ—ค๋” ๋ผ์šฐํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ๋˜๋Š” ํ•ฉ์„ฑ ํŠธ๋ž˜ํ”ฝ๋งŒ ์ƒˆ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
  2. 100%-ํŠธ๋ž˜ํ”ฝ ๋ฏธ๋Ÿฌ๋ง: ์นด๋‚˜๋ฆฌ์•„ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์‚ฌ์šฉ์ž ํŠธ๋ž˜ํ”ฝ์„ ๋ฏธ๋Ÿฌ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž ํŠธ๋ž˜ํ”ฝ์„ 100% ์ด ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋ณต์‚ฌํ•˜์—ฌ ์นด๋‚˜๋ฆฌ์•„ ํด๋Ÿฌ์Šคํ„ฐ์˜ ์šฉ๋Ÿ‰์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค.
  3. 90%-10%: 10%์˜ ๋ถ„ํ•  ํŠธ๋ž˜ํ”ฝ์„ ์นด๋‚˜๋ฆฌ์•„๋กœ ํ…Œ์ŠคํŠธํ•˜์—ฌ ์ƒˆ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ผ์ด๋ธŒ ํŠธ๋ž˜ํ”ฝ์— ๋А๋ฆฌ๊ฒŒ ๋…ธ์ถœ์‹œํ‚ต๋‹ˆ๋‹ค.
  4. 0%-100%: ์˜ค๋ฅ˜๊ฐ€ ๊ด€์ธก๋œ ๊ฒฝ์šฐ ๋‹ค์‹œ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜๊ณผ ํ•จ๊ป˜ ์ƒˆ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์™„์ „ํžˆ ์ปท์˜ค๋ฒ„ํ•ฉ๋‹ˆ๋‹ค.

๋‘ GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ ๋ธ”๋ฃจ-๊ทธ๋ฆฐ ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• 

์ด ์˜ˆ์‹œ๋Š” ์ด์ „ ์˜ˆ์‹œ์™€ ๋น„์Šทํ•˜์ง€๋งŒ ๋Œ€์‹  ๋‚ด๋ถ€ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด VPC ๋‚ด์—์„œ ๋น„๊ณต๊ฐœ๋กœ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋ฐฐํฌํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์š”๊ฑด

๋‹ค์Œ ์˜ˆ์‹œ๋Š” ์™ธ๋ถ€ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ์˜ ๋‹จ๊ณ„ ์ค‘ ์ผ๋ถ€์— ๋”ฐ๋ผ ๋นŒ๋“œ๋ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์ „์— ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

  1. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์‚ฌ์šฉ ์„ค์ •

  2. ๋ฐ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ด๋ฏธ ์„ค์ •๋œ ์ƒํƒœ์˜ gke-west-1 ๋ฐ gke-west-2 ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํด๋Ÿฌ์Šคํ„ฐ๋Š” gke-l7-rilb-mc GatewayClass๊ฐ€ ๋ฆฌ์ „๋ณ„ ํด๋ž˜์Šค์ด๊ณ  ๋™์ผํ•œ ๋ฆฌ์ „์˜ ํด๋Ÿฌ์Šคํ„ฐ ๋ฐฑ์—”๋“œ๋งŒ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผํ•œ ๋ฆฌ์ „์— ์žˆ์Šต๋‹ˆ๋‹ค.

  3. ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ํ•„์š”ํ•œ ์„œ๋น„์Šค ๋ฐ ServiceExports๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ์˜ˆ์‹œ์—์„œ Service ๋ฐ ServiceExport๋ฅผ ๋ฐฐํฌํ•œ ๊ฒฝ์šฐ ์ด๋ฏธ ์ผ๋ถ€๊ฐ€ ๋ฐฐํฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-1-service.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-2-service.yaml
    

    ๋น„์Šทํ•œ ๋ฆฌ์†Œ์Šค ์ง‘ํ•ฉ์„ ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

    service/store created
    serviceexport.net.gke.io/store created
    service/store-west-2 created
    serviceexport.net.gke.io/store-west-2 created
    

ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท ๊ตฌ์„ฑ

์•„์ง ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•˜์œผ๋ฉด ๋‚ด๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋ฐฐํฌํ•˜๋ ค๋Š” ๊ฐ ๋ฆฌ์ „์—์„œ ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ์„œ๋ธŒ๋„ท์€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ ํ”„๋ก์‹œ์— ๋‚ด๋ถ€ IP ์ฃผ์†Œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ --purpose๊ฐ€ REGIONAL_MANAGED_PROXY๋กœ๋งŒ ์„ค์ •๋œ ์ƒํƒœ๋กœ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋งŒ๋“ค๊ธฐ ์ „์— ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Virtual Private Cloud(VPC) ๋„คํŠธ์›Œํฌ์˜ ๊ฐ ๋ฆฌ์ „์—๋Š” ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

gcloud compute networks subnets create ๋ช…๋ น์–ด๋Š” ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

gcloud compute networks subnets create SUBNET_NAME \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=REGION \
    --network=VPC_NETWORK_NAME \
    --range=CIDR_RANGE

๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  • SUBNET_NAME: ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • REGION: ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์˜ ๋ฆฌ์ „์ž…๋‹ˆ๋‹ค.
  • VPC_NETWORK_NAME: ์„œ๋ธŒ๋„ท์ด ํฌํ•จ๋œ VPC ๋„คํŠธ์›Œํฌ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • CIDR_RANGE: ์„œ๋ธŒ๋„ท์˜ ๊ธฐ๋ณธ IP ์ฃผ์†Œ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค. ๋ฆฌ์ „์˜ ํ”„๋ก์‹œ์—์„œ 64๊ฐœ ์ด์ƒ์˜ IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก /26 ์ด์ƒ์˜ ์„œ๋ธŒ๋„ท ๋งˆ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ถŒ์žฅ ์„œ๋ธŒ๋„ท ๋งˆ์Šคํฌ๋Š” /23์ž…๋‹ˆ๋‹ค.

๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ

๋‹ค์Œ ๊ฒŒ์ดํŠธ์›จ์ด๋Š” gke-l7-rilb-mc GatewayClass์—์„œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋™์ผํ•œ ๋ฆฌ์ „์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ๋งŒ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์ „๋ณ„ ๋‚ด๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด์ž…๋‹ˆ๋‹ค.

  1. ๋‹ค์Œ Gateway ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-rilb-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    
  2. ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ฒŒ์ดํŠธ์›จ์ด์—์„œ ์ด๋ฒคํŠธ๋ฅผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    kubectl get events --field-selector involvedObject.kind=Gateway,involvedObject.name=internal-http --context=gke-west-1 --namespace store
    

    ์ถœ๋ ฅ์ด ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•˜๋ฉด ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ๊ฐ€ ์„ฑ๊ณตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    LAST SEEN   TYPE     REASON   OBJECT                  MESSAGE
    5m18s       Normal   ADD      gateway/internal-http   store/internal-http
    3m44s       Normal   UPDATE   gateway/internal-http   store/internal-http
    3m9s        Normal   SYNC     gateway/internal-http   SYNC on store/internal-http was a success
    

ํ—ค๋” ๊ธฐ๋ฐ˜ ์นด๋‚˜๋ฆฌ์•„

ํ—ค๋” ๊ธฐ๋ฐ˜ ์นด๋‚˜๋ฆฌ์•„๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค ์†Œ์œ ์ž๋Š” ์‹ค์ œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ํ•ฉ์„ฑ ํ…Œ์ŠคํŠธ ํŠธ๋ž˜ํ”ฝ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž๋ฅผ ์ง์ ‘ ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š๊ณ ๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋ณธ ๋„คํŠธ์›Œํ‚น์ด ์ž‘๋™ํ•˜๋Š”์ง€ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‹ค์Œ HTTPRoute ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Matches for env=canary and sends it to store-west-2 ServiceImport
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-west-2
            port: 8080
      # All other traffic goes to store-west-1 ServiceImport
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
    EOF
    

    ๋ฐฐํฌ๋œ ๋‹ค์Œ์—๋Š” ์ด HTTPRoute๊ฐ€ ๋‹ค์Œ ๋ผ์šฐํŒ… ๋™์ž‘์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • env: canary HTTP ํ—ค๋”๊ฐ€ ์—†๋Š” store.example.internal ํ—ค๋”์— ๋Œ€ํ•œ ๋‚ด๋ถ€ ์š”์ฒญ์€ gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.
    • env: canary HTTP ํ—ค๋”๊ฐ€ ์žˆ๋Š” store.example.internal์— ๋Œ€ํ•œ ๋‚ด๋ถ€ ์š”์ฒญ์€ gke-west-2 ํด๋Ÿฌ์Šคํ„ฐ์˜ store ํฌ๋“œ๋กœ ๋ผ์šฐํŒ…๋ฉ๋‹ˆ๋‹ค.

    HTTPRoute๋Š” HTTP ํ—ค๋”๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ๋กœ์˜ ๋ผ์šฐํŒ…์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

    ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•˜์—ฌ HTTPRoute๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  2. internal-http์—์„œ ๋‚ด๋ถ€ IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ VIP๋ฅผ ์ถœ๋ ฅ์œผ๋กœ ์ˆ˜์‹ ๋˜๋Š” IP ์ฃผ์†Œ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  3. env: canary HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŠธ๋ž˜ํ”ฝ์ด gke-west-2๋กœ ๋ผ์šฐํŒ…๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. GKE ํด๋Ÿฌ์Šคํ„ฐ์™€ ๋™์ผํ•œ VPC์—์„œ ๋น„๊ณต๊ฐœ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ผ์šฐํŒ…๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋Š” ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ์— ๋Œ€ํ•ด ๋น„๊ณต๊ฐœ ์•ก์„ธ์Šค ๊ถŒํ•œ์ด ์žˆ๋Š” ๋จธ์‹ ์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    curl -H "host: store.example.internal" -H "env: canary" http://VIP
    

    ์ด ์ถœ๋ ฅ์€ ์š”์ฒญ์ด gke-west-2 ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ์—์„œ ์ œ๊ณต๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    {
        "cluster_name": "gke-west-2", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-2-default-pool-4cde1f72-m82p.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-9kdb5",
        "pod_name_emoji": "๐Ÿ˜‚",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:21:55",
        "zone": "us-west1-a"
    }
    

ํŠธ๋ž˜ํ”ฝ ๋ฏธ๋Ÿฌ๋ง

์ด ๋‹จ๊ณ„์—์„œ๋Š” ์˜๋„๋œ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•˜์ง€๋งŒ ๋˜ํ•œ ์นด๋‚˜๋ฆฌ์•„ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ฏธ๋Ÿฌ๋งํ•ฉ๋‹ˆ๋‹ค.

๋ฏธ๋Ÿฌ๋ง ์‚ฌ์šฉ์€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•œ ์‘๋‹ต์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ํŠธ๋ž˜ํ”ฝ ๋กœ๋“œ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์„ ํ™•์ธํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ข…๋ฅ˜์˜ ์ถœ์‹œ์— ํ•„์š”ํ•˜์ง€๋Š” ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์„ฑ๋Šฅ ๋˜๋Š” ๋กœ๋“œ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋Œ€๊ทœ๋ชจ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ถœ์‹œํ•  ๋•Œ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‹ค์Œ HTTPRoute ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Sends all traffic to store-west-1 ServiceImport
      - backendRefs:
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
        # Also mirrors all traffic to store-west-2 ServiceImport
        filters:
        - type: RequestMirror
          requestMirror:
            backendRef:
              group: net.gke.io
              kind: ServiceImport
              name: store-west-2
              port: 8080
    EOF
    
  2. ๋น„๊ณต๊ฐœ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ internal-http ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ๋‹จ๊ณ„์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ์—์„œ ์ด ์š”์ฒญ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋„๋ก /mirror ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    curl -H "host: store.example.internal" http://VIP/mirror
    
  3. ์ถœ๋ ฅ์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ์—์„œ ์‘๋‹ต์„ ์ˆ˜์‹ ํ–ˆ์Œ์ด ํ™•์ธ๋ฉ๋‹ˆ๋‹ค.

    {
        "cluster_name": "gke-west-1", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-1-default-pool-65059399-ssfq.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-brg5w",
        "pod_name_emoji": "๐ŸŽ–",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:24:51",
        "zone": "us-west1-a"
    }
    

    ์ฆ‰, ๊ธฐ๋ณธ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ํŠธ๋ž˜ํ”ฝ์— ์‘๋‹ตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ค‘์ธ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๋ฏธ๋Ÿฌ๋ง๋œ ํŠธ๋ž˜ํ”ฝ์„ ์ˆ˜์‹ ํ•˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  4. gke-west-2 ํด๋Ÿฌ์Šคํ„ฐ์—์„œ store ํฌ๋“œ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด ๋กœ๊ทธ๋กœ ํฌ๋“œ๊ฐ€ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์—์„œ ๋ฏธ๋Ÿฌ๋ง๋œ ํŠธ๋ž˜ํ”ฝ์„ ์ˆ˜์‹ ํ–ˆ๋Š”์ง€ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค.

    kubectl logs deployment/store --context gke-west-2 -n store | grep /mirror
    
  5. ์ด ์ถœ๋ ฅ์€ gke-west-2 ํด๋Ÿฌ์Šคํ„ฐ์˜ ํฌ๋“œ๊ฐ€ ๋™์ผํ•œ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์€ ํด๋ผ์ด์–ธํŠธ๋กœ ๋‹ค์‹œ ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์— ํ‘œ์‹œ๋œ IP ์ฃผ์†Œ๋Š” ํ•ด๋‹น ํฌ๋“œ์™€ ํ†ต์‹ ํ•˜๋Š” ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์˜ ๋‚ด๋ถ€ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค.

    Found 2 pods, using pod/store-5c65bdf74f-vpqbs
    [2023-10-12 21:05:20,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:20] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,158] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    

ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• 

ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• ์€ ์ƒˆ ์ฝ”๋“œ๋ฅผ ์ถœ์‹œํ•˜๊ฑฐ๋‚˜ ์ƒˆ ํ™˜๊ฒฝ์— ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์†Œ์œ ์ž๋Š” ์‹ค์ œ ์‚ฌ์šฉ์ž ์š”์ฒญ์— ๋Œ€ํ•ด ์ˆ˜๋ฝ๋˜๋Š” ์œ„ํ—˜ ์ˆ˜์ค€์— ๋”ฐ๋ผ ์ถœ์‹œ ์„ฑ๊ณต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์ผ๋ฐ˜์ ์œผ๋กœ ์ „์ฒด ํŠธ๋ž˜ํ”ฝ์˜ ๊ทน์†Œ๋Ÿ‰์— ํ•ด๋‹นํ•˜๋Š” ์นด๋‚˜๋ฆฌ์•„ ๋ฐฑ์—”๋“œ๋กœ ์ „์†ก๋˜๋Š” ๋ช…์‹œ์ ์ธ ํŠธ๋ž˜ํ”ฝ ๋ฐฑ๋ถ„์œจ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

ํŠธ๋ž˜ํ”ฝ์˜ ์†Œ๋Ÿ‰์— ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์„œ๋น„์Šค ์†Œ์œ ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ์‘๋‹ต ์ƒํƒœ๋ฅผ ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‹ ํ˜ธ๊ฐ€ ์ •์ƒ ์ƒํƒœ๋กœ ๋ณด์ด๋ฉด ์ „์ฒด ์ปท์˜ค๋ฒ„๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‹ค์Œ HTTPRoute ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      - backendRefs:
        # 90% of traffic to store-west-1 ServiceImport
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 90
        # 10% of traffic to store-west-2 ServiceImport
        - name: store-west-2
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 10
    EOF
    
  2. ๋น„๊ณต๊ฐœ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์ ์ธ curl ์š”์ฒญ์„ internal- http ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    ์ถœ๋ ฅ์€ ์ด์™€ ๋น„์Šทํ•˜๋ฉฐ, 90/10 ํŠธ๋ž˜ํ”ฝ ๋ถ„ํ• ์ด ์ˆ˜ํ–‰๋จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    ...
    

ํŠธ๋ž˜ํ”ฝ ์ปท์˜ค๋ฒ„

๋ธ”๋ฃจ-๊ทธ๋ฆฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์˜ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” ์ƒˆ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์™„์ „ํžˆ ์ปท์˜ค๋ฒ„ํ•˜๊ณ  ์ด์ „ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์†Œ์œ ์ž๊ฐ€ ์‹ค์ œ๋กœ ๋‘ ๋ฒˆ์งธ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ธฐ์กด ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์˜จ๋ณด๋”ฉํ•˜๊ณ  ์žˆ์—ˆ๋˜ ๊ฒฝ์šฐ์—๋Š” ์ตœ์ข… ๋‹จ๊ณ„๋กœ ํŠธ๋ž˜ํ”ฝ์ด ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘๋กœ ์ „์†ก๋˜๋ฏ€๋กœ, ์ด ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” gke-west-1 ๋ฐ gke-west-2 ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘์˜ ํฌ๋“œ๊ฐ€ ํฌํ•จ๋œ ๋‹จ์ผ store ServiceImport๊ฐ€ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๊ฐ€ ๊ทผ์ ‘์„ฑ, ์ƒํƒœ, ์šฉ๋Ÿ‰์„ ๊ธฐ์ค€์œผ๋กœ ํ™œ์„ฑ-ํ™œ์„ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•ด ํŠธ๋ž˜ํ”ฝ์ด ์ „์†ก๋  ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‹ค์Œ HTTPRoute ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
        - backendRefs:
          # No traffic to the store-west-1 ServiceImport
          - name: store-west-1
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 0
          # All traffic to the store-west-2 ServiceImport
          - name: store-west-2
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 100
    EOF
    
  2. ๋น„๊ณต๊ฐœ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์†์ ์ธ curl ์š”์ฒญ์„ internal- http ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์ด gke-west-2๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    ...
    

์ด ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ๋Š” ํ•˜๋‚˜์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋‹ค๋ฅธ GKE ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์ „์ฒด ๋ธ”๋ฃจ-๊ทธ๋ฆฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์šฉ๋Ÿ‰ ๊ธฐ๋ฐ˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ ๋ฐฐํฌ

์ด ์„น์…˜์˜ ์—ฐ์Šต์—์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋ฆฌ์ „์—์„œ 2๊ฐœ์˜ GKE ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜์—ฌ ์ „์—ญ ๋ถ€ํ•˜ ๋ถ„์‚ฐ ๋ฐ ์„œ๋น„์Šค ์šฉ๋Ÿ‰ ๊ฐœ๋…์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ ๋ฆฌ์ „ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์ด ๋ถ€ํ•˜ ๋ถ„์‚ฐ๋˜๋Š” ๋ฐฉ์‹์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์ดˆ๋‹น ์š”์ฒญ ์ˆ˜(RPS) ์ˆ˜์ค€์œผ๋กœ ์ƒ์„ฑ๋œ ํŠธ๋ž˜ํ”ฝ์ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋ฐฐํฌํ•  ํ† ํด๋กœ์ง€์™€ ํŠธ๋ž˜ํ”ฝ์ด ์„œ๋น„์Šค ์šฉ๋Ÿ‰์„ ์ดˆ๊ณผํ•  ๋•Œ ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ ๋ฆฌ์ „ ๊ฐ„์— ํŠธ๋ž˜ํ”ฝ์ด ์˜ค๋ฒ„ํ”Œ๋กœ๋˜๋Š” ๋ฐฉ์‹์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์˜ค๋ฒ„ํ”Œ๋กœ๋˜๋Š” ํŠธ๋ž˜ํ”ฝ

ํŠธ๋ž˜ํ”ฝ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด GKE ํŠธ๋ž˜ํ”ฝ ๊ด€๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ค€๋น„

  1. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์‚ฌ์šฉ ์„ค์ •์— ๋”ฐ๋ผ ํ™˜๊ฒฝ์„ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.

  2. GatewayClass ๋ฆฌ์†Œ์Šค๊ฐ€ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ์— ์„ค์น˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

    kubectl get gatewayclasses --context=gke-west-1
    

    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

    NAME                                  CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed        networking.gke.io/gateway   True       16h
    gke-l7-global-external-managed-mc     networking.gke.io/gateway   True       14h
    gke-l7-gxlb                           networking.gke.io/gateway   True       16h
    gke-l7-gxlb-mc                        networking.gke.io/gateway   True       14h
    gke-l7-regional-external-managed      networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed-mc   networking.gke.io/gateway   True       14h
    gke-l7-rilb                           networking.gke.io/gateway   True       16h
    gke-l7-rilb-mc                        networking.gke.io/gateway   True       14h
    

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ

๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘์— ์ƒ˜ํ”Œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml

์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

namespace/store created
deployment.apps/store created

์„œ๋น„์Šค, ๊ฒŒ์ดํŠธ์›จ์ด, HTTPRoute ๋ฐฐํฌ

  1. ๋‹ค์Œ Service ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ gke-west-1 ๋ฐ gke-east-1 ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: traffic-test
      annotations:
        networking.gke.io/max-rate-per-endpoint: "10"
    spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: http
      selector:
        app: store
      type: ClusterIP
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: traffic-test
    EOF
    
    cat << EOF | kubectl apply --context gke-east-1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: traffic-test
      annotations:
        networking.gke.io/max-rate-per-endpoint: "10"
    spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: http
      selector:
        app: store
      type: ClusterIP
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: traffic-test
    EOF
    

    ์„œ๋น„์Šค์— ์ดˆ๋‹น ์š”์ฒญ 10๊ฐœ๋กœ ์„ค์ •๋œ max-rate-per-endpoint ์ฃผ์„์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ๋ณต์ œ๋ณธ์ด ํด๋Ÿฌ์Šคํ„ฐ๋‹น 2๊ฐœ ์žˆ๋Š” ๊ฐ ์„œ๋น„์Šค์˜ ์šฉ๋Ÿ‰์€ ํด๋Ÿฌ์Šคํ„ฐ๋‹น 20RPS์ž…๋‹ˆ๋‹ค.

    ์„œ๋น„์Šค์˜ ์„œ๋น„์Šค ์šฉ๋Ÿ‰ ์ˆ˜์ค€์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์„œ๋น„์Šค ์šฉ๋Ÿ‰ ๊ฒฐ์ •์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  2. ๋‹ค์Œ Gateway ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store
      namespace: traffic-test
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    ์ด ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋Š” ๊ณต๊ฐœ์ ์œผ๋กœ ์•ก์„ธ์Šค ๊ฐ€๋Šฅํ•œ IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋ฅผ ๋ฐฐํฌํ•˜๋Š” ์™ธ๋ถ€์˜ ์ „์—ญ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค.

  3. ๋‹ค์Œ HTTPRoute ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ(์ด ์˜ˆ์‹œ์—์„œ๋Š” gke-west-1)์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store
      namespace: traffic-test
      labels:
        gateway: store
    spec:
      parentRefs:
      - kind: Gateway
        namespace: traffic-test
        name: store
      rules:
      - backendRefs:
        - name: store
          group: net.gke.io
          kind: ServiceImport
          port: 8080
    EOF
    

    ์ด ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋Š” ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์„ ์ €์žฅ์†Œ ServiceImport๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ผ์šฐํŒ… ๊ทœ์น™์„ ์‚ฌ์šฉํ•ด์„œ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” HTTPRoute๋ฅผ ๊ธฐ์ˆ ํ•ฉ๋‹ˆ๋‹ค. store ServiceImport๋Š” ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— store ์„œ๋น„์Šค ํฌ๋“œ๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๊ณ  ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์—์„œ ๋‹จ์ผ ์„œ๋น„์Šค๋กœ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

    ๋ช‡ ๋ถ„ ํ›„ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฒคํŠธ๋ฅผ ๊ฒ€์‚ฌํ•˜์—ฌ ๋ฐฐํฌ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    kubectl describe gateway store -n traffic-test --context gke-west-1
    

    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

    ...
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.102.159.147
      Conditions:
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
        Observed Generation:   1
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T21:40:59Z
        Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
        Observed Generation:   1
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2023-10-12T21:40:59Z
          Message:               
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T21:40:59Z
          Message:               The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
          Observed Generation:   1
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age                  From                   Message
      ----    ------  ----                 ----                   -------
      Normal  ADD     12m                  mc-gateway-controller  traffic-test/store
      Normal  SYNC    6m43s                mc-gateway-controller  traffic-test/store
      Normal  UPDATE  5m40s (x4 over 12m)  mc-gateway-controller  traffic-test/store
      Normal  SYNC    118s (x6 over 10m)   mc-gateway-controller  SYNC on traffic-test/store was a success
    

    ์ด ์ถœ๋ ฅ์€ ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌ๋˜์—ˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ๋ฐฐํฌ๋œ ํ›„ ํŠธ๋ž˜ํ”ฝ ์ „๋‹ฌ์ด ์‹œ์ž‘๋˜๋ ค๋ฉด ์—ฌ์ „ํžˆ ๋ช‡ ๋ถ„ ์ •๋„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ์ด ์ถœ๋ ฅ์—์„œ IP ์ฃผ์†Œ๋ฅผ ๊ธฐ๋กํ•ด ๋‘ก๋‹ˆ๋‹ค.

ํŠธ๋ž˜ํ”ฝ ํ™•์ธ

curl ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ „๋‹ฌ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

curl GATEWAY_IP_ADDRESS

์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

{
  "cluster_name": "gke-west-1",
  "host_header": "34.117.182.69",
  "pod_name": "store-54785664b5-mxstv",
  "pod_name_emoji": "๐Ÿ‘ณ๐Ÿฟ",
  "project_id": "project",
  "timestamp": "2021-11-01T14:06:38",
  "zone": "us-west1-a"
}

์ด ์ถœ๋ ฅ์€ ์š”์ฒญ์ด ์ฒ˜๋ฆฌ๋œ ๋ฆฌ์ „์„ ๋‚˜ํƒ€๋‚ด๋Š” ํฌ๋“œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ ํ™•์ธ

๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๊ฐ€ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ํŠธ๋ž˜ํ”ฝ ์ƒ์„ฑ๊ธฐ๋ฅผ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠธ๋ž˜ํ”ฝ ์ƒ์„ฑ๊ธฐ๋Š” ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ์˜ ์šฉ๋Ÿ‰ ๋ฐ ์˜ค๋ฒ„ํ”Œ๋กœ ์„ฑ๋Šฅ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๋ถ€ํ•˜ ์ˆ˜์ค€์œผ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ๋Š” ์„ธ ๊ฐ€์ง€ ๋ถ€ํ•˜ ์ˆ˜์ค€์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

  • 10 RPS๋Š” gke-west-1์—์„œ ์ €์žฅ์†Œ ์„œ๋น„์Šค ์šฉ๋Ÿ‰ ์•„๋ž˜์— ์žˆ์Šต๋‹ˆ๋‹ค.
  • 30 RPS๋Š” gke-west-1 ์ €์žฅ์†Œ ์„œ๋น„์Šค ์šฉ๋Ÿ‰์„ ์ดˆ๊ณผํ•˜๊ณ  ํŠธ๋ž˜ํ”ฝ์ด gke-east-1๋กœ ์˜ค๋ฒ„ํ”Œ๋กœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • 60 RPS๋Š” ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘ ์„œ๋น„์Šค์˜ ์šฉ๋Ÿ‰์„ ์ดˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์‹œ๋ณด๋“œ ๊ตฌ์„ฑ

  1. ๊ฒŒ์ดํŠธ์›จ์ด์— ๋Œ€ํ•ด ๊ธฐ๋ณธ URLmap ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
    

    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

    /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
    
  2. Google Cloud ์ฝ˜์†”์—์„œ ์ธก์ •ํ•ญ๋ชฉ ํƒ์ƒ‰๊ธฐ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ์ธก์ •ํ•ญ๋ชฉ ํƒ์ƒ‰๊ธฐ๋กœ ์ด๋™

  3. ์ธก์ •ํ•ญ๋ชฉ ์„ ํƒ์—์„œ ์ฝ”๋“œ: MQL์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  4. ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์— ์ €์žฅ์†Œ ์„œ๋น„์Šค์˜ ํŠธ๋ž˜ํ”ฝ ์ธก์ •ํ•ญ๋ชฉ์„ ๊ด€์ธกํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์ฟผ๋ฆฌ๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    fetch https_lb_rule
    | metric 'loadbalancing.googleapis.com/https/backend_request_count'
    | filter (resource.url_map_name == 'GATEWAY_URL_MAP')
    | align rate(1m)
    | every 1m
    | group_by [resource.backend_scope],
        [value_backend_request_count_aggregate:
            aggregate(value.backend_request_count)]
    

    GATEWAY_URL_MAP์„ ์ด์ „ ๋‹จ๊ณ„์˜ URLmap ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  5. ์ฟผ๋ฆฌ ์‹คํ–‰์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ธก์ •ํ•ญ๋ชฉ์ด ์ฐจํŠธ์— ํ‘œ์‹œ๋˜๋„๋ก ๋‹ค์Œ ์„น์…˜์—์„œ ๋กœ๋“œ ์ƒ์„ฑ๊ธฐ๋ฅผ ๋ฐฐํฌํ•œ ํ›„ ์ตœ์†Œ 5๋ถ„ ์ด์ƒ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

10 RPS ํ…Œ์ŠคํŠธ

  1. ํฌ๋“œ๋ฅผ gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 10'
    

    GATEWAY_IP_ADDRESS๋ฅผ ์ด์ „ ๋‹จ๊ณ„์˜ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๋ฉฐ, ํŠธ๋ž˜ํ”ฝ ์ƒ์„ฑ๊ธฐ๊ฐ€ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•˜๊ณ  ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

    If you don't see a command prompt, try pressing enter.
    

    ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋Š” ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ๊ณ„์† 10 RPS๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋ž˜ํ”ฝ์ด Google Cloud ๋ฆฌ์ „ ๋‚ด๋ถ€์—์„œ ์‹œ์ž‘๋˜์ง€๋งŒ ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋Š” ์ด๊ฒƒ์„ ๋ฏธ๊ตญ ์„œ๋ถ€ ํ•ด์•ˆ์—์„œ ์‹œ์ž‘๋˜๋Š” ํด๋ผ์ด์–ธํŠธ ํŠธ๋ž˜ํ”ฝ์œผ๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ์™€ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ ๋‹ค์–‘์„ฑ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•ด ๋ถ€ํ•˜ ๋ถ„์‚ฐ๊ธฐ๋Š” ๊ฐ HTTP ์š”์ฒญ์„ ์ƒˆ๋กœ์šด TCP ์—ฐ๊ฒฐ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํŠธ๋ž˜ํ”ฝ์ด ๋ฐฑ์—”๋“œ ํฌ๋“œ ๊ฐ„์— ๋ณด๋‹ค ๊ณ ๋ฅด๊ฒŒ ๋ถ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

    ์ƒ์„ฑ๊ธฐ๊ฐ€ ๋Œ€์‹œ๋ณด๋“œ์— ๋Œ€ํ•ด ํŠธ๋ž˜ํ”ฝ์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ์ตœ๋Œ€ 5๋ถ„๊นŒ์ง€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

  2. ์ธก์ •ํ•ญ๋ชฉ ํƒ์ƒ‰๊ธฐ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋Œ€ํ•ด ํŠธ๋ž˜ํ”ฝ์ด ๋ถ€ํ•˜ ๋ถ„์‚ฐ๋œ ์ •๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” 2๊ฐœ ์ค„์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    ํด๋Ÿฌ์Šคํ„ฐ์— ๋ถ€ํ•˜ ๋ถ„์‚ฐ๋˜๋Š” ํŠธ๋ž˜ํ”ฝ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ทธ๋ž˜ํ”„

    us-east1-b๊ฐ€ ํŠธ๋ž˜ํ”ฝ์„ ์ˆ˜์‹ ํ•˜์ง€ ์•Š๋Š” ๋™์•ˆ us-west1-a์—์„œ ์•ฝ 10 RPS ํŠธ๋ž˜ํ”ฝ์„ ์ˆ˜์‹ ํ•˜๋Š” ๊ฒƒ์ด ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. ํŠธ๋ž˜ํ”ฝ ์ƒ์„ฑ๊ธฐ๊ฐ€ us-west1์—์„œ ์‹คํ–‰๋˜๋ฏ€๋กœ, ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์ด gke-west-1 ํด๋Ÿฌ์Šคํ„ฐ์˜ ์„œ๋น„์Šค๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

  3. Ctrl+C๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ค‘์ง€ํ•˜๊ณ  ํฌ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

    kubectl delete pod loadgen --context gke-west-1
    

30 RPS ํ…Œ์ŠคํŠธ

  1. 30 RPS๋ฅผ ์ „์†กํ•˜๋„๋ก ๊ตฌ์„ฑํ•ด์„œ ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ๋‹ค์‹œ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 30'
    

    ์ƒ์„ฑ๊ธฐ๊ฐ€ ๋Œ€์‹œ๋ณด๋“œ์— ๋Œ€ํ•ด ํŠธ๋ž˜ํ”ฝ์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ์ตœ๋Œ€ 5๋ถ„๊นŒ์ง€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

  2. Cloud ์ž‘์—… ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    gke-east-1๋กœ ์˜ค๋ฒ„ํ”Œ๋กœ๋˜๋Š” ํŠธ๋ž˜ํ”ฝ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ทธ๋ž˜ํ”„

    ์•ฝ 20 RPS๊ฐ€ us-west1-a๋กœ ์ „์†ก๋˜๊ณ  10 RPS๊ฐ€ us-east1-b๋กœ ์ „์†ก๋˜๋Š” ๊ฒƒ์œผ๋กœ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ gke-west-1์˜ ์„œ๋น„์Šค๊ฐ€ ์™„์ „ํžˆ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๊ณ  ํŠธ๋ž˜ํ”ฝ์˜ 10 RPS๋ฅผ gke-east-1์˜ ์„œ๋น„์Šค๋กœ ์˜ค๋ฒ„ํ”Œ๋กœํ•˜๊ณ  ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

  3. Ctrl+C๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ค‘์ง€ํ•˜๊ณ  ํฌ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

    kubectl delete pod loadgen --context gke-west-1
    

60 RPS ํ…Œ์ŠคํŠธ

  1. 60 RPS๋ฅผ ์ „์†กํ•˜๋„๋ก ๊ตฌ์„ฑ๋œ ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

    kubectl run --context gke-west-1 -i --tty --rm loadgen  \
        --image=cyrilbkr/httperf  \
        --restart=Never  \
        -- /bin/sh -c 'httperf  \
        --server=GATEWAY_IP_ADDRESS  \
        --hog --uri="/zone" --port 80  --wsess=100000,1,1 --rate 60'
    
  2. 5๋ถ„ ์ •๋„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  Cloud ์ž‘์—… ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋‘ ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‘ ์•ฝ 30 RPS๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์„œ๋น„์Šค๊ฐ€ ์ „๋ฐ˜์ ์œผ๋กœ ์ดˆ๊ณผ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ž˜ํ”ฝ ์Šคํ•„์˜ค๋ฒ„๊ฐ€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š์œผ๋ฉฐ, ์„œ๋น„์Šค๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์„ ํก์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

    ์ดˆ๊ณผ ์‚ฌ์šฉ๋˜๋Š” ์„œ๋น„์Šค๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ทธ๋ž˜ํ”„

  3. Ctrl+C๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ถ€ํ•˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ค‘์ง€ํ•˜๊ณ  ํฌ๋“œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

    kubectl delete pod loadgen --context gke-west-1
    

์‚ญ์ œ

์ด ํŽ˜์ด์ง€์˜ ์—ฐ์Šต์„ ์™„๋ฃŒํ•œ ํ›„์—๋Š” ๋‹ค์Œ ๋‹จ๊ณ„์— ๋”ฐ๋ผ ์ž์‹ ์˜ ๊ณ„์ •์— ์›์น˜ ์•Š๋Š” ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

  1. ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

  2. ๋‹ค๋ฅธ ๋ชฉ์ ์œผ๋กœ ๋“ฑ๋กํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉด Fleet์—์„œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋“ฑ๋ก ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค.

  3. multiclusterservicediscovery ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค.

    gcloud container fleet multi-cluster-services disable
    
  4. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์ธ๊ทธ๋ ˆ์Šค ์‚ฌ์šฉ ์ค‘์ง€

    gcloud container fleet ingress disable
    
  5. API๋ฅผ ์‚ฌ์šฉ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค.

    gcloud services disable \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com \
        trafficdirector.googleapis.com \
        --project=PROJECT_ID
    

๊ณต์œ  VPC์™€ ํ•จ๊ป˜ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์‚ฌ์šฉ

์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ† ํด๋กœ์ง€๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๊ณต์œ  VPC ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ํ‘œ์—์„œ๋Š” ๊ณต์œ  VPC ํ™˜๊ฒฝ ๋‚ด์—์„œ ์ง€์›๋˜๋Š” ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด ํ† ํด๋กœ์ง€๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์‹œ๋‚˜๋ฆฌ์˜ค Fleet ํ˜ธ์ŠคํŠธ ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ ์›Œํฌ๋กœ๋“œ ํด๋Ÿฌ์Šคํ„ฐ
1 ๊ณต์œ  VPC ํ˜ธ์ŠคํŠธ ํ”„๋กœ์ ํŠธ ๊ณต์œ  VPC ํ˜ธ์ŠคํŠธ ํ”„๋กœ์ ํŠธ ๊ณต์œ  VPC ํ˜ธ์ŠคํŠธ ํ”„๋กœ์ ํŠธ
2 ๊ณต์œ  VPC ์„œ๋น„์Šค ํ”„๋กœ์ ํŠธ ๊ณต์œ  VPC ์„œ๋น„์Šค ํ”„๋กœ์ ํŠธ
(Fleet ์„œ๋น„์Šค ํ”„๋กœ์ ํŠธ์™€ ๋™์ผ)
๊ณต์œ  VPC ์„œ๋น„์Šค ํ”„๋กœ์ ํŠธ
(Fleet ์„œ๋น„์Šค ํ”„๋กœ์ ํŠธ์™€ ๋™์ผ)

๊ณต์œ  VPC ํ™˜๊ฒฝ์—์„œ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. ๊ณต์œ  VPC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค๋ฅผ ์„ค์ •ํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

  2. ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค์–ด ๊ตฌ์„ฑ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

  3. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  4. ๋ฉ€ํ‹ฐ ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€ ๋˜๋Š” ๋‚ด๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐ HTTPRoute๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ด ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•˜๋ฉด ํ† ํด๋กœ์ง€์— ๋”ฐ๋ผ ๋ฐฐํฌ๋ฅผ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ ํ•ด๊ฒฐ

๋‚ด๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์ด ์—†์Œ

๋‚ด๋ถ€ ๊ฒŒ์ดํŠธ์›จ์ด์— ๋‹ค์Œ ์ด๋ฒคํŠธ๊ฐ€ ํ‘œ์‹œ๋˜๋ฉด ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์ด ํ•ด๋‹น ๋ฆฌ์ „์— ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ํ”„๋ก์‹œ ์ „์šฉ ์„œ๋ธŒ๋„ท์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

์ •์ƒ ์—…์ŠคํŠธ๋ฆผ ์—†์Œ

์ฆ์ƒ:

๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(503 ์‘๋‹ต ์ฝ”๋“œ).

no healthy upstream

์ด์œ :

์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ์ƒํƒœ ์ ๊ฒ€ ํ”„๋กœ๋ฒ„๊ฐ€ ์ •์ƒ ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๊ฐ€ ์ •์ƒ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ƒํƒœ ์ ๊ฒ€์„ ๋งž์ถค์„ค์ •ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด HealthCheckPolicy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์š”๊ตฌ์‚ฌํ•ญ(์˜ˆ: /health)์— ๋”ฐ๋ผ ์ƒํƒœ ์ ๊ฒ€์„ ๋งž์ถค์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„