使用 Infinispan Operator 部署高可用 Infinispan

在 Kubernetes 上部署 Infinispan 的构建块

本指南介绍了在多集群环境(跨站点)中部署 Infinispan 所需的步骤。为了简化说明,本主题使用允许 Keycloak 与外部 Infinispan 配合使用的最少配置。

本指南假设有两个名为 Site-ASite-B 的 OpenShift 集群。

这是遵循 多站点部署概念 指南中描述的概念的构建块。有关概述,请参阅 多站点部署 指南。

外部 Infinispan 部署仅支持 Infinispan 版本 15.0.8.Final 或更新的补丁版本。

架构

此设置在两个具有低延迟网络连接的站点中部署了两个同步复制的 Infinispan 集群。这种场景的示例可能是同一个 AWS 区域中的两个可用区。

为了简化说明,以下图表已删除 Keycloak、负载均衡器和数据库。

infinispan crossdc az.dio

先决条件

步骤

  1. 安装 Infinispan Operator

  2. 配置访问 Infinispan 集群的凭据。

    Keycloak 需要此凭据才能对 Infinispan 集群进行身份验证。以下 identities.yaml 文件设置具有管理员权限的用户名和密码

    credentials:
      - username: developer
        password: strong-password
        roles:
          - admin

    identities.yaml 可以作为以下之一设置在秘密中

    • 作为 Kubernetes 资源

      凭据秘密
      apiVersion: v1
      kind: Secret
      type: Opaque
      metadata:
        name: connect-secret
        namespace: keycloak
      data:
        identities.yaml: Y3JlZGVudGlhbHM6CiAgLSB1c2VybmFtZTogZGV2ZWxvcGVyCiAgICBwYXNzd29yZDogc3Ryb25nLXBhc3N3b3JkCiAgICByb2xlczoKICAgICAgLSBhZG1pbgo= (1)
      1 之前示例中 identities.yaml 的 base64 编码。
    • 使用 CLI

      kubectl create secret generic connect-secret --from-file=identities.yaml

      有关更多详细信息,请查看 配置身份验证 文档。

      这些命令必须在两个 OpenShift 集群上执行。

  3. 创建一个服务帐户。

    需要服务帐户才能在集群之间建立连接。Infinispan Operator 使用它来检查来自远程站点的网络配置,并相应地配置本地 Infinispan 集群。

    有关更多详细信息,请参阅 管理跨站点连接 文档。

    1. 创建以下类型的 service-account-token 秘密。相同的 YAML 文件可以在两个 OpenShift 集群中使用。

      xsite-sa-secret-token.yaml
      apiVersion: v1
      kind: Secret
      metadata:
        name: ispn-xsite-sa-token (1)
        annotations:
          kubernetes.io/service-account.name: "xsite-sa" (2)
      type: kubernetes.io/service-account-token
      1 秘密名称。
      2 服务帐户名称。
    2. 在两个 OpenShift 集群中创建服务帐户并生成访问令牌。

      Site-A 中创建服务帐户
      kubectl create sa -n keycloak xsite-sa
      oc policy add-role-to-user view -n keycloak -z xsite-sa
      kubectl create -f xsite-sa-secret-token.yaml
      kubectl get secrets ispn-xsite-sa-token -o jsonpath="{.data.token}" | base64 -d > Site-A-token.txt
      Site-B 中创建服务帐户
      kubectl create sa -n keycloak xsite-sa
      oc policy add-role-to-user view -n keycloak -z xsite-sa
      kubectl create -f xsite-sa-secret-token.yaml
      kubectl get secrets ispn-xsite-sa-token -o jsonpath="{.data.token}" | base64 -d > Site-B-token.txt
    3. 下一步是将 Site-A 中的令牌部署到 Site-B,反之亦然

      Site-B 的令牌部署到 Site-A
      kubectl create secret generic -n keycloak xsite-token-secret \
        --from-literal=token="$(cat Site-B-token.txt)"
      Site-A 的令牌部署到 Site-B
      kubectl create secret generic -n keycloak xsite-token-secret \
        --from-literal=token="$(cat Site-A-token.txt)"
  4. 创建 TLS 秘密

    在本指南中,Infinispan 使用 OpenShift 路由进行跨站点通信。它使用 TLS 的 SNI 扩展将流量定向到正确的 Pod。为了实现这一点,JGroups 使用 TLS 套接字,这些套接字需要具有正确证书的密钥库和信任库。

    有关更多信息,请参阅 保护跨站点连接 文档或此 Red Hat 开发人员指南

    将密钥库和信任库上传到 OpenShift 秘密中。秘密包含文件内容、访问它的密码以及存储的类型。创建证书和存储的说明超出了本指南的范围。

    要将密钥库作为秘密上传,请使用以下命令

    部署密钥库
    kubectl -n keycloak create secret generic xsite-keystore-secret \
      --from-file=keystore.p12="./certs/keystore.p12" \ (1)
      --from-literal=password=secret \ (2)
      --from-literal=type=pkcs12 (3)
    1 密钥库的文件名和路径。
    2 访问密钥库的密码。
    3 密钥库类型。

    要将信任库作为秘密上传,请使用以下命令

    部署信任库
    kubectl -n keycloak create secret generic xsite-truststore-secret \
            --from-file=truststore.p12="./certs/truststore.p12" \  (1)
            --from-literal=password=caSecret \  (2)
            --from-literal=type=pkcs12  (3)
    1 信任库的文件名和路径。
    2 访问信任库的密码。
    3 信任库类型。
    密钥库和信任库必须上传到两个 OpenShift 集群中。
  5. 创建具有跨站点功能的 Infinispan 集群

    有关如何创建和配置支持跨站点的 Infinispan 集群(包括前面的步骤)的全部信息,请参阅 设置跨站点 文档。

    本指南提供了一个基本示例,使用上一步中的命令创建的凭据、令牌和 TLS 密钥库/信任库。

    Site-AInfinispan CR
    apiVersion: infinispan.org/v1
    kind: Infinispan
    metadata:
      name: infinispan (1)
      namespace: keycloak
      annotations:
        infinispan.org/monitoring: 'true' (2)
    spec:
      replicas: 3
      jmx:
        enabled: true
      security:
        endpointSecretName: connect-secret (3)
      service:
        type: DataGrid
        sites:
          local:
            name: site-a (4)
            expose:
              type: Route (5)
            maxRelayNodes: 128
            encryption:
              transportKeyStore:
                secretName: xsite-keystore-secret (6)
                alias: xsite (7)
                filename: keystore.p12 (8)
              routerKeyStore:
                secretName: xsite-keystore-secret (6)
                alias: xsite (7)
                filename: keystore.p12 (8)
              trustStore:
                secretName: xsite-truststore-secret (9)
                filename: truststore.p12 (10)
          locations:
            - name: site-b (11)
              clusterName: infinispan
              namespace: keycloak (12)
              url: openshift://api.site-b (13)
              secretName: xsite-token-secret (14)
    1 集群名称
    2 允许 Prometheus 监控集群。
    3 如果使用自定义凭据,请在此配置秘密名称。
    4 本地站点的名称,在本例中为 Site-A
    5 使用 OpenShift 路由公开跨站点连接。
    6 密钥库所在的秘密名称,如前一步所定义。
    7 密钥库中证书的别名。
    8 密钥库的秘密密钥(文件名),如前一步所定义。
    9 信任库所在的秘密名称,如前一步所定义。
    10 信任库的密钥(文件名),如前一步所定义。
    11 远程站点的名称,在本例中为 Site-B
    12 远程站点上 Infinispan 集群的命名空间。
    13 远程站点的 OpenShift API URL。
    14 包含访问令牌以对远程站点进行身份验证的秘密。

    对于 Site-BInfinispan CR 与上面类似。请注意第 4、11 和 13 点的差异。

    Site-BInfinispan CR
    apiVersion: infinispan.org/v1
    kind: Infinispan
    metadata:
      name: infinispan (1)
      namespace: keycloak
      annotations:
        infinispan.org/monitoring: 'true' (2)
    spec:
      replicas: 3
      jmx:
        enabled: true
      security:
        endpointSecretName: connect-secret (3)
      service:
        type: DataGrid
        sites:
          local:
            name: site-b (4)
            expose:
              type: Route (5)
            maxRelayNodes: 128
            encryption:
              transportKeyStore:
                secretName: xsite-keystore-secret (6)
                alias: xsite (7)
                filename: keystore.p12 (8)
              routerKeyStore:
                secretName: xsite-keystore-secret (6)
                alias: xsite (7)
                filename: keystore.p12 (8)
              trustStore:
                secretName: xsite-truststore-secret (9)
                filename: truststore.p12 (10)
          locations:
            - name: site-a (11)
              clusterName: infinispan
              namespace: keycloak (12)
              url: openshift://api.site-a (13)
              secretName: xsite-token-secret (14)
  6. 为 Keycloak 创建缓存。

    Keycloak 需要以下缓存存在:actionTokensauthenticationSessionsloginFailureswork

    Infinispan 的 缓存 CR 允许在 Infinispan 集群中部署缓存。跨站点需要按缓存启用,如 跨站点文档 中所述。该文档包含有关本指南使用的选项的更多详细信息。以下示例显示了 Site-ACache CR。

    1. Site-A 中为上面提到的每个缓存创建一个 Cache CR,其内容如下。以下是对 authenticationSessions 缓存的示例

    apiVersion: infinispan.org/v2alpha1
    kind: Cache
    metadata:
      name: authenticationsessions
      namespace: keycloak
    spec:
      clusterName: infinispan
      name: authenticationSessions
      template: |-
        distributedCache:
          mode: "SYNC"
          owners: "2"
          statistics: "true"
          remoteTimeout: "5000"
          encoding:
            media-type: "application/x-protostream"
          locking:
            acquireTimeout: "4000"
          transaction:
            mode: "NON_XA" (1)
            locking: "PESSIMISTIC" (2)
          stateTransfer:
            chunkSize: "16"
          backups:
            site-b: (3)
              backup:
                strategy: "SYNC" (4)
                timeout: "4500" (5)
                failurePolicy: "FAIL" (6)
                stateTransfer:
                  chunkSize: "16"
    1 事务模式。
    2 事务使用的锁定模式。
    3 远程站点名称。
    4 跨站点通信策略,在本例中为 SYNC
    5 跨站点复制超时。
    6 跨站点复制失败策略。

    以上示例是实现最佳数据一致性的推荐配置。

    背景信息

    在活动-活动设置中可能会发生死锁,因为条目在两个站点中同时修改。

    transaction.mode: NON_XA 确保如果发生这种情况,事务将回滚,从而保持数据一致性。在这种情况下,需要设置 backup.failurePolicy: FAIL。它将抛出一个错误,允许事务安全地回滚。发生这种情况时,Keycloak 将尝试重试。

    transaction.locking: PESSIMISTIC 是唯一支持的锁定模式;OPTIMISTIC 不推荐使用,因为它会产生网络成本。相同的设置还可以防止一个站点更新而另一个站点无法访问。

    backup.strategy: SYNC 确保在 Keycloak 请求完成时,数据在另一个站点中可见并存储。

    可以在死锁场景中减少 locking.acquireTimeout 以快速失败。backup.timeout 必须始终大于 locking.acquireTimeout

    对于 Site-BCache CR 类似,除了上面图表中第 3 点所概述的 backups.<name>

    Site-B 中的 authenticationSessions Cache CR
    apiVersion: infinispan.org/v2alpha1
    kind: Cache
    metadata:
      name: authenticationsessions
      namespace: keycloak
    spec:
      clusterName: infinispan
      name: authenticationSessions
      template: |-
        distributedCache:
          mode: "SYNC"
          owners: "2"
          statistics: "true"
          remoteTimeout: "5000"
          encoding:
            media-type: "application/x-protostream"
          locking:
            acquireTimeout: "4000"
          transaction:
            mode: "NON_XA" (1)
            locking: "PESSIMISTIC" (2)
          stateTransfer:
            chunkSize: "16"
          backups:
            site-a: (3)
              backup:
                strategy: "SYNC" (4)
                timeout: "4500" (5)
                failurePolicy: "FAIL" (6)
                stateTransfer:
                  chunkSize: "16"

验证部署

确认 Infinispan 集群已形成,并且在 OpenShift 集群之间建立了跨站点连接。

等待 Infinispan 集群形成
kubectl wait --for condition=WellFormed --timeout=300s infinispans.infinispan.org -n keycloak infinispan
等待 Infinispan 跨站点连接建立
kubectl wait --for condition=CrossSiteViewFormed --timeout=300s infinispans.infinispan.org -n keycloak infinispan

将 Infinispan 连接到 Keycloak

现在 Infinispan 服务器正在运行,以下是在 使用 Keycloak Operator 部署高可用 Keycloak 指南中连接到 Keycloak 所需的相关 Keycloak CR 更改。

  1. 创建一个包含连接到外部 Infinispan 部署的用户名和密码的秘密

    apiVersion: v1
    kind: Secret
    metadata:
      name: remote-store-secret
      namespace: keycloak
    type: Opaque
    data:
      username: ZGV2ZWxvcGVy # base64 encoding for 'developer'
      password: c2VjdXJlX3Bhc3N3b3Jk # base64 encoding for 'secure_password'
  2. 使用如下所示的 additionalOptions 扩展 Keycloak 自定义资源。

    以下 CR 中省略了所有内存、资源和数据库配置,因为它们已经在 使用 Keycloak Operator 部署高可用 Keycloak 指南中进行了描述。管理员应保持这些配置不变。

    apiVersion: k8s.keycloak.org/v2alpha1
    kind: Keycloak
    metadata:
      labels:
        app: keycloak
      name: keycloak
      namespace: keycloak
    spec:
      additionalOptions:
        - name: cache-remote-host (1)
          value: "infinispan.keycloak.svc"
        - name: cache-remote-port (2)
          value: "11222"
        - name: cache-remote-username (3)
          secret:
            name: remote-store-secret
            key: username
        - name: cache-remote-password (4)
          secret:
            name: remote-store-secret
            key: password
        - name: spi-connections-infinispan-quarkus-site-name (5)
          value: keycloak
    1 远程 Infinispan 集群的主机名。
    2 远程 Infinispan 集群的端口。这是可选的,默认值为 11222
    3 包含 Infinispan 用户名凭据的秘密 namekey
    4 包含 Infinispan 密码凭据的秘密 namekey
    5 spi-connections-infinispan-quarkus-site-name 是一个任意的 Infinispan 站点名称,Keycloak 在使用远程存储时需要使用它来部署其 Infinispan 缓存。此站点名称仅与 Infinispan 缓存相关,不需要与外部 Infinispan 部署中的任何值匹配。如果您在跨数据中心的设置中为 Keycloak 使用多个站点,例如 使用 Infinispan Operator 部署高可用 Infinispan,则每个站点中的站点名称必须不同。

架构

这使用由 TLS 1.3 保护的 TCP 连接将 Keycloak 连接到 Infinispan。它使用 Keycloak 的信任库来验证 Infinispan 的服务器证书。由于 Keycloak 使用其 Operator 在 OpenShift 上部署(如以下先决条件中所列),因此 Operator 已将 service-ca.crt 添加到信任库,该信任库用于签署 Infinispan 的服务器证书。在其他环境中,请将必要的证书添加到 Keycloak 的信任库。

后续步骤

在 Aurora AWS 数据库和 Infinispan 部署并运行后,请使用 使用 Keycloak Operator 部署高可用 Keycloak 指南中的步骤部署 Keycloak 并将其连接到之前创建的所有构建块。

相关选项

cache-remote-host

远程存储配置的远程服务器主机名。

它替换了通过 XML 文件(参见 cache-config-file 选项)指定的配置中 remote-server 标签的 host 属性。如果指定了该选项,则还需要 cache-remote-usernamecache-remote-password,并且 XML 文件中的相关配置不应存在。

CLI: --cache-remote-host
Env: KC_CACHE_REMOTE_HOST

cache-remote-password

对远程存储的远程服务器进行身份验证的密码。

它替换了通过 XML 文件(参见 cache-config-file 选项)指定的配置中 digest 标签的 password 属性。如果指定了此选项,则还需要 cache-remote-username,并且 XML 文件中的相关配置应该不存在。

CLI: --cache-remote-password
Env: KC_CACHE_REMOTE_PASSWORD

仅在设置远程主机时可用

cache-remote-port

远程存储配置的远程服务器端口。

它替换了通过 XML 文件(参见 cache-config-file 选项)指定的配置中 remote-server 标签的 port 属性。

CLI: --cache-remote-port
Env: KC_CACHE_REMOTE_PORT

仅在设置远程主机时可用

11222(默认)

cache-remote-tls-enabled

启用 TLS 支持以与安全的远程 Infinispan 服务器通信。

建议在生产环境中启用。

CLI: --cache-remote-tls-enabled
Env: KC_CACHE_REMOTE_TLS_ENABLED

仅在设置远程主机时可用

true(默认),false

cache-remote-username

用于对远程存储的远程服务器进行身份验证的用户名。

它替换了通过 XML 文件(参见 cache-config-file 选项)指定的配置中 digest 标签的 username 属性。如果指定了此选项,则还需要 cache-remote-password,并且 XML 文件中的相关配置应该不存在。

CLI: --cache-remote-username
Env: KC_CACHE_REMOTE_USERNAME

仅在设置远程主机时可用

在此页面上