Kubernetes 高可用性集群上的 Keycloak(使用 ldap 作为用户联盟)使用 codecentrics Helm Charts

Keycloak on Kubernetes high availability cluster (with ldap as user federation) using codecentrics Helm Charts

我们想在 Kubernetes 上建立一个高可用的 Keycloak 集群(使用 ldap 作为用户联盟)。我们决定使用 codecentrics helm charts,因为我们正在尝试将它们用于单个 Keycloak 实例设置并且效果很好。对于集群,我们 运行 在尝试正确设置所有内容时遇到了一些问题,但没有在广泛的互联网上找到最佳资源。因此,我决定写一个简短的总结,说明我们的主要问题在哪里以及我们如何解决这些问题。

this website(以及其他)中描述了我们的问题的解决方案,但描述的内容非常简短,感觉部分不完整。

我们遇到的问题:

  1. 选择正确的jgroups.discoveryProtocol
  2. 添加正确的 discoveryProperties
  3. 需要自己覆盖的部分values.yaml

奖金问题(我们已经面对单实例设置):

  1. 设置信任库以通过 ladps 连接 ldap 作为用户联盟
  2. 为 keycloak 添加自定义主题

如果由于 codecentrics 更新他们的 helm 图表而发生变化,我会尝试更新这个。

顺便感谢 codecentrics 提供 helm 图表!

免责声明:
这是我们设置它的方式 - 我希望这会有所帮助,但我不对配置错误和由此产生的安全漏洞负责。我们还浏览了互联网上的许多不同来源,很抱歉我不能把所有的都归功于他们,但是已经过了几天我再也不能把它们放在一起了...

CODECENTRIC 图表版本 < 9.0.0

主要问题:
1。选择正确的 jgroups.discoveryProtocol:
我不会在这里解释,但对我们来说,正确使用的协议是 org.jgroups.protocols.JDBC_PING。了解有关协议(和一般集群设置)的更多信息 here

discoveryProtocol: org.jgroups.protocols.JDBC_PING

使用 JDBC_PING jgroups 将管理实例发现。因此,为了缓存用户会话,为 keycloak 提供的数据库将通过额外的表得到增强,例如JGROUPSPING.

2。设置发现属性: 这个需要设置为

discoveryProperties: >
      "datasource_jndi_name=java:jboss/datasources/KeycloakDS"

避免出现如下错误:

java.lang.IllegalStateException: java.lang.IllegalArgumentException: 
Either the 4 configuration properties starting with 'connection_' or 
the datasource_jndi_name must be set

3。其他需要设置的部分(主要在codecentrics github 的自述文件和github 中的values.yaml 的评论中描述):

  • 根据您的集群设置clusterDomain
  • replicas 的数量设置为大于 1 以启用集群
  • 设置 service.type:我们使用 ClusterIP,但它也可以与其他设置一起使用,例如 LoadBalancer,具体取决于您的设置
  • 可选但推荐:设置 maxUnavailableminAvailable 以始终根据您的需要提供足够的 pods。
  • 设置我们的 Ingress(看起来非常标准):
 ingress:
    enabled: true
    path: /
    annotations: {
      kubernetes.io/ingress.class: nginx
    }
    hosts:
      - your.host.org

奖金问题:

1.信任库:
为了让 Keycloak 通过 ldaps 与 ldap 通信,我们必须设置一个信任库,其中包含我们的 ldap 证书:

从 ldap 接收证书并将其保存在某处:

openssl s_client -connect your.ldap.domain.org < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /path/to/ldap.cert

创建一个新的密钥库:

keytool -genkey -alias replserver \
-keyalg RSA -keystore /path/to/keystore.jks \
-dname "CN=AddCommonName, OU=AddOrganizationalUnit, O=AddOrganisation, L=AddLocality, S=AddStateOrProvinceName, C=AddCountryName" \
-storepass use_the_same_password \
-keypass use_the_same_password \
-deststoretype pkcs12

将下载的证书添加到密钥库:

keytool -import -alias ldaps -file /path/to/ldap.cert -storetype JKS -keystore path/to/keystore.jks   

输入所需的密码:use_the_same_password.
通过键入 'yes'.

来信任证书

在 configmap 中提供密钥库:

kubectl create configmap cert-keystore --from-file=path/to/keystore.jks

增强您的 values.yaml 信任库:

添加并挂载配置映射:

extraVolumes: |
    - name: cert-keystore
      configMap:
        name: cert-keystore

extraVolumeMounts: |
    - name: cert-keystore
      mountPath: "/keystore/"
      readOnly: true

告诉java你使用它:

javaToolOptions: >-
    -[maybe some other settings of yours]
    -Djavax.net.ssl.trustStore=/keystore/keystore.jks
    -Djavax.net.ssl.trustStorePassword=<<keystore_password>>

因为我们不想将密钥库密码上传到 git,所以我们在管道中添加了一个步骤,它将 sed 放入 values.yaml,替换 <<keystore_password>>.

2。添加自定义主题:
我们主要提供一个 docker 容器,其中包含我们的自定义主题:

extraInitContainers: |
    - name: theme-provider
      image: docker_repo_url/themeContainer:version
      imagePullPolicy: IfNotPresent
      command:
        - sh
      args:
        - -c
        - |
          echo "Copying theme..."
          cp -R /custom-theme/* /theme
      volumeMounts:
        - name: theme
          mountPath: /theme

添加并挂载主题:

extraVolumes: |
    - name: theme
      emptyDir: {}

extraVolumeMounts: |
    - name: theme
      mountPath: /opt/jboss/keycloak/themes/custom-theme

您现在应该可以通过 Realm Settings -> Themes 在 Keycloak 管理 UI 中选择自定义主题。

CODECENTRIC CHART 版本 9.0.0 到 9.3.2(可能更高)

1.聚类
我们仍然使用 JDBC_PING,因为我们在使用 DNS_PING 时遇到了问题,如 Codecentric Repo 自述文件中所述:

extraEnv: |
  ## KEYCLOAK CONFIG
  - name: PROXY_ADDRESS_FORWARDING
    value: "true"
  ### CLUSTERING
  - name: JGROUPS_DISCOVERY_PROTOCOL
    value: org.jgroups.protocols.JDBC_PING
  - name: JGROUPS_DISCOVERY_PROPERTIES
    value: 'datasource_jndi_name=java:jboss/datasources/KeycloakDS'
  - name: CACHE_OWNERS_COUNT
    value: "2"
  - name: CACHE_OWNERS_AUTH_SESSIONS_COUNT
    value: "2"

将服务设置为 ClusterIP:

service:
  annotations: {}
  labels: {}
  type: ClusterIP
  loadBalancerIP: ""
  httpPort: 80
  httpNodePort: null
  httpsPort: 8443
  httpsNodePort: null
  httpManagementPort: 9990
  httpManagementNodePort: null
  extraPorts: []

2。 502 错误入口问题
我们在使用 Codecentrics 图表 9.x.x 时遇到了 502 错误,修复需要一段时间才能解决。 here 也描述了一个解决方案,我们从中汲取了灵感,但对我们来说,以下入口设置就足够了:

ingress:
  enabled: true
  servicePort: http
  # Ingress annotations
  annotations: {
    kubernetes.io/ingress.class: nginx,
    nginx.ingress.kubernetes.io/proxy-buffer-size: 128k,
  }

CODECENTRIC 图表版本 9.5.0(可能更高)

更新到9.5.0需要测试。特别是如果需要使用 KUBE_PING 甚至自动缩放。 如果有重大变化,我会在测试后更新。