在容器中執行 Keycloak

了解如何從容器映像執行 Keycloak

本指南說明如何最佳化並執行 Keycloak 容器映像,以提供最佳的容器執行體驗。

建立自訂和最佳化的容器映像

預設的 Keycloak 容器映像已準備好進行配置和最佳化。

為了讓您的 Keycloak 容器有最佳的啟動體驗,請在容器建置期間執行 build 步驟來建置映像。此步驟將在容器映像的每個後續啟動階段節省時間。

撰寫您最佳化的 Keycloak Containerfile

以下 Containerfile 建立一個預先配置的 Keycloak 映像,該映像啟用健康檢查和度量端點、啟用令牌交換功能,並使用 PostgreSQL 資料庫。

Containerfile
FROM quay.io/keycloak/keycloak:latest as builder

# Enable health and metrics support
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true

# Configure a database vendor
ENV KC_DB=postgres

WORKDIR /opt/keycloak
# for demonstration purposes only, please make sure to use proper certificates in production instead
RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/

# change these values to point to a running postgres instance
ENV KC_DB=postgres
ENV KC_DB_URL=<DBURL>
ENV KC_DB_USERNAME=<DBUSERNAME>
ENV KC_DB_PASSWORD=<DBPASSWORD>
ENV KC_HOSTNAME=localhost
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

建置過程包含多個階段

  • 執行 build 命令來設定伺服器建置選項,以建立最佳化的映像。

  • build 階段產生的檔案會複製到新的映像中。

  • 在最終映像中,會設定主機名稱和資料庫的其他配置選項,因此您在執行容器時不需要再次設定它們。

  • 在進入點中,kc.sh 啟用對所有發行子命令的存取。

要安裝自訂提供者,您只需要定義一個步驟,將 JAR 檔案包含到 /opt/keycloak/providers 目錄中。此步驟必須放置在 RUN build 命令的行之前,如下所示

# A example build step that downloads a JAR file from a URL and adds it to the providers directory
FROM quay.io/keycloak/keycloak:latest as builder

...

# Add the provider JAR file to the providers directory
ADD --chown=keycloak:keycloak --chmod=644 <MY_PROVIDER_JAR_URL> /opt/keycloak/providers/myprovider.jar

...

# Context: RUN the build command
RUN /opt/keycloak/bin/kc.sh build

安裝額外的 RPM 套件

如果您嘗試在 FROM quay.io/keycloak/keycloak 的階段中安裝新軟體,您會注意到 microdnfdnf 甚至是 rpm 都未安裝。此外,只有極少的可用套件,僅足以運行 bash shell 和 Keycloak 本身。這是由於安全強化措施,減少了 Keycloak 容器的攻擊面。

首先,請考慮您的使用案例是否可以以不同的方式實作,從而避免在最終容器中安裝新的 RPM。

  • 您 Containerfile 中的 RUN curl 指令可以使用 ADD 來取代,因為該指令原生支援遠端 URL。

  • 某些常見的 CLI 工具可以使用 Linux 檔案系統的創意使用方式來取代。例如,ip addr show tap0 變成 cat /sys/class/net/tap0/address

  • 需要 RPM 的任務可以移到映像建置的前一個階段,然後將結果複製過去。

這是一個範例。在前一個建置階段執行 update-ca-trust,然後將結果向前複製

FROM registry.access.redhat.com/ubi9 AS ubi-micro-build
COPY mycertificate.crt /etc/pki/ca-trust/source/anchors/mycertificate.crt
RUN update-ca-trust

FROM quay.io/keycloak/keycloak
COPY --from=ubi-micro-build /etc/pki /etc/pki

如果絕對需要,可以按照 ubi-micro 建立的這種兩階段模式來安裝新的 RPM。

FROM registry.access.redhat.com/ubi9 AS ubi-micro-build
RUN mkdir -p /mnt/rootfs
RUN dnf install --installroot /mnt/rootfs <package names go here> --releasever 9 --setopt install_weak_deps=false --nodocs -y && \
    dnf --installroot /mnt/rootfs clean all && \
    rpm --root /mnt/rootfs -e --nodeps setup

FROM quay.io/keycloak/keycloak
COPY --from=ubi-micro-build /mnt/rootfs /

這種方法使用 chroot,/mnt/rootfs,以便只安裝您指定的套件及其相依性,因此可以輕鬆地複製到第二階段,而無需猜測。

某些套件具有大型的相依性樹。透過安裝新的 RPM,您可能會在無意中增加容器的攻擊面。請仔細檢查已安裝的套件清單。

建置容器映像

要建置實際的容器映像,請從包含您 Containerfile 的目錄中執行以下命令

podman|docker build . -t mykeycloak

啟動最佳化的 Keycloak 容器映像

要啟動映像,請執行

podman|docker run --name mykeycloak -p 8443:8443 -p 9000:9000 \
        -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me \
        mykeycloak \
        start --optimized --hostname=localhost

Keycloak 以生產模式啟動,僅使用安全的 HTTPS 通訊,並且可在 https://127.0.0.1:8443 上使用。

開啟 https://127.0.0.1:9000/metrics 會導向一個包含操作指標的頁面,您的監控解決方案可以使用這些指標。

將容器公開到不同的端口

預設情況下,伺服器使用端口 80808443 分別偵聽 httphttps 請求。

如果您想使用不同的端口公開容器,則需要相應地設定 hostname

  1. 使用預設端口以外的端口公開容器

podman|docker run --name mykeycloak -p 3000:8443 \
        -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me \
        mykeycloak \
        start --optimized --hostname=https://127.0.0.1:3000

透過將 hostname 選項設定為完整的 URL,您現在可以在 https://127.0.0.1:3000 上存取伺服器。

在開發模式下嘗試 Keycloak

從容器嘗試 Keycloak 進行開發或測試的最簡單方法是使用開發模式。您可以使用 start-dev 命令

podman|docker run --name mykeycloak -p 8080:8080 \
        -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me \
        quay.io/keycloak/keycloak:latest \
        start-dev

調用此命令會以開發模式啟動 Keycloak 伺服器。

此模式應嚴格避免在生產環境中使用,因為它具有不安全的預設值。有關在生產中執行 Keycloak 的更多資訊,請參閱 配置 Keycloak 以進行生產

執行標準 Keycloak 容器

為了符合諸如不可變基礎架構的概念,容器需要定期重新配置。在這些環境中,您需要快速啟動的容器,因此您需要建立如前一節所述的最佳化映像。但是,如果您的環境有不同的需求,您可以只執行 start 命令來執行標準的 Keycloak 映像。例如

podman|docker run --name mykeycloak -p 8080:8080 \
        -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me \
        quay.io/keycloak/keycloak:latest \
        start \
        --db=postgres --features=token-exchange \
        --db-url=<JDBC-URL> --db-username=<DB-USER> --db-password=<DB-PASSWORD> \
        --https-key-store-file=<file> --https-key-store-password=<password>

執行此命令會啟動一個 Keycloak 伺服器,該伺服器會先偵測並套用建置選項。在範例中,行 --db=postgres --features=token-exchange 將資料庫供應商設定為 PostgreSQL,並啟用令牌交換功能。

然後 Keycloak 會啟動並套用特定環境的配置。這種方法會顯著增加啟動時間,並建立一個可變的映像,這不是最佳實務。

在容器中執行時提供初始管理員憑證

Keycloak 僅允許從本機網路連線建立初始管理員使用者。當在容器中執行時,情況並非如此,因此您在執行映像時必須提供以下環境變數

# setting the admin username
-e KC_BOOTSTRAP_ADMIN_USERNAME=<admin-user-name>

# setting the initial password
-e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me

在啟動時匯入領域

Keycloak 容器有一個目錄 /opt/keycloak/data/import。如果您透過掛載磁碟區或其他方式將一個或多個匯入檔案放入該目錄中,並加入啟動參數 --import-realm,則 Keycloak 容器將在啟動時匯入該資料!這可能僅在開發模式下才有意義。

podman|docker run --name keycloak_unoptimized -p 8080:8080 \
        -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me \
        -v /path/to/realm/data:/opt/keycloak/data/import \
        quay.io/keycloak/keycloak:latest \
        start-dev --import-realm

歡迎加入有關管理員引導程序增強功能的開放 GitHub 討論

指定不同的記憶體設定

Keycloak 容器不指定初始和最大堆大小的硬編碼值,而是使用相對於容器總記憶體的相對值。此行為是透過 JVM 選項 -XX:MaxRAMPercentage=70-XX:InitialRAMPercentage=50 實現的。

-XX:MaxRAMPercentage 選項表示最大堆大小為容器總記憶體的 70%。-XX:InitialRAMPercentage 選項表示初始堆大小為容器總記憶體的 50%。這些值是根據對 Keycloak 記憶體管理的深入分析而選擇的。

由於堆大小是根據容器總記憶體動態計算的,因此您應始終設定容器的記憶體限制。先前,最大堆大小設定為 512 MB,為了接近相似的值,您應將記憶體限制設定為至少 750 MB。對於較小的生產環境部署,建議的記憶體限制為 2 GB。

與堆相關的 JVM 選項可以透過設定環境變數 JAVA_OPTS_KC_HEAP 來覆寫。您可以在 kc.shkc.bat 腳本的原始碼中找到 JAVA_OPTS_KC_HEAP 的預設值。

例如,您可以指定環境變數和記憶體限制,如下所示

podman|docker run --name mykeycloak -p 8080:8080 -m 1g \
        -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=change_me \
        -e JAVA_OPTS_KC_HEAP="-XX:MaxHeapFreeRatio=30 -XX:MaxRAMPercentage=65" \
        quay.io/keycloak/keycloak:latest \
        start-dev
如果未設定記憶體限制,則記憶體消耗會迅速增加,因為堆大小最多可以增加到容器總記憶體的 70%。一旦 JVM 配置了記憶體,使用目前的 Keycloak GC 設定,它會不情願地將記憶體傳回給作業系統。

相關選項

db

資料庫供應商。

CLI: --db
Env: KC_DB

dev-file (預設), dev-mem, mariadb, mssql, mysql, oracle, postgres

db-password

資料庫使用者的密碼。

CLI: --db-password
Env: KC_DB_PASSWORD

db-url

完整的資料庫 JDBC URL。

如果未提供,則會根據選定的資料庫供應商設定預設 URL。例如,如果使用 postgres,則預設 JDBC URL 將為 jdbc:postgresql://127.0.0.1/keycloak

CLI: --db-url
Env: KC_DB_URL

db-username

資料庫使用者的使用者名稱。

CLI: --db-username
Env: KC_DB_USERNAME

features

啟用一組或多個功能。

CLI: --features
Env: KC_FEATURES

account-api[:v1]account[:v3]admin-api[:v1]admin-fine-grained-authz[:v1]admin[:v2]authorization[:v1]cache-embedded-remote-store[:v1]ciba[:v1]client-policies[:v1]client-secret-rotation[:v1]client-types[:v1]clusterless[:v1]declarative-ui[:v1]device-flow[:v1]docker[:v1]dpop[:v1]dynamic-scopes[:v1]fips[:v1]hostname[:v2]impersonation[:v1]kerberos[:v1]login[:v2,v1]multi-site[:v1]oid4vc-vci[:v1]opentelemetry[:v1]organization[:v1]par[:v1]passkeys[:v1]persistent-user-sessions[:v1]previewrecovery-codes[:v1]scripts[:v1]step-up-authentication[:v1]token-exchange[:v1]transient-users[:v1]update-email[:v1]web-authn[:v1]

hostname

伺服器公開的位址。

可以是完整的 URL,或僅是主機名稱。當僅提供主機名稱時,協定、埠號和上下文路徑會從請求中解析。

CLI: --hostname
Env: KC_HOSTNAME

僅在啟用 hostname:v2 功能時可用

https-key-store-file

存放憑證資訊的金鑰儲存檔案,可取代單獨指定檔案的方式。

CLI: --https-key-store-file
Env: KC_HTTPS_KEY_STORE_FILE

https-key-store-password

金鑰儲存檔案的密碼。

CLI: --https-key-store-password
Env: KC_HTTPS_KEY_STORE_PASSWORD

password (預設)

health-enabled

是否讓伺服器公開健康檢查端點。

如果啟用,健康檢查將可在 /health/health/ready/health/live 端點上使用。

CLI: --health-enabled
Env: KC_HEALTH_ENABLED

true, false (預設)

metrics-enabled

是否讓伺服器公開指標。

如果啟用,指標將可在 /metrics 端點上使用。

CLI: --metrics-enabled
Env: KC_METRICS_ENABLED

true, false (預設)

在此頁面