# Kubernetes (Helm) 部署指南

本文档介绍如何使用 Helm 在 Kubernetes 集群中部署 MaaS-Base 平台。Helm 方式适合生产环境和大规模部署。

> **注意：** Kubernetes 部署模式下，内嵌 Higress 网关目前为实验性阶段，详见[限制](#限制)部分。

## 前置要求

| 组件 | 版本要求 |
|------|---------|
| Kubernetes | >= v1.30.0 |
| Helm | v3.18.4+ |
| 存储 | 默认 StorageClass（用于 PVC）或配置 hostPath |
| GPU 节点 | Linux 节点，已安装 GPU 驱动和对应 Container Runtime |

---

## 1. 安装 Kubernetes 集群

以下以 k3s 为例，其他发行版（RKE2、kubeadm、云厂商托管 Kubernetes）同样适用。

```bash
# 安装 k3s v1.30.11，禁用 Traefik（使用 Higress 作为 Ingress 控制器）
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.30.11+k3s1 \
    INSTALL_K3S_EXEC="--disable=traefik" sh -
```

验证安装：

```bash
kubectl version
```

> **HA 集群：** 对于高可用 k3s 集群，请参考 [k3s 文档](https://docs.k3s.io/datastore/ha)。

---

## 2. 安装 Helm

如果尚未安装 Helm：

```bash
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
```

---

## 3. 获取 Helm Chart

```bash
git clone https://github.com/your-org/maas-base.git
cd maas-base/charts
```

---

## 4. 部署 MaaS-Base

### 4.1 默认部署（内嵌 Higress 网关）

```bash
helm install -n gpustack-system gpustack ./gpustack --create-namespace
```

此命令会部署以下组件：

- **`gpustack-server`** — StatefulSet（1 副本），含内嵌 PostgreSQL
- **`gpustack-worker`** — DaemonSet，在每个 GPU 节点上运行 Worker
- **`higress`** — Higress 网关（子 Chart），负责 API 路由和负载均衡
- **`higress-plugins`** — Higress 插件服务 Deployment
- **RBAC** — Server 和 Worker 的 ServiceAccount、ClusterRole、ClusterRoleBinding

### 4.2 使用已安装的 Higress

如果集群中已有 Higress，跳过内嵌网关部署：

```bash
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set higress-core.enabled=false \
  --set gateway.ingressClassname=<your-higress-ingressclass>
```

验证 Higress IngressClass 是否存在：

```bash
kubectl get ingressclass higress
# NAME      CONTROLLER                      PARAMETERS   AGE
# higress   higress.io/higress-controller   <none>       3m46s
```

### 4.3 独立安装 Higress

如需单独安装兼容版本的 Higress：

```bash
# 添加 Higress Helm 仓库
helm repo add higress.io https://higress.io/helm-charts

# 安装 higress-core v2.1.9
helm install higress higress.io/higress-core -n higress-system --create-namespace --version 2.1.9
```

---

## 5. 访问 MaaS-Base

### 5.1 获取初始管理员密码

```bash
kubectl exec -it -n gpustack-system gpustack-server-0 -- cat /var/lib/gpustack/initial_admin_password
```

### 5.2 获取访问地址

如果配置了 `server.ingress.hostname`：

```bash
kubectl get ingress -n gpustack-system gpustack
```

否则，通过 Service 的 LoadBalancer IP 访问：

```bash
kubectl get svc -n gpustack-system gpustack-server
```

或使用端口转发临时访问：

```bash
kubectl port-forward -n gpustack-system svc/gpustack-server 8080:80
# 然后访问 http://localhost:8080
```

---

## 6. 自定义配置

### 6.1 使用外部数据库

推荐生产环境使用外部 PostgreSQL 而非内嵌数据库：

```bash
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set server.externalDatabaseURL="postgresql://user:password@db-host:5432/gpustack"
```

### 6.2 配置 TLS

```bash
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set server.ingress.hostname=maas.example.com \
  --set server.ingress.tls.cert="$(cat tls.crt)" \
  --set server.ingress.tls.key="$(cat tls.key)"
```

### 6.3 配置 Worker GPU 厂商

```bash
# NVIDIA GPU（默认）
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set worker.gpuVendor=nvidia

# AMD GPU
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set worker.gpuVendor=amd

# Ascend NPU
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set worker.gpuVendor=ascend
```

支持的 GPU 厂商见 [values.yaml 配置参考](#7-valuesyaml-配置参考)。

### 6.4 使用 hostPath 替代 PVC

如果没有默认 StorageClass，可以使用 hostPath：

```bash
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set server.dataVolume.hostPath=/data/gpustack/server
```

### 6.5 使用自定义镜像

```bash
helm install -n gpustack-system gpustack ./gpustack --create-namespace \
  --set image.repository=my-registry/maas-base \
  --set image.tag=v2.2.0 \
  --set image.pullPolicy=Always
```

### 6.6 完整的自定义 values 文件

```bash
cat > my-values.yaml << 'EOF'
debug: false
server:
  externalDatabaseURL: postgresql://user:password@db-host:5432/gpustack
  ingress:
    hostname: maas.example.com
  apiPort: 30080
  metricsPort: 10161
worker:
  gpuVendor: nvidia
  port: 10150
  metricsPort: 10151
higress-core:
  enabled: true
  global:
    hub: docker.io/gpustack
EOF

helm install -n gpustack-system gpustack ./gpustack --create-namespace -f my-values.yaml
```

---

## 7. values.yaml 配置参考

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `debug` | `false` | 启用调试模式 |
| `registrationToken` | `null` | Worker 注册令牌，null 时自动生成 |
| `systemDefaultContainerRegistry` | `null` | 默认镜像仓库前缀 |
| `image.repository` | `gpustack/gpustack` | 镜像仓库 |
| `image.tag` | `null` | 镜像标签，默认使用 Chart 的 appVersion |
| `image.pullPolicy` | `IfNotPresent` | 镜像拉取策略 |
| `server.ingress.hostname` | `null` | Ingress 主机名 |
| `server.ingress.tls.cert` | `null` | TLS 证书内容 |
| `server.ingress.tls.key` | `null` | TLS 私钥内容 |
| `server.externalDatabaseURL` | `null` | 外部数据库连接串 |
| `server.dataVolume.hostPath` | `null` | Server 数据 hostPath |
| `server.dataVolume.size` | `10Gi` | Server 数据 PVC 大小 |
| `server.apiPort` | `30080` | API 服务端口 |
| `server.metricsPort` | `10161` | 指标端口 |
| `server.environmentConfig` | `{}` | Server 额外环境变量 |
| `gateway.ingressClassname` | `higress` | Higress IngressClass 名称 |
| `higress-core.enabled` | `true` | 是否部署 Higress 子 Chart |
| `higress-core.global.ingressClass` | `higress` | 需匹配 `gateway.ingressClassname` |
| `higress-core.global.enablePluginServer` | `false` | GPUStack 自行管理插件 |
| `higress-core.global.hub` | `docker.io/gpustack` | Higress 镜像仓库 |
| `higressPlugins.image.repository` | `gpustack/higress-plugins` | Higress 插件镜像仓库 |
| `higressPlugins.image.tag` | `"0.2.0"` | Higress 插件镜像标签 |
| `worker.enabled` | `true` | 启用 Worker 节点 |
| `worker.gpuVendor` | `nvidia` | GPU 厂商 |
| `worker.port` | `10150` | Worker 服务端口 |
| `worker.metricsPort` | `10151` | Worker 指标端口 |
| `worker.environmentConfig` | `{}` | Worker 额外环境变量 |
| `worker.dataDir` | `/var/lib/gpustack` | Worker 数据目录 |
| `worker.extraVolumeMounts` | `[]` | Worker 额外卷挂载 |
| `worker.extraVolumes` | `[]` | Worker 额外卷 |

### GPU 厂商配置值

| `worker.gpuVendor` | 适用硬件 | 特殊处理 |
|---------------------|---------|---------|
| `nvidia` | NVIDIA GPU | runtimeClassName: nvidia |
| `mthreads` | Moore Threads GPU | runtimeClassName: mthreads |
| `amd` | AMD GPU (ROCm) | 挂载 `/opt/rocm` |
| `ascend` | Huawei Ascend NPU | 挂载 `/usr/local/Ascend/driver` 和 `/usr/local/Ascend/ascend-toolkit` |
| `hygon` | Hygon DCU | 挂载 `/opt/hyhal` 和 `/opt/dtk` |
| `metax` | MetaX GPU | 挂载 `/opt/mxdriver` 和 `/opt/maca` |
| `iluvatar` | Iluvatar GPU | 挂载 `/usr/local/corex` |
| `cambricon` | Cambricon MLU | 挂载 `/usr/bin/cnmon` 和 `/usr/local/neuware` |
| `thead` | T-Head PPU | 挂载 `/usr/local/PPU_SDK` |
| `null` | CPU-only | 无特殊处理 |

---

## 8. 更新与卸载

### 8.1 更新

```bash
# 更新 Chart
helm upgrade -n gpustack-system gpustack ./gpustack

# 使用新 values 更新
helm upgrade -n gpustack-system gpustack ./gpustack -f my-values.yaml
```

### 8.2 卸载

```bash
helm uninstall -n gpustack-system gpustack
```

> **注意：** 卸载 Helm release 不会删除 PVC 中的数据。如需完全清理：
>
> ```bash
> kubectl delete pvc -n gpustack-system -l app=gpustack-server
> ```

---

## 9. 限制

- **Server 不支持多副本：** Server 以 StatefulSet 部署，目前仅支持 1 个副本
- **内嵌 PostgreSQL：** 默认使用内嵌嵌入式 PostgreSQL，推荐使用 `server.externalDatabaseURL` 配置外部数据库
- **PVC 要求：** StatefulSet 使用 `volumeClaimTemplates`（默认 10Gi），需配置默认 StorageClass；或使用 `server.dataVolume.hostPath` 指定 hostPath
- **Higress 插件依赖：** Higress 网关重启时会从 `gpustack/higress-plugins` Deployment 下载插件，该服务不可用时会阻塞网关启动
- **现有 Ingress 控制器冲突：** 如果集群中已有其他 Ingress 控制器，需设置 `higress-core.enabled=false` 并配置 `gateway.ingressClassname`

---

## 10. 端口说明

| 端口 | 组件 | 用途 |
|------|------|------|
| `30080` | Server API | REST API + Web UI（NodePort/Ingress） |
| `10161` | Server Metrics | Prometheus 指标 |
| `10150` | Worker | Worker 通信端口 |
| `10151` | Worker Metrics | Worker 指标 |

---

## 下一步

- 部署模型 → [快速开始](../README.md#快速开始)
- Docker Compose 部署方式 → [Docker Compose 部署指南](./docker-compose.md)
- Worker 节点独立部署 → [Worker 节点部署指南](./worker.md)
