在Kubernetes上安装Alluxio

本文档展示了如何通过 Operator(Kubernetes 管理应用程序的扩展)在 Kubernetes 上安装 Alluxio。

系统要求

  • Kubernetes

    • 至少1.19版本的 Kubernetes 集群,支持特性门控

    • 确保集群的 Kubernetes 网络策略允许应用程序(Alluxio 客户端)与定义端口上的 Alluxio Pods 之间建立连接

    • Kubernetes 集群已安装至少3.6.0版本的 Helm 3

    • 用于存储和管理容器镜像的镜像仓库

  • 硬件

    • 每个节点至少 8个 CPU 和 32GB 内存

    • 每个节点至少100GB 的存储空间

  • 权限。参考:使用 RBAC 授权

    • 创建 CRD(自定义资源定义)的权限

    • 为 Operator Pod 创建 ServiceAccount、ClusterRole 和 ClusterRoleBinding 的权限

    • 创建 operator 所在命名空间的权限

准备

下载 Alluxio operator 和 Alluxio 集群的安装包

联系您的 Alluxio 客户经理(邮箱:sales@alluxio.com),获取 Alluxio Enterprise DA 的试用版本。按照说明将文件下载到准备好的目录中。

获取下列文件:

  • alluxio-operator-{{site.ALLUXIO_OPERATOR_VERSION_STRING}}-helmchart.tgz 用于部署 Alluxio operator 的 Helm chart

  • alluxio-operator-{{site.ALLUXIO_OPERATOR_VERSION_STRING}}-docker.tar包含所有 Alluxio operator 组件的 Docker 镜像

  • alluxio-enterprise-{{site.ALLUXIO_VERSION_STRING}}-docker.tarAlluxio 的 Docker 镜像

  • alluxio-enterprise-{{site.ALLUXIO_VERSION_STRING}}-release.tar.gz包含与特定计算集成的 JAR 文件的压缩包,使计算能够连接到 Alluxio 集群。 该文件不会在本文档说明中使用,但在准备计算集群时需要确保其可用。

此外,还需获取后续章节提到的名为 <ALLUXIO_LICENSE_STRING>的许可证字符串。

将镜像上传到镜像仓库

镜像仓库是存储和共享容器镜像的中心化位置。镜像仓库可以是公共的,也可以是私有的。云服务厂商会提供容器镜像仓库服务作为其云服务的一部分, 包括

Amazon Elastic Container Registry(ECR), Azure Container Registry (ACR), Google Container Registry (GCR)。 您甚至可以在本地系统或组织内部运行私有镜像仓库。

以下示例展示了如何上传 Alluxio operator 镜像。

# 加载镜像到本地
$ docker load -i alluxio-operator-{{site.ALLUXIO_OPERATOR_VERSION_STRING}}-docker.tar
$ docker load -i alluxio-enterprise-{{site.ALLUXIO_VERSION_STRING}}-docker.tar

# 将镜像更改为私有镜像仓库
$ docker tag alluxio/operator:{{site.ALLUXIO_OPERATOR_VERSION_STRING}} <PRIVATE_REGISTRY>/alluxio-operator:{{site.ALLUXIO_OPERATOR_VERSION_STRING}}
$ docker tag alluxio/alluxio-enterprise:{{site.ALLUXIO_VERSION_STRING}} <PRIVATE_REGISTRY>/alluxio-enterprise:{{site.ALLUXIO_VERSION_STRING}}

# 上传镜像到私有镜像仓库
$ docker push <PRIVATE_REGISTRY>/alluxio-operator:{{site.ALLUXIO_OPERATOR_VERSION_STRING}}
$ docker push <PRIVATE_REGISTRY>/alluxio-enterprise:{{site.ALLUXIO_VERSION_STRING}}

为 operator 解压 Helm chart

# 将文件解压到目录 alluxio-operator
$ tar zxf alluxio-operator-{{site.ALLUXIO_OPERATOR_VERSION_STRING}}-helmchart.tgz

解压后的alluxio-operator 目录包含用于部署 operator 的 Helm chart 文件。

部署

部署 Alluxio operator

创建 alluxio-operator/alluxio-operator.yaml 文件,以指定用于部署 operator 的镜像和版本。 以下示例演示了如何指定 operatorcsi 镜像及其版本:

global:
  image: <PRIVATE_REGISTRY>/alluxio-operator
  imageTag: {{site.ALLUXIO_OPERATOR_VERSION_STRING}}
alluxio-csi:
  enabled: false

进入到 alluxio-operator 目录,执行以下命令来部署 operator:

$ cd alluxio-operator
# 最后一个参数表示是 helm chart 文件的路径,"." 表示当前目录
$ helm install operator -f alluxio-operator.yaml .
NAME: operator
LAST DEPLOYED: Wed May 15 17:32:34 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

# 确认 operator 是否正常运行
$ kubectl get pod -n alluxio-operator
NAME                                              READY   STATUS    RESTARTS   AGE
alluxio-cluster-controller-5647cc664d-lrx84       1/1     Running   0          14s
alluxio-collectinfo-controller-667b746fd6-hfzqk   1/1     Running   0          14s
alluxio-ufs-controller-5f6d7c4d66-drjgm           1/1     Running   0          14s

部署 Alluxio

创建alluxio-operator/alluxio-cluster.yaml, 用于部署 Alluxio 集群。下面的文件展示了最简配置。

请参阅资源需求和兼容性,获取资源规划建议。 默认情况下,operator 已按照生产部署的推荐配置进行设置。如果您需要修改配置,可以编辑 alluxio-cluster.yaml 文件中的 .spec.properties 字段。常见用例章节描述了修改这些属性的部分场景。

.spec.properties 字段下指定的属性将附加到 alluxio-site.properties 配置文件中,Alluxio 进程将读取该文件。您可以通过查看 /opt/alluxio/conf/alluxio-site.properties 来找到您在 Alluxio coordinator或 worker pod 中的配置。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
metadata:
  name: alluxio
spec:
  image: <PRIVATE_REGISTRY>/alluxio-enterprise
  imageTag: {{site.ALLUXIO_VERSION_STRING}}
  properties:
    alluxio.license: <ALLUXIO_LICENSE_STRING>
  worker:
    count: 2

  pagestore:
    size: 100Gi

  fuse:
    type: none
  • 如果您的数据存储在 S3 等存储中,并且计算任务可以通过 s3://访问数据,您可以通过在启动 Alluxio 集群后通过创建 UFS 资源, 实现将底层文件系统挂载到 Alluxio 中,从而加速工作负载。

进入到 alluxio-operator目录,执行以下命令来部署 Alluxio 集群:

$ cd alluxio-operator

$ kubectl create -f alluxio-cluster.yaml
alluxiocluster.k8s-operator.alluxio.com/alluxio created

# 集群即将启动
$ kubectl get pod
NAME                                          READY   STATUS              RESTARTS   AGE
alluxio-coordinator-0                         0/1     Init:0/1            0          7s
alluxio-etcd-0                                0/1     ContainerCreating   0          7s
alluxio-etcd-1                                0/1     ContainerCreating   0          7s
alluxio-etcd-2                                0/1     ContainerCreating   0          7s
alluxio-monitor-grafana-847fd46f4b-84wgg      0/1     Running             0          7s
alluxio-monitor-prometheus-778547fd75-rh6r6   1/1     Running             0          7s
alluxio-worker-76c846bfb6-2jkmr               0/1     Init:0/2            0          7s
alluxio-worker-76c846bfb6-nqldm               0/1     Init:0/2            0          7s

# 检查集群状态
$ kubectl get alluxiocluster
NAME      CLUSTERPHASE   AGE
alluxio   Ready          2m18s

# 集群准备就绪后,查看集群中的 pod
$ kubectl get pod
NAME                                          READY   STATUS    RESTARTS   AGE
alluxio-coordinator-0                         1/1     Running   0          2m3s
alluxio-etcd-0                                1/1     Running   0          2m3s
alluxio-etcd-1                                1/1     Running   0          2m3s
alluxio-etcd-2                                1/1     Running   0          2m3s
alluxio-monitor-grafana-7b9477d66-mmcc5       1/1     Running   0          2m3s
alluxio-monitor-prometheus-78dbb89994-xxr4c   1/1     Running   0          2m3s
alluxio-worker-85fd45db46-c7n9p               1/1     Running   0          2m3s
alluxio-worker-85fd45db46-sqv2c               1/1     Running   0          2m3s

在 Alluxio 3.x 中,coordinator 是一个无状态的控制组件,用于托管如分布式加载这样的任务,以及作为 operator 调用 API 的 gateway。

如果集群中的有些组件状态无法达到 Running 状态,可以通过kubectl describe pod查看详细信息,找到问题所在。 部署过程中遇到的具体问题, 可以参考常见问题

启动 Alluxio 集群还包括 etcd 和监控组件,如果无法从公共镜像仓库拉取镜像导致 etcd 和监控启动失败, 请参考配置 Alluxio 集群镜像

将底层存储挂载到 Alluxio

Alluxio 支持对接多种底层存储,包括 S3和HDFS 等。 请参考存储集成概述

通过 operator 我们可以通过创建 UnderFileSystem 资源来挂载底层存储。一个 UnderFileSystem 资源对应 Alluxio 中的一个挂载点。 关于 Alluxio 以及底层存储命名空间, 请参考Alluxio 命名空间和底层文件系统命名空间

下面我们提供了将S3作为底层存储挂载的示例。

创建alluxio-operator/ufs.yaml文件来指定UFS配置。下述示例展示如何将一个S3存储桶挂载到Alluxio:

apiVersion: k8s-operator.alluxio.com/v1
kind: UnderFileSystem
metadata:
  name: alluxio-s3
spec:
  alluxioCluster: alluxio
  path: s3://my-bucket/path/to/mount
  mountPath: /s3
  mountOptions:
    s3a.accessKeyId: <YOUR_S3_ACCESS_KEY>
    s3a.secretKey: <YOUR_S3_SECRET_KEY>
    alluxio.underfs.s3.region: us-east-1

有关将S3挂载到Alluxio的更多详细信息,请参阅 Amazon AWS S3

挂载操作

首先需要确认 Alluxio 集群已经启动,状态为 Ready。(或者状态为 WaitingForReady 也可以挂载 UFS)

# 检查集群的状态
$ kubectl get alluxiocluster
NAME      CLUSTERPHASE   AGE
alluxio   Ready          2m18s

在创建 UnderFileSystem 资源后,执行以下命令将底层存储挂载到 Alluxio 命名空间:

$ cd alluxio-operator
$ kubectl create -f ufs.yaml
underfilesystem.k8s-operator.alluxio.com/alluxio-s3 created

# 确认存储的状态
$ kubectl get ufs
NAME         PHASE   AGE
alluxio-s3   Ready   46s

# 同时通过 Alluxio 命令行检查挂载表
$ kubectl exec -it alluxio-coordinator-0 -- alluxio mount list 2>/dev/null
Listing all mount points
s3://my-bucket/path/to/mount  on  /s3/ properties={s3a.secretKey=xxx, alluxio.underfs.s3.region=us-east-1, s3a.accessKeyId=xxx}

监控

部署 Alluxio 集群默认开启监控,通过 Grafana 可以直观地查看 Alluxio 各种指标, 请参考监控和指标中的 Kubernetes Operator 章节。

常见用例

更改资源限制

对于每个组件,如 worker 和 coordinator ,我们都可以通过以下配置更改资源的使用量 :

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  worker: 
    count: 2
    resources:
      limits:
        cpu: "12"
        memory: "36Gi"
      requests:
        cpu: "1"
        memory: "32Gi"
    jvmOptions:
      - "-Xmx22g"
      - "-Xms22g"
      - "-XX:MaxDirectMemorySize=10g"
  coordinator:
    resources:
      limits:
        cpu: "12"
        memory: "36Gi"
      requests:
        cpu: "1"
        memory: "32Gi"
    jvmOptions:
      - "-Xmx4g"
      - "-Xms1g"
  • 容器将永远无法访问超过限制的资源,这个请求限制会在调度过程中生效。如需了解更多信息,请参阅 为 Pod 和容器管理资源

  • 内存限制应略大于堆内存(-Xmx)和直接内存(-XX:MaxDirectMemorySize=10g)的大小之和,以避免内存不足。

  • 为便于演示,建议设置较小的资源限制,例如:

  worker:
    resources:
      limits:
        cpu: "8"
        memory: "4Gi"
      requests:
        cpu: "1"
        memory: "1Gi"

将 PVC 用于 page store

这里的 page store 是指Alluxio使用的缓存。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  pagestore:
    type: persistentVolumeClaim
    storageClass: ""
    size: 100Gi
  • PVC 由 operator 创建

  • storageClass 默认设置为standard,但可以指定为空字符串进行静态绑定

挂载自定义配置映射

在Pods上可以使用自定义configmap提供配置文件。虽然也可以用于其他用途,例如环境变量,但以下示例重点关注文件。

从本地文件创建一个新的 configmap

kubectl create configmap my-configmap --from-file=/path/to/my-configmap

声明(declare)配置映射及其挂载点。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  configMaps:
    my-configmap: /path/to/mount
  • 键是 ConfigMap 的名称,值是容器中的挂载路径

  • 默认情况下,/opt/alluxio/conf 已被挂载。这意味着其他文件无法直接挂载到 conf/目录内。自定义配置映射需要挂载到其他路径。

    • 以缓存过滤器的json文件为例,将其挂载到 /opt/alluxio/conf/cachefilter/cache_filter.json, 并将此路径设置为 alluxio.user.client.cache.filter.config.file的值,以便Alluxio读取该文件。

将文件作为 Secret 添加至 Pods

该机制可以用于在 Pods 上提供凭证文件。

从本地文件创建一个新的 secret

kubectl create secret my-file --from-file=/path/to/my-file

指定要加载哪些 secret 以及在 Pods 上的文件路径。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  secrets:
    worker:
      my-file: /home/alluxio/my-file
    coordinator:
      my-file: /home/alluxio/my-file

使用 root 用户

进程默认使用 uid 为1000的用户。在容器中,用户名为 alluxio。 要将其更改为 root 用户,请使用此配置:

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  user: 0
  group: 0
  fsGroup: 0
  • 如果文件可由 root 用户组访问,指定 .spec.fsGroup = 0 即可。

  • 如果将挂载主机路径(如页面存储路径和日志路径)的所有权更改为 root 用户,则其所有权将转移到 root。

使用外部 ETCD

如果有外部的 ETCD 集群,可以指定 Alluxio 使用的端点。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  etcd:
    enabled: false
  properties:
    alluxio.etcd.endpoints: http://external-etcd:2379

当客户端与服务器之间通过 HTTPS 进行安全传输时,SSL/TLS和ETCD的连接会使用证书。因此,请准备好一个已签名的 key pair(server.crt, pkcs8_key.pem)。

这里需要的是PKCS8 key,可使用以下命令进行转换:

$ openssl pkcs8 -topk8 -nocrypt -in server.key -out pkcs8_key.pem

在Kubernetes中使用已创建的server.crtpkcs8_key.pem来创建 secret。

$ kubectl create secret generic cfssl --from-file=/home/ubuntu/cfssl-demo/server.crt --from-file=/home/ubuntu/cfssl-demo/pkcs8_key.pem

alluxio-cluster.yaml文件中配置 etcd 属性,并为 coordinator 和 worker 指定 secret.

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  etcd:
    enabled: false
  properties:
    alluxio.etcd.endpoints: https://external-etcd:2379
    alluxio.etcd.tls.enable: "true"
    alluxio.etcd.tls.client.cert: /secrets/cfssl/server.crt
    alluxio.etcd.tls.client.key: /secrets/cfssl/pkcs8_key.pem
  secrets:
    coordinator:
      cfssl: /secrets/cfssl
    worker:
      cfssl: /secrets/cfssl

在运行中的集群中动态更新 Alluxio 配置

  1. 获取 ConfigMap

$ kubectl get configmap
NAME                      DATA   AGE
alluxio-alluxio-conf      4      7m48s
  1. 编辑 ConfigMap 以更新 Alluxio 配置

$ kubectl edit configmap alluxio-alluxio-conf

ConfigMap 中应包含以下四个文件:alluxio-env.shalluxio-site.propertieslog4j2.xmlmetrics.properties。根据需要进行编辑后,保存 ConfigMap。

configmap/alluxio-alluxio-conf edited
  1. 根据需要重启 Alluxio 组件 假设集群名称为 alluxio:

  • coordinator: kubectl rollout restart statefulset alluxio-coordinator

  • worker: kubectl rollout restart deployment alluxio-worker

常见问题

etcd pod 一直处于 Pending 状态

比如三个 etcd pod 一直处于 Pending 状态,可以通过 kubectl describe pod 查看详细信息:

# 查看集群中的 pod 状态
kubectl get pod

NAME                                          READY   STATUS     RESTARTS   AGE
alluxio-coordinator-0                         0/1     Init:1/2   0          73s
alluxio-etcd-0                                0/1     Pending    0          73s
alluxio-etcd-1                                0/1     Pending    0          73s
alluxio-etcd-2                                0/1     Pending    0          73s
alluxio-monitor-grafana-79db8c7dd9-lsq2l      1/1     Running    0          73s
alluxio-monitor-prometheus-7c6cbc4b4c-9nk25   1/1     Running    0          73s
alluxio-worker-8c79d5fd4-2c994                0/1     Init:1/2   0          73s
alluxio-worker-8c79d5fd4-jrchj                0/1     Init:1/2   0          73s

# 查看 etcd pod 的详细信息
kubectl describe pod alluxio-etcd-0

Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  3m57s  default-scheduler  0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling., .

# 检查集群中的 PVC 状态
# 如果发现 PVC 一直处于 pending 状态,可进一步查看原因。
kubectl get pvc

NAME                           STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS                AGE
data-alluxio-etcd-0            Pending                                                                  3h41m
data-alluxio-etcd-1            Pending                                                                  3h41m
data-alluxio-etcd-2            Pending                                                                  3h41m

# 查看 pvc 的详细信息。
kubectl describe pvc data-alluxio-etcd-0

Events:
  Type    Reason         Age                      From                         Message
  ----    ------         ----                     ----                         -------
  Normal  FailedBinding  4m16s (x889 over 3h44m)  persistentvolume-controller  no persistent volumes available for this claim and no storage class is set

由报错信息可知,etcd Pods 处于 Pending 状态是因为没有设置 storage class。您可以通过在 alluxio-operator/alluxio-cluster.yaml 文件中指定 etcd 的 storage class 来解决。

  etcd:
    persistence:
      storageClass: <STORAGE_CLASS>
      size: 

首先删除 Alluxio 集群, 并且删除 etcd 的 pvc,然后重新创建 Alluxio 集群:

# 删除 Alluxio 集群
$ kubectl delete -f alluxio-operator/alluxio-cluster.yaml

#  删除 etcd 的 pvc
$ kubectl delete pvc data-alluxio-etcd-0
$ kubectl delete pvc data-alluxio-etcd-1
$ kubectl delete pvc data-alluxio-etcd-2

# 重新创建 Alluxio 集群
$ kubectl create -f alluxio-operator/alluxio-cluster.yaml

另外一种情况是 etcd pvc 指定了 storage class,但是 etcd pod 和 pvc 依然是 pending 状态。例如下面的 pvc 详细信息中所展示, etcd pvc 指定的 storage class 不支持动态制备,存储卷需要由集群管理员手动创建。

# 查看 etcd pvc 的详细信息
kubectl describe pvc data-alluxio-etcd-0

Events:
  Type    Reason                Age               From                         Message
  ----    ------                ----              ----                         -------
  Normal  WaitForFirstConsumer  25s               persistentvolume-controller  waiting for first consumer to be created before binding
  Normal  ExternalProvisioning  8s (x3 over 25s)  persistentvolume-controller  Waiting for a volume to be created either by the external provisioner 'none' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.

类似的 etcd pod 一直处于 Pending 状态的问题,可以通过上述方法进行排查。

无法访问公共镜像仓库

启动 Alluxio 集群还包括 etcd 和监控组件。如果无法访问公共镜仓库,则需要从私有镜像仓库拉取这些组件的镜像。

您可以将依赖镜像下载到本地,上传到您的私有镜像仓库,然后修改 alluxio-operator.yaml 文件中的镜像地址,再重新部署 operator。

组件镜像名版本用途

集群 ETCD

docker.io/bitnami/etcd

3.5.9-debian-11-r24

etcd 依赖

集群 ETCD

docker.io/bitnami/os-shell

11-debian-11-r2

os-shell 依赖

集群监控

grafana/grafana

10.4.5

监控仪表盘

集群监控

prom/prometheus

v2.52.0

指标采集

拉取 docker 镜像并且上传到私有镜像仓库的命令如下:

# 拉取 docker 镜像
$ docker pull docker.io/bitnami/etcd:3.5.9-debian-11-r24
$ docker pull docker.io/bitnami/os-shell:11-debian-11-r2
$ docker pull grafana/grafana:10.4.5
$ docker pull prom/prometheus:v2.52.0

# 将镜像更改为私有镜像仓库
$ docker tag docker.io/bitnami/etcd:3.5.9-debian-11-r24 <PRIVATE_REGISTRY>/etcd:3.5.9-debian-11-r24
$ docker tag docker.io/bitnami/os-shell:11-debian-11-r2 <PRIVATE_REGISTRY>/os-shell:11-debian-11-r2
$ docker tag grafana/grafana:10.4.5 <PRIVATE_REGISTRY>/grafana:10.4.5
$ docker tag prom/prometheus:v2.52.0 <PRIVATE_REGISTRY>/prometheus:v2.52.0

# 上传镜像到私有镜像仓库 
$ docker push <PRIVATE_REGISTRY>/etcd:3.5.9-debian-11-r24
$ docker push <PRIVATE_REGISTRY>/os-shell:11-debian-11-r2
$ docker push <PRIVATE_REGISTRY>/grafana:10.4.5
$ docker push <PRIVATE_REGISTRY>/prometheus:v2.52.0

相应地修改 alluxio-operator/alluxio-cluster.yaml 文件中的镜像地址。

apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
metadata:
  name: alluxio
spec:
  image: <PRIVATE_REGISTRY>/alluxio-enterprise
  imageTag: {{site.ALLUXIO_VERSION_STRING}}
  properties:

  worker:
    count: 2

  pagestore:
    size: 100Gi
  
  etcd:
    image:
      registry: <PRIVATE_REGISTRY>
      repository: <PRIVATE_REPOSITORY>/etcd
      tag: 3.5.9-debian-11-r24
    volumePermissions:
      image:
        registry: <PRIVATE_REGISTRY>
        repository: <PRIVATE_REPOSITORY>/os-shell
        tag: 11-debian-11-r2
    
  alluxio-monitor:
    prometheus:
      image: <PRIVATE_REGISTRY>/prometheus
      imageTag: v2.52.0
    grafana:
      image: <PRIVATE_REGISTRY>/grafana
      imageTag: 10.4.5

Last updated