> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/ee-ai-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.alluxio.io/ee-ai-cn/start/installing-on-kubernetes.md).

# Kubernetes 安装

本文档介绍如何通过 [Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) 在 Kubernetes 上安装 Alluxio。

## 概览

### 制品

您将收到包含三个制品的下载链接：

| 制品          | 文件名                                                       | 用途                                     |
| ----------- | --------------------------------------------------------- | -------------------------------------- |
| Helm chart  | `alluxio-operator-3.6.1-helmchart.tgz`                    | 将 Operator 部署到 Kubernetes              |
| Operator 镜像 | `alluxio-operator-3.6.1-linux-amd64-docker.tar`           | Operator pod 的容器镜像                     |
| Alluxio 镜像  | `alluxio-enterprise-AI-3.9-16.0.0-linux-amd64-docker.tar` | Alluxio worker 和 coordinator pod 的容器镜像 |
| License     |                                                           | 激活集群所必需                                |

> **版本**：以上文件名中的版本字符串仅为示例，您收到的下载链接中包含销售代表为您提供的实际版本。 **平台**：x86 节点使用 `-linux-amd64-docker.tar`，ARM 节点使用 `-linux-arm64-docker.tar`。

Docker 镜像**从不从公共镜像仓库拉取** — 它们从 `.tar` 文件加载后推送至您的私有镜像仓库，再由 Kubernetes 部署。

```
Helm chart (.tgz)
  └─► 部署 ─► Operator pod  (alluxio-operator image)
                 └─► 监听 AlluxioCluster CRD
                        └─► 创建 ─► Alluxio pods  (alluxio-enterprise image)
```

### Kubernetes 组件

部署的 Alluxio 集群包含以下组件：

* **Operator** — 管理 Alluxio 集群的生命周期。每个 Kubernetes 集群安装一次。
* **Coordinator** — 处理后台操作（数据加载、释放）。1 个副本。
* **Worker** — 缓存数据并通过 S3 API 或 FUSE 提供读取服务。水平扩展以增加缓存容量。
* **ETCD** — 服务发现和挂载表存储。建议 3 个副本以实现仲裁。
* **监控**（可选） — Prometheus 和 Grafana。默认启用。

## 开始之前

在开始之前运行以下检查（约 2 分钟）。跳过此步骤是部署失败最常见的原因。

* [ ] **Docker** 已安装在执行以下步骤的机器上——步骤 0 中加载和推送镜像需要用到
* [ ] **Kubernetes 1.24 或更高**：

  ```shell
  kubectl version
  ```
* [ ] **Helm 3.10.0 或更高：**

  ```shell
  helm version
  ```
* [ ] **RBAC 权限** — kubeconfig 须能创建 CRD、ServiceAccount、ClusterRole 和 ClusterRoleBinding
* [ ] **kubectl** 已配置并指向正确的集群
* [ ] **可用节点**满足各 Alluxio 组件需求：
  * Coordinator：至少 1 个节点
  * Worker：至少 1 个节点
  * ETCD：测试环境至少 1 个节点，生产环境建议 3 个节点以实现仲裁
* [ ] **StorageClass** 已存在且支持动态 provisioning（ETCD 和 Coordinator metastore PVC 需要）：

  ```shell
  kubectl get storageclass
  ```

  不同平台在 StorageClass 和 FUSE 挂载方面可能存在差异。请参阅[附录 G：平台特定说明](#g-平台特定说明)了解 EKS、GKE 和 kind 的具体要求。
* [ ] **Worker 缓存存储已规划** —— [page store](https://documentation.alluxio.io/ee-ai-cn/start/pages/uw7Vlrzw6022oCfnpoka#id-5.-worker-cun-chu-page-store) 默认使用节点文件系统上的 `hostPath: /mnt/alluxio/pagestore`。对于多盘节点或需要缓存跨 pod 重启存活的场景，请在部署前查看生产建议中的 [Worker Page Store](#worker-page-store) 段落。
* [ ] **网络策略**允许 Alluxio Pod 之间以及应用 Pod 与 Worker 之间的所需端口通信。完整端口列表请参阅[先决条件 → 网络](/ee-ai-cn/start/prerequisites.md)。
* [ ] **已下载全部三个制品**（来自邮件链接）：Helm chart `.tgz`、Operator 镜像 `.tar`、Alluxio 镜像 `.tar`
* [ ] **私有镜像仓库**可用，且本地 Docker 已认证可向其推送镜像
* [ ] **Alluxio License 字符串**已准备就绪
* [ ] \*\*S3 存储桶及凭据（如使用 S3）\*\*已准备就绪

各组件资源规格（CPU、内存、缓存磁盘）请参阅[先决条件 → 资源规格](https://documentation.alluxio.io/ee-ai-cn/start/pages/u5ytEWeeFKI3ZN07lNwB#资源规格)。

{% hint style="warning" %}
**EKS 1.23+**：内置 EBS 驱动已被移除。请在部署 Alluxio **之前**安装 [AWS EBS CSI driver](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html) 插件，否则 etcd PVC 将持续处于 `Pending` 状态且没有明确的错误提示。
{% endhint %}

## 安装步骤

### 0. 将 Alluxio 镜像推送至私有镜像仓库

> **跳过此步骤**：如果 Alluxio 镜像已存在于您的私有镜像仓库中，可跳过此步骤。

Alluxio 镜像以 `.tar` 文件方式交付，必须先加载并推送至私有镜像仓库，Helm chart 才能部署它们。

**将镜像加载至本地 Docker：**

```shell
docker load -i alluxio-operator-3.6.1-linux-amd64-docker.tar
docker load -i alluxio-enterprise-AI-3.9-16.0.0-linux-amd64-docker.tar
```

**✅ 成功标志：** `docker images` 显示两个镜像：

```console
REPOSITORY                    TAG
alluxio/operator              3.6.1
alluxio/alluxio-enterprise    AI-3.9-16.0.0
```

**重新打标签并推送至私有镜像仓库：**

```shell
docker tag alluxio/operator:3.6.1 <PRIVATE_REGISTRY>/alluxio-operator:3.6.1
docker tag alluxio/alluxio-enterprise:AI-3.9-16.0.0 <PRIVATE_REGISTRY>/alluxio-enterprise:AI-3.9-16.0.0

docker push <PRIVATE_REGISTRY>/alluxio-operator:3.6.1
docker push <PRIVATE_REGISTRY>/alluxio-enterprise:AI-3.9-16.0.0
```

**✅ 成功标志：** 两个镜像现已推送至私有镜像仓库。请记下完整的镜像路径，后续步骤 1 和步骤 4 中将用到。

> 如果您的 Kubernetes 集群也无法访问公共镜像仓库（离线环境），第三方镜像（etcd、CSI）也需要迁移。请参阅[附录 A：离线部署](#a.-li-xian-bu-shu)。

### 1. 准备 Helm Chart

解压 Helm chart：

```shell
tar zxf alluxio-operator-3.6.1-helmchart.tgz
# 生成 ./alluxio-operator/ 目录
```

在 chart 目录外创建 `alluxio-operator.yaml`，指定私有镜像仓库中的 Operator 镜像：

```yaml
global:
  image: <PRIVATE_REGISTRY>/alluxio-operator
  imageTag: 3.6.1
```

### 2. 创建命名空间

```shell
kubectl create namespace alx-ns
```

### 3. 部署 Operator

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

**✅ 成功标志：** Helm 命令完成后立即打印 `STATUS: deployed`：

```console
NAME: operator
STATUS: deployed
REVISION: 1
```

然后验证所有 pod 正在运行：

```shell
kubectl -n alluxio-operator get pod
```

**✅ 成功标志：** 所有 Operator pod 显示 `READY 1/1` 或 `2/2`，`STATUS = Running`，且 `RESTARTS = 0`。

示例输出如下：

```console
NAME                                              READY   STATUS    RESTARTS   AGE
alluxio-cluster-controller-5db4f967f5-hg4v4       1/1     Running   0          30s
alluxio-collectinfo-controller-6c88f67c5d-ggj4w   1/1     Running   0          30s
alluxio-csi-controller-77d8d7bd56-27tqh           2/2     Running   0          30s
alluxio-csi-nodeplugin-2pzrq                      2/2     Running   0          31s
alluxio-csi-nodeplugin-94mjw                      2/2     Running   0          31s
alluxio-csi-nodeplugin-tgs86                      2/2     Running   0          31s
alluxio-license-controller-6c76b59f9b-lfkmz       1/1     Running   0          30s
alluxio-ufs-controller-5c8bdf48c9-tnw48           1/1     Running   0          30s
```

> 如果 etcd 或 CSI 镜像拉取失败，请参阅[附录 A：离线部署](#a.-li-xian-bu-shu)。

### 4. 部署集群

{% hint style="warning" %}
**部署前先配置 Hash Ring。** Hash Ring 决定数据如何在 Worker 间分布。部署后修改是破坏性操作——所有缓存数据将丢失。如果您的集群有异构 Worker 或特定容量需求，请在执行下方命令前先查阅[附录 B：Hash Ring 处理](#b.-处理-hash-ring)。
{% endhint %}

创建一个最小化的 `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.9-16.0.0
  properties:
    alluxio.license: <YOUR_LICENSE>   # 集群许可证；如果使用部署许可证，删除此行并参阅附录 C
  worker:
    count: 1
    pagestore:
      # 默认使用节点文件系统上的 hostPath: /mnt/alluxio/pagestore。
      # 多盘节点或需要 PVC 时，请参阅"生产建议 → Worker Page Store"。
      size: 90Gi       # 每个 Worker 的缓存容量，不得超过 Worker 节点的可用磁盘空间。
      reservedSize: 9Gi
  etcd:
    replicaCount: 3
```

部署：

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

{% hint style="info" %}
首次集群升级：Bitnami ETCD 用 `ETCD_INITIAL_CLUSTER_STATE=new` 初始化新集群，然后在第一次升级的时候将其改为 `existing`。因此首次集群升级时，ETCD pod 重启是符合预期的。
{% endhint %}

**✅ 成功标志：** 启动通常需要 **2–3 分钟**。如果需要从仓库拉取 Alluxio 镜像（约 1.8 GB），首次部署可能耗时更长。实时查看进度：

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

所有 pod 运行后，`kubectl -n alx-ns get alluxiocluster` 显示 `CLUSTERPHASE` = `Ready`

```console
NAME              CLUSTERPHASE   AGE
alluxio-cluster   Ready          2m18s
```

且 `kubectl -n alx-ns get pod` 显示所有 pod 变为 `Ready` 且 `STATUS = Running`。

```console
NAME                                          READY   STATUS    RESTARTS   AGE
alluxio-cluster-coordinator-0                 1/1     Running   0          2m3s
alluxio-cluster-etcd-0                        1/1     Running   0          2m3s
alluxio-cluster-etcd-1                        1/1     Running   0          2m3s
alluxio-cluster-etcd-2                        1/1     Running   0          2m3s
alluxio-cluster-worker-85fd45db46-c7n9p       1/1     Running   0          2m3s
alluxio-cluster-grafana-585d767c84-p8wcp      1/1     Running   0          2m3s
alluxio-cluster-prometheus-6f697b6db8-sbvvg   1/1     Running   0          2m3s
```

> 如果任何组件无法启动，请参阅[附录 D：故障排除](#d.-gu-zhang-pai-chu)。

如需访问 Grafana 仪表盘并导入 Alluxio 仪表盘模板，请参阅[监控](/ee-ai-cn/administration/monitoring-alluxio.md)。

### 5. 挂载存储

创建 `ufs.yaml`（S3 示例；其他存储系统请参阅[底层存储](/ee-ai-cn/ufs.md)）：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: UnderFileSystem
metadata:
  name: alluxio-s3
  namespace: alx-ns
spec:
  alluxioCluster: alluxio-cluster
  path: s3://<S3_BUCKET>/<S3_DIRECTORY>
  mountPath: /s3
  mountOptions:
    s3a.accessKeyId: <S3_ACCESS_KEY_ID>
    s3a.secretKey: <S3_SECRET_KEY>
    alluxio.underfs.s3.region: <S3_REGION>
```

应用：

```shell
kubectl apply -f ufs.yaml
```

**✅ 成功标志：** `kubectl -n alx-ns get ufs` 显示 `PHASE = Ready`。

示例输出：

```console
NAME         PHASE   AGE
alluxio-s3   Ready   32s
```

### 6. 验证集群

```shell
kubectl -n alx-ns exec -i alluxio-cluster-coordinator-0 -- alluxio mount list
```

**✅ 成功标志：** 输出显示您的挂载点（例如 `s3://my-bucket/... on /s3/`）。

示例输出：

```console
Defaulted container "alluxio-coordinator" out of: alluxio-coordinator, path-permission (init), wait-etcd (init)
Listing all mount points
s3://<S3_BUCKET>/  on  /s3/ properties={alluxio.underfs.s3.region=<S3_REGION>}
```

### 7. 验证数据访问

```shell
kubectl -n alx-ns exec -i alluxio-cluster-coordinator-0 -- alluxio fs ls /
```

**✅ 成功标志：** 返回目录列表且没有错误。

**下一步：把你的应用接入集群**，选择一种访问方式：

* [**POSIX API (FUSE)**](/ee-ai-cn/data-access/fuse-based-posix-api.md#quick-start) —— 把 Alluxio 挂成标准文件系统。
* [**S3 API**](/ee-ai-cn/data-access/s3-api.md#kuai-su-ru-men) —— HTTP 端点，兼容 S3 客户端。
* [**Python FSSpec API**](/ee-ai-cn/data-access/fsspec.md) —— 用于 Python ML 框架。

## 卸载

要从集群中移除 Alluxio 部署，请按顺序运行以下命令：

**1. 删除 UFS 挂载和集群：**

```shell
kubectl delete -f ufs.yaml
kubectl delete -f alluxio-cluster.yaml
```

**2. 卸载 Operator：**

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

**3. 删除命名空间：**

```shell
kubectl delete namespace alx-ns
kubectl delete namespace alluxio-operator
```

**✅ 成功标志：** `kubectl get namespace` 不再显示 `alx-ns` 或 `alluxio-operator`，且 `kubectl get alluxiocluster -A` 返回 `No resources found`。

## 下一步：生产部署配置

上述配置适用于评估。生产部署（节点固定、资源调优、持久化 metastore、许可证、哈希环部署前配置、异构 Worker 等）请参阅 [生产部署配置](https://documentation.alluxio.io/ee-ai-cn/start/pages/cuG1KYD7QZM6zV5EoHQ1#id-1.-sheng-chan-bu-shu-pei-zhi)。

***

## 附录

使用下表查找与您的场景相关的附录章节：

| 场景                     | 章节                                                                                        |
| ---------------------- | ----------------------------------------------------------------------------------------- |
| **离线环境**（集群无法访问公共镜像仓库） | [A. 离线部署](#a.-li-xian-bu-shu)、[B.5. 配置镜像拉取密钥](#b.5.-pei-zhi-jing-xiang-la-qu-secret)      |
| **外部或自定义 ETCD**        | [B.3. 外部 ETCD](#b.3.-shi-yong-wai-bu-etcd)、[B.4. 自定义 ETCD](#b.4.-zi-ding-yi-etcd-pei-zhi) |
| **生产许可证**              | [C. 许可证管理](#c.-xu-ke-zheng-guan-li)                                                       |
| **出现问题**               | [D. 故障排除](#d.-gu-zhang-pai-chu)                                                           |

### A. 离线部署

#### 预检：验证节点到镜像仓库的连通性

部署前，先验证 worker 节点能否从私有镜像仓库拉取镜像。提前发现问题可以避免部署中途出现 `ImagePullBackOff`。

SSH 登录每个 worker 节点，执行：

```shell
crictl pull <PRIVATE_REGISTRY>/alluxio-enterprise:<TAG>
```

`crictl` 在运行 containerd 或 CRI-O 的节点上均已预装。若拉取失败，请先解决节点的镜像仓库连通性或认证问题，再继续部署。

#### 症状：部署后出现 ImagePullBackOff

**症状**：部署 Operator 或集群后，部分 pod 卡在 `ImagePullBackOff` 状态。您的 Kubernetes 集群无法访问公共镜像仓库拉取第三方组件镜像（CSI、etcd、监控）。

Alluxio 镜像已在[准备步骤](#准备将-alluxio-镜像推送至私有镜像仓库)中推送至私有镜像仓库。需要迁移的其余镜像取决于您的具体 Operator 版本。通过检查卡住的 pod 来识别它们：

```shell
kubectl get pods -A | grep -E "ImagePullBackOff|ErrImagePull"
kubectl describe pod <pod-name> -n <namespace> | grep "image:"
```

对每个无法拉取的镜像：在有公网访问权限的机器上拉取，为私有镜像仓库重新打标签并推送。然后更新 `alluxio-operator.yaml` 或 `alluxio-cluster.yaml`，将该组件指向您的私有镜像仓库。

CSI 镜像（属于 Operator）可在 `alluxio-operator.yaml` 中覆盖：

```yaml
alluxio-csi:
  controllerPlugin:
    provisioner:
      image: <PRIVATE_REGISTRY>/csi-provisioner:<TAG>
  nodePlugin:
    driverRegistrar:
      image: <PRIVATE_REGISTRY>/csi-node-driver-registrar:<TAG>
```

etcd 镜像（属于集群）可在 `alluxio-cluster.yaml` 中覆盖：

```yaml
spec:
  etcd:
    image:
      registry: <PRIVATE_REGISTRY>
      repository: <PRIVATE_REPOSITORY>/etcd
      tag: <TAG>
```

### B. 高级配置

本节介绍适应不同场景的常见配置。

#### B.1. 配置 Alluxio 属性

要修改 Alluxio 的配置，请编辑 `alluxio-cluster.yaml` 文件中的 `.spec.properties` 字段。这些属性会附加到 Alluxio pod 内的 `alluxio-site.properties` 文件中。

#### B.2. 挂载自定义 ConfigMap 或 Secret

您可以将自定义的 `ConfigMap` 或 `Secret` 文件挂载到您的 Alluxio pod 中。这对于提供像 `core-site.xml` 这样的配置文件或凭据很有用。

**示例：挂载一个 Secret**

1. 从本地文件创建 Secret：

   ```shell
   kubectl -n alx-ns create secret generic my-secret --from-file=/path/to/my-file
   ```
2. 在 `alluxio-cluster.yaml` 中指定要加载的 Secret 和挂载路径：

   ```yaml
   apiVersion: k8s-operator.alluxio.com/v1
   kind: AlluxioCluster
   spec:
     secrets:
       worker:
         my-secret: /opt/alluxio/secret
       coordinator:
         my-secret: /opt/alluxio/secret
   ```

   文件 `my-file` 将在 pod 的 `/opt/alluxio/secret/my-file` 路径下可用。

#### B.3. 使用外部 ETCD

如果您有外部的 ETCD 集群，您可以配置 Alluxio 使用它，而不是由 Operator 部署的那个。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  etcd:
    enabled: false
  properties:
    alluxio.etcd.endpoints: http://external-etcd:2379
    # If using TLS for ETCD, add the following:
    # alluxio.etcd.tls.enabled: "true"
```

#### B.4. 自定义 ETCD 配置

`spec.etcd` 下的字段遵循 [Bitnami ETCD helm chart](https://github.com/bitnami/charts/blob/main/bitnami/etcd/values.yaml)。例如，要设置 ETCD pod 的节点亲和性，可以按照 [Kubernetes 文档](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity) 中的说明使用 `affinity` 字段。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  etcd:
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: topology.kubernetes.io/zone
              operator: In
              values:
              - antarctica-east1
              - antarctica-west1
```

#### B.5. 配置镜像拉取 Secret

如果您的容器镜像存储在需要身份验证的私有仓库中，您需要创建一个 Kubernetes Secret 来存储您的仓库凭据。

此 Secret 必须在您计划安装 Alluxio 的命名空间中创建。

```shell
kubectl create secret docker-registry <SECRET_NAME> \
  --docker-server=<REGISTRY_SERVER> \
  --docker-username=<USERNAME> \
  --docker-password=<PASSWORD> \
  -n <NAMESPACE>
```

### C. 许可证管理

Alluxio 需要由 Alluxio 销售代表提供的许可证。许可证有两种类型：

* **集群许可证** — 作用范围为单个集群，通过 `alluxio-cluster.yaml` 中的 `alluxio.license` 属性内联设置。适用于评估环境和单集群生产部署。
* **部署许可证** — 覆盖多个集群，每个集群在许可证内拥有各自独立的容量约束。通过单独的 `License` Kubernetes 资源应用。适用于管理多个 Alluxio 集群的场景。

#### C.1. 集群许可证

在 `alluxio-cluster.yaml` 中直接填入许可证字符串：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  properties:
    alluxio.license: <YOUR_CLUSTER_LICENSE>
```

#### C.2. 部署许可证

部署许可证以独立的 `License` Kubernetes 资源方式应用，可覆盖多个集群。各集群的缓存容量依据部署许可证中为其各自定义的约束条件独立计算——并非共享总配额。

**步骤 1：不携带许可证部署集群**

按主指南步骤 5 部署 Alluxio 集群，但在 `alluxio-cluster.yaml` 中**省略** `alluxio.license` 属性。Pod 将启动，但保持 `Init` 状态直到许可证被应用。

**步骤 2：应用许可证**

创建 `alluxio-license.yaml`。`clusters` 列表中的 `name` 和 `namespace` 必须与 `AlluxioCluster` 的 metadata 完全匹配。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: License
metadata:
  name: alluxio-license
  namespace: alx-ns
spec:
  clusters:
  - name: alluxio-cluster
    namespace: alx-ns
  licenseString: <YOUR_DEPLOYMENT_LICENSE>
```

```shell
kubectl create -f alluxio-license.yaml
```

Pod 检测到许可证后将转换为 `Running` 状态。

{% hint style="warning" %}
`clusters` 字段中只能列出已在运行的集群。如果 Operator 找不到列出的某个集群，列表中所有集群的许可证操作都将失败。
{% endhint %}

#### C.3. 更新部署许可证

要更新现有的部署许可证，请更新 `alluxio-license.yaml` 中的 `licenseString` 并重新应用它：

```shell
kubectl delete -f alluxio-license.yaml
kubectl create -f alluxio-license.yaml
```

#### C.4. 检查许可证状态

您可以从 Alluxio Coordinator pod 内部检查许可证详细信息和使用情况。

```shell
# Get a shell into the coordinator pod
kubectl -n alx-ns exec -it alluxio-cluster-coordinator-0 -- /bin/bash

# View license details (expiration, capacity)
alluxio license show

# View current utilization
alluxio license status
```

### D. 故障排除

#### D.1. ETCD pod 卡在 pending 状态

如果 `etcd` pod 处于 `Pending` 状态，通常是由于存储问题。使用 `kubectl describe pod <etcd-pod-name>` 检查事件。

**症状**：事件消息显示 `pod has unbound immediate PersistentVolumeClaims`。

**原因**：PVC 未设置 `storageClass`，或没有可用的 PV。

**解决方案**：在 `alluxio-cluster.yaml` 中指定一个 `storageClass`：

```yaml
spec:
  etcd:
    persistence:
      storageClass: <YOUR_STORAGE_CLASS>
      size: 10Gi # Example size
```

然后，在重新创建集群之前删除旧的集群和 PVC。

**症状**：事件消息显示 `waiting for first consumer`。

**原因**：`storageClass` 不支持动态配置，卷必须由管理员手动创建。

**解决方案**：要么使用动态配置程序，要么手动创建一个满足声明的 PersistentVolume。

#### D.2. etcd pod 因反亲和性卡在 Pending（节点数少于 3）

**现象**：etcd pod 处于 `Pending` 状态，事件消息为 `0/N nodes are available: N node(s) didn't match pod anti-affinity rules`。

**原因**：Operator 为 etcd 配置了基于主机名的 `requiredDuringSchedulingIgnoredDuringExecution` 反亲和性。默认 `etcd.replicaCount: 3` 需要 3 个不同的节点。若集群节点数少于 3，etcd pod 无法完成调度。

**解决方案**：对于节点数少于 3 的开发/测试集群，减小副本数：

```yaml
spec:
  etcd:
    replicaCount: 1   # 仅用于单节点开发/测试；生产环境请使用 3
```

> 不要在生产环境中使用 `replicaCount: 1`——单节点 etcd 没有法定人数，不具备容错能力。

#### D.3. alluxio-cluster-fuse PVC 处于 pending 状态

`alluxio-cluster-fuse` PVC 保持在 `Pending` 状态是正常的。一旦客户端应用程序 pod 开始使用它，它将自动绑定到一个卷并变为 `Bound`。

#### D.4. Worker pod 卡在 CrashLoopBackOff

**症状**：Worker pod 反复崩溃并重启。

首先检查 Worker 日志：

```shell
kubectl -n alx-ns logs <worker-pod-name> --previous
```

常见原因包括：

* **Pagestore 配额超出磁盘空间** — 日志显示 `quota (NNN) exceeds the total disk space`。云提供商通常以 GB（十进制）报告磁盘大小，而 Kubernetes 将 `Gi` 解释为 GiB（二进制）。修复：将 `pagestore.size` 减少到实际可用空间的约 90%（通过 `df -h /mnt/alluxio` 检查），将 `reservedSize` 设置为 `size` 的约 10%。
* **许可证过期或无效** — 日志显示许可证错误。修复：应用新许可证。请参阅[附录 C：许可证管理](#e.-license-management)。
* **OOM 终止** — 日志显示 `Exit Code 137` 或 `OutOfMemoryError`。修复：增加容器内存限制并调整 `-Xmx` / `-XX:MaxDirectMemorySize`。请参阅 [D.2. 资源和 JVM 调优](#d.2.-resource-and-jvm-tuning)。

### E. 平台特定说明

主安装步骤与平台无关。本节记录了特定 Kubernetes 环境的已知差异。

#### Amazon EKS

**EKS 1.23+ 需要 EBS CSI 驱动**：Kubernetes 1.23 移除了内置 EBS 卷驱动。在 EKS 1.23+ 上，需安装 [AWS EBS CSI driver](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html) 插件，否则即使 StorageClass 有输出，PVC 创建仍会静默失败。

验证：

```shell
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver --no-headers | head -1
```

如果没有输出，说明驱动未安装。

#### Google GKE

**`/mnt` 路径为只读**：GKE 节点的根文件系统为只读。多个 Alluxio 组件默认使用 `/mnt/alluxio/` 下的 hostPath，导致 worker pod 启动失败并报错：

```console
MountVolume.SetUp failed for volume "pagestore-0" : mkdir /mnt/alluxio: read-only file system
MountVolume.SetUp failed for volume "logs" : mkdir /mnt/alluxio: read-only file system
MountVolume.SetUp failed for volume "metastore" : mkdir /mnt/alluxio: read-only file system
```

**解决方法**：在 `alluxio-cluster.yaml` 中将所有 hostPath 重定向到可写的基础目录（例如 `/home/alluxio/`）：

```yaml
spec:
  coordinator:
    metastore:
      hostPath: /home/alluxio/metastore
    log:
      hostPath: /home/alluxio/logs
  worker:
    pagestore:
      hostPath: /home/alluxio/pagestore
    metastore:
      hostPath: /home/alluxio/metastore
    log:
      hostPath: /home/alluxio/logs
  fuse:
    log:
      hostPath: /home/alluxio/logs/fuse
    hostPathForMigration: /home/alluxio/migration
  gateway:
    log:
      hostPath: /home/alluxio/logs/gateway
  prometheus:
    persistence:
      hostPath: /home/alluxio/prometheus
```

此外，配置 worker 身份持久化，防止 worker 每次重启后注册为新实例（导致旧 worker 残留为 OFFLINE 状态）。有关其重要性及对哈希环影响的完整说明，请参阅[重启 Worker](/ee-ai-cn/administration/managing-ring.md#zhong-qi-worker)。

```yaml
spec:
  worker:
    useExternalId: false
    systemInfo:
      hostPath: /home/alluxio/system-info
```

#### kind（本地开发）

**镜像加载**：`kind load docker-image` 在处理多平台镜像时可能因 digest 错误而失败。请使用以下替代方式：

```shell
docker save <IMAGE> | docker exec -i <KIND_CONTAINER> ctr --namespace=k8s.io images import --snapshotter=overlayfs -
```

获取 kind 容器名称：`docker ps | grep kindest`。

## 相关文档

* [Alluxio 工作原理](/ee-ai-cn/how-alluxio-works.md) — 架构概述、一致性哈希和故障转移行为
* [集群管理](/ee-ai-cn/administration/managing-alluxio.md) — 部署后运维：扩缩容、哈希环调优、Worker 生命周期和 UFS 挂载管理
* [监控](/ee-ai-cn/administration/monitoring-alluxio.md) — Grafana 访问、仪表盘导入、告警规则和 Datadog 集成
