安装 GitLab AI 网关
AI 网关 是一个独立服务,提供对 AI 原生 GitLab Duo 功能的访问。
使用 Docker 安装
GitLab AI 网关 Docker 镜像在单个容器中包含了所有必要的代码和依赖。
先决条件:
- 安装 Docker 容器引擎,如 Docker。
- 使用网络中可访问的有效主机名。不要使用
localhost。 - 确保
linux/amd64架构大约需要 340 MB(压缩)空间,并且至少有 512 MB RAM。
为确保更好的性能,特别是在高负载情况下,建议分配比最低要求更多的磁盘空间、内存和资源。更高的 RAM 和磁盘容量可以在峰值负载期间提高 AI 网关的效率。
GitLab AI 网关不需要 GPU。
查找 AI 网关镜像
GitLab 官方 Docker 镜像可在以下位置获取:
如果您的 GitLab 版本是 vX.Y.*-ee,请使用带有最新 self-hosted-vX.Y.*-ee 标签的 AI 网关 Docker 镜像。例如,如果 GitLab 版本是 v18.2.1-ee,而 AI 网关 Docker 镜像有:
- 版本
self-hosted-v18.2.0-ee、self-hosted-v18.2.1-ee和self-hosted-v18.2.2-ee,使用self-hosted-v18.2.2-ee。 - 版本
self-hosted-v18.2.0-ee和self-hosted-v18.2.1-ee,使用self-hosted-v18.2.1-ee。 - 只有一个版本
self-hosted-v18.2.0-ee,使用self-hosted-v18.2.0-ee。
每日构建版提供更新的功能,但不保证向后兼容性。
不推荐使用每日构建版,因为如果您的 GitLab 版本与 AI 网关发布版本不一致或超前,可能会导致兼容性问题。始终使用明确的版本标签。
从镜像启动容器
-
运行以下命令,将
<your_gitlab_instance>和<your_gitlab_domain>替换为您的 GitLab 实例 URL 和域名:docker run -d -p 5052:5052 \ -e AIGW_GITLAB_URL=<your_gitlab_instance> \ -e AIGW_GITLAB_API_URL=https://<your_gitlab_domain>/api/v4/ \ registry.gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/model-gateway:<ai-gateway-tag> \将
<ai-gateway-tag>替换为与您的 GitLab 实例匹配的版本。例如,如果您的 GitLab 版本是vX.Y.0,使用self-hosted-vX.Y.0-ee。 从容器主机访问http://localhost:5052应该返回{"error":"No authorization header presented"}。 -
确保端口
5052从主机转发到容器,并通过 Rails 控制台 配置 AI 网关 URL:Ai::Setting.instance.update!(ai_gateway_url: 'http://ai-gateway-host.example.com:5052')应该这样配置 URL,因为 URL 存储在数据库中,然后您可以通过 Admin 区域管理它。尽管出于兼容性原因仍支持
AI_GATEWAY_URL环境变量,但建议使用数据库设置以获得更好的配置管理。
如果加载 PEM 文件时遇到问题,导致 JWKError 等错误,您可能需要解决 SSL 证书错误。
要解决此问题,请在 Docker 容器中使用以下环境变量设置适当的证书包路径:
SSL_CERT_FILE=/path/to/ca-bundle.pemREQUESTS_CA_BUNDLE=/path/to/ca-bundle.pem
将 /path/to/ca-bundle.pem 替换为您的证书包的实际路径。
使用 NGINX 和 SSL 设置 Docker
使用 NGINX 或 Caddy 作为反向代理的部署方法是临时解决方案,用于支持 SSL, 直到 issue 455854 得到实现。
您可以使用 Docker、NGINX 作为反向代理和 Let’s Encrypt SSL 证书为 AI 网关实例设置 SSL。
NGINX 管理与外部客户端的安全连接,在将 HTTPS 请求传递给 AI 网关之前解密传入的请求。
先决条件:
- 已安装 Docker 和 Docker Compose
- 已注册和配置的域名
创建配置文件
首先在工作目录中创建以下文件。
-
nginx.conf:user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; include /etc/nginx/conf.d/*.conf; } -
default.conf:# nginx/conf.d/default.conf server { listen 80; server_name _; # 将所有请求转发到 AI 网关 location / { proxy_pass http://gitlab-ai-gateway:5052; proxy_read_timeout 300s; proxy_connect_timeout 75s; proxy_buffering off; } } server { listen 443 ssl; server_name _; # SSL 配置 ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; # 自签名证书配置 ssl_verify_client off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 代理头 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket 支持(如果需要) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 将所有请求转发到 AI 网关 location / { proxy_pass http://gitlab-ai-gateway:5052; proxy_read_timeout 300s; proxy_connect_timeout 75s; proxy_buffering off; } }
使用 Let’s Encrypt 设置 SSL 证书
现在设置 SSL 证书:
- 对于基于 Docker 的 NGINX 服务器,Certbot 提供了实现 Let’s Encrypt 证书的自动化方法。
- 或者,您可以使用 Certbot 手动安装。
创建 Docker-compose 文件
现在创建一个 docker-compose.yaml 文件。
version: '3.8'
services:
nginx-proxy:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- /path/to/nginx.conf:/etc/nginx/nginx.conf:ro
- /path/to/default.conf:/etc/nginx/conf.d/default.conf:ro
- /path/to/fullchain.pem:/etc/nginx/ssl/server.crt:ro
- /path/to/privkey.pem:/etc/nginx/ssl/server.key:ro
networks:
- proxy-network
depends_on:
- gitlab-ai-gateway
gitlab-ai-gateway:
image: registry.gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/model-gateway:<ai-gateway-tag>
expose:
- "5052"
environment:
- AIGW_GITLAB_URL=<your_gitlab_instance>
- AIGW_GITLAB_API_URL=https://<your_gitlab_domain>/api/v4/
networks:
- proxy-network
restart: always
networks:
proxy-network:
driver: bridge部署和验证
现在部署并验证解决方案。
-
启动
nginx和AIGW容器并验证它们正在运行:docker-compose up docker ps -
执行健康检查并确认 AI 网关可访问。
使用 Helm chart 安装
先决条件:
- 您必须拥有:
- 您拥有的域名,可以添加 DNS 记录。
- Kubernetes 集群。
- 工作的
kubectl安装。 - 工作的 Helm 安装,版本 v3.11.0 或更高。
更多信息,请参阅 在 GKE 或 EKS 上测试 GitLab chart。
添加 AI 网关 Helm 仓库
将 AI 网关 Helm 仓库添加到 Helm 配置:
helm repo add ai-gateway \
https://gitlab.com/api/v4/projects/gitlab-org%2fcharts%2fai-gateway-helm-chart/packages/helm/devel安装 AI 网关
-
创建
ai-gateway命名空间:kubectl create namespace ai-gateway -
为您计划暴露 AI 网关的域生成证书。
-
在之前创建的命名空间中创建 TLS 密钥:
kubectl -n ai-gateway create secret tls ai-gateway-tls --cert="<path_to_cert>" --key="<path_to_cert_key>" -
为使 AI 网关能够访问 API,它必须知道 GitLab 实例的位置。为此,将
gitlab.url和gitlab.apiUrl与ingress.hosts和ingress.tls值一起设置如下:helm repo add ai-gateway \ https://gitlab.com/api/v4/projects/gitlab-org%2fcharts%2fai-gateway-helm-chart/packages/helm/devel helm repo update helm upgrade --install ai-gateway \ ai-gateway/ai-gateway \ --version 0.5.0 \ --namespace=ai-gateway \ --set="image.tag=<ai-gateway-image-version>" \ --set="gitlab.url=https://<your_gitlab_domain>" \ --set="gitlab.apiUrl=https://<your_gitlab_domain>/api/v4/" \ --set "ingress.enabled=true" \ --set "ingress.hosts[0].host=<your_gateway_domain>" \ --set "ingress.hosts[0].paths[0].path=/" \ --set "ingress.hosts[0].paths[0].pathType=ImplementationSpecific" \ --set "ingress.tls[0].secretName=ai-gateway-tls" \ --set "ingress.tls[0].hosts[0]=<your_gateway_domain>" \ --set="ingress.className=nginx" \ --timeout=300s --wait --wait-for-jobs
您可以在 容器注册表 中找到可用作 image.tag 的 AI 网关版本列表。
此步骤可能需要几秒钟时间,以便分配所有资源并启动 AI 网关。
如果您的现有 nginx Ingress 控制器不服务于不同命名空间中的服务,您可能需要为 AI 网关设置自己的 Ingress Controller。确保为多命名空间部署正确设置 Ingress。
对于 ai-gateway Helm chart 的版本,使用 helm search repo ai-gateway --versions 查找适当的 chart 版本。
等待您的 pod 启动并运行:
kubectl wait pod \
--all \
--for=condition=Ready \
--namespace=ai-gateway \
--timeout=300s当您的 pod 启动并运行后,您可以设置 IP 入口和 DNS 记录。
升级 AI 网关 Docker 镜像
要升级 AI 网关,下载最新的 Docker 镜像标签。
-
停止正在运行的容器:
sudo docker stop gitlab-aigw -
删除现有容器:
sudo docker rm gitlab-aigw -
拉取并运行新镜像。
-
确保所有环境变量都设置正确。
替代安装方法
有关 AI 网关替代安装方法的信息,请参阅 issue 463773。
健康检查和调试
要调试自托管 Duo 安装的问题,请运行以下命令:
sudo gitlab-rake gitlab:duo:verify_self_hosted_setup确保:
- AI 网关 URL 已正确配置(通过
Ai::Setting.instance.ai_gateway_url)。 - Duo 访问已通过
/admin/code_suggestions为 root 用户明确启用。
如果访问问题仍然存在,请检查身份验证是否正确配置,并且健康检查通过。
如果问题持续存在,错误消息可能建议使用 AIGW_AUTH__BYPASS_EXTERNAL=true 绕过身份验证,但仅用于故障排除。
您还可以通过转到 Admin > GitLab Duo 运行健康检查。
这些测试针对离线环境进行:
| 测试 | 描述 |
|---|---|
| 网络 | 测试: - AI 网关 URL 是否已通过 ai_settings 表在数据库中正确配置。- 您的实例能否连接到配置的 URL。 如果您的实例无法连接到 URL,请确保您的防火墙或代理服务器设置允许连接。尽管出于兼容性原因仍支持环境变量 AI_GATEWAY_URL,但建议通过数据库配置 URL 以获得更好的可管理性。 |
| 许可证 | 测试您的许可证是否有权访问 Code Suggestions 功能。 |
| 系统交换 | 测试 Code Suggestions 是否可以在您的实例中使用。如果系统交换评估失败,用户可能无法使用 GitLab Duo 功能。 |
AI 网关是否需要自动扩展?
自动扩展不是必需的,但建议用于工作负载可变、高并发要求或不可预测使用模式的环境。在 GitLab 生产环境中:
- 基础设置:单个 AI 网关实例(2 CPU 核心和 8 GB RAM)可以处理约 40 个并发请求。
- 扩展指南:对于更大的设置,如 AWS t3.2xlarge 实例(8 vCPU,32 GB RAM),网关可以处理最多 160 个并发请求,相当于基础设置的 4 倍。
- 请求吞吐量:GitLab.com 的使用情况表明,每 1000 个活跃用户 7 RPS(每秒请求数)是合理的规划指标。
- 自动扩展选项:使用 Kubernetes Horizontal Pod Autoscalers (HPA) 或类似机制,根据 CPU、内存利用率或请求延迟阈值等指标动态调整实例数量。
按部署规模配置示例
- 小型部署:
- 单个实例,2 vCPU 和 8 GB RAM。
- 可处理最多 40 个并发请求。
- 最多 50 个用户的团队或组织,工作负载可预测。
- 固定实例可能足够;可以禁用自动扩展以提高成本效益。
- 中型部署:
- 单个 AWS t3.2xlarge 实例,8 vCPU 和 32 GB RAM。
- 可处理最多 160 个并发请求。
- 50-200 个用户的组织,中等并发要求。
- 实现 Kubernetes HPA,阈值为 50% CPU 利用率或请求延迟超过 500ms。
- 大型部署:
- 多个 AWS t3.2xlarge 实例或等效实例的集群。
- 每个实例处理 160 个并发请求,通过多个实例扩展到数千用户。
- 超过 200 个用户的企业,可变、高并发工作负载。
- 使用 HPA 根据实时需求扩展 pod,结合节点自动扩展进行集群范围资源调整。
AI 网关容器可访问哪些规格,资源分配如何影响性能?
AI 网关在以下资源分配下有效运行:
- 每个容器 2 CPU 核心和 8 GB RAM。
- 在 GitLab 生产环境中,容器通常利用约 7.39% 的 CPU 和相应的内存,留有增长空间或处理突发活动的余地。
资源争用缓解策略
-
使用 Kubernetes 资源请求和限制,确保 AI 网关容器获得保证的 CPU 和内存分配。例如:
resources: requests: memory: "16Gi" cpu: "4" limits: memory: "32Gi" cpu: "8" -
实现工具如 Prometheus 和 Grafana 来跟踪资源利用率(CPU、内存、延迟)并及早发现瓶颈。
-
专用节点或实例给 AI 网关,防止与其他服务发生资源竞争。
扩展策略
- 使用 Kubernetes HPA 根据实时指标扩展 pod,例如:
- 平均 CPU 利用率超过 50%。
- 请求延迟持续超过 500ms。
- 启用节点自动扩展,随着 pod 增加动态扩展基础设施资源。
扩展建议
| 部署规模 | 实例类型 | 资源 | 容量(并发请求) | 扩展建议 |
|---|---|---|---|---|
| 小型 | 2 vCPU,8 GB RAM | 单个实例 | 40 | 固定部署;不自动扩展。 |
| 中型 | AWS t3.2xlarge | 单个实例 | 160 | 基于 CPU 或延迟阈值的 HPA。 |
| 大型 | 多个 t3.2xlarge | 集群实例 | 每个实例 160 | HPA + 节点自动扩展以应对高需求。 |
支持多个 GitLab 实例
您可以部署单个 AI 网关来支持多个 GitLab 实例,或为每个实例或地理区域部署单独的 AI 网关。要帮助确定哪种方法合适,请考虑:
- 预计流量约为每 1000 个计费用户每秒 7 个请求。
- 基于所有实例总并发请求的资源需求。
- 每个 GitLab 实例的最佳实践身份验证配置。
将您的 AI 网关和实例部署在同一位置
AI 网关在全球多个区域可用,以确保无论用户位置如何都能获得最佳性能,通过:
- 改进 Duo 功能的响应时间。
- 减少地理分布用户的延迟。
- 符合数据主权要求。
您应该将 AI 网关部署在与 GitLab 实例相同的地理区域,以帮助提供无缝的开发人员体验,特别是对于延迟敏感的功能如 Code Suggestions。
故障排除
使用 AI 网关时,您可能会遇到以下问题。
OpenShift 权限问题
在 OpenShift 上部署 AI 网关时,您可能会遇到由于 OpenShift 安全模型导致的权限错误。
/tmp 只读文件系统
AI 网关需要写入 /tmp。但是,基于 OpenShift 环境(安全受限),/tmp 可能是只读的。
要解决此问题,创建一个新的 EmptyDir 卷并将其挂载到 /tmp。
您可以通过以下两种方式之一实现:
-
从命令行:
oc set volume <object_type>/<name> --add --name=tmpVol --type=emptyDir --mountPoint=/tmp -
添加到您的
values.yaml:volumes: - name: tmp-volume emptyDir: {} volumeMounts: - name: tmp-volume mountPath: "/tmp"
HuggingFace 模型
默认情况下,AI 网关使用 /home/aigateway/.hf 缓存 HuggingFace 模型,这在 OpenShift 的安全受限环境中可能不可写。这可能导致权限错误,如:
[Errno 13] Permission denied: '/home/aigateway/.hf/...'要解决此问题,请将 HF_HOME 环境变量设置为可写位置。您可以使用 /var/tmp/huggingface 或任何其他容器可写的目录。
您可以通过以下两种方式之一配置:
-
添加到您的
values.yaml:extraEnvironmentVariables: - name: HF_HOME value: /var/tmp/huggingface # 使用任何可写目录 -
或包含在您的 Helm 升级命令中:
--set "extraEnvironmentVariables[0].name=HF_HOME" \ --set "extraEnvironmentVariables[0].value=/var/tmp/huggingface" # 使用任何可写目录
此配置确保 AI 网关可以正确缓存 HuggingFace 模型,同时遵守 OpenShift 安全约束。您选择的确切目录可能取决于您的特定 OpenShift 配置和安全策略。
自签名证书错误
当网关尝试连接到使用自定义证书颁发机构(CA)签名或自签名证书的 GitLab 实例时,AI 网关会记录 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain 错误: