Kubernetes ยท Networking ยท

[Kubernetes] ๐Ÿ”€ LB IP ํ•˜๋‚˜๋กœ ์—ฌ๋Ÿฌ TCP ์„œ๋น„์Šค ๋…ธ์ถœ โ€” Contour passthrough + Kong SNI

LoadBalancer IP๋ฅผ ํ•˜๋‚˜๋ฐ–์— ๋ชป ์“ฐ๋Š” ์ œ์•ฝ์—์„œ ์—ฌ๋Ÿฌ TCP ์„œ๋น„์Šค๋ฅผ ๋„๋ฉ”์ธ์œผ๋กœ ๋…ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ•ต์‹ฌ์€ Contour(Envoy)๊ฐ€ TLS๋ฅผ ๋ณตํ˜ธํ™”ํ•˜์ง€ ์•Š๊ณ (passthrough) SNI๋งŒ ๋ณด๊ณ  Kong์œผ๋กœ ํ†ต์งธ๋กœ ๋„˜๊ธฐ๊ณ , ์‹ค์ œ TLS ์ข…๋‹จ๊ณผ ์„ธ๋ถ€ ๋ผ์šฐํŒ…์€ Kong์ด ๋งก๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋„๋ฉ”์ธ(SNI)์ด ์‚ฌ์‹ค์ƒ “๊ฐ€์ƒ ํฌํŠธ” ์—ญํ• ์„ ํ•ด์„œ, ๊ณ ์ •๋œ IPยทํฌํŠธ ํ•˜๋‚˜ ์œ„์—์„œ ๋ฐฑ์—”๋“œ๋ฅผ ๊ณ„์† ๋Š˜๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์ œ: Envoy LoadBalancer IP๊ฐ€ ์ œํ•œ์ (์˜ˆ: ์ตœ๋Œ€ 2๊ฐœ)์ด๋ผ ๋‹จ์ผ IP๋กœ ์šด์šฉํ•ด์•ผ ํ•˜๊ณ , ์‚ฌ์šฉ์ž๋Š” ๋„๋ฉ”์ธ์œผ๋กœ RedisยทDB ๊ฐ™์€ TCP ์„œ๋น„์Šค์— ์ ‘์†ํ•˜๋ ค๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.


๐Ÿง… TLS passthrough๋ž€? #

TLS passthrough๋Š” ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ TLS๋ฅผ ๋ณตํ˜ธํ™”ํ•˜์ง€ ์•Š๊ณ , ์•”ํ˜ธํ™”๋œ ์ฑ„๋กœ ๋’ค ๋ฐฑ์—”๋“œ์— ๊ทธ๋Œ€๋กœ ํ˜๋ ค๋ณด๋‚ด๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋ด‰ํˆฌ์— ๋น„์œ ํ•˜๋ฉด ์ด๋ ‡์Šต๋‹ˆ๋‹ค.

  • TLS termination(์ข…๋‹จ): ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ๋ด‰ํˆฌ๋ฅผ ๋œฏ์–ด์„œ ๋ณตํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค โ†’ ๊ฒŒ์ดํŠธ์›จ์ด์— ์ธ์ฆ์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • TLS passthrough: ๋ด‰ํˆฌ๋ฅผ ์•ˆ ๋œฏ๊ณ , ๊ฒ‰๋ฉด์˜ ์ˆ˜์‹ ์ธ ์ด๋ฆ„(SNI)๋งŒ ๋ณด๊ณ  ๋ด‰์ธ๋œ ์ฑ„๋กœ ๋’ค๋กœ ๋„˜๊น๋‹ˆ๋‹ค.

์ฆ‰ Contour(Envoy)๋Š” ๋ณตํ˜ธํ™”ํ•˜์ง€ ์•Š๊ณ  SNI๋งŒ ๋ณด๊ณ  “์ด๊ฑด Kong์œผ๋กœ” ํ˜๋ ค๋ณด๋‚ด๋ฉฐ, ์‹ค์ œ TLS ์ข…๋‹จ์€ ๋’ค์˜ Kong์ด ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์™œ termination์ด ์•„๋‹ˆ๋ผ passthrough์—ฌ์•ผ ํ•˜๋‚˜? #

SNI๋Š” ๋ด‰ํˆฌ ๊ฒ‰๋ฉด(TLS ํ•ธ๋“œ์…ฐ์ดํฌ์˜ ClientHello)์— ์‹ค๋ ค ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ Contour๊ฐ€ ๋ด‰ํˆฌ๋ฅผ ๋œฏ์–ด(termination) ๋ฒ„๋ฆฌ๋ฉด ๊ทธ SNI ์ •๋ณด๊ฐ€ Kong๊นŒ์ง€ ๋„๋‹ฌํ•˜์ง€ ๋ชปํ•˜๊ณ , Kong์˜ SNI ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…์ด ๊นจ์ง‘๋‹ˆ๋‹ค. passthrough์—ฌ์•ผ ์›๋ณธ SNI๊ฐ€ Kong๊นŒ์ง€ ์‚ด์•„์„œ ๋„์ฐฉํ•ด, Kong์ด ๊ทธ ๊ฐ’์œผ๋กœ ๋ฐฑ์—”๋“œ๋ฅผ ๊ณ ๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”ง ๋‹จ์ผ ๊ตฌ์„ฑ (์‹ค์ œ๋กœ ์“ด ํ˜•ํƒœ) #

Contour์˜ HTTPProxy์— passthrough: true์™€ tcpproxy๋ฅผ ํ•จ๊ป˜ ์ง€์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. virtualhost.fqdn์ด SNI ๋งค์นญ ๊ธฐ์ค€์ด ๋˜๊ณ , ๋งค์นญ๋œ ์—ฐ๊ฒฐ์€ ๋ด‰ํˆฌ์งธ kong-proxy๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

 1apiVersion: projectcontour.io/v1
 2kind: HTTPProxy
 3metadata:
 4  name: redis-cache
 5spec:
 6  virtualhost:
 7    fqdn: redis-cache.example.com      # SNI ๋งค์นญ ๊ธฐ์ค€
 8    tls:
 9      passthrough: true                # ๋ด‰ํˆฌ ์•ˆ ๋œฏ์Œ (์ธ์ฆ์„œ ๋ถˆํ•„์š”)
10  tcpproxy:
11    services:
12      - name: kong-proxy               # ๋ด‰ํˆฌ์งธ Kong์œผ๋กœ ์ „๋‹ฌ
13        port: 9443

์™œ routes๊ฐ€ ์•„๋‹ˆ๋ผ tcpproxy์ธ๊ฐ€? #

passthrough๋ฉด ๋ณตํ˜ธํ™”๋ฅผ ์•ˆ ํ•˜๋ฏ€๋กœ HTTP ๊ฒฝ๋กœยทํ—ค๋”๋ฅผ ๋ณผ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜ routes๋Š” ๋ณตํ˜ธํ™”๊ฐ€ ์ „์ œ๋ผ ์“ธ ์ˆ˜ ์—†๊ณ , “SNI๋งŒ ๋ณด๊ณ  ํ†ต์งธ๋กœ TCP ์ „๋‹ฌ"ํ•˜๋Š” tcpproxy๋ฅผ ์”๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ tls.passthrough: true โ†” tcpproxy๋Š” ํ•ญ์ƒ ์ง์œผ๋กœ ๊ฐ‘๋‹ˆ๋‹ค(๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ ์žˆ์œผ๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

Kong ์ชฝ์€ stream ๋ฆฌ์Šค๋„ˆ :9443 ssl์„ ์—ด๊ณ  Route์— protocols: [tls] + snis๋ฅผ ์„ค์ •ํ•ด TLS๋ฅผ ์ข…๋‹จํ•œ ๋’ค ๋ฐฑ์—”๋“œ๋กœ ๋ถ„๋ฐฐํ•ฉ๋‹ˆ๋‹ค โ€” ์ด ๋ถ€๋ถ„์€ Kong์œผ๋กœ TCP/TLS ์„œ๋น„์Šค ์™ธ๋ถ€ ๋…ธ์ถœํ•˜๊ธฐ ๊ธ€์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.


๐Ÿ“ˆ ํ™•์žฅ ๊ตฌ์กฐ โ€” ๋„“ํžˆ๋Š” ๊ฑด ์–‘์ชฝ ๋, ๊ฐ€์šด๋ฐ๋Š” ๊ณ ์ • #

ํ•ต์‹ฌ์€ “๊ฐ€์šด๋ฐ(LB IPยทํฌํŠธ)๋Š” ๊ณ ์ •ํ•˜๊ณ , ์–‘์ชฝ ๋(๋„๋ฉ”์ธ)๋งŒ ๋Š˜๋ฆฐ๋‹ค” ์ž…๋‹ˆ๋‹ค. ๋„๋ฉ”์ธ๋งˆ๋‹ค Contour HTTPProxy 1๊ฐœ์™€ Kong Service+Route 1์„ธํŠธ๋ฅผ ๋”ํ•  ๋ฟ, LB IP์™€ ํฌํŠธ(9443)๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Contour passthrough + Kong SNI ํ™•์žฅ ๊ตฌ์กฐ

  • Contour: ๋„๋ฉ”์ธ๋งˆ๋‹ค HTTPProxy 1๊ฐœ(๊ฐ fqdn + passthrough + tcpproxy โ†’ kong-proxy). ์ „๋ถ€ ๊ฐ™์€ kong-proxy๋กœ ๋ชจ์๋‹ˆ๋‹ค.
  • Kong: ๋ด‰ํˆฌ์งธ ๋ฐ›์•„ TLS๋ฅผ ์ข…๋‹จํ•œ ๋’ค Route.snis๋กœ ์ตœ์ข… ๋ถ„๋ฐฐํ•ฉ๋‹ˆ๋‹ค. ๋„๋ฉ”์ธ๋งˆ๋‹ค Service+Route 1์„ธํŠธ๋ฅผ ๋‘ก๋‹ˆ๋‹ค.

์˜ˆ์‹œ ๋งคํ•‘์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค.

๋„๋ฉ”์ธ(SNI)Contour HTTPProxyKong Service
redis-cache.example.comredis-cacheredis-cache-svc
redis-queue.example.comredis-queueredis-queue-svc
postgres-main.example.compostgrespostgres-svc

์ด ๊ตฌ์กฐ์—์„œ ๋„๋ฉ”์ธ(SNI)์ด ๊ณง “๊ฐ€์ƒ ํฌํŠธ” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ฆฌ ํฌํŠธ๋Š” 9443 ํ•˜๋‚˜์ง€๋งŒ, SNI๋กœ ์‚ฌ์‹ค์ƒ ๋ฌดํ•œํžˆ ๋งŽ์€ ์„œ๋น„์Šค๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


โš ๏ธ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํ•จ์ • โ€” SNI๊ฐ€ ๋‘ ๋ฒˆ ์“ฐ์ธ๋‹ค #

์ด ๊ตฌ์กฐ์—์„œ SNI(๋„๋ฉ”์ธ)๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์ง€์ ์—์„œ ๊ฐ๊ฐ ๋งค์นญ์— ์“ฐ์ž…๋‹ˆ๋‹ค. ์ด ๋‘˜์ด ์–ด๊ธ‹๋‚˜๋ฉด ์—ฐ๊ฒฐ์ด ๋Š๊น๋‹ˆ๋‹ค.

  1. Contour๊ฐ€ virtualhost.fqdn์œผ๋กœ 1์ฐจ ๋งค์นญ โ€” “์ด ์—ฐ๊ฒฐ์ด ์ด HTTPProxy ๋‹ด๋‹น์ธ๊ฐ€”
  2. Kong์ด Route.snis๋กœ 2์ฐจ ๋ถ„๋ฐฐ โ€” “๋ณตํ˜ธํ™”ํ–ˆ๋”๋‹ˆ ์–ด๋А ๋ฐฑ์—”๋“œ๋กœ ๋ณด๋‚ด์•ผ ํ•˜๋‚˜”

์ฆ‰ โ‘ ์˜ fqdn๊ณผ โ‘ก์˜ snis๊ฐ€ ๊ฐ™์€ ๋„๋ฉ”์ธ์ด์–ด์•ผ ํด๋ผ์ด์–ธํŠธ๋ถ€ํ„ฐ ๋ฐฑ์—”๋“œ๊นŒ์ง€ ๋๊นŒ์ง€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜๋ผ๋„ ์˜คํƒ€๋‚˜ ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ์œผ๋ฉด “Contour๋Š” ๋„˜๊ฒผ๋Š”๋ฐ Kong์ด ๋ชป ๊ฐ€๋ฅด๋Š”” ์ฆ์ƒ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค โ€” Contour ๋กœ๊ทธ์—” ์ •์ƒ ์ „๋‹ฌ๋กœ ๋ณด์ด๋Š”๋ฐ Kong์—์„œ ๋งค์นญ ์‹คํŒจ๋กœ ๋Š๊ธฐ๋ฏ€๋กœ ์›์ธ ํŒŒ์•…์ด ํ—ท๊ฐˆ๋ฆฝ๋‹ˆ๋‹ค.


โž• ๋ฐฑ์—”๋“œ ์ถ”๊ฐ€ ์ ˆ์ฐจ #

๋ฐฑ์—”๋“œ ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ํ•˜๋Š” ์ผ์€ ๋„๋ฉ”์ธ ํ•œ ์Œ์„ ์–‘ ๋์— ๋”ํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค.

  1. Contour: HTTPProxy 1๊ฐœ ์ถ”๊ฐ€ (fqdn: redis-c.example.com, passthrough: true, tcpproxy โ†’ kong-proxy)
  2. Kong: Service + Route(snis: redis-c.example.com) 1์„ธํŠธ ์ถ”๊ฐ€
  3. LB IPยทํฌํŠธ(9443)๋Š” ๊ทธ๋Œ€๋กœ โ€” ๋„๋ฉ”์ธ๋งŒ ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค.

๐Ÿงฏ ์‹ค๋ฌด ์ฃผ์˜์  #

  • passthrough ๋ฆฌ์Šค๋„ˆ ๊ณต์กด: HTTPProxy๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์—ฌ๋„ ๊ฐ™์€ passthrough ๋ฆฌ์Šค๋„ˆ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค(SNI๋กœ ๊ฐˆ๋ฆฌ๋‹ˆ ์„œ๋กœ ์ถฉ๋Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค). ๋‹ค๋งŒ ๊ฐ™์€ IP์—์„œ HTTP termination ์„œ๋น„์Šค์™€ ํฌํŠธ๋ฅผ ํ•จ๊ป˜ ์“ฐ๋ฉด ๋ถ€๋”ชํž ์ˆ˜ ์žˆ์œผ๋‹ˆ ํฌํŠธ ์„ค๊ณ„๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ SNI๋ฅผ ๋ชป ๋ณด๋‚ผ ๋•Œ: Redis ๊ฐ™์€ ํ‰๋ฌธ TCP ํด๋ผ์ด์–ธํŠธ๊ฐ€ TLS SNI๋ฅผ ์‹ค์–ด ๋ณด๋‚ด์ง€ ๋ชปํ•˜๋ฉด, ์—ฌ์ „ํžˆ stunnel ๋“ฑ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ์ชฝ์—์„œ SNI๋ฅผ ๋ถ€์—ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฑด ContourยทKong๊ณผ ๋ฌด๊ด€ํ•œ ํด๋ผ์ด์–ธํŠธ ์ธก ํ•œ๊ณ„์ž…๋‹ˆ๋‹ค.
  • YAML์€ ๋ฐ˜๋“œ์‹œ ๋ฒ„์ „ ๊ด€๋ฆฌ: fqdn โ†” snis ์ง์ด ๋Š˜์–ด๋‚ ์ˆ˜๋ก ๊ด€๋ฆฌ ๋ถ€๋‹ด์ด ์ปค์ง‘๋‹ˆ๋‹ค. ๋„ค์ด๋ฐ ๊ทœ์น™(๋„๋ฉ”์ธยท๋ฆฌ์†Œ์Šค๋ช… ์ผ๊ด€์„ฑ)์„ ์ •ํ•˜๊ณ  Git์œผ๋กœ ๊ด€๋ฆฌํ•˜์„ธ์š”. ํŠนํžˆ Kong CRD๋Š” ์‚ญ์ œ ์‹œ ์ปค์Šคํ…€ ๋ฆฌ์†Œ์Šค๊ฐ€ ์—ฐ์‡„ ์‚ญ์ œ๋  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋ฐฑ์—…ยท๊ฒ€ํ†  ํ›„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.

โ“ ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ #

Q. Contour์— ์ธ์ฆ์„œ๋ฅผ ๋„ฃ์–ด์•ผ ํ•˜๋‚˜์š”? ์•„๋‹ˆ์š”. passthrough๋Š” ๋ณตํ˜ธํ™”๋ฅผ ์•ˆ ํ•˜๋ฏ€๋กœ Contour์—๋Š” ์ธ์ฆ์„œ๊ฐ€ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค. TLS ์ข…๋‹จ์€ ๋’ค์˜ Kong์ด ํ•˜๋‹ˆ ์ธ์ฆ์„œ๋Š” Kong ์ชฝ์— ๋‘ก๋‹ˆ๋‹ค.

Q. ์™œ tcpproxy๋ฅผ ์“ฐ๊ณ  routes๋Š” ๋ชป ์“ฐ๋‚˜์š”? passthrough๋ฉด ์•”ํ˜ธ๋ฌธ์„ ๊ทธ๋Œ€๋กœ ๋„˜๊ธฐ๋ฏ€๋กœ HTTP ๊ฒฝ๋กœยทํ—ค๋”๋ฅผ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜ routes๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , SNI๋งŒ ๋ณด๊ณ  ํ†ต์งธ๋กœ ๋„˜๊ธฐ๋Š” tcpproxy๋งŒ ๋ฉ๋‹ˆ๋‹ค.

Q. ์„œ๋น„์Šค๊ฐ€ ๋Š˜์–ด๋‚˜๋ฉด LB IP๋‚˜ ํฌํŠธ๋„ ๋Š˜๋ ค์•ผ ํ•˜๋‚˜์š”? ์•„๋‹ˆ์š”. IPยทํฌํŠธ๋Š” 9443 ํ•˜๋‚˜๋กœ ๊ณ ์ •์ด๊ณ , ๋„๋ฉ”์ธ(SNI)๋งŒ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. SNI๊ฐ€ ๊ฐ€์ƒ ํฌํŠธ ์—ญํ• ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Q. ์—ฐ๊ฒฐ์ด ์•ˆ ๋˜๋Š”๋ฐ ์–ด๋””๋ถ€ํ„ฐ ๋ด์•ผ ํ•˜๋‚˜์š”? ๋จผ์ € Contour์˜ fqdn๊ณผ Kong์˜ Route.snis๊ฐ€ ์™„์ „ํžˆ ๊ฐ™์€ ๋„๋ฉ”์ธ์ธ์ง€ ํ™•์ธํ•˜์„ธ์š”. ๊ฐ€์žฅ ํ”ํ•œ ์›์ธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ Kong stream ๋ฆฌ์Šค๋„ˆ(:9443 ssl)์™€ SNI ๋ผ์šฐํŒ…์„ ์ ๊ฒ€ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“š ์ฐธ๊ณ  #