Operator 指南
第 1 章 Red Hat build of Keycloak Operator 安装
如何在 OpenShift 上安装 Operator。
使用这个流程在 OpenShift 集群中安装红帽构建的 Keycloak Operator。
- 打开 OpenShift Container Platform Web 控制台。
- 在左列中,单击 Home, Operators, OperatorHub。
- 在搜索输入框中搜索 "Keycloak"。
- 从结果列表中选择 Operator。
- 按照屏幕上的说明进行操作。
有关使用 CLI 或 Web 控制台安装 Operator 的常规说明,请参阅 在命名空间中安装 Operator。在默认目录中,Operator 被命名为 rhbk-operator
。确保使用与所需红帽构建的 Keycloak 版本对应的频道。
1.1. 为 OLM 升级配置手动批准
重要: 自动 OLM 升级
默认情况下,当发布新版本时,OLM 会自动更新 Keycloak Operator 的 Red Hat build。这可能导致几个严重的问题:
- 当使用默认红帽构建的 Keycloak 镜像时,Operator 会使用对应的红帽构建的 Keycloak 版本匹配的镜像,从而导致在 Operator 升级时 意外地升级 Keycloak 升级。
- 即使使用自定义镜像,主要的 Operator 升级可能会引入与现有 Keycloak CR 配置相关的重要兼容性问题,可能需要手动干预
- Keycloak CR 中的新字段或行为更改可能会影响现有部署
- 由于与数据库迁移相关的更改,没有将红帽降级到以前的红帽 Keycloak 版本的选项
建议:
我们强烈建议在 Red Hat build of Keycloak Operator 中使用手动批准模式。这样可确保您可以:
- 在批准升级前,请参阅发行注记并按照迁移更改进行操作
- 为升级调度维护窗口
- 首先在非生产环境中测试升级
- 备份数据库,以便在出现问题时降级到以前的红帽 Keycloak 构建
要防止 OLM 自动升级,请在安装 Operator 时将批准策略设置为 Manual
:
1.1.1. 使用 OpenShift Web 控制台
安装 Operator 时,在更新批准策略部分选择 Manual
approval :

1.1.2. 使用 CLI
对于命令行安装,创建一个带有 installPlanApproval: Manual
的订阅:
apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: rhbk-operator namespace: <target-namespace> spec: channel: <desired-channel> name: rhbk-operator source: redhat-operators sourceNamespace: openshift-marketplace installPlanApproval: Manual
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: rhbk-operator
namespace: <target-namespace>
spec:
channel: <desired-channel>
name: rhbk-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
installPlanApproval: Manual
安装后,任何升级都需要通过 OLM 界面或通过 CLI 进行手动批准。
1.2. 安装多个 Operator
Operator 不完全支持它来监控多个命名空间或所有命名空间。要监视多个命名空间,请安装多个 Operator。
在这种情况下,请考虑以下几点:
- 所有 Operator 都会共享自定义资源定义(CRD)。
- 较新的 Operator 版本的 CRD 修订不会引入有问题的更改,但最终删除一段时间的字段除外。因此,较新的 CRD 通常向后兼容。
- 上次安装的 CRD 成为正在使用的 CRD。此规则也适用于 OLM 安装 ; 如果集群中已存在,则最后安装的 Operator 版本也会安装并覆盖 CRD。
- 旧的 CRD 可能无法与较新的 Operator 使用的新字段兼容。当使用 OLM 时,它会检查您的自定义资源是否与要安装的 CRD 兼容,因此使用新字段可能会阻止同时安装旧的 Operator 版本。
- 旧的 Operator 不支持较新的 CRD 中引入的字段。旧的 Operator 无法处理使用此类新字段的 CR,并带有非识别字段的反序列化错误。
因此,在多个 Operator 安装场景中,推荐的方法是尽可能保持版本一致,以最大程度降低不同版本的潜在问题。
第 2 章 基本的 Red Hat build of Keycloak 部署
使用 Operator 安装红帽构建的 Keycloak。
2.1. 执行基本红帽构建的 Keycloak 部署
本章论述了如何使用 Operator 在 OpenShift 中执行 Keycloak Deployment 的基本红帽构建。
2.1.1. 准备部署
在集群命名空间中安装并运行 Red Hat build of Keycloak Operator 后,您可以设置其他部署先决条件。
- 数据库
- 主机名
- TLS 证书和相关密钥
2.1.1.1. 数据库
数据库应该可用,并可从安装 Red Hat build of Keycloak 的集群命名空间中访问。有关支持的数据库列表 ,请参阅配置数据库。Red Hat build of Keycloak Operator 不管理数据库,您需要自己置备它。考虑验证您的云供应商产品或使用数据库操作器。
对于开发目的,您可以使用临时 PostgreSQL pod 安装。要置备它,请遵循以下方法:
创建 YAML 文件 example-postgres.yaml
:
apiVersion: apps/v1 kind: StatefulSet metadata: name: postgresql-db spec: serviceName: postgresql-db-service selector: matchLabels: app: postgresql-db replicas: 1 template: metadata: labels: app: postgresql-db spec: containers: - name: postgresql-db image: postgres:15 volumeMounts: - mountPath: /data name: cache-volume env: - name: POSTGRES_USER value: testuser - name: POSTGRES_PASSWORD value: testpassword - name: PGDATA value: /data/pgdata - name: POSTGRES_DB value: keycloak volumes: - name: cache-volume emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: postgres-db spec: selector: app: postgresql-db type: LoadBalancer ports: - port: 5432 targetPort: 5432
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 1
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:15
volumeMounts:
- mountPath: /data
name: cache-volume
env:
- name: POSTGRES_USER
value: testuser
- name: POSTGRES_PASSWORD
value: testpassword
- name: PGDATA
value: /data/pgdata
- name: POSTGRES_DB
value: keycloak
volumes:
- name: cache-volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: postgres-db
spec:
selector:
app: postgresql-db
type: LoadBalancer
ports:
- port: 5432
targetPort: 5432
应用更改:
oc apply -f example-postgres.yaml
oc apply -f example-postgres.yaml
2.1.1.2. 主机名
对于生产环境就绪安装,您需要一个主机名,可用于联系红帽构建的 Keycloak。有关可用 配置,请参阅配置主机名(v2)。
出于开发目的,本章将使用 test.keycloak.org
。
在 OpenShift 上运行 ingress 时,启用了 ingress,并将 spec.ingress.classname 设置为 openshift-default,您可能会使 spec.hostname.hostname 不在 Keycloak CR 中填充。Operator 会将默认主机名分配给 CR 的存储版本,类似于没有显式主机的 OpenShift Route 创建的内容,即 ingress-namespace.appsDomain 如果 appsDomain 发生了变化,或者因为任何原因需要不同的主机名,然后更新 Keycloak CR。
如果您设置了 hostname-admin
或已弃用的 hostname-admin-url
,即使启用了 ingress,也不会为 admin 访问创建 ingress。通常,通过单独的主机名的管理员访问权限通常具有访问限制,这目前无法通过 Keycloak CR 表达。另外,默认入口不会阻止访问 admin 端点,因此当您为 admin 端点有单独的主机名时,您可能都不希望通过 Keycloak CR 启用入口处理。
2.1.1.3. TLS 证书和密钥
查看您的认证认证机构以获取证书和密钥。
对于开发目的,您可以输入以下命令获取自签名证书:
openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
您应该通过输入以下命令将其在集群命名空间中作为 Secret 安装:
oc create secret tls example-tls-secret --cert certificate.pem --key key.pem
oc create secret tls example-tls-secret --cert certificate.pem --key key.pem
2.1.2. 部署红帽构建的 Keycloak
要部署红帽构建的 Keycloak,您需要根据 Keycloak 自定义资源定义(CRD)创建一个自定义资源(CR)。
考虑将数据库凭据存储在单独的 Secret 中。输入以下命令:
oc create secret generic keycloak-db-secret \ --from-literal=username=[your_database_username] \ --from-literal=password=[your_database_password]
oc create secret generic keycloak-db-secret \
--from-literal=username=[your_database_username] \
--from-literal=password=[your_database_password]
您可以使用 Keycloak CRD 自定义多个字段。对于基本部署,您可以保留以下方法:
创建 YAML 文件 example-kc.yaml
:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: instances: 1 db: vendor: postgres host: postgres-db usernameSecret: name: keycloak-db-secret key: username passwordSecret: name: keycloak-db-secret key: password http: tlsSecret: example-tls-secret hostname: hostname: test.keycloak.org proxy: headers: xforwarded # double check your reverse proxy sets and overwrites the X-Forwarded-* headers
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
instances: 1
db:
vendor: postgres
host: postgres-db
usernameSecret:
name: keycloak-db-secret
key: username
passwordSecret:
name: keycloak-db-secret
key: password
http:
tlsSecret: example-tls-secret
hostname:
hostname: test.keycloak.org
proxy:
headers: xforwarded # double check your reverse proxy sets and overwrites the X-Forwarded-* headers
应用更改:
oc apply -f example-kc.yaml
oc apply -f example-kc.yaml
要检查集群中是否已置备了红帽构建的 Keycloak 实例,请输入以下命令来检查创建的 CR 的状态:
oc get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
oc get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
当部署就绪时,查找类似如下的输出:
CONDITION: Ready STATUS: true MESSAGE: CONDITION: HasErrors STATUS: false MESSAGE: CONDITION: RollingUpdate STATUS: false MESSAGE:
CONDITION: Ready
STATUS: true
MESSAGE:
CONDITION: HasErrors
STATUS: false
MESSAGE:
CONDITION: RollingUpdate
STATUS: false
MESSAGE:
2.1.3. 访问红帽构建的 Keycloak 部署
红帽构建的 Keycloak 部署可以通过提供的主机名访问的基本 Ingress 公开。
在有多个默认 IngressClass 实例的安装中,或在 OpenShift 4.12+ 上运行时,您应该通过将 ingress
spec with className
属性设置为所需的类名称来提供 ingressClassName:
编辑 YAML 文件 example-kc.yaml
:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... ingress: className: openshift-default
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
ingress:
className: openshift-default
如果默认入口不适用于您的用例,请通过将带有 enabled
属性的 ingress
spec 设置为 false
来禁用它:
编辑 YAML 文件 example-kc.yaml
:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... ingress: enabled: false
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
ingress:
enabled: false
应用更改:
oc apply -f example-kc.yaml
oc apply -f example-kc.yaml
然后,您可以提供一个指向服务 < keycloak-cr-name>-service
的替代入口资源。例如,在 OpenShift 中,您不能在启用了 HTTP/2 的 passthrough Routes 上使用通配符证书。使用默认 IngressClass 的通配符证书启用了 TLS 的 Keycloak CR 会创建这样的路由。在这种情况下,您必须使用 .spec.ingress.enabled: false
禁用内置入口。然后,可通过创建重新加密路由来提供访问:
$ oc create route reencrypt --service=<keycloak-cr-name>-service --cert=<configured-certificate> --key=<certificate-key> --dest-ca-cert=<ca-certificate> --ca-cert=<ca-certificate> --hostname=<hostname>
$ oc create route reencrypt --service=<keycloak-cr-name>-service --cert=<configured-certificate> --key=<certificate-key> --dest-ca-cert=<ca-certificate> --ca-cert=<ca-certificate> --hostname=<hostname>
为了进行调试和开发目的,请考虑使用端口转发直接连接到红帽构建的 Keycloak 服务。例如,输入以下命令:
oc port-forward service/example-kc-service 8443:8443
oc port-forward service/example-kc-service 8443:8443
2.1.3.1. 配置与 Ingress Controller 匹配的反向代理设置
Operator 支持配置哪些反向代理标头应该被服务器接受,其中包括 Forwarded
和 X-Forwarded fluentd
标头。
如果您 Ingress 实现集并覆盖 Forwarded
或 X-ForwardedDebug
标头,您可以反映在 Keycloak CR 中,如下所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... proxy: headers: forwarded|xforwarded
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
proxy:
headers: forwarded|xforwarded
如果没有指定 proxy.headers
字段,Operator 默认通过隐式设置 proxy=passthrough
来回退到旧的行为。这会在服务器日志中出现弃用警告。这个回退将在以后的发行版本中被删除。
使用 proxy.headers
字段时,请确保您的 Ingress 正确设置并分别覆盖 Forwarded
或 X-Forwarded fluentd
标头。要设置这些标头,请查阅 Ingress Controller 的文档。考虑为重新加密或边缘 TLS 终止配置它,因为 passthrough TLS 不允许 Ingress 修改请求标头。错误配置会使红帽构建 Keycloak 暴露于安全漏洞。
如需了解更多详细信息 ,请参阅配置反向代理 指南。
2.1.4. 访问管理控制台
在部署红帽构建的 Keycloak 时,Operator 会生成一个任意初始 admin 用户名和密码
,并将这些凭证作为 basic-auth Secret 对象存储在与 CR 相同的命名空间中。
在进行生产环境前,更改默认 admin 凭证并在红帽构建的 Keycloak 中启用 MFA。
要获取初始 admin 凭证,您必须读取和解码 Secret。Secret 名称派生自 Keycloak CR 名称以及固定的后缀 -initial-admin
。要获取 example-kc
CR 的用户名和密码,请输入以下命令:
oc get secret example-kc-initial-admin -o jsonpath='{.data.username}' | base64 --decode oc get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode
oc get secret example-kc-initial-admin -o jsonpath='{.data.username}' | base64 --decode
oc get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode
您可以使用这些凭证访问 Admin Console 或 Admin REST API。
2.1.5. 安全注意事项
创建或编辑 Keycloak CR 的任何人都应是一个命名空间级别 admin。
设置 Keycloak CR 镜像需要高度信任,因为运行的任何镜像都可以访问任何用于环境变量的 Secret。
与不支持的 podTemplate 类似,可以部署替代工作负载,这些工作负载可能被授予与 Operator 本身相同的权限,这包括可以访问命名空间中的 Secret。
第 3 章 自动导入域
使用操作器自动执行 realm 导入。
3.1. 导入红帽构建的 Keycloak Realm
使用红帽构建的 Keycloak Operator,您可以为 Keycloak Deployment 执行域导入。
- 如果红帽构建的 Keycloak 中已存在具有相同名称的 Realm,则不会覆盖它。
- Realm Import CR 只支持创建新域,且不会更新或删除它们。直接在红帽构建的 Keycloak 上执行的域更改不会在 CR 中同步。
3.1.1. 创建 Realm 导入自定义资源
以下是 Realm Import 自定义资源(CR)的示例:
apiVersion: k8s.keycloak.org/v2alpha1 kind: KeycloakRealmImport metadata: name: my-realm-kc spec: keycloakCRName: <name of the keycloak CR> realm: ...
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakRealmImport
metadata:
name: my-realm-kc
spec:
keycloakCRName: <name of the keycloak CR>
realm:
...
此 CR 应在与 Keycloak Deployment CR 相同的命名空间中创建,在字段 keycloakCRName
中定义。realm
字段接受完整的 RealmRepresentation。
获取 RealmRepresentation
的建议方法是利用导出功能 导入和导出域。
- 将 Realm 导出到单个文件。
- 将 JSON 文件转换为 YAML。
-
复制并粘贴获取的 YAML 文件作为
realm
键的正文,确保缩进正确。
3.1.2. 应用 Realm Import CR
使用 oc
在正确的集群命名空间中创建 CR:
创建 YAML 文件 example-realm-import.yaml
:
apiVersion: k8s.keycloak.org/v2alpha1 kind: KeycloakRealmImport metadata: name: my-realm-kc spec: keycloakCRName: <name of the keycloak CR> realm: id: example-realm realm: example-realm displayName: ExampleRealm enabled: true
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakRealmImport
metadata:
name: my-realm-kc
spec:
keycloakCRName: <name of the keycloak CR>
realm:
id: example-realm
realm: example-realm
displayName: ExampleRealm
enabled: true
应用更改:
oc apply -f example-realm-import.yaml
oc apply -f example-realm-import.yaml
要检查正在运行的导入的状态,请输入以下命令:
oc get keycloakrealmimports/my-realm-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
oc get keycloakrealmimports/my-realm-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
当导入成功完成后,输出将类似以下示例:
CONDITION: Done STATUS: true MESSAGE: CONDITION: Started STATUS: false MESSAGE: CONDITION: HasErrors STATUS: false MESSAGE:
CONDITION: Done
STATUS: true
MESSAGE:
CONDITION: Started
STATUS: false
MESSAGE:
CONDITION: HasErrors
STATUS: false
MESSAGE:
3.1.3. 占位符
导入支持引用环境变量的占位符,请参阅 导入和导出域。KeycloakRealmImport
CR 允许您通过 spec.placeholders
小节利用此功能,例如:
apiVersion: k8s.keycloak.org/v2alpha1 kind: KeycloakRealmImport metadata: name: my-realm-kc spec: keycloakCRName: <name of the keycloak CR> placeholders: ENV_KEY: secret: name: SECRET_NAME key: SECRET_KEY ...
apiVersion: k8s.keycloak.org/v2alpha1
kind: KeycloakRealmImport
metadata:
name: my-realm-kc
spec:
keycloakCRName: <name of the keycloak CR>
placeholders:
ENV_KEY:
secret:
name: SECRET_NAME
key: SECRET_KEY
...
在上例中,将启用占位符替换,并且将从键为 'SECRET_KEY 的 Secret SECRET_NAME 的值创建环境变量
。目前只支持 Secret,它们必须与 Keycloak CR 位于同一个命名空间中。
ENV_KEY
第 4 章 高级配置
调优 Keycloak CR 的高级方面。
4.1. 高级配置
本章论述了如何使用自定义资源(CR)进行红帽构建的 Keycloak 部署的高级配置。
4.1.1. 服务器配置详情
许多服务器选项都作为 Keycloak CR 中的第一类会面字段公开。CR 的结构基于红帽构建的 Keycloak 的配置结构。例如,若要配置服务器的 https-port
,请在 CR 中遵循类似模式,并使用 httpsPort
字段。以下示例是复杂的服务器配置,但它演示了服务器选项和 Keycloak CR 之间的关系:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: db: vendor: postgres usernameSecret: name: usernameSecret key: usernameSecretKey passwordSecret: name: passwordSecret key: passwordSecretKey host: host database: database port: 123 schema: schema poolInitialSize: 1 poolMinSize: 2 poolMaxSize: 3 http: httpEnabled: true httpPort: 8180 httpsPort: 8543 tlsSecret: my-tls-secret hostname: hostname: https://my-hostname.tld admin: https://my-hostname.tld/admin strict: false backchannelDynamic: true features: enabled: - docker - authorization disabled: - admin - step-up-authentication transaction: xaEnabled: false
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
db:
vendor: postgres
usernameSecret:
name: usernameSecret
key: usernameSecretKey
passwordSecret:
name: passwordSecret
key: passwordSecretKey
host: host
database: database
port: 123
schema: schema
poolInitialSize: 1
poolMinSize: 2
poolMaxSize: 3
http:
httpEnabled: true
httpPort: 8180
httpsPort: 8543
tlsSecret: my-tls-secret
hostname:
hostname: https://my-hostname.tld
admin: https://my-hostname.tld/admin
strict: false
backchannelDynamic: true
features:
enabled:
- docker
- authorization
disabled:
- admin
- step-up-authentication
transaction:
xaEnabled: false
有关选项列表,请参阅 Keycloak CRD。有关配置选项的详情,请查看 所有配置。
4.1.1.1. 其他选项
一些专家服务器选项作为 Keycloak CR 中的专用字段不可用。以下是省略的字段示例:
- 需要深入了解底层红帽构建的 Keycloak 实现的字段
- 与 OpenShift 环境无关的字段
- 供应商配置的字段,因为它们基于使用的供应商实现动态
Keycloak CR 的 additionalOptions
字段可让红帽构建 Keycloak 以键值对的形式接受任何可用的配置。您可以使用此字段包含 Keycloak CR 中省略的任何选项。有关配置选项的详情,请查看 所有配置。
这些值可以表示为纯文本字符串或 Secret 对象引用,如下例所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... additionalOptions: - name: spi-connections-http-client-default-connection-pool-size secret: # Secret reference name: http-client-secret # name of the Secret key: poolSize # name of the Key in the Secret - name: spi-email-template-mycustomprovider-enabled value: true # plain text value
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
additionalOptions:
- name: spi-connections-http-client-default-connection-pool-size
secret: # Secret reference
name: http-client-secret # name of the Secret
key: poolSize # name of the Key in the Secret
- name: spi-email-template-mycustomprovider-enabled
value: true # plain text value
以这种方式定义的选项名称格式与配置文件中指定的选项的密钥格式相同。有关各种配置格式的详情,请参阅配置红帽构建的 Keycloak。
4.1.2. Secret 参考
Secret References 由 Keycloak CR 中的一些专用选项使用,如 tlsSecret
,或作为 additionalOptions
中的值。
同样,ConfigMap 引用也被选项(如 configMapFile
)使用。
在指定 Secret 或 ConfigMap 参考时,请确保包含引用密钥的 Secret 或 ConfigMap 存在于与引用它的 CR 相同的命名空间中。
Operator 每分钟会轮询大约一分钟,以更改引用的 Secret 或 ConfigMap。当检测到有意义的更改时,Operator 会执行红帽构建的 Keycloak Deployment 的滚动重启来获取更改。
4.1.3. 不支持的功能
CR 的 unsupported
字段包含没有完全测试且技术预览的高实验配置选项。
4.1.3.1. Pod 模板
Pod 模板是一种原始 API 表示,用于 Deployment 模板。如果用例的 CR 的顶层没有支持的字段,则此字段是一个临时解决方案。
Operator 将提供的模板的字段与 Operator 为特定 Deployment 生成的值合并。使用此功能,您可以访问高级别的自定义。但是,没有保证 Deployment 将按预期工作。
以下示例演示了注入标签、注解、卷和卷挂载:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... unsupported: podTemplate: metadata: labels: my-label: "keycloak" spec: containers: - volumeMounts: - name: test-volume mountPath: /mnt/test volumes: - name: test-volume secret: secretName: keycloak-additional-secret
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
unsupported:
podTemplate:
metadata:
labels:
my-label: "keycloak"
spec:
containers:
- volumeMounts:
- name: test-volume
mountPath: /mnt/test
volumes:
- name: test-volume
secret:
secretName: keycloak-additional-secret
4.1.3.1.1. 探测超时
不受支持的 podTemplate 可以用来覆盖默认探测。
特别是当长时间运行迁移的情况下,默认启动探测超时时间可能太短。
如果您的实例遇到此启动失败,或者您希望主动阻止此类启动失败,则应增加启动探测超时。
使用其他默认设置时,类似以下内容的内容会将超时时间增加到 20 分钟:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... unsupported: podTemplate: spec: containers: startupProbe: httpGet: path: "/health/started" port: 9000 scheme: "HTTPS" failureThreshold: 1200 periodSeconds: 1
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
unsupported:
podTemplate:
spec:
containers:
startupProbe:
httpGet:
path: "/health/started"
port: 9000
scheme: "HTTPS"
failureThreshold: 1200
periodSeconds: 1
请注意,使用相对 HTTP 路径或替代管理端口需要更改探测配置。
4.1.4. 禁用所需选项
Red Hat build of Keycloak 和 Red Hat build of Keycloak Operator 提供了最佳的生产环境就绪体验。但是,在开发阶段,您可以禁用关键安全功能。
特别是,您可以禁用主机名和 TLS,如下例所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... http: httpEnabled: true hostname: strict: false
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
http:
httpEnabled: true
hostname:
strict: false
4.1.5. 资源要求
Keycloak CR 允许指定资源选项来管理红帽构建的 Keycloak 容器的计算资源。它提供通过 Keycloak CR 独立请求和限制资源的功能,以及通过 Realm Import CR 为 realm 导入作业进行隔离。
如果没有指定值,默认 请求内存
设置为 1700MiB
,限制
内存设置为 2GiB
。根据红帽构建的 Keycloak 内存管理深度分析来选择这些值。
如果没有在 Realm Import CR 中指定值,它将回退到 Keycloak CR 中指定的值,或者返回上述定义的默认值。
您可以根据要求指定自定义值,如下所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... resources: requests: cpu: 1200m memory: 896Mi limits: cpu: 6 memory: 3Gi
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
resources:
requests:
cpu: 1200m
memory: 896Mi
limits:
cpu: 6
memory: 3Gi
此外,红帽构建的 Keycloak 容器通过提供堆大小的相对值,从而更有效地管理堆大小。它可以通过提供某些 JVM 选项来实现。
如需了解更多详细信息,请参阅 在容器中运行红帽构建的 Keycloak。
4.1.6. 调度
您可以通过 Keycloak CR 控制服务器 Pod 调度的一些方面。scheduling 小节会公开可选的标准 Kubernetes 关联性、容限、拓扑分布约束和优先级类名称,以微调服务器 Pod 的调度和放置。
使用所有调度字段的示例:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: scheduling: priorityClassName: custom-high affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchLabels: app: keycloak app.kubernetes.io/managed-by: keycloak-operator app.kubernetes.io/component: server topologyKey: topology.kubernetes.io/zone weight: 10 tolerations: - key: "some-taint" operator: "Exists" effect: "NoSchedule" topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule ... ...
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
scheduling:
priorityClassName: custom-high
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app: keycloak
app.kubernetes.io/managed-by: keycloak-operator
app.kubernetes.io/component: server
topologyKey: topology.kubernetes.io/zone
weight: 10
tolerations:
- key: "some-taint"
operator: "Exists"
effect: "NoSchedule"
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
...
...
有关调度概念的更多信息 ,请参阅 kubernetes 文档。
如果没有指定自定义关联性,您的 Pod 将具有同一区的关联性,以及同一节点的反关联性以提高可用性。如果可能有助于防止跨区缓存集群流量超过延迟,则调度到同一区。
4.1.7. 管理界面
要更改管理界面的端口,请在 Keycloak CR 中使用第一类色列字段 httpManagement.port
。要更改管理界面的属性,您可以通过提供 additionalOptions
字段来实现它。
您可以指定 port
和 additionalOptions
,如下所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: httpManagement: port: 9001 additionalOptions: - name: http-management-relative-path value: /management
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
httpManagement:
port: 9001
additionalOptions:
- name: http-management-relative-path
value: /management
如果使用自定义镜像,Operator 会 不知道 在其中可能指定的任何配置选项。例如,它可能会导致管理界面使用 https
模式,但当自定义镜像中指定 TLS 设置时,Operator 会通过 http
访问它。为确保正确的 TLS 配置,请使用 Keycloak CR 中的 tlsSecret
和 truststores
字段,以便 Operator 可以反映这一点。
如需了解更多详细信息 ,请参阅配置管理界面。
4.1.8. truststores
如果您需要提供可信证书,Keycloak CR 提供了顶级功能来配置服务器的信任存储,如 配置可信证书 中所述。
使用 Keycloak spec 的 truststores 小节来指定包含 PEM 编码文件的 Secret,或使用扩展名 .p12
、.pfx
或 .pkcs12
文件的 PKCS12 文件,例如:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... truststores: my-truststore: secret: name: my-secret
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
truststores:
my-truststore:
secret:
name: my-secret
其中 my-secret 的内容可以是 PEM 文件,例如:
apiVersion: v1 kind: Secret metadata: name: my-secret stringData: cert.pem: | -----BEGIN CERTIFICATE----- ...
apiVersion: v1
kind: Secret
metadata:
name: my-secret
stringData:
cert.pem: |
-----BEGIN CERTIFICATE-----
...
在 Kubernetes 或 OpenShift 环境中,自动包含可信证书的已知位置。这包括 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
和 /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
。
4.1.9. 管理 Bootstrapping
当您创建新实例时,Keycloak CR spec.bootstrapAdmin 小节可用于配置 bootstrap 用户和/或服务帐户。如果没有为 spec.bootstrapAdmin 指定任何内容,Operator 将创建一个名为 "metadata.name"-initial-admin 的 Secret,其带有用户名 temp-admin 和生成的密码。如果您为 bootstrap admin 用户指定 Secret 名称,则 Secret 将需要包含用户名和密码键值对。
如果您为 bootstrap admin 服务帐户指定 Secret 名称,则 Secret 将需要包含
client-id
和 client-secret
键值对。
如果已为集群创建了 master 域,则 spec.boostrapAdmin 会被有效地忽略。如果您需要创建恢复 admin 帐户,则需要直接在 Pod 上运行 CLI 命令。
有关如何引导临时 admin 用户或服务帐户并恢复丢失的 admin 访问权限的更多信息,请参阅 Bootstrapping 和恢复管理员帐户 指南。
4.1.10. 追踪(OpenTelemetry)
追踪允许对每个请求的生命周期进行详细监控,这有助于快速识别和诊断问题,从而更有效地调试和维护。
您可以通过 Keycloak CR 字段更改追踪配置,如下所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: tracing: enabled: true # default 'false' endpoint: http://my-tracing:4317 # default 'http://localhost:4317' samplerType: parentbased_traceidratio # default 'traceidratio' samplerRatio: 0.01 # default '1' resourceAttributes: some.attribute: something additionalOptions: - name: tracing-jdbc-enabled value: false # default 'true'
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
tracing:
enabled: true # default 'false'
endpoint: http://my-tracing:4317 # default 'http://localhost:4317'
samplerType: parentbased_traceidratio # default 'traceidratio'
samplerRatio: 0.01 # default '1'
resourceAttributes:
some.attribute: something
additionalOptions:
- name: tracing-jdbc-enabled
value: false # default 'true'
这些字段应该反映在 1:1 关联,
它们包括了更多信息。
tracing-jdbc-enabled
不会被推广为第一类的会面,因为它可能无法在将来被良好管理,因此需要通过 additionalOptions
字段进行设置。
有关追踪的详情,请参阅 Root 原因分析追踪。
4.1.11. 网络策略
NetworkPolicies 允许您为集群中的流量流指定规则,并在 Pod 和外部世界之间指定规则。集群必须使用支持 NetworkPolicy 强制的网络插件来限制网络流量。
Operator 会自动创建一个 NetworkPolicy 来拒绝访问红帽构建的 Keycloak Pod 的集群端口。HTTP (S)端点打开到来自任何命名空间和外部世界的流量。
要禁用 NetworkPolicy,在 Keycloak CR 中设置 spec.networkPolicy.enabled
,如下例所示。
启用网络策略的 Keycloak CR
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: networkPolicy: enabled: false
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
networkPolicy:
enabled: false
默认情况下,所有源都允许到 HTTP 端点的流量和管理端点。Keycloak CR 可以扩展为由红帽构建 Keycloak 公开的每个端点包含规则列表。这些规则指定允许流量的位置(源),并可与红帽的 Keycloak Pod 构建通信。
扩展网络策略配置
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: networkPolicy: enabled: true http: <list of rules> https: <list of rules> management: <list of rules>
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
networkPolicy:
enabled: true
http: <list of rules>
https: <list of rules>
management: <list of rules>
规则语法与 Kubernetes Network Policy 使用的语法相同。可以轻松地将现有规则迁移到 Keycloak CP 中。如需更多信息,请检查 规则语法。
4.1.11.1. 使用 OpenShift 的示例
例如,我们假设有一个红帽构建的 Keycloak 部署在 OpenShift 集群中运行。用户必须有权访问红帽构建的 Keycloak 才能登录,因此红帽构建的 Keycloak 必须可以被互联网访问。
要使此示例更有趣,让我们假设是否监控红帽构建的 Keycloak。启用监控,如 OpenShift 文档页面中所述: 为用户定义的项目启用监控项目。
根据这些要求,Keycloak CR 将类似如下(大多数部分都会被忽略,如 DB 连接和安全):
Keycloak CR
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ingress: enabled: true networkPolicy: enabled: true https: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: openshift-ingress management: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: openshift-user-workload-monitoring
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
ingress:
enabled: true
networkPolicy:
enabled: true
https:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-ingress
management:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-user-workload-monitoring
有关 NetworkPolicies 的更多信息,请参阅 Kubernetes Network Policies 文档。
第 5 章 通过滚动更新避免停机时间
避免在优化镜像中更改主题、提供程序或配置时停机。
默认情况下,红帽构建的 Keycloak Operator 将在不停机的情况下在配置更改上执行滚动更新,并在镜像名称或标签更改时重新创建更新。
本章论述了如何通过配置红帽构建的 Keycloak Operator 来尽可能自动执行红帽构建的 Keycloak 的滚动更新,以及如何为滚动更新覆盖自动检测。
例如,使用它来避免在向主题、供应商或构建时间配置在自定义或优化镜像中推出更新时造成停机。
5.1. 支持的更新策略
Operator 支持以下更新策略:
- 滚动更新
- 以滚动方式更新 StatefulSet,避免在至少两个副本运行时出现停机。
- 重新创建更新
- 在应用更新前缩减 StatefulSet,从而导致临时停机时间。
5.2. 配置更新策略
在 Keycloak CR YAML 定义的 spec
部分中指定 update 策略:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: update: strategy: RecreateOnImageChange|Auto|Explicit revision: "abc"
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
update:
strategy: RecreateOnImageChange|Auto|Explicit
revision: "abc"
value | 停机时间? | 描述 |
---|---|---|
| 在镜像名称或标签更改时 | 模拟红帽构建的 Keycloak 26.1 或旧行为。当 image 字段更改时,Operator 会在应用新镜像前缩减 StatefulSet。 |
| 不兼容的更改 | Red Hat build of Keycloak Operator 会检测是否可以滚动或重新创建更新。 在当前版本中,如果红帽构建的 Keycloak 版本与旧镜像相同,则红帽构建的 Keycloak 版本会执行滚动更新。红帽构建的 Keycloak 的未来版本将改变该行为,并使用配置中的附加信息、镜像和版本来确定是否可以滚动更新来减少停机时间。 |
|
只有 |
Red Hat build of Keycloak Operator 会检查 |
5.2.1. 了解 Auto
和 Explicit
更新策略
使用自动更新策略时,Red Hat build of Keycloak Operator 会自动启动一个作业来评估滚动更新的可行。如果可能滚动更新,请参阅检查滚动更新中有关 流程的更多信息。这个过程会在检查时消耗集群资源,并在 StatefulSet 更新开始前引入小延迟。
如果将 Keycloak CR 配置为 不支持的配置参数
的一部分,则 Keycloak Operator 最好为启动的作业使用这些设置。仍然可能会因为
podTemplate
功能的灵活性及其不受支持的性质而丢失一些设置。
因此,如果从 podTemplate
中的 Secret、ConfigMap 或卷拉取的 podTemplate
或信息进行更改,Operator 可能会绘制错误的结论。
因此,如果您使用不受支持的 podTemplate
,您可能需要使用其它更新策略。
Explicit
更新策略将更新决策委派给用户。revision
字段充当用户控制的触发器。虽然红帽构建的 Keycloak Operator 不会解释 修订值本身,但
保持不变时对自定义资源(CR)的任何更改都会提示滚动更新。
修订版本
在进行自动 Operator 升级时请小心。Operator Lifecycle Manager (OLM)可能会升级 Keycloak Operator 的红帽构建,如果使用 Explicit
更新策略,这可能会导致意外行为或部署失败,因为 Operator 会在实际不支持时尝试滚动更新。如果您使用 Explicit
更新策略,请在升级前在非生产环境中进行全面的测试。
5.2.2. CR 状态
RecreateUpdateUsed
的 Keycloak CR 状态指示最后一次更新操作过程中使用的更新策略。lastTransitionTime
字段指示最后一次更新发生的时间。使用这些信息观察 Operator 所采取的操作和决策。
Status | 描述 |
---|---|
| 初始状态。这意味着没有更新。 |
| Operator 在最后一次更新中应用了滚动更新策略。 |
|
Operator 在最后一次更新中应用了 recreate 更新策略。 |
第 6 章 使用自定义红帽构建的 Keycloak 镜像
自定义和优化红帽构建的 Keycloak 容器。
6.1. Red Hat build of Keycloak 自定义镜像使用 Operator
使用 Keycloak 自定义资源(CR),您可以为红帽构建的 Keycloak 服务器指定自定义容器镜像。
为确保 Operator 和 Operand 的完整兼容性,请确保自定义镜像中使用的红帽构建的 Keycloak 版本与 Operator 的版本一致。
6.1.1. 最佳实践
当使用默认红帽构建的 Keycloak 镜像时,服务器会在每次 Pod 启动时执行成本的重新增加。为避免这种延迟,您可以为自定义镜像提供从镜像构建时间增强内置项。
使用自定义镜像,您还可以在构建容器期间指定 Keycloak 构建时 配置和扩展。
当使用优化的自定义镜像时,需要在 Containerfile 中明确设置 启用了健康的选项和启用了指标
的选项。
有关如何构建此类镜像的说明,请参阅 在容器中运行红帽构建的 Keycloak。
6.1.2. 提供自定义红帽构建的 Keycloak 镜像
要提供自定义镜像,您可以在 Keycloak CR 中定义 image
字段,如下例所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: instances: 1 image: quay.io/my-company/my-keycloak:latest http: tlsSecret: example-tls-secret hostname: hostname: test.keycloak.org
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
instances: 1
image: quay.io/my-company/my-keycloak:latest
http:
tlsSecret: example-tls-secret
hostname:
hostname: test.keycloak.org
使用自定义镜像时,每个构建时间选项都会通过专用字段传递,否则会忽略 additionalOptions
。
Operator 不知道 自定义镜像中指定的任何配置选项。将 Keycloak CR 用于需要 Operator 感知的任何配置,即 TLS 和 HTTP (S)设置在配置服务和探测时反映。
6.1.3. 非优化的自定义镜像
虽然最佳实践是使用预防的镜像,但如果您想要使用非优化的自定义镜像或构建时间属性,仍有可能使用增强镜像。您只需要将 startOptimized
字段设置为 false
,如下例所示:
apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: instances: 1 image: quay.io/my-company/my-keycloak:latest startOptimized: false http: tlsSecret: example-tls-secret hostname: hostname: test.keycloak.org
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
instances: 1
image: quay.io/my-company/my-keycloak:latest
startOptimized: false
http:
tlsSecret: example-tls-secret
hostname:
hostname: test.keycloak.org
请记住,每次开始都会考虑这一点。