๋ค์ด๊ฐ๊ธฐ์ ์,
*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/enabletls, https://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 ์คํ๋ก๋, ์ธ์ ์ดํผ๋ํฐ, ํฌ์ค์ฒดํฌ, ๋ผ์ฐํ ์๊ณ ๋ฆฌ์ฆ ์ ํ ๋ฑ์ ๊ธฐ๋ฅ ์ ๊ณต)์ ๋๊ฐ์๋ฐ ๊ด๋ฆฌํ ํ์๊ฐ ๊ฑฐ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.