概述
本教程将指导您如何使用 OpenHands、Kubernetes、Ingress 和账户管理系统(接入微软 Azure Active Directory)搭建一个多租户版的 OpenHands 系统。通过本教程,您将实现:
- 多用户支持:每个用户登录后访问自己的 OpenHands 实例。
- 身份验证:通过 Azure AD 实现用户身份验证。
- 动态实例分配:根据用户动态分配 OpenHands 实例。
- 数据隔离:确保每个用户的实例和数据互不干扰。
系统架构
系统架构如下:
- 用户通过浏览器访问系统。
- 系统引导用户通过 Azure AD 登录。
- 登录成功后,系统根据用户 ID 查询或分配 OpenHands 实例。
- 用户被路由到对应的 OpenHands 实例。
[用户] --> [账户管理系统] --> [Azure AD 登录]
--> [用户实例映射表] --> [Ingress/反向代理] --> [OpenHands 实例]
准备工作
- Docker 镜像:确保 OpenHands 的 Docker 镜像已构建并可用(例如
docker.all-hands.dev/all-hands-ai/openhands:0.27
)。 - Kubernetes 集群:确保 Kubernetes 集群已配置好(可以使用 Minikube、Kind 或云服务如 GKE、EKS 等)。
- kubectl 工具:确保本地安装了
kubectl
并已连接到 Kubernetes 集群。 - Azure AD 应用:在 Azure AD 中注册一个应用,用于用户身份验证。
步骤 1: 部署 OpenHands 到 Kubernetes
创建 Kubernetes 配置文件
以下是一个示例的 Kubernetes 配置文件,包含 Deployment 和 Service:
openhands-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: openhands-deployment
labels:
app: openhands
spec:
replicas: 3 # 启动 3 个实例,可以根据需要调整
selector:
matchLabels:
app: openhands
template:
metadata:
labels:
app: openhands
spec:
containers:
- name: openhands
image: docker.all-hands.dev/all-hands-ai/openhands:0.27
ports:
- containerPort: 3000
env:
- name: SANDBOX_RUNTIME_CONTAINER_IMAGE
value: "docker.all-hands.dev/all-hands-ai/runtime:0.27-nikolaik"
- name: LOG_ALL_EVENTS
value: "true"
volumeMounts:
- name: openhands-state
mountPath: /.openhands-state
volumes:
- name: openhands-state
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: openhands-service
spec:
selector:
app: openhands
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
部署到 Kubernetes
将上述配置文件保存为 openhands-deployment.yaml
,然后运行以下命令:
kubectl apply -f openhands-deployment.yaml
验证部署
- 检查 Pod 是否运行正常:
kubectl get pods
- 检查 Service 是否分配了外部 IP(如果使用 LoadBalancer 类型):
您可以通过分配的外部 IP 访问 OpenHands 实例。kubectl get service openhands-service
步骤 2: 配置 Ingress 实现路由
使用 Kubernetes 的 Ingress 控制器,通过不同的子路径或子域名分配实例。例如:
- 用户 A 访问
http://example.com/user-a
- 用户 B 访问
http://example.com/user-b
示例 Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: openhands-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /user-a
pathType: Prefix
backend:
service:
name: openhands-user-a
port:
number: 80
- path: /user-b
pathType: Prefix
backend:
service:
name: openhands-user-b
port:
number: 80
将上述配置保存为 openhands-ingress.yaml
,然后运行:
kubectl apply -f openhands-ingress.yaml
步骤 3: 接入 Azure AD 实现身份验证
注册 Azure AD 应用
- 登录 Azure Portal。
- 在 Azure AD 中注册一个新的应用:
- 设置重定向 URI,例如
https://example.com/auth/callback
。 - 获取应用的
Client ID
和Client Secret
。
- 设置重定向 URI,例如
- 配置 API 权限,确保应用有
openid
和profile
权限。
配置身份验证中间件
在账户管理系统中,使用支持 OAuth 2.0 或 OIDC 的库(如 Python 的 authlib
)来处理用户登录。
示例代码(Python Flask 应用)
from flask import Flask, redirect, url_for, session
from authlib.integrations.flask_client import OAuth
app = Flask(__name__)
app.secret_key = 'random_secret_key'
oauth = OAuth(app)
azure = oauth.register(
name='azure',
client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
server_metadata_url='https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0/.well-known/openid-configuration',
client_kwargs={
'scope': 'openid profile email',
}
)
@app.route('/')
def home():
return 'Welcome to OpenHands! <a href="/login">Login with Azure AD</a>'
@app.route('/login')
def login():
redirect_uri = url_for('auth_callback', _external=True)
return azure.authorize_redirect(redirect_uri)
@app.route('/auth/callback')
def auth_callback():
token = azure.authorize_access_token()
user_info = token.get('userinfo')
session['user'] = user_info
return f'Hello, {user_info["name"]}!'
if __name__ == '__main__':
app.run()
步骤 4: 用户与 OpenHands 实例的映射
数据库存储映射关系
使用数据库(如 PostgreSQL 或 MongoDB)存储用户与实例的映射。例如:
用户 ID (Azure AD) | OpenHands 实例 URL |
---|---|
user1@domain.com | http://openhands-1.com |
user2@domain.com | http://openhands-2.com |
user3@domain.com | http://openhands-3.com |
动态路由
使用 Ingress 或反向代理(如 Nginx)根据用户的身份动态路由到对应的实例。
示例 Nginx 配置
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://openhands-instance-$user_id;
}
}
注意事项
- 单用户限制:OpenHands 默认是单用户模式。如果需要支持多用户共享一个实例,可能需要对 OpenHands 的代码进行修改。
- 安全性:
- 确保所有通信使用 HTTPS。
- 配置 Azure AD 的权限范围,避免过多权限暴露。
- 扩展性:
- 使用 Kubernetes 的自动扩展功能,根据用户数量动态扩展实例。
- 定期清理未使用的实例,优化资源利用。
通过本教程,您可以成功搭建一个多租户版的 OpenHands 系统。如果您有任何问题或需要进一步的帮助,请随时联系!