๐ŸŒฑ Infra/KeyCloak

[keycloak ๋ง›๋ณด๊ธฐ #7] Production Keycloak์„ ์œ„ํ•œ ์„ค์ •

mini_world 2025. 2. 16. 16:58
๋ชฉ์ฐจ ์ ‘๊ธฐ

๋“ค์–ด๊ฐ€๊ธฐ์ „์—, 

*https://www.keycloak.org/server/configuration-production 

Keycloak์€ ์ˆ˜๋ฐฑ~์ˆ˜์ฒœ๋ช…์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•ˆ์ „ํ•œ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ๋ถ€์—ฌ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ๋‹ค.
์•ˆ์ „ํ•˜๊ณ  ์•ˆ์ •์ ์ธ Keycloak์„ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•ด ์„ค์ •ํ•ด์•ผ ํ•  ๋ถ€๋ถ„๋“ค์„ ํ™•์ธ ํ•ด ๋ณด์ž.

 

 

1. Keycloak์˜ Hostname ์„ค์ •

* ๊ณต์‹๋ฌธ์„œ: https://www.keycloak.org/server/hostname

 

โœ“ Hostname์„ ์„ค์ •ํ•ด์•ผํ•˜๋Š” ์ด์œ 

keycloak์€ ๋ณด์•ˆ์ƒ์˜ ์ด์œ ๋กœ hostname ์„ค์ •์„ ํ•„์ˆ˜๋กœํ•œ๋‹ค.

โ–ช๏ธŽ ์„ค๋ช…

Keycloak์€ OIDC Discovery ์—”๋“œํฌ์ธํŠธ, ์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ ์—”๋“œํฌ์ธํŠธ ๋“ฑ์˜ URL์ด ์™ธ๋ถ€๋กœ ๊ณต๊ฐœ๋œ๋‹ค.
์ด๋•Œ, hostname์ด ์„ค์ •๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด ๊ฐ€์งœ ๋„๋ฉ”์ธ์œผ๋กœ redirectํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •๋ณด(token, password)๋ฅผ ํƒˆ์ทจ ๋‹นํ• ์ˆ˜๋„ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ Hostname์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์œผ๋กœ ํ† ํฐ์ด ๋ฐœ๊ธ‰๋˜๋Š”๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

keycloak์˜ ๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•ด ์•„๋ž˜ 3๊ฐ€์ง€๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •ํ•˜๋Š”๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.

  • ํ•ญ์ƒ https ์‚ฌ์šฉ
  • ๊ด€๋ฆฌ์ž ์ฝ˜์†” ๋ถ„๋ฆฌ
  • ํ”„๋ก์‹œ ์„ค์ • ์‹œ ์‹ ๋ขฐํ• ์ˆ˜์žˆ๋Š” ํ”„๋ก์‹œ ์ฃผ์†Œ ์„ค์ •

โ–ช๏ธŽ ํƒˆ์ทจ ์‹œ๋‚˜๋ฆฌ์˜ค

๊ณต๊ฒฉ์ž๊ฐ€ ์กฐ์ž‘๋œ Hostํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Keycloak Redirect URL์„ ์ƒ์„ฑํ• ๋•Œ ์•…์˜์ ์ธ ๋„๋ฉ”์ธ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ my.keycloak.com์—์„œ ๋กœ๊ทธ์ธ์„ ์‹œ๋„
↓
๊ณต๊ฒฉ์ž๊ฐ€ Host ํ—ค๋”๋ฅผ fake-site.com์œผ๋กœ ๋ณ€์กฐ
↓
๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URL์ด fake-site.com์œผ๋กœ ์ƒ์„ฑ๋จ
↓
์‚ฌ์šฉ์ž๊ฐ€ ํ”ผ์‹ฑ ์‚ฌ์ดํŠธ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋จ

ํ˜น์€ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„ค์ •๋„ ์˜ค์šฉ ๋  ์ˆ˜ ์žˆ๋‹ค.
๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์„ค์ •์€ ๋’ค์—์„œ ์กฐ๊ธˆ ๋” ๋‹ค๋ค„๋ณด๋„๋ก ํ•œ๋‹ค.

Client -> Reverse Proxy -> Keycloak
                      ↑
                      | 
                      ๊ณต๊ฒฉ์ž๊ฐ€ X-Forwarded-Host 
                      ํ—ค๋”๋ฅผ ์กฐ์ž‘

 

 

โœ“ ์„ธ๊ฐ€์ง€ ์ฃผ์š” ์—”๋“œํฌ์ธํŠธ ๊ทธ๋ฃน

Keycloak์€ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ชฉ์ ์„ ๊ฐ€์ง„ 3๊ฐ€์ง€ ์ฃผ์š” ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์žˆ๋‹ค.
์ผ๋ฐ˜์ ์ธ ํ™˜๊ฒฝ์—์„œ ์–ด๋–ป๊ฒŒ ์“ฐ์ด๋Š”์ง€ ์ข€ ๋” ํ™•์ธํ•ด๋ณด์ž.

โ–ช๏ธŽ frontend

์‚ฌ์šฉ์ž ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๊ณต๊ฐœ ์—”๋“œํฌ์ธํŠธ๋‹ค.
๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ/๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ •  URL ๋˜๋Š” ์„ธ์…˜ ๊ด€๋ฆฌ์™€ ๊ด€๋ จ๋œ ์—”๋“œํฌ์ธํŠธ ๋“ฑ์ด์žˆ๋‹ค.

bin/kc.[sh|bat] start --hostname https://auth.my.com

โ–ช๏ธŽ Backend

ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ Keycloak๊ฐ„์˜ ๋‚ด๋ถ€ํ†ต์‹ ์„ ์œ„ํ•œ ์—”๋“œํฌ์ธํŠธ๋‹ค.
์ธ์ฆ ์—”๋“œํฌ์ธํŠธ, ํ† ํฐ ๋ฐ ํ† ํฐ ์ธํŠธ๋กœ์ŠคํŽ™์…˜ ์—”๋“œํฌ์ธํŠธ, userinfo ์—”๋“œํฌ์ธํŠธ, JWKS URI ์—”๋“œํฌ์ธํŠธ ๋“ฑ์ด ์žˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” hostname-backchannel-dynamic ์˜ต์…˜์ด false๋กœ ์„ค์ •๋˜์–ด์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์กฐ๊ธˆ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์€ hostname-backchannel-dynamic ์˜ต์…˜ ์„ค์ •์„ true๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด 
๋‚ด๋ถ€ ํ†ต์‹ ์„ ์œ„ํ•œ ๋‚ด๋ถ€ endpoint๊ฐ€ ํ™œ์„ฑํ™” ๋œ๋‹ค๋Š” ๋œป์ด๋ผ๋Š” ๊ฑฐ๋‹ค.
์„œ๋ธŒ๋„๋ฉ”์ธ์„ ๋ณ„๋„๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. 

hostname-backchannel-dynamic=False hostname-backchannel-dynamic=True
- ๋ฐฑ์ฑ„๋„ ํ†ต์‹ ๋„ --hostname ๊ฐ’ ์‚ฌ์šฉ
- ๋‚ด๋ถ€ ์„œ๋น„์Šค๊ฐ„ ํ†ต์‹ ๋„ ์™ธ๋ถ€ URL์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง
- ๋ฐฑ์ฑ„๋„ ํ†ต์‹ ์€ ์‹ค์ œ ์š”์ฒญ์ด ๋“ค์–ด์˜จ ํ˜ธ์ŠคํŠธ/IP ์‚ฌ์šฉ
- ๋‚ด๋ถ€ ํ†ต์‹  ์ตœ์ ํ™” ๊ฐ€๋Šฅ

๋ฐฑ์—”๋“œ ์—”๋“œํฌ์ธํŠธ๋Š” ์•„๋ž˜ ์„ค์ •์œผ๋กœ ํ™œ์„ฑํ™” ํ•  ์ˆ˜์žˆ๋‹ค.

bin/kc.[sh|bat] start --hostname https://auth.my.com --hostname-backchannel-dynamic true

โ–ช๏ธŽ Administrator

๊ด€๋ฆฌ์šฉ ์ฝ˜์†” ์—”๋“œํฌ์ธํŠธ๋‹ค.
๋ณ„๋„์˜ ํ˜ธ์ŠคํŠธ ๋„ค์ž„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

bin/kc.[sh|bat] start --hostname https://auth.my.com --hostname-admin https://admin.auth.my.com:8443

 

 

 

2. Keycloak TLS ํ™œ์„ฑํ™”

* ๊ณต์‹๋ฌธ์„œ: https://www.keycloak.org/server/enabletlshttps://www.keycloak.org/server/keycloak-truststore

๋„ˆ๋ฌด๋‚˜ ๋‹น์—ฐํ•˜๊ฒŒ๋„, ์™ธ๋ถ€ ์ธํ„ฐ๋„ท์œผ๋กœ ๋…ธ์ถœ๋œ Keycloak์—”๋“œํฌ์ธํŠธ๋Š” ๋ฐ˜๋“œ์‹œ https/TLS๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
๋‹ค๋งŒ, AWS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ALB์—์„œ SSL์„ ํ•ด์ œํ•˜์—ฌ ์™ธ๋ถ€ ๋…ธ์ถœ๋œ ์—”๋“œํฌ์ธํŠธ๋Š” TLS์„ค์ •์„, ๋‚ด๋ถ€ ๋„คํŠธ์›Œํฌ์—์„œ๋Š” ํ‰๋ฌธํ†ต์‹ ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

Keycloak์€ PEM ํ˜•์‹์˜ ํŒŒ์ผ์ด๋‚˜ Java Keystore์—์„œ ํ•„์š”ํ•œ ์ธ์ฆ์„œ ์ธํ”„๋ผ๋ฅผ ๋กœ๋“œํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ,
๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ์„ค์ •๋œ ๊ฒฝ์šฐ PEM ํŒŒ์ผ์ด Java Keystore๋ณด๋‹ค ์šฐ์„ ํ•œ๋‹ค.

โ–ช๏ธŽ AWS ALB(+ACM)์—์„œ TLS/SSL ์˜คํ”„๋กœ๋“œ

 [ํด๋ผ์ด์–ธํŠธ] → HTTPS → [ALB(+ACM)] → HTTP → [Keycloak]

bin/kc.[sh|bat] start \
 --hostname auth.my.com \
 --proxy edge \
 --http-enabled=true \
 --http-port=8080
  • ์ธ์ฆ์„œ ๊ด€๋ฆฌ๊ฐ€ AWS AWS Certificate Manager(ACM)๋กœ ๊ฐ„ํŽธํ™”
  • ACM์—์„œ ์ธ์ฆ์„œ ์ž๋™๊ฐฑ์‹ 
  • ALB์—์„œ์˜ TLS/SSL ์˜คํ”„๋กœ๋”ฉ์œผ๋กœ Keycloak ์„œ๋ฒ„ ๋ถ€ํ•˜ ๊ฐ์†Œ

 

โ–ช๏ธŽ End to End TLS/SSL ์‚ฌ์šฉ

[ํด๋ผ์ด์–ธํŠธ] → HTTPS → [ALB] → HTTPS → [Keycloak]

# PEM ํŒŒ์ผ ์‚ฌ์šฉ๋ฐฉ์‹
bin/kc.[sh|bat] start \
 --hostname auth.my.com \
 --proxy passthrough \
 --https-certificate-file=/path/to/cert.pem \
 --https-certificate-key-file=/path/to/key.pem \
 --http-enabled=false

# Java Keystore (JKS) ๋ฐฉ์‹
###1. Keystore ์ƒ์„ฑ
keytool -genkeypair \
  -alias keycloak \
  -keyalg RSA \
  -keysize 2048 \
  -validity 365 \
  -keystore keycloak.jks \
  -dname "CN=auth.my.com" \
  -storepass store123 \
  -keypass key123
### 2. Keycloak ์‹œ์ž‘ ๋ช…๋ น์–ด
bin/kc.[sh|bat] start \
  --hostname auth.my.com \
  --proxy passthrough \
  --https-key-store-file=/path/to/keycloak.jks \
  --https-key-store-password=store123 \
  --https-key-store-type=JKS \
  --http-enabled=false
  • ์ „ ๊ตฌ๊ฐ„ ์•”ํ˜ธํ™”๋กœ ๋” ๋†’์€ ๋ณด์•ˆ์„ฑ

 

 

3. Keycloak Database ์„ค์ •

* ๊ณต์‹๋ฌธ์„œ: https://www.keycloak.org/server/db

Keycloak ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ• ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” database engine์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.
(mariadb, mssql, mysql, oracle, postgres..)

์ฒ˜์Œ์— ํ…Œ์ŠคํŠธ๋กœ ์„ค์น˜ํ• ๋•Œ๋Š” dev-file ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋•Œ๋ฌธ์—, ํ”„๋กœ๋•์…˜์— ๊ตฌ์„ฑํ• ๋• ๋ฐ˜๋“œ์‹œ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

โ–ช๏ธŽ Postgres Database๋ฅผ ์ด์šฉํ•œ ์„ค์ • ์˜ˆ์‹œ

conf/keycloak.conf ํŒŒ์ผ์—์„œ Database ๋ฅผ ์œ„ํ•œ ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

# conf/keycloak.conf
db=postgres # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์œ ํ˜•(mariadb, mysql, postgres..๋“ฑ์ด ์žˆ์Œ)
db-username=keycloak # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ์ž ์ด๋ฆ„
db-password=password # ์‚ฌ์šฉ์ž ํŒจ์Šค์›Œ๋“œ
db-url-host=keycloak-postgres # DB ์—”๋“œํฌ์ธํŠธ

์„ค์ •ํŒŒ์ผ์„ ์ˆ˜์ •ํ–ˆ๋‹ค๋ฉด ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

bin/kc.[sh|bat] build
bin/kc.[sh|bat] start --optimized

์„ค์ •ํŒŒ์ผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ ์ปค๋ฉ˜๋“œ๋กœ๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

bin/kc.[sh|bat] start --db postgres --db-url-host keycloak-postgres --db-username keycloak --db-password password

 

โ–ช๏ธŽ ์„ค์ • ์˜ต์…˜๋“ค๊ณผ ์ฃผ์˜์‚ฌํ•ญ

์„ค์ • ๊ฐ€๋Šฅํ•œ ์˜ต์…˜๋“ค์€ ์—ฌ๊ธฐ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 
oracle์„ ์ œ์™ธํ•œ ๋Œ€๋ถ€๋ถ„์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—”์ง„ ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์„ค์น˜๋˜์–ด์žˆ๊ณ , ์‚ฌ์šฉ์‹œ ๊ธฐ๋ณธ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋ณ„๋„๋กœ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์ • ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ์ฃผ์˜ํ•ด์•ผํ•  ๋ถ€๋ถ„์€ connection pool ๋ถ€๋ถ„์ผ ๊ฒƒ์ด๋‹ค.
ํ”„๋กœ๋•์…˜์ธ ๊ฒฝ์šฐ, max,min connection pool์„ ์ž˜ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๊ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—”์ง„์— ๋”ฐ๋ผ ์„ค์ • ๋ฐฉ๋ฒ•์ด ๊ณต์‹๋ฌธ์„œ์— ์ž˜ ์„ค๋ช…๋˜์–ด์žˆ์œผ๋‹ˆ, ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ†ตํ•ด ๊ตฌ์„ฑํ•˜๋Š”๊ฒƒ์ด ์ข‹๋‹ค.

 

 

4. Keycloak  ๋‹ค์ค‘ ๋…ธ๋“œ ํด๋Ÿฌ์Šคํ„ฐ ์„ค์ • - Cache

* ๊ณต์‹๋ฌธ์„œ: https://www.keycloak.org/server/caching

 

โ–ช๏ธŽ ์•„ํ‚คํ…์ณ

Keycloak์€ ๊ณ ๊ฐ€์šฉ์„ฑ(HA) ๋ฐ ๋‹ค์ค‘ ๋…ธํŠธ ํด๋Ÿฌ์Šคํ„ฐ๋ง ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ๋‹ค.
์—ฌ๋Ÿฌ๋Œ€์˜ Keycloak๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ์จ, ํŠน์ • ๋…ธ๋“œ๊ฐ€ ์ค‘๋‹จ๋˜๋„ ์žฅ์• ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ณ , ๋ถ€ํ•˜์— ๋”ฐ๋ผ ๋…ธ๋“œ๋ฅผ ํ™•์žฅ/์ถ•์†Œ ํ•จ์œผ๋กœ์จ ๊ฐ€์šฉ์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ๋‹ค.

Keycloak ํด๋Ÿฌ์Šคํ„ฐ๋ง์˜ ํ•ต์‹ฌ์€ Reverse Proxy(LoadBalanceing) ๋ฐ ์บ์‹œ ๊ตฌ์„ฑ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.
Keycloak์€ Infinispan์„ ๊ธฐ๋ฐ˜์œผ๋กœ (key-value In-memory) ํด๋Ÿฌ์Šคํ„ฐ ์บ์‹œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•œ๋‹ค.
์บ์‹œ ๊ตฌ์„ฑ์ด ํด๋Ÿฌ์Šคํ„ฐ ์„ค์ •์— ์–ด๋–ค์—ญํ• ์„ ํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณธ๋‹ค.

 

โ–ช๏ธŽ Cache ์˜ต์…˜

Keycloak์˜ ์บ์‹œ๋Š” --cache ์˜ต์…˜์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ณ , ์˜ต์…˜์€ local/ ispn์ด ์žˆ๋‹ค.

  • --cache=local ์ธ ๊ฒฝ์šฐ ๋ชจ๋“  ์บ์‹œ๊ฐ€ ๋กœ์ปฌ์—์„œ๋งŒ ๋™์ž‘(ํด๋Ÿฌ์Šคํ„ฐ๋งโŒ๋ถˆ๊ฐ€๋Šฅ):
    • sessions, clientSessions๋„ ๋กœ์ปฌ์—๋งŒ ์ €์žฅ
    • realms, users ๋“ฑ๋„ ๋กœ์ปฌ์—๋งŒ ์ €์žฅ
    • ๋…ธ๋“œ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ณต์œ  ์—†์Œ 
  • --cache=ispn* ์ธ ๊ฒฝ์šฐ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด ๊ณต์œ ๋˜์–ด์•ผํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธ๋“œ ์™ธ๋ถ€์— ์บ์‹œ๋กœ ์ €์žฅ (ํด๋Ÿฌ์Šคํ„ฐ๋ง ๐ŸŸข๊ฐ€๋Šฅ):
    • Session ๋“ฑ ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด์— ๊ณต์œ ๋˜์–ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์™ธ๋ถ€ ์บ์‹œ์— ์ €์žฅ๋จ (์•„๋ž˜ ํ‘œ ์ฐธ๊ณ )
๊ตฌ๋ถ„ Local Cache Distribute Cache
๋ชฉ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ถ€ํ•˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•œ ๋กœ์ปฌ ์บ์‹œ ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด์— ๊ณต์œ ๋˜์–ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์บ์‹œ
์ข…๋ฅ˜ - realms: Realm ๋ฐ์ดํ„ฐ
- users: ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ
- authorization: ๊ถŒํ•œ ๋ฐ์ดํ„ฐ
- keys: ๊ณต๊ฐœํ‚ค ๋ฐ์ดํ„ฐ
- authenticationSessions: ์ธ์ฆ ํ”„๋กœ์„ธ์Šค ์ค‘์ธ ์„ธ์…˜
- sessions: ์‚ฌ์šฉ์ž ์„ธ์…˜
- clientSessions: ํด๋ผ์ด์–ธํŠธ ์„ธ์…˜
- loginFailures: ๋กœ๊ทธ์ธ ์‹คํŒจ ๊ธฐ๋ก
- actionTokens: ์ผํšŒ์šฉ ์•ก์…˜ ํ† ํฐ
๋“ฑ..
ํŠน์ง• - ๋…ธ๋“œ๋ณ„๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘
- ํด๋ผ์ด์–ธํŠธ ์„ธ์…˜ ์บ์‹œ ๊ธฐ๋ณธ 10,000๊ฐœ ์—”ํŠธ๋ฆฌ ์ €์žฅ
- ๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ work ์บ์‹œ*๋ฅผ ํ†ตํ•ด ๋ฌดํšจํ™”
- ์„ธ์…˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํŠน์ • ๋…ธ๋“œ๋“ค์— ๋ถ„์‚ฐ ์ €์žฅ
- owners ์„ค์ •์— ๋”ฐ๋ผ ๋ณต์ œ๋ณธ ์ˆ˜ ๊ฒฐ์ •
- ๋…ธ๋“œ ์žฅ์• ์‹œ ์ž๋™ ๋ณต๊ตฌ

* ispn์€ Infinispan(ispn/๋งํฌ)์„ ๋งํ•˜๋ฉฐ, Redis๋‚˜ Memcache์™€ ๊ฐ™์€ ์บ์‹œ ์‹œ์Šคํ…œ์ด๋‹ค.
keycloak์€ ๊ณต์‹์ ์œผ๋กœ ispn๋งŒ ์ง€์›ํ•œ๋‹ค.
* work cache๋Š” ์บ์‹œ ๋ฌดํšจํ™”๋ฅผ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. (๋งํฌ) ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด A,B,C 3๊ฐœ์˜ ๋…ธ๋“œ ๋ฅผ ์šด์˜ํ• ๋•Œ A๋…ธ๋“œ์—์„œ User๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ  ํ•˜๋ฉด, A๋…ธ๋“œ๋Š” User์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ   Work Cache์— ๋ฌดํšจํ™” ๋ฉ”์‹œ์ง€ ์ „์†กํ•˜๊ณ , Work Cache๊ฐ€ ๋ชจ๋“  ๋…ธ๋“œ์— ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธํ•˜๋ฉฐ ๊ฐ ๋…ธ๋“œ๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•ด์•ผ ๋ฐ์ดํ„ฐ์˜ ์ˆ˜์ •์ด ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

 

โ–ช๏ธŽ Cache ์„ค์ • ๋ฐฉ๋ฒ•

์ผ๋ฐ˜ ๋ช…๋ น์–ด๋กœ๋Š” ์•„๋ž˜ ์„ค์ •์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์œ„ํ•œ ์บ์‹œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

bin/kc.sh start \
  --cache=ispn \
  --cache-stack=kubernetes \
  --cache-owners=2 \
  --features-disabled=persistent-user-session \
  --spi-sticky-session-encoder-infinispan-should-attach-route=true \ 
  --metrics-enabled=true \
  --cache-metrics-histograms-enabled=true
  • --cache=ispn: ํด๋Ÿฌ์Šคํ„ฐ๋ง ํ™œ์„ฑํ™”
  • --cache-stack=kubernetes: Discovery ๋ฐฉ๋ฒ• ์„ ํƒ (jdbc-ping, kubernetes)
  • --cache-owners*=2: ๊ฐ ์บ์‹œ ์—”ํŠธ๋ฆฌ ๋ณต์ œ๋ณธ ์ˆ˜
  • --features-disabled=persistent-user-session: ์„ธ์…˜ DB์ €์žฅ ๋น„ํ™œ์„ฑํ™”
  • --spi-sticky-session-encoder-infinispan-should-attach-route=true : ์Šคํ‹ฐํ‚ค ์„ธ์…˜ ํ™œ์„ฑํ™”, ์„ธ์…˜ ์†Œ์œ  ๋…ธ๋“œ๋กœ ์š”์ฒญ ๋ผ์šฐํŒ…, ์บ์‹œ ์ ‘๊ทผ ์ตœ์ ํ™”
  • --metrics-enabled=true: ๋ชจ๋‹ˆํ„ฐ๋ง ํ™œ์„ฑํ™”
  • --cache-metrics-histograms-enabled=true: ์บ์‹œ ๋ฉ”ํŠธ๋ฆญ ํžˆ์Šคํ† ๊ทธ๋žจ ํ™œ์„ฑํ™”

* --cache-owners ์„ค์ •์€ ์—”ํŠธ๋ฆฌ(๋ฐ์ดํ„ฐ)์˜ ๋ณต์ œ๋ณธ์„ ๋ช‡๊ฐœ ์‚ฌ์šฉํ• ๊ฑด์ง€ ์„ค์ •ํ•œ๋‹ค.
์ด ์„ค์ •์€ ๋„ˆ๋ฌด ํฐ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋„คํŠธ์›Œํฌ,CPU๋“ฑ์— ๋ถ€ํ•˜๋ฅผ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ , ์ผ๋ฐ˜์ ์œผ๋กœ 2~3๊ฐœ์˜ ๋ณต์ œ๋ณธ์„ ๊ถŒ์žฅํ•œ๋‹ค. owners=2๋Š” ํ•œ ๋…ธ๋“œ ์žฅ์• ๋ฅผ, owners=3์€ ๋‘ ๋…ธ๋“œ ์žฅ์• ๋ฅผ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

bitnami์—์„œ ์ œ๊ณตํ•˜๋Š” keycloak helm chart ์„ค์ •์œผ๋กœ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •๋œ๋‹ค. (ํŠน๋ณ„ํžˆ ์ปค์Šคํ…€ํ• ๊ฒŒ ์—†๋‹ค)

# https://artifacthub.io/packages/helm/bitnami/keycloak?modal=values
## Keycloak cache configuration
## ref: https://www.keycloak.org/server/caching
## @param cache.enabled Switch to enable or disable the keycloak distributed cache for kubernetes.
## NOTE: Set to false to use 'local' cache (only supported when replicaCount=1).
## @param cache.stackName Set infinispan cache stack to use
## @param cache.stackFile Set infinispan cache stack filename to use
## @param cache.useHeadlessServiceWithAppVersion Set to true to create the headless service used for ispn containing the app version
##
cache:
  enabled: true
  stackName: kubernetes
  stackFile: ""
  useHeadlessServiceWithAppVersion: false

 

 

 


5. Keycloak  ๋‹ค์ค‘ ๋…ธ๋“œ ํด๋Ÿฌ์Šคํ„ฐ ์„ค์ • - Reverse Proxy

* ๊ณต์‹๋ฌธ์„œ: https://www.keycloak.org/server/reverseproxy

 


โ–ช๏ธŽ ์•„ํ‚คํ…์ณ

์œ„์—์„œ ์„ค๋ช…ํ•œ๋ฐ๋กœ, Keycloak์€ ๊ณ ๊ฐ€์šฉ์„ฑ(HA) ๋ฐ ๋‹ค์ค‘ ๋…ธํŠธ ํด๋Ÿฌ์Šคํ„ฐ๋ง ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ์œผ๋ฉฐ, 
Keycloak ํด๋Ÿฌ์Šคํ„ฐ๋ง์˜ ํ•ต์‹ฌ์€ Reverse Proxy(LoadBalanceing) ๋ฐ ์บ์‹œ ๊ตฌ์„ฑ์ด๋‹ค.
์ด๋ฒˆ ๋‹จ๊ณ„์—์„œ๋Š” Reverse Proxy(=API Gateway, LoadBalancer) ๋ถ€๋ถ„์„ ํ™•์ธํ•ด๋ณด์ž.


โ–ช๏ธŽ Reverse Proxy์˜ ์—ญํ• 

๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ๊ฐ€ ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š” ์—ญํ• ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๊ตฌ๋ถ„ ์„ค๋ช…
๋…ธ๋“œ ๋ถ€ํ•˜ ๋ถ„์‚ฐ - ํŠธ๋ž˜ํ”ฝ์„ ์—ฌ๋Ÿฌ Keycloak ๋…ธ๋“œ์— ๊ท ๋“ฑํ•˜๊ฒŒ ๋ถ„๋ฐฐํ•œ๋‹ค.
- ๋ถ€ํ•˜ ๋ถ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์ ˆํ•˜๊ฒŒ ์„ ํƒํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.
      - Round Robin: ์ˆœ์ฐจ์  ๋ถ„๋ฐฐ
      - Least Connection: ์—ฐ๊ฒฐ ์ˆ˜๊ฐ€ ์ ์€ ๋…ธ๋“œ ์šฐ์„ 
      - Response Time: ์‘๋‹ต ์‹œ๊ฐ„ ๊ธฐ์ค€

์˜ˆ์‹œ ์„ค์ • (nginx):
upstream keycloak {
    server keycloak1:8080;
    server keycloak2:8080;
    server keycloak3:8080;
}
์„ธ์…˜ ์–ดํ”ผ๋‹ˆํ‹ฐ 
(Sticky Session)
๊ณต์‹๋ฌธ์„œ ๋งํฌ
- ์บ์‹œ ํžˆํŠธ์œจ ํ–ฅ์ƒ/ ์„ธ์…˜ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์ตœ์ ํ™”/ ๋ถˆํ•„์š”ํ•œ ๋…ธ๋“œ๊ฐ„ ํ†ต์‹  ๊ฐ์†Œ๋ฅผ ์œ„ํ•ด
   ๋™์ผ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๊ฐ™์€ ๋…ธ๋“œ๋กœ ๋ผ์šฐํŒ…
- ํ•„์ˆ˜ ์„ค์ •์€ ์•„๋‹ˆ์ง€๋งŒ ์„ค์ •ํ•˜๋ฉด ๋ถ€ํ•˜ ๊ฐ์†Œ ๋ฐ ์ฒ˜๋ฆฌ ์†๋„์— ์ด์ ์ด ์žˆ์Œ

์˜ˆ์‹œ ์„ค์ • (nginx):
upstream keycloak {
    ip_hash;  # ๋˜๋Š” sticky cookie
    server keycloak1:8080;
    server keycloak2:8080;
}
ํ—ค๋” ์ „์†ก
๊ณต์‹๋ฌธ์„œ ๋งํฌ
- ํด๋ผ์ด์–ธํŠธ ์ •๋ณด๋ฅผ Keycloak์— ์ „๋‹ฌ
- ์ฃผ์š” ํ—ค๋”:
     - X-Forwarded-For: ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ IP
     - X-Forwarded-Proto: ์›๋ณธ ํ”„๋กœํ† ์ฝœ
     - X-Forwarded-Host: ์›๋ณธ ํ˜ธ์ŠคํŠธ
     - X-Real-IP: ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ IP
- --proxy-headers ์˜ต์…˜์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด, Origin ์ฒดํฌ ์‹คํŒจํ•˜๊ณ  403(Forbidden)์„ ๋ฐ˜ํ™˜ํ•จ

์˜ˆ์‹œ ์„ค์ • (nginx):
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
SSL/TLS ์ฒ˜๋ฆฌ ์ตœ์ ํ™” - SSL/TLS ์˜คํ”„๋กœ๋“œ๋ฅผ Reverse Proxy์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ
- "2. Keycloak TLS ํ™œ์„ฑํ™”" ์ฐธ๊ณ 
๋…ธ๋“œ ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง - ํƒ€๊ฒŸ ๋…ธ๋“œ์˜ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ , ๋น„์ •์ƒ์ ์ธ ๋…ธ๋“œ์— ํŠธ๋ž˜ํ”ฝ ์ฐจ๋‹จ

์˜ˆ์‹œ ์„ค์ • (nginx):
health_check uri=/health interval=5s;

 

โ–ช๏ธŽ ๋…ธ์ถœํ•  ์—”๋“œํฌ์ธํŠธ ์ง€์ •

Reverse Proxy๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ๋ฅผ ๋‹ค ๋…ธ์ถœํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•„์š”ํ•œ ๋ช‡๊ฐœ์˜ ์—”๋“œํฌ์ธํŠธ๋งŒ ๋…ธ์ถœํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค.
(๊ณต์‹๋ฌธ์„œ๋งํฌ)

Keycloak Path Reverse Proxy Path Exposed ์„ค๋ช…
/   โŒ ๋ถˆํ•„์š”ํ•œ ๊ด€๋ฆฌ์ž ๊ฒฝ๋กœ ๋…ธ์ถœ๋  ์šฐ๋ ค๊ฐ€ ์žˆ์Œ
/admin/   โŒ ๋ถˆํ•„์š”ํ•œ ๊ด€๋ฆฌ์ž ๊ฒฝ๋กœ ๋…ธ์ถœ๋  ์šฐ๋ ค๊ฐ€ ์žˆ์Œ
/realms/ /realms/ โœ… - OIDC ์—”๋“œํฌ์ธํŠธ ํ•„์š”
- ์ธ์ฆ/์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค ํ•„์ˆ˜
- ํด๋ผ์ด์–ธํŠธ ์—ฐ๋™ ํ•„์š”
/resources/ /resources/ โœ… - UI ์ž์› ์ œ๊ณต
- ์ •์  ํŒŒ์ผ ์„œ๋น„์Šค
- CDN ์‚ฌ์šฉ ๊ฐ€๋Šฅ
/metrics   โŒ ์‹œ์Šคํ…œ ์ •๋ณด/์„ฑ๋Šฅ๋ฐ์ดํ„ฐ/๋‚ด๋ถ€ ๋ชจ๋‹ˆํ„ฐ๋ง ๋…ธ์ถœ ๋ถˆํ•„์š”
/health   โŒ ์‹œ์Šคํ…œ ์ƒํƒœ ์ •๋ณด ๋…ธ์ถœ ๋ถˆํ•„์š”
๋‚ด๋ถ€ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์šฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋ถˆํ•„์š”ํ•œ ๊ณต๊ฒฉ ์ •๋ณด๊ฐ€ ์ œ๊ณต๋จ

 

โ–ช๏ธŽ ๊ธฐํƒ€ ์•Œ๋ฉด ์ข‹์€๊ฒƒ..

๊ณต์‹๋ฌธ์„œ์—๋Š” reverse proxy๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋ก์‹œ๋กœ nginx, haproxy, nginx๋ฅผ ๋งํ•˜์ง€๋งŒ,
AWSํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ AWS ALB๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. 

AWS ALB๋Š” ๋‹ค๋ฅธ ํ”„๋ก์‹œ๋“ค๊ณผ ๋น„๊ตํ•ด๋ณด์ž๋ฉด, ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ (SSL/TLS ์˜คํ”„๋กœ๋“œ, ์„ธ์…˜ ์–ดํ”ผ๋‹ˆํ‹ฐ, ํ—ฌ์Šค์ฒดํฌ, ๋ผ์šฐํŒ… ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํƒ ๋“ฑ์˜ ๊ธฐ๋Šฅ ์ œ๊ณต)์€ ๋˜‘๊ฐ™์€๋ฐ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ๊ฑฐ์˜ ์—†๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

 

728x90