在 Kubernetes 中使用 hostname-backchannel-dynamic 解决 Keycloak 内部与外部访问
Source: Dev.to
请提供您希望翻译的正文内容(包括任何 Markdown 格式的文本),我将为您翻译成简体中文,同时保留代码块、URL 和技术术语的原样不变。谢谢!
介绍
在基础设施中使用 OpenID Connect(OIDC)作为身份验证来源是一种最佳实践,因为它显著提升了安全性和可维护性。Keycloak 是一个广受欢迎的开源项目,非常适合用于此目的。它支持众多功能和存储后端(如 PostgreSQL),并在官方站点提供了简明的部署说明。
然而,在 Kubernetes 中部署 Keycloak 时,可能会暴露出内部服务通信问题,需要进行特定的配置。
问题:外部主机名 vs 内部访问
在 Kubernetes 中部署 Keycloak 时,通常会使用 --hostname=https://auth.example.com 参数指定一个公共主机名。这对于外部客户端访问您的认证服务能够完美工作。
挑战出现在同一 Kubernetes 集群内部的其他服务——例如容器镜像仓库或 CI 服务器——需要使用 Keycloak 进行认证时。这些服务必须访问发现 URL:
https://auth.example.com/realms/{realm-name}/.well-known/openid-configuration
Keycloak 总是会重定向到(并基于)启动时提供的主机名来生成令牌/URL。如果该公共 URL 在集群内部不可解析,内部 pod 将无法通过后端通道请求(令牌自省、userinfo 等)访问 Keycloak,尽管它们可以通过内部 DNS 访问该 pod。
解决方案:动态回程通道主机名
Keycloak 提供了一个 CLI 选项来解决此问题(在启用 hostname:v2 功能时可用):
--features=hostname:v2
--hostname-backchannel-dynamic=true
使用此配置,Keycloak 会根据传入请求动态确定回程通道(内部)URL,允许通过以下方式访问:
- 直接 IP 地址
- 内部 Kubernetes DNS(例如
keycloak.keycloak-namespace.svc.cluster.local:8080/realms/{realm-name}/.well-known/openid-configuration)
工作原理
当启用 --hostname-backchannel-dynamic=true 时:
| 访问类型 | 使用的 URL |
|---|---|
| 外部 | https://auth.example.com(公共主机名) |
| 内部 | 内部 Kubernetes 服务 DNS 名称(或 Pod IP) |
这种双重访问方式确保:
- 外部客户端获得用于认证流程的正确公共 URL。
- 内部服务可以通过集群内部 DNS 解析可靠地访问 Keycloak。
- 无需为内部通信单独配置额外的网络路由或 Ingress。
生产环境注意事项: 确保您的 Ingress/反向代理正确转发 Forwarded 或 X‑Forwarded‑* 头部,并考虑在外部和内部路径上都启用 HTTPS。
示例配置
以下是一个最小的 Kubernetes 部署清单,启用动态回程通道主机名:
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
spec:
template:
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:latest
args:
- start
- --features=hostname:v2 # required for dynamic backchannel
- --hostname=https://auth.example.com
- --hostname-backchannel-dynamic=true
- --db=postgres
- --proxy-headers=forwarded # important for correct header handling behind proxy/ingress
# ... other configuration (ports, HTTPS, DB credentials via env vars, etc.)
结论
--hostname-backchannel-dynamic=true 标志(结合 hostname:v2 功能)为 Kubernetes 中混合内部/外部访问场景提供了一个简单而强大的解决方案。公共 URL 仍然是外部客户端访问的理想选择,而内部服务间通信则受益于动态回通道解析的灵活性。
Keycloak 的主机名配置选项使其成为容器化环境中认证基础设施的可靠选择。