# 集群管理

本指南涵盖集群级别的管理操作：将基础安装加固为生产部署、日常生命周期操作（扩展、升级、动态配置）和多租户。关于作业提交、调度和 Coordinator HA，请参阅 [Job Service](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-job-service.md)。关于哈希环相关操作（Worker 生命周期、身份持久化、环膨胀），请参阅 [哈希环与 Worker 生命周期](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-ring.md)。关于单个 Worker 的配置（存储、资源、JVM、网络），请参阅 [Worker 配置](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-worker.md)。

## 1. 生产部署配置

[Kubernetes 安装](/ee-ai-cn/ai-3.8-15.1.x-cn/start/installing-on-kubernetes.md)指南中展示的基础配置适用于评估场景。生产部署需要在此基础上追加以下配置，以实现高可用、资源调优、持久化元数据和 Worker 身份持久化。

### 标记节点

通常的做法是为每个 Alluxio 组件分配专用节点。这可以防止组件之间的资源竞争（例如 ETCD I/O 干扰 Worker 缓存 I/O），并为容量规划提供可预测的调度位置。

```shell
kubectl label nodes <coordinator-node> alluxio-role=coordinator
kubectl label nodes <worker-node-1> alluxio-role=worker
kubectl label nodes <worker-node-2> alluxio-role=worker
kubectl label nodes <worker-node-3> alluxio-role=worker
kubectl label nodes <etcd-node-1> alluxio-role=etcd
kubectl label nodes <etcd-node-2> alluxio-role=etcd
kubectl label nodes <etcd-node-3> alluxio-role=etcd
```

Worker pod 默认具有反亲和规则——多个 Worker pod 不会被调度到同一节点。

### 生产 `alluxio-cluster.yaml`

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
metadata:
  name: alluxio-cluster
  namespace: alx-ns
spec:
  image: <PRIVATE_REGISTRY>/alluxio-enterprise
  imageTag: AI-3.8-15.1.0
  properties:
    alluxio.license: <YOUR_CLUSTER_LICENSE>
  coordinator:
    nodeSelector:
      alluxio-role: coordinator
    metastore:
      type: persistentVolumeClaim
      storageClass: "gp2"
      size: 4Gi
    resources:
      # 与 Worker 一样，将 requests 设为与 limits 相同，进入 Guaranteed QoS 级别。
      limits:
        cpu: "8"
        memory: "16Gi"
      requests:
        cpu: "8"
        memory: "16Gi"
    jvmOptions:
      - "-Xmx8g"
      - "-Xms8g"
  worker:
    nodeSelector:
      alluxio-role: worker
    count: 3
    pagestore:
      size: 1000Gi
      reservedSize: 100Gi
    resources:
      # 将 requests 与 limits 设为相同的值，使 Worker 进入 Guaranteed QoS 级别，
      # 在节点资源紧张时被驱逐的优先级最低。
      limits:
        cpu: "8"
        memory: "24Gi"
      requests:
        cpu: "8"
        memory: "24Gi"
    jvmOptions:
      - "-Xmx12g"
      - "-Xms12g"
      - "-XX:MaxDirectMemorySize=12g"
  etcd:
    replicaCount: 3
    nodeSelector:
      alluxio-role: etcd
```

与基本配置的主要区别：

* **节点选择器**：将每个组件固定到专用节点，防止资源竞争并确保可预测的调度位置。请参阅上方的标记命令。
* **Worker 数量**：根据目标缓存容量和目标吞吐量确定 Worker 数量。部署后的扩缩容指南请参阅 [扩展集群](#kuo-zhan-ji-qun)。
* **ETCD 副本数**：3 个，用于基于仲裁的高可用。部署在专用的稳定节点上。
* **资源限制和 JVM 选项**：显式设置以防止 OOM。容器内存限制必须超过 `-Xmx` 和 `-XX:MaxDirectMemorySize` 之和。对于 Worker 和 Coordinator，均建议将 `requests` 设为与 `limits` 相同——这会使 Pod 进入 [Guaranteed QoS 级别](https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/)，在节点出现内存或 CPU 压力时最后才会被驱逐。Burstable 的 Pod（requests < limits）即使自身未超限，也可能因其他 Pod 超出 request 而被驱逐，导致缓存突然丢失（Worker）或调度中断（Coordinator）。
* **持久化 metastore**：Coordinator 元数据在 pod 重启后得以保留。

其他重要设置：

* **许可证管理**：集群许可证是入门的最简单方法。对于生产环境，建议使用**部署许可证**。有关两种选项的详细信息，请参阅 [附录 C：许可证管理](https://documentation.alluxio.io/ee-ai-cn/ai-3.8-15.1.x-cn/administration/pages/u6NKmbvIV7CjUn3lzlvL#c.-xu-ke-zheng-guan-li)。
* **哈希环配置**：在部署**之前**配置哈希环至关重要，因为后续更改可能是破坏性的。详细指南请参阅 [哈希环部署前配置](https://documentation.alluxio.io/ee-ai-cn/ai-3.8-15.1.x-cn/administration/pages/fe2L5cgviojA997ler3h#id-1.-bu-shu-qian-pei-zhi)。
* **Worker 身份持久化**：配置 `worker.systemInfo.hostPath`，使 Worker 重启后以相同 UUID 重新加入。若未配置，每次重启都会在哈希环中累积过期 `OFFLINE` 条目，导致缓存命中率下降。参见 [重启 Worker](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-ring.md#zhong-qi-worker)。
* **异构集群**：如果您的集群包含不同容量的 Worker，则必须定义特定的数据分发策略。配置步骤请参阅 [异构 Worker](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-worker.md#yi-gou-worker)。
* **Worker Page Store**：[page store](https://documentation.alluxio.io/ee-ai-cn/ai-3.8-15.1.x-cn/administration/pages/Wn3y11xQd8qYMq3DfLRF#id-5.-worker-cun-chu-page-store) 是每个 Worker 缓存数据的位置。关键默认值和选项：
  * **默认值**：`type: hostPath`、`hostPath: /mnt/alluxio/pagestore`。Worker 将缓存写入节点文件系统上的该路径。在多盘节点上，请确认该路径位于数据盘而非系统盘。
  * **多盘节点**：显式将 `pagestore.hostPath` 设置为数据盘路径（例如 `/mnt/data1/alluxio/pagestore`）。多盘配置示例请参阅 [多盘配置](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-worker.md#duo-pan-pei-zhi)。
  * **缓存跨 pod 重启存活**：使用 PVC 代替 hostPath。参见 [配置 Page Store 位置](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-worker.md#pei-zhi-page-store-wei-zhi)。
  * **容量规划**：`size` 参数设置缓存容量；`reservedSize` 为内部操作（临时页面写入、文件元数据缓存）分配空间。建议将 `reservedSize` 设置为 `size` 的约 10%（10–100 GiB），并确保总大小（size + reservedSize）适合 Worker 的存储空间。缓存总容量建议设置为**工作集大小的 110%–120%**（即需要保持热数据的数据集大小）。Alluxio 默认在使用率达到高水位阈值（默认为 `size` 的 90%）时开始驱逐数据，预留 10–20% 的余量可以避免在 load job 高峰期驱逐正在使用的数据。
* **高级配置**：关于资源和 JVM 调优，请参阅 [Worker 配置 — 资源与 JVM 调优](https://documentation.alluxio.io/ee-ai-cn/ai-3.8-15.1.x-cn/administration/pages/3I91A2lVU1eLtHtKSj6F#id-2.-zi-yuan-yu-jvm-diao-you)。关于其他设置（如外部 etcd），请参阅 [附录 B：高级配置](https://documentation.alluxio.io/ee-ai-cn/ai-3.8-15.1.x-cn/administration/pages/u6NKmbvIV7CjUn3lzlvL#b.-gao-ji-pei-zhi)。

### 在共享节点上运行多个集群

若在同一个 Kubernetes 集群的不同 namespace 下部署多个 Alluxio 集群，不同集群的服务可能被调度到同一节点，导致部署失败。可以为节点打标签以标识其所属集群：

```shell
kubectl label nodes <node-name> cluster=alluxio-a
kubectl label nodes <node-name> cluster=alluxio-b
```

然后在每个 `alluxio-cluster.yaml` 的集群级别指定 `nodeSelector`：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  image: <PRIVATE_REGISTRY>/alluxio-enterprise
  imageTag: AI-3.8-15.1.0
  nodeSelector:
    cluster: alluxio-a
```

## 2. 集群生命周期和配置

本节涵盖与集群生命周期相关的基本操作，如扩展、升级和动态配置更新。

### 扩展集群

Alluxio 使用一致性哈希环将文件映射到 Worker。添加或移除 Worker 会重新分片哈希环——原本映射到现有 Worker 的部分文件会重新映射到新 Worker（或在缩容后映射到其他 Worker），这些槽位初始缓存为空。因此，**扩缩容操作必须与运行中的 load job 协调进行**，以避免缓存覆盖缺口。

{% hint style="warning" %}
扩缩容前必须先停止运行中的 load job。在哈希环拓扑变更过程中运行的 load job 可能导致缓存覆盖不完整——扩容后重新映射到新 Worker 的文件将无法被加载。
{% endhint %}

#### 扩容（增加 Worker）

**步骤 1：停止所有运行中的 load job。**

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
# 列出运行中的 job
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job list --job-type LOAD --job-state RUNNING
# 预期：无运行中 job 时输出为空

# 按路径停止每个运行中的 job
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job load --path <path> --stop
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio job list --job-type LOAD --job-state RUNNING
# 预期：无运行中 job 时输出为空

bin/alluxio job load --path <path> --stop
```

{% endtab %}
{% endtabs %}

**步骤 2：增加 worker 数量并应用。**

修改 `alluxio-cluster.yaml`，增加 `worker.count`（示例：2 → 3）：

```shell
kubectl apply -f alluxio-cluster.yaml
```

```console
alluxiocluster.k8s-operator.alluxio.com/alluxio-cluster configured
```

**步骤 3：等待所有 Worker 就绪。**

```shell
kubectl -n alx-ns get pod -l app.kubernetes.io/component=worker
```

```console
NAME                                          READY   STATUS    RESTARTS   AGE
alluxio-cluster-worker-58999f8ddd-cd6r2       1/1     Running   0          5m21s
alluxio-cluster-worker-58999f8ddd-rtftk       1/1     Running   0          4m21s
alluxio-cluster-worker-58999f8ddd-p6n59       1/1     Running   0          34s
```

或使用超时等待：

```shell
kubectl -n alx-ns wait pod -l app.kubernetes.io/component=worker \
  --for=condition=Ready --timeout=300s
```

**步骤 4：重新触发数据加载。**

重新分片后，新 Worker 没有任何缓存数据——映射到它的文件的客户端请求将从 UFS 提供，直到被加载。现有 Worker 上的数据**不会自动删除或迁移**；映射到新 Worker 的那些文件在旧 Worker 上成为孤儿副本，不再被路由访问，会通过 LRU 自然淘汰。

根据缓存容量情况选择策略：

| 情况                        | 命令                          | 效果                                      |
| ------------------------- | --------------------------- | --------------------------------------- |
| 缓存有富余空间；可以等待孤儿副本自然淘汰      | `job load --skip-if-exists` | 从 UFS 将缺失文件加载到新 Worker；不影响旧 Worker      |
| 缓存空间紧张，或需要立即释放旧 Worker 空间 | `job rebalance`             | 从现有 Worker（而非 UFS）复制数据到新 Worker，并删除孤儿副本 |

**方案 A — `job load --skip-if-exists`**

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job load --path <ufs-or-alluxio-path> --submit --skip-if-exists

# 监控直到 SUCCEEDED
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job load --path <ufs-or-alluxio-path> --progress
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio job load --path <ufs-or-alluxio-path> --submit --skip-if-exists

# 监控直到 SUCCEEDED
bin/alluxio job load --path <ufs-or-alluxio-path> --progress
```

{% endtab %}
{% endtabs %}

**方案 B — `job rebalance`（主动均衡）**

`job rebalance` 分为两个阶段：**load 阶段**（从现有 Worker 复制数据到新 Worker）和 **prune 阶段**（删除旧 Worker 上的孤儿副本）。如有训练负载并发运行，可用 `--load-bandwidth` / `--prune-bandwidth` 限速。使用 `--skip-prune` 可跳过删除阶段，让 LRU 自然处理。

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job rebalance --submit --target ALL

# 监控直到 SUCCEEDED
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job rebalance --progress --target ALL
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio job rebalance --submit --target ALL

# 监控直到 SUCCEEDED
bin/alluxio job rebalance --progress --target ALL
```

{% endtab %}
{% endtabs %}

#### 缩容（减少 Worker）

**步骤 1：停止所有运行中的 load job**（同扩容步骤 1）。

**步骤 2：减少 worker 数量并应用。**

```shell
kubectl apply -f alluxio-cluster.yaml
```

等待被移除的 Worker Pod 终止：

```shell
kubectl -n alx-ns wait pod -l app.kubernetes.io/component=worker \
  --for=delete --timeout=120s
```

缩容会从哈希环中移除 Worker。其缓存数据将变为不可访问并最终被驱逐。仅缓存在被移除 Worker 上的文件将从 UFS 提供服务，直到通过被动缓存或新的 `job load` 重新加载。

**步骤 3：可选——注销过期的 Worker 条目。**

在动态模式（默认）下，`OFFLINE` 条目会在 `alluxio.worker.failure.detection.timeout` 超时后自动清除。在静态模式下，需要对每个已下线的 Worker 运行 `alluxio process remove-worker`——详情参阅 [永久移除 Worker](/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-ring.md#yong-jiu-yi-chu-worker)。

### 升级 Alluxio

升级过程包括两个主要步骤：升级 Alluxio Operator，然后升级 Alluxio 集群本身。

#### 步骤 1：升级 Operator

Operator 是无状态的，可以安全地重新安装，而不会影响正在运行的 Alluxio 集群。

1. 获取 Operator 的新 Docker 镜像和新的 Helm chart。
2. 卸载旧的 Operator 并安装新的。

卸载当前的 Operator：

```shell
helm -n alluxio-operator uninstall operator --wait
```

```console
release "operator" uninstalled
```

从新的 Helm chart 目录创建和替换新的 CRD：

```shell
kubectl create -f alluxio-operator/crds
kubectl replace -f alluxio-operator/crds
```

```console
customresourcedefinition.apiextensions.k8s.io/alluxioclusters.k8s-operator.alluxio.com replaced
customresourcedefinition.apiextensions.k8s.io/clustergroups.k8s-operator.alluxio.com replaced
customresourcedefinition.apiextensions.k8s.io/collectinfoes.k8s-operator.alluxio.com replaced
customresourcedefinition.apiextensions.k8s.io/licenses.k8s-operator.alluxio.com replaced
customresourcedefinition.apiextensions.k8s.io/underfilesystems.k8s-operator.alluxio.com replaced
```

使用您的配置文件安装新的 Operator（更新镜像标签）：

```shell
helm -n alluxio-operator install operator -f alluxio-operator.yaml --create-namespace .
```

#### 步骤 2：升级 Alluxio 集群

Operator 将对 Alluxio 组件执行滚动升级。

1. 将新的 Alluxio Docker 镜像上传到您的注册表。
2. 将 `alluxio-cluster.yaml` 中的 `imageTag` 更新为新版本。
3. 应用配置更改。

应用更新后的集群定义：

```shell
kubectl apply -f alluxio-cluster.yaml
```

```console
alluxiocluster.k8s-operator.alluxio.com/alluxio-cluster configured
```

监控滚动升级过程：

```shell
kubectl -n alx-ns get pod
```

```console
NAME                                          READY   STATUS     RESTARTS   AGE
alluxio-cluster-coordinator-0                 0/1     Init:0/2   0          7s
...
alluxio-cluster-worker-58999f8ddd-cd6r2       0/1     Init:0/2   0          7s
alluxio-cluster-worker-5d6786f5bf-cxv5j       1/1     Running    0          10m
```

检查集群状态，直到其返回 'Ready'：

```shell
kubectl -n alx-ns get alluxiocluster
```

```console
NAME              CLUSTERPHASE   AGE
alluxio-cluster   Updating       10m
...
NAME              CLUSTERPHASE   AGE
alluxio-cluster   Ready          12m
```

验证新版本是否正在运行：

```shell
kubectl -n alx-ns exec -it alluxio-cluster-coordinator-0 -- alluxio info version 2>/dev/null
```

```console
AI-3.8-15.1.0
```

在滚动升级过程中，worker 会分批重启，即当前批次中的工作进程必须完全准备就绪后才能启动下一个批次。默认批次大小为 worker 总数的 10%。

可以减少批次中的 worker 数量，以最大程度地减少期间对正在运行的工作负载的中断，但代价是延长升级周期。要控制比例或设置需要重启的具体 worker 数量，请在 `alluxio-cluster.yaml` 文件中进行以下设置：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  worker:
    rollingUpdate:
      maxUnavailable: 1  # 默认情况下是 10%，但除了设置百分比值外，还可以设置为精确数字
```

### 动态更新配置

您可以通过编辑其 ConfigMap 来更改正在运行的集群中的 Alluxio 属性。

1. **找到您的集群的 ConfigMap**。

   ```shell
   kubectl -n alx-ns get configmap
   ```

   ```console
   NAME                              DATA   AGE
   alluxio-cluster-alluxio-conf      4      7m48s
   ...
   ```
2. **编辑 ConfigMap** 以修改 `alluxio-site.properties`、`alluxio-env.sh` 等。

   ```shell
   kubectl -n alx-ns edit configmap alluxio-cluster-alluxio-conf
   ```
3. **重新启动组件** 以应用更改。
   * **Coordinator:** `kubectl -n alx-ns rollout restart statefulset alluxio-cluster-coordinator`
   * **Workers:** `kubectl -n alx-ns rollout restart deployment alluxio-cluster-worker`
   * **DaemonSet FUSE:** `kubectl -n alx-ns rollout restart daemonset alluxio-fuse`
   * **CSI FUSE:** 这些 pod 必须通过退出应用程序 pod 或手动删除 FUSE pod 来重新启动（`kubectl -n alx-ns delete pod <fuse-pod-name>`）。

## 3. 多租户和联邦

对于大规模企业部署，Alluxio 提供了多租户和集群联邦的高级功能。这允许多个团队和业务部门安全高效地共享数据基础设施，同时简化管理开销。

下面的参考架构展示了一个 API 网关，它集中处理多个 Alluxio 集群的身份验证和授权。

### 核心概念

#### 身份验证

Alluxio 与外部企业身份提供商（如 **Okta**）集成。当用户登录时，提供商会对其进行身份验证并生成一个 [**JSON Web Token (JWT)**](https://auth0.com/docs/secure/tokens/access-tokens/access-token-profiles)。此 JWT 随后会与每个后续请求一起发送到 Alluxio API 网关，以验证用户身份。

#### 授权

一旦用户通过身份验证，Alluxio 会使用外部策略引擎 [**Open Policy Agent (OPA)**](https://www.openpolicyagent.org/docs/latest/#running-opa) 来确定用户有权执行哪些操作。管理员可以在 OPA 的声明性语言 **Rego** 中编写细粒度的访问控制策略，以控制哪些用户可以访问哪些资源。API 网关会为每个请求查询 OPA，以确保其已获授权。

#### 多租户和隔离

Alluxio 在租户之间强制隔离，以确保安全并防止干扰。这是通过以下方式实现的：

* **用户角色：** 定义具有特定访问级别和权限的不同角色。
* **缓存隔离：** 分配特定于租户的缓存配置，包括配额、TTL 和驱逐策略，确保一个租户的工作负载不会对另一个租户产生负面影响。

### 集群联邦

对于拥有多个 Alluxio 集群（例如，跨不同区域或为不同业务部门）的组织，联邦简化了管理。中央**管理控制台**提供了一个单一的管理界面，用于：

* 跨集群监控和指标。
* 同时在多个集群上执行操作。
* 所有集群的集中式许可证管理。

### 示例工作流：更新缓存策略

此工作流演示了各组件如何协同工作：

1. **身份验证：** 用户登录到**管理控制台**，该控制台将他们重定向到 **Okta** 进行身份验证。成功后，Okta 会颁发一个 JWT。
2. **请求提交：** 用户使用控制台提交更改缓存 TTL 的请求。包含 JWT 的请求被发送到 **API 网关**。
3. **授权：** API 网关验证 JWT 并查询 **OPA 策略引擎**，以检查用户是否有权修改目标租户的缓存设置。
4. **执行：** 如果请求获得授权，API 网关会将命令转发到相关 Alluxio 集群的Coordinator，后者随后应用新的 TTL 策略。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.alluxio.io/ee-ai-cn/ai-3.8-15.1.x-cn/administration/managing-alluxio.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
