Kubernetes MCP服务器OAuth配置指南
本指南解释了如何配置Kubernetes MCP服务器,使其使用带有Keycloak的OAuth身份验证,并使用用户上下文而不是服务帐户凭据运行操作。
概述
Kubernetes MCP服务器可以配置为使用Keycloak的OAuth2/OIDC身份验证。当配置为 require_oauth = true,服务器:
- 接受来自客户端的OAuth令牌
- 与Keycloak进行令牌交换以获取Kubernetes/OpenShift令牌
- 使用用户的身份来执行Kubernetes操作(用户上下文)
- 尊重用户在群集中的RBAC权限
这实现了细粒度的访问控制,其中每个用户的操作都受到其各自的Kubernetes RBAC权限的限制。
先决条件
- OpenShift 4.19或更高版本 (外部身份验证-技术预览功能需要)
- 具有集群管理员权限的OpenShift/Kubernetes集群访问
ocCLI工具已安装并配置kustomize安装jq已安装(用于测试)envsubst已安装(通常随附gettext包装)- 访问
llama-stack命名空间(或创建它)
⚠️ 重要:此设置使用外部身份验证,这是一种 技术预览功能 在OpenShift 4.19+中可用。请参阅 Keycloak设置指南 有关先决条件、限制和部署步骤的详细信息。
建筑
上面的架构图说明了完整的身份验证和授权流程。下面是详细的解释:
身份验证流程
User → Playground → Keycloak (mcp-client) → JWT Token
↓
Kubernetes MCP Server → Keycloak (mcp-server) → Token Exchange → OpenShift Token → Kubernetes Cluster详细流程说明
- User → 游乐场:用户访问Llama Stack游乐场应用程序
- 游乐场→ Keycloak(mcp客户端):Playground使用Keycloak进行身份验证
mcp-client公共客户端,并接收JWT令牌mcp-server范围 - 游乐场→ Kubernetes MCP服务器:Playground使用JWT令牌向MCP服务器发送请求(受众:
mcp-server) - Kubernetes MCP服务器→ 密钥斗篷(mcp服务器):MCP服务器与Keycloak进行令牌交换
mcp-server保密客户:
- 发送用户的JWT令牌(主题令牌) - 请求令牌交换 openshift 观众 - 请求: mcp:openshift 范围
- 钥匙斗篷→ Kubernetes MCP服务器:Keycloak返回一个新的JWT令牌,其中包含:
- 观众: openshift - 范围: mcp:openshift
- Kubernetes MCP服务器→ Kubernetes集群:MCP服务器使用OpenShift JWT令牌作为经过身份验证的用户进行Kubernetes API调用
关键组件
- 游乐场:通过Keycloak对用户进行身份验证的面向用户的应用程序
- 钥匙斗篷:具有三个客户的身份提供者:
- mcp-client:用于用户身份验证的公共客户端 - mcp-server:代币交换的机密客户 - openshift:用于OpenShift API身份验证的客户端
- Kubernetes MCP服务器:执行令牌交换并使用用户上下文进行Kubernetes API调用的服务器
- Kubernetes集群:使用用户的RBAC权限执行操作的目标群集
逐步配置
本指南使用具有环境变量替换的模板文件(envsubst)以配置组件。所有配置文件都使用 ${VARIABLE_NAME} 在部署时被替换的占位符。
步骤1:部署Keycloak实例和领域
首先,部署Keycloak并使用必要的客户端配置域。此设置使用 外部认证 (OpenShift 4.19+的技术预览功能)。
📖 有关Keycloak设置的详细说明,请参阅 Keycloak设置指南
部署Keycloak:
cd redhat-bk
./script.sh此脚本将:
- 通过FeatureGate启用技术预览功能(外部身份验证所需)
- 部署Keycloak运营商的Red Hat Build
- 创建PostgreSQL数据库
- 部署Keycloak实例
- 配置
openshift领域:
- mcp-client:MCP客户端进行身份验证的公共客户端 - mcp-server:代币交换的机密客户 - openshift:用于OpenShift API身份验证的客户端 - openshift-cli:用于CLI身份验证的公共客户端
- 为OpenShift配置外部身份验证
- 提取并创建Keycloak CA证书ConfigMap
重要:
- 需要OpenShift 4.19+ 用于外部身份验证
- 保存生成的机密 由脚本输出显示:
MCP_SERVER_SECRET=
MCP_CLIENT_SECRET=
OPENSHIFT_SECRET=
OPENSHIFT_CONSOLE_SECRET=
CLUSTER_NAME=- 启用后无法禁用FeatureGate
步骤2:设置环境变量
在运行主部署脚本之前,请导出步骤1中的机密:
# Get cluster name (auto-detected by script, but can be set manually)
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' 2>/dev/null | sed 's|https://api\.||' | sed 's|:6443||' || echo "")
# Export secrets from Keycloak deployment (from redhat-bk/script.sh output)
# These are REQUIRED - the script will fail if not set
export MCP_SERVER_SECRET= # From redhat-bk/script.sh output
export MCP_CLIENT_SECRET= # From redhat-bk/script.sh output
# Cookie secret is auto-generated by the script, but can be set manually
export COOKIE_SECRET=$(openssl rand -base64 24) # Optional - script generates if not set备注:脚本将自动检测 CLUSTER_NAME 如果没有设置,但是 MCP_SERVER_SECRET 和 MCP_CLIENT_SECRET 必须在运行脚本之前导出。
步骤3:部署所有组件
从根目录运行主部署脚本:
./script.sh此脚本将:
- Kubernetes MCP服务器设置:
- 用途 mcp-openshift/base/configmap.yaml.template 随着 envsubst - 生成 configmap.yaml 用替换值 - 创建Keycloak CA证书ConfigMap - 使用OAuth配置部署MCP服务器
- OpenShift AI设置:
- 部署OpenShift AI操作员(稳定-2.25) - 部署OpenShift AI实例
- Llama堆叠设置:
- 副本 llama-stack-secret.yaml.template 到 llama-stack-secret.yaml - 用途 llama-stack/base/configmap.yaml.template 随着 envsubst - 生成 configmap.yaml 用替换值 - 备注:您需要手动更新 llama-stack-secret.yaml 使用实际API令牌
- Llama Stack游乐场设置:
- 使用以下命令生成随机cookie密钥 openssl rand -base64 24 - 替换 GENERATE_RANDOM_BASE64_STRING 占位符在 values.yaml 带有生成的cookie密钥(如果占位符存在) - 将目录更改为 llama-stack-playground/chart/llama-stack-playground - 用途 values.yaml.template 随着 envsubst 生成 values.yaml (替代品 ${CLUSTER_NAME}, ${MCP_CLIENT_SECRET}, ${COOKIE_SECRET}) - 通过Kustomize使用Helm进行部署 llama-stack-playground/overlay
步骤4:模板文件配置
部署使用需要替换环境变量的模板文件:
MCP服务器配置
模板: mcp-openshift/base/configmap.yaml.template
模板使用 ${CLUSTER_NAME} 和 ${MCP_SERVER_SECRET} 变量:
data:
config.toml: |
# OAuth/OIDC Configuration
require_oauth = true
authorization_url = "https://keycloak-admin.apps.${CLUSTER_NAME}/realms/openshift"
oauth_scopes = ["openid", "mcp-server"]
sts_client_id = "mcp-server"
sts_client_secret = "${MCP_SERVER_SECRET}"
sts_audience = "openshift"
sts_scopes = ["mcp:openshift"]
certificate_authority = "/etc/pki/keycloak-ca/ca.crt"
oauth_audience = "account"
validate_token = falseLlama堆栈配置
模板: llama-stack/base/configmap.yaml.template
模板使用 ${CLUSTER_NAME} 用于Keycloak URL。
Llama堆叠游乐场配置
文件: llama-stack-playground/chart/llama-stack-playground/values.yaml
值文件使用环境变量替换为 envsubst:
${CLUSTER_NAME}用于Keycloak URL和重定向URL${MCP_CLIENT_SECRET}用于Keycloak客户端密钥${COOKIE_SECRET}对于OAuth2代理cookie密钥(如果未设置,则由脚本自动生成)
步骤5:验证部署
检查所有组件是否正在运行:
# Check MCP Server
oc get pods -n llama-stack -l app=ocp-mcp-server
oc logs -n llama-stack -l app=ocp-mcp-server --tail=50
# Check OpenShift AI
oc get pods -n redhat-ods-applications
# Check Llama Stack
oc get pods -n llama-stack -l app=llama-stack
# Check Llama Stack Playground
oc get pods -n llama-stack -l app.kubernetes.io/name=llama-stack-playground您应该看到指示OAuth已启用的日志:
OAuth required: true
Authorization URL: https://keycloak-admin.apps...快速启动(自动部署)
要实现完全自动化的部署,请使用主脚本:
# Step 1: Deploy Keycloak (run once, save the secrets)
cd redhat-bk
./script.sh
# Save the output secrets displayed:
# MCP_SERVER_SECRET=
# MCP_CLIENT_SECRET=
# OPENSHIFT_SECRET=
# OPENSHIFT_CONSOLE_SECRET=
# CLUSTER_NAME=
# Step 2: Set environment variables (REQUIRED before running main script)
cd ..
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' | sed 's|https://api\.||' | sed 's|:6443||')
export MCP_SERVER_SECRET=
export MCP_CLIENT_SECRET=
# COOKIE_SECRET is optional - script will generate if not set
export COOKIE_SECRET=$(openssl rand -base64 24)
# Step 3: Deploy all components
./script.sh重要提示:
- 脚本自动检测
CLUSTER_NAME如果不出口 MCP_SERVER_SECRET和MCP_CLIENT_SECRET必须 在运行前导出- 脚本使用
envsubst替换模板文件中的环境变量 - 模板文件必须存在:
configmap.yaml.template文件和values.yaml.template(如果使用)
在本地运行服务器(开发)
对于本地开发和测试:
1.构建服务器
cd ../kubernetes-mcp-server # Navigate to the server source
make build2.创建配置文件
创建一个 config.toml 文件:
port = "8080"
cluster_provider_strategy = "kubeconfig"
kubeconfig = "/path/to/your/kubeconfig"
log_level = 2
list_output = "table"
toolsets = ["core", "config", "helm"]
read_only = false
disable_destructive = false
# OAuth/OIDC Configuration
require_oauth = true
authorization_url = "https://keycloak-admin.apps./realms/openshift"
oauth_scopes = ["openid", "mcp-server"]
sts_client_id = "mcp-server"
sts_client_secret = ""
sts_audience = "openshift"
sts_scopes = ["mcp:openshift"]
certificate_authority = "/path/to/keycloak-ca.crt"
oauth_audience = "account"
validate_token = false3.运行服务器
./kubernetes-mcp-server --port 8080 --require-oauth --config config.toml或者使用命令行标志:
./kubernetes-mcp-server \
--port 8080 \
--require-oauth \
--authorization-url "https://keycloak-admin.apps./realms/openshift" \
--oauth-scopes "openid,mcp-server" \
--sts-client-id "mcp-server" \
--sts-client-secret "" \
--sts-audience "openshift" \
--sts-scopes "mcp:openshift" \
--certificate-authority "/path/to/keycloak-ca.crt" \
--oauth-audience "account"测试设置
1.获取OAuth令牌
使用Keycloak进行身份验证以获取OAuth令牌:
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' | sed 's|https://api\.||' | sed 's|:6443||')
export RHBK_HOST="https://keycloak-admin.apps.${CLUSTER_NAME}"
export RHBK_REALM="openshift"
export RHBK_USERNAME="testdeveloper" # User created in Keycloak
export RHBK_PASSWORD="
"
export MCP_CLIENT_ID="mcp-client"
export MCP_CLIENT_SECRET="" # From redhat-bk/script.sh output
RHBK_TOKEN=$(curl -s -X POST ${RHBK_HOST}/realms/${RHBK_REALM}/protocol/openid-connect/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d scope=mcp-server \
-d username=${RHBK_USERNAME} \
-d password=${RHBK_PASSWORD} \
-d grant_type=password \
-d client_id=${MCP_CLIENT_ID} \
-d client_secret=${MCP_CLIENT_SECRET} | jq -r '.access_token')
echo "Token: $RHBK_TOKEN"2.测试令牌交换(服务器端)
服务器将自动执行令牌交换。手动测试:
export MCP_SERVER_ID="mcp-server"
export MCP_SERVER_SECRET="" # From redhat-bk/script.sh output
K8S_TOKEN=$(curl -s ${RHBK_HOST}/realms/${RHBK_REALM}/protocol/openid-connect/token \
-d grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
-d client_id=${MCP_SERVER_ID} \
-d subject_token="${RHBK_TOKEN}" \
-d subject_token_type=urn:ietf:params:oauth:token-type:access_token \
-d audience=openshift \
-d client_secret=${MCP_SERVER_SECRET} \
-d requested_token_type=urn:ietf:params:oauth:token-type:access_token \
-d scope=mcp:openshift | jq -r '.access_token')
echo "K8S Token: $K8S_TOKEN"3.使用MCP检验员进行测试
使用MCP检查器测试服务器:
npx @modelcontextprotocol/inspector@latest配置它以使用OAuth令牌连接到您的MCP服务器。
4.验证用户上下文
检查操作是否以经过身份验证的用户身份执行:
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' | sed 's|https://api\.||' | sed 's|:6443||')
export OPENSHIFT_API_SERVER="https://api.${CLUSTER_NAME}:6443"
curl -k -H "Authorization: Bearer ${K8S_TOKEN}" \
"${OPENSHIFT_API_SERVER}/apis/authentication.k8s.io/v1/selfsubjectreviews" \
-H "Content-Type: application/json" \
-X POST -d '{"kind":"SelfSubjectReview","apiVersion":"authentication.k8s.io/v1","metadata":{"creationTimestamp":null},"status":{"userInfo":{}}}'这应该从令牌中返回用户信息。
用户上下文与服务帐户
服务帐户上下文(默认, require_oauth = false)
- 服务器使用服务帐户凭据
- 所有操作都使用服务帐户的权限
- 没有用户特定的访问控制
- 设置更简单,安全性更低
用户上下文(启用OAuth, require_oauth = true)
- 服务器使用用户的OAuth令牌(通过令牌交换)
- 每个操作都使用经过身份验证的用户的权限
- 基于用户RBAC的细粒度访问控制
- 更安全,尊重用户权限
Keycloak领域配置
Keycloak领域包括:
客户范围
- 群组:将用户组映射到令牌声明
- mcp服务器:MCP服务器的受众范围
- mcp:openshift:OpenShift API访问范围
客户
- mcp客户端 (公共)
- MCP客户端用于身份验证 - 已启用直接访问权限 - 可选范围: mcp-server
- mcp服务器 (机密)
- MCP服务器用于令牌交换 - 已启用令牌交换 - 默认范围: groups - 可选范围: mcp:openshift
- 开源容器平台 (机密)
- 用于OpenShift API身份验证 - 用户名、电子邮件、组的协议映射器
- openshift cli (公共)
- 使用 oc CLI用于身份验证
故障排除
服务器不接受OAuth令牌
- 验证
require_oauth = true在配置中 - 检查Keycloak URL是否正确
- 验证CA证书是否正确装载
- 检查服务器日志中的OAuth错误
令牌交换失败
- 验证
MCP_SERVER_SECRET是正确的 - 检查
mcp-server客户端在Keycloak中启用了令牌交换 - 验证
sts_audience匹配Keycloak客户端配置 - 检查Keycloak领域日志
权限被拒绝错误
- 验证用户是否具有适当的RBAC权限
- 检查令牌包含正确的组/声明
- 验证令牌交换成功(检查日志)
- 直接使用测试令牌
kubectl或oc
CA证书问题
- 确保
keycloak-oidc-caConfigMap已存在 - 验证配置中的证书路径是否与装载路径匹配
- 检查证书是否有效且未过期
- 对于自签名证书,设置
validate_token = false在开发过程中
安全考虑
- 秘密管理:商店
MCP_SERVER_SECRET安全(使用密封秘密、外部秘密等) - 令牌验证:启用
validate_token = true生产中 - 传输层安全:始终对Keycloak端点使用HTTPS
- RBAC:确保用户具有所需的最小权限
- 令牌到期:在客户端中实现令牌刷新
- 审计日志:启用审核日志记录以跟踪用户操作
其他资源
- Keycloak设置指南 -部署带外部身份验证的Keycloak的详细指南(技术预览)
- Keycloak代币交换文档
- OpenShift外部身份验证文档
- OpenShift功能门
- Kubernetes MCP服务器文档
手动配置(脚本的替代方案)
如果您更喜欢手动配置而不是使用脚本:
1.配置MCP服务器
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' | sed 's|https://api\.||' | sed 's|:6443||')
export MCP_SERVER_SECRET=
cd mcp-openshift/base
envsubst configmap.yaml
oc apply -k .2.配置Llama堆栈
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' | sed 's|https://api\.||' | sed 's|:6443||')
cd llama-stack/base
cp llama-stack-secret.yaml.template llama-stack-secret.yaml
# Edit llama-stack-secret.yaml with actual API tokens
envsubst configmap.yaml
cd ../overlay
oc apply -k .3.配置Llama Stack游乐场
export CLUSTER_NAME=$(oc get infrastructure cluster -o jsonpath='{.status.apiServerURL}' | sed 's|https://api\.||' | sed 's|:6443||')
export MCP_CLIENT_SECRET=
export COOKIE_SECRET=$(openssl rand -base64 24)
cd llama-stack-playground/chart/llama-stack-playground
# Generate cookie secret
cookieSecret=$(openssl rand -base64 24)
sed -i '' 's|cookieSecret: "GENERATE_RANDOM_BASE64_STRING"|cookieSecret: "'${cookieSecret}'"|g' values.yaml
# Substitute environment variables (if template exists)
if [ -f values.yaml.template ]; then
envsubst values.yaml
else
envsubst values.yaml.tmp && mv values.yaml.tmp values.yaml
fi
cd ../../overlay
kustomize build --enable-helm . | oc apply -f-环境变量引用
部署脚本使用以下环境变量:
| 变量 | 来源 | 描述 |
|---|---|---|
CLUSTER_NAME | 自动检测或手动 | OpenShift群集域名 |
MCP_SERVER_SECRET | redhat-bk/script.sh output | Keycloak mcp服务器客户端机密 |
MCP_CLIENT_SECRET | redhat-bk/script.sh output | Keycloak mcp客户端机密 |
COOKIE_SECRET | 自动生成或手动 | OAuth2代理cookie加密密钥 |
OPENSHIFT_SECRET | redhat-bk/script.sh output | Keycloak openshift客户端密码 |
OPENSHIFT_CONSOLE_SECRET | redhat-bk/script.sh output | Keycloak openshift控制台客户端密码 |
POSTGRES_PASSWORD | redhat-bk/script.sh output | PostgreSQL数据库密码 |
模板文件
所有配置文件都使用模板文件 ${VARIABLE} 占位符:
mcp-openshift/base/configmap.yaml.template-MCP服务器OAuth配置(使用${CLUSTER_NAME},${MCP_SERVER_SECRET})llama-stack/base/configmap.yaml.template-Llama Stack钥匙斗篷配置(使用${CLUSTER_NAME})llama-stack/base/llama-stack-secret.yaml.template-Llama Stack API令牌模板(复制后需要手动更新)llama-stack-playground/chart/llama-stack-playground/values.yaml或values.yaml.template-Playground Helm值(使用${CLUSTER_NAME},${MCP_CLIENT_SECRET},${COOKIE_SECRET};脚本也会替换GENERATE_RANDOM_BASE64_STRING使用生成的cookie密钥)
演示
视频演示
观看Kubernetes MCP Server OAuth设置的视频演示:
Your browser does not support the video tag.
替代: 下载演示视频
演示显示了什么
视频演示了:
- Keycloak部署和配置
- OAuth身份验证流程
- 代币兑换流程
- Kubernetes中的用户上下文操作
- Llama Stack游乐场集成
