[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: ๋๋ฉ์ธ๋ง๋ค
HTTPProxy1๊ฐ(๊ฐfqdn+passthrough+tcpproxyโkong-proxy). ์ ๋ถ ๊ฐ์kong-proxy๋ก ๋ชจ์๋๋ค. - Kong: ๋ดํฌ์งธ ๋ฐ์ TLS๋ฅผ ์ข
๋จํ ๋ค
Route.snis๋ก ์ต์ข ๋ถ๋ฐฐํฉ๋๋ค. ๋๋ฉ์ธ๋ง๋คService+Route1์ธํธ๋ฅผ ๋ก๋๋ค.
์์ ๋งคํ์ ์ด๋ ์ต๋๋ค.
| ๋๋ฉ์ธ(SNI) | Contour HTTPProxy | Kong Service |
|---|---|---|
redis-cache.example.com | redis-cache | redis-cache-svc |
redis-queue.example.com | redis-queue | redis-queue-svc |
postgres-main.example.com | postgres | postgres-svc |
์ด ๊ตฌ์กฐ์์ ๋๋ฉ์ธ(SNI)์ด ๊ณง “๊ฐ์ ํฌํธ” ์ญํ ์ ํฉ๋๋ค. ๋ฌผ๋ฆฌ ํฌํธ๋ 9443 ํ๋์ง๋ง, SNI๋ก ์ฌ์ค์ ๋ฌดํํ ๋ง์ ์๋น์ค๋ฅผ ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
โ ๏ธ ๊ฐ์ฅ ์ค์ํ ํจ์ โ SNI๊ฐ ๋ ๋ฒ ์ฐ์ธ๋ค #
์ด ๊ตฌ์กฐ์์ SNI(๋๋ฉ์ธ)๋ ์๋ก ๋ค๋ฅธ ๋ ์ง์ ์์ ๊ฐ๊ฐ ๋งค์นญ์ ์ฐ์ ๋๋ค. ์ด ๋์ด ์ด๊ธ๋๋ฉด ์ฐ๊ฒฐ์ด ๋๊น๋๋ค.
- Contour๊ฐ
virtualhost.fqdn์ผ๋ก 1์ฐจ ๋งค์นญ โ “์ด ์ฐ๊ฒฐ์ด ์ด HTTPProxy ๋ด๋น์ธ๊ฐ” - Kong์ด
Route.snis๋ก 2์ฐจ ๋ถ๋ฐฐ โ “๋ณตํธํํ๋๋ ์ด๋ ๋ฐฑ์๋๋ก ๋ณด๋ด์ผ ํ๋”
์ฆ โ ์ fqdn๊ณผ โก์ snis๊ฐ ๊ฐ์ ๋๋ฉ์ธ์ด์ด์ผ ํด๋ผ์ด์ธํธ๋ถํฐ ๋ฐฑ์๋๊น์ง ๋๊น์ง ์ฐ๊ฒฐ๋ฉ๋๋ค. ํ๋๋ผ๋ ์คํ๋ ๋ถ์ผ์น๊ฐ ์์ผ๋ฉด “Contour๋ ๋๊ฒผ๋๋ฐ Kong์ด ๋ชป ๊ฐ๋ฅด๋” ์ฆ์์ด ๋์ต๋๋ค โ Contour ๋ก๊ทธ์ ์ ์ ์ ๋ฌ๋ก ๋ณด์ด๋๋ฐ Kong์์ ๋งค์นญ ์คํจ๋ก ๋๊ธฐ๋ฏ๋ก ์์ธ ํ์
์ด ํท๊ฐ๋ฆฝ๋๋ค.
โ ๋ฐฑ์๋ ์ถ๊ฐ ์ ์ฐจ #
๋ฐฑ์๋ ํ๋๋ฅผ ์ถ๊ฐํ ๋ ํ๋ ์ผ์ ๋๋ฉ์ธ ํ ์์ ์ ๋์ ๋ํ๋ ๊ฒ๋ฟ์ ๋๋ค.
- Contour:
HTTPProxy1๊ฐ ์ถ๊ฐ (fqdn: redis-c.example.com,passthrough: true,tcpproxyโkong-proxy) - Kong:
Service+Route(snis: redis-c.example.com) 1์ธํธ ์ถ๊ฐ - 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 ๋ผ์ฐํ
์ ์ ๊ฒํฉ๋๋ค.
๐ ์ฐธ๊ณ #
- Contour ๊ณต์ ๋ฌธ์ โ TLS passthrough / TCPProxy
- Kong โ TCP/TLS proxying & stream_listen
- Kong โ Route ์ํฐํฐ(protocolsยทsnis)
- Kong โ SNI ์ํฐํฐ(์ธ์ฆ์-ํธ์คํธ๋ค์ ๋งคํ)
- KIC ํํ ๋ฆฌ์ผ โ Proxy TCP traffic over TLS by SNI
- Kong charts values.yaml โ proxy.stream(ssl)
- ๊ด๋ จ ๊ธ: Kong์ผ๋ก TCP/TLS ์๋น์ค ์ธ๋ถ ๋ ธ์ถํ๊ธฐ (LoadBalancer + SNI) ยท Ingress์์ Gateway API HTTPRoute๋ก