Kubernetes 部署#

前置条件#

在 Kubernetes 集群管理机器上安装Xorbits。参考 安装教程

Kubernetes 部署#

确保机器上有一个可用的 Kubernetes 集群,同时开启 ingress 服务

例如,如果你的机器上安装的是 Minikube ,运行如下命令以启动集群和开启 ingress :

$ minikube start
$ minikube addons enable ingress

参考 Minikube 文档 以验证 ingress 服务是否正确启动。

对于 macOS 操作系统上基于 docker 后端的 Minikube 集群,由于其网络架构的 限制,需要安装 docker-mac-net-connect 以正确使用 ingress 服务代理出来的地址。参考以下命令:

# Install via Homebrew
$ brew install chipmk/tap/docker-mac-net-connect

# Run the service and register it to launch at boot
# Notice that this command must be executed with sudo
$ sudo brew services start chipmk/tap/docker-mac-net-connect

然后可以通过 python 代码部署 Xorbits 至你的 Kubernetes 集群,例如:

from kubernetes import config
from xorbits.deploy.kubernetes import new_cluster
cluster = new_cluster(config.new_client_from_config(), worker_cpu=1, worker_mem='4g')

请务必确保机器上的 kubectl 命令指向你的 Kubernetes 集群。

运行上述部署代码后,控制台将出现形如 Xorbits endpoint http://<ingress_service_ip>:80 is ready! 的日志。此时意味着部署成功,你可以通过日志中的地址访问 Xorbits 集群的网页。

部署代码中的 new_cluster 接口的完整参数和说明请参考 xorbits.deploy.kubernetes.client.new_cluster()

在同一控制台中运行如下代码验证 Xorbits 集群是否正常工作:

import xorbits.pandas as pd
print(pd.DataFrame({'a': [1,2,3,4]}).sum())

Docker 镜像#

Xorbits 默认使用 xprobe/xorbits 中的镜像。每个 Xorbits 的发布版本均会包含带有版本号标签 <xorbits version> 的镜像,形式为 xprobe/xorbits:<xorbits version>

备注

v0.1.2 起,每个 Xorbits 的发布版本支持 python 3.73.83.93.10 四个版本,镜像标签以 -py<python_version> 为后缀。

例如,标签为 xprobe/xorbits:v0.1.2-py3.10 的镜像代表着该镜像中的 Xorbits 基于 python 3.10 版本构建。

默认情况下,标签为 xprobe/xorbits:<xorbits version> 的镜像依然存在,它基于python 3.9 构建。

v0.2.0 起, 默认情况下,Xorbits 将根据本地的 Python 版本自动选择 Kubernetes 部署时的镜像。例如,如果你的本地 Python 版本为 3.9,Xorbits 将默认在部署过程中使用标签为 xprobe/xorbits:<xorbits version>-py3.9 的镜像。

v0.2.1 起,Xorbits 镜像不再支持 Python 3.7,同时新增对 Python 3.11 的支持。标签为 xprobe/xorbits:<xorbits version> 的镜像基于 Python 3.10 构建。

If you need to build an image from source, the related Dockerfiles exists at this position for reference. You can follow the Docker document to build your own Xorbits image.

一旦你的镜像构建完成,需要将其上传至一个你的 Kubernetes 集群能够访问到的仓库,例如,你自己的 Dockerhub 命名空间。

最后,使用部署接口 xorbits.deploy.kubernetes.client.new_cluster() 中的 image 选项去指定你的镜像即可。

安装 Python 包#

Refer DockerFile for the python packages included in the Xorbits image. If you want to install additional python packages in your Xorbits K8s cluster, use pip and conda options of the xorbits.deploy.kubernetes.client.new_cluster() api.

注意,使用 pipconda 选项时,请确保你的 Kubernetes 集群能够访问 PyPiconda对应的通道

JuiceFS on Kubernetes#

Xorbits 现在集成了 JuiceFS ,一个可以与 Kubernetes 轻松集成来提供持久化存储的分布式 POSIX 文件系统。

前置条件#

Xorbits#

在计划使用JuiceFS的机器上安装Xorbits。请参考 安装文档 进行操作。

元数据存储#

JuiceFS将数据和元数据进行解耦。支持多种数据库。请查看 如何设置元数据引擎 ,选择适合的元数据存储方式。

在我们的例子中,我们选择使用Redis作为我们的元数据存储。

请按照 使用ConfigMap配置Redis的教程 进行操作,在默认命名空间内创建一个Pod。

您应该将maxmemory设置为50mb,因为示例中的2mb太小了。

确保redis的pod正在运行:

$ kubectl get po redis
NAME    READY   STATUS    RESTARTS    AGE
redis   1/1     Running   0           6d6h

检查Redis Pod的IP地址。在这个例子中,Redis的IP地址是172.17.0.8。

$ kubectl get po redis -o custom-columns=IP:.status.podIP --no-headers
172.17.0.8

您可以通过运行以下命令来查看Redis Pod获得了多少CPU和内存资源:

$ kubectl get po redis

并检查相应的字段。

Kubernetes 部署#

$ pip install kubernetes

请按照先前提供的Kubernetes部分的步骤,在您的机器上初始化一个Kubernetes集群。

安装kubectl,它是一个用于与Kubernetes集群进行交互的命令行工具,并验证其安装。

$ kubectl version --client
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"25", GitVersion:"v1.25.4", GitCommit:"872a965c6c6526caa949f0c6ac028ef7aff3fb78", GitTreeState:"clean", BuildDate:"2022-11-09T13:36:36Z", GoVersion:"go1.19.3", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v4.5.7

JuiceFS 安装#

我们将带您逐步完成在Kubernetes集群上安装JuiceFS的过程,使您能够充分利用其功能和优势。在Kubernetes上使用JuiceFS有三种方式,可以参考在Kubernetes上使用 JuiceFS 文档进行操作。

但是我们在Kubernetes中的JuiceFS的实现必须依赖CSI,因为CSI提供更好的可移植性、增强的隔离性和更高级的功能。

参考页面:JuiceFS CSI驱动程序

JuiceFS CSI 驱动#

使用Helm安装#

参考页面:用Helm安装JuiceFS

首先,安装Helm

其次,下载JuiceFS CSI驱动程序的Helm Chart。

$ helm repo add juicefs https://juicedata.github.io/charts/
$ helm repo update
$ helm fetch --untar juicefs/juicefs-csi-driver
$ cd juicefs-csi-driver
# Installation configurations is included in values.yaml, review this file and modify to your needs
$ cat values.yaml

在设置CPU和内存的限制和请求时,您应该根据您的系统设置进行谨慎操作。请根据实际情况进行相应的更改。这里我们为您提供最小配置。

resources:
  limits:
    cpu: 100m
    memory: 50Mi
  requests:
    cpu: 100m
    memory: 50Mi

然后,执行以下命令以部署JuiceFS CSI驱动程序:

$ helm install juicefs-csi-driver juicefs/juicefs-csi-driver -n kube-system -f ./values.yaml`

接着,验证安装

$ kubectl -n kube-system get pods -l app.kubernetes.io/name=juicefs-csi-driver
NAME                       READY   STATUS    RESTARTS   AGE
juicefs-csi-controller-0   3/3     Running   0          22m
juicefs-csi-node-v9tzb     3/3     Running   0          14m

如果您将来想要删除JuiceFS CSI驱动程序,可以运行以下命令:

$ helm list -n kube-system
NAME                NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                           APP VERSION
juicefs-csi-driver  kube-system     1               2023-05-31 03:12:16.717087425 +0000 UTC deployed        juicefs-csi-driver-0.15.1       0.19.0

$ helm uninstall juicefs-csi-driver -n kube-system
创建并使用PV#

如果您想直接在Kubernetes上使用JuiceFS,则可以跳过此创建和使用PV部分,因为在Xorbits中,new_cluster函数将为您创建密钥(Secret)、持久卷(PV)和持久卷声明(PVC)。

如果您想了解挂载是如何工作的以及配置中每个参数的含义,您可以浏览这一部分内容。

JuiceFS利用持久卷(Persistent Volumes)来存储数据。

参考页面:创建和使用PV

我们将创建几个YAML文件。在使用之前,请在 YAML验证器 上验证其格式。

首先,创建kubernetes密钥:

$ vim secret.yaml

请将以下内容写入YAML文件中:

apiVersion: v1
kind: Secret
metadata:
  name: juicefs-secret
type: Opaque
stringData:
  name: jfs
  metaurl: redis://172.17.0.8:6379/1 # Replace with your own metadata storage URL
  storage: file # Check out full supported list on `Set Up Object Storage <https://juicefs.com/docs/community/how_to_setup_object_storage/>`_.
  bucket: /var # Bucket URL. Read `Set Up Object Storage <https://juicefs.com/docs/community/how_to_setup_object_storage/>`_ to learn how to setup different object storage.

在我们的例子中,我们不需要访问密钥(access-key)和秘密密钥(secret-key)。如果您需要对象存储凭据,请添加相应内容。

其次,使用静态配置创建持久卷(Persistent Volume)和持久卷声明(Persistent Volume Claim)。

阅读 使用方法,了解静态配置和动态配置之间的区别。

$ vim static_provisioning.yaml

请将以下内容写入YAML文件中:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: juicefs-pv
  labels:
    juicefs-name: juicefs-fs # Works as a match-label for selector
spec:
  # For now, JuiceFS CSI Driver doesn't support setting storage capacity for static PV. Fill in any valid string is fine.
  capacity:
    storage: 10Pi
  volumeMode: Filesystem
  mountOptions: ["subdir=/data/subdir"]  # Mount in sub directory to achieve data isolation. See https://juicefs.com/docs/csi/guide/pv/#create-storage-class for more references.
  accessModes:
    - ReadWriteMany # accessModes is restricted to ReadWriteMany because it's the most suitable mode for our system. See https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes for more reference.
  persistentVolumeReclaimPolicy: Retain # persistentVolumeReclaimPolicy is restricted to Retain for Static provisioning. See https://juicefs.com/docs/csi/guide/resource-optimization/#reclaim-policy for more references.
  csi:
    # A CSIDriver named csi.juicefs.com is created during installation
    driver: csi.juicefs.com
    # volumeHandle needs to be unique within the cluster, simply using the PV name is recommended
    volumeHandle: juicefs-pv
    fsType: juicefs
    # Reference the volume credentials (Secret) created in previous step
    # If you need to use different credentials, or even use different JuiceFS volumes, you'll need to create different volume credentials
    nodePublishSecretRef:
      name: juicefs-secret
      namespace: xorbits-ns-cc53e351744f4394b20180a0dafd8b91 # change the namespace to your Xorbits namespace
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: juicefs-pvc
  namespace: xorbits-ns-cc53e351744f4394b20180a0dafd8b91 # change the namespace to your Xorbits namespace
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  # Must use an empty string as storageClassName
  # Meaning that this PV will not use any StorageClass, instead will use the PV specified by selector
  storageClassName: ""
  # For now, JuiceFS CSI Driver doesn't support setting storage capacity for static PV. Fill in any valid string that's lower than the PV capacity.
  resources:
    requests:
      storage: 10Pi
  selector:
    matchLabels:
      juicefs-name: juicefs-fs

接着,在您的命名空间中应用密钥(Secret)、持久卷(PV)和持久卷声明(PVC),并进行验证:

创建您的命名空间(或Xorbits命名空间),然后运行以下命令:

$ kubectl apply -f secret.yaml -n {your_namespace}
$ kubectl apply -f static_provisioning -n {your_namespace}
$ kubectl get pv
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                       STORAGECLASS   REASON   AGE
juicefs-pv    10Pi       RWX            Retain           Bound    xorbits-ns-cc53e351744f4394b20180a0dafd8b91/juicefs-pvc                             17h

$ kubectl get pvc --all-namespaces
NAMESPACE                                     NAME           STATUS   VOLUME        CAPACITY   ACCESS MODES   STORAGECLASS   AGE
xorbits-ns-cc53e351744f4394b20180a0dafd8b91   juicefs-pvc    Bound    juicefs-pv    10Pi       RWX                           17h

然后,创建一个pod

$ vim pod.yaml

请将以下内容写入YAML文件中:

apiVersion: v1
kind: Pod
metadata:
  name: juicefs-app
  namespace: xorbits-ns-cc53e351744f4394b20180a0dafd8b91 # Replace with your namespace
spec:
  containers:
  - args:
    - -c
    - while true; do echo $(date -u) >> /juicefs-data/out.txt; sleep 5; done
    command:
    - /bin/sh
    image: centos
    name: app
    volumeMounts:
    - mountPath: /juicefs-data
      name: data
    resources:
      requests:
        cpu: 10m
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: juicefs-pvc

在Pod启动并运行后,您将在JuiceFS挂载点/juicefs-data内看到容器创建的out.txt文件。

恭喜!您已成功在Kubernetes上设置了JuiceFS。

部署集群#

在部署之前,请前往我们的 DockerHub 获取最新的Docker镜像。

通过运行以下命令来检查镜像:

$ docker image ls
REPOSITORY                              TAG                                      IMAGE ID       CREATED         SIZE
xprobe/xorbits                          v0.4.0-py3.10                            4166e1b0676d   5 days ago      3.38GB

部署Xorbits集群,例如:

from kubernetes import config
from xorbits.deploy.kubernetes import new_cluster


cluster = new_cluster(config.new_client_from_config(), worker_num=1, worker_cpu=1, worker_mem='1g', supervisor_cpu=1, supervisor_mem='1g', image='xprobe/xorbits:v0.4.0-py3.10', external_storage='juicefs',external_storage_config={"metadata_url": "redis://172.17.0.8:6379/1","bucket": "/var", "mountPath": "/juicefs-data"},)

目前,我们仅支持将JuiceFS作为存储后端之一。当您希望从Shared Memory切换到JuiceFS时,您必须在初始化新集群时明确指定 external_storage='juicefs'

JuiceFS有相应的参数,您应该在名为external_storage_config的字典中指定这些参数。

您必须明确指定连接URL metadata_url ,在我们的例子中为 redis://172.17.0.8:6379/1 。172.17.0.8是Redis服务器的IP地址,6379是Redis服务器监听的默认端口号,1表示Redis数据库编号。

使用 bucket 指定存储桶URL,如果您不想更改存储桶的目录,则可以使用默认值 /var 。参考 设置对象存储 以设置不同的对象存储。

使用 mountPath 指定挂载路径,或者使用默认值 /juicefs-data

几分钟后,您将看到 Xorbits endpoint http://<ingress_service_ip>:80 已准备就绪!

通过运行一个简单的任务来验证集群。

import xorbits
xorbits.init('http://<ingress_service_ip>:80')
import xorbits.pandas as pd
pd.DataFrame({'a': [1,2,3,4]}).sum()

如果集群正常工作,输出应该是10。

验证存储#

在我们的示例中,我们将JuiceFS存储数据挂载在 /juicefs-data 目录下,这也是默认路径。

首先,获取以 xorbits 开头的命名空间,并获取其Pods。

$ kubectl get namespaces
NAME                                          STATUS   AGE
default                                       Active   38d
kube-node-lease                               Active   38d
kube-public                                   Active   38d
kube-system                                   Active   38d
xorbits-ns-cc53e351744f4394b20180a0dafd8b91   Active   4m5s

$ kubectl get po -n xorbits-ns-cc53e351744f4394b20180a0dafd8b91
NAME                                 READY   STATUS             RESTARTS   AGE
xorbitssupervisor-84754bf5f4-dcstd   1/1     Running            0          80s
xorbitsworker-5b9b976767-sfpkk       1/1     Running            0          80s

然后,在属于Xorbits命名空间的Pod中执行一个交互式的shell(bash)。您可以验证主管(supervisor)Pod或工作(worker)Pod,或者验证它们两个。

$ kubectl exec -it xorbitssupervisor-84754bf5f4-dcstd -n xorbits-ns-cc53e351744f4394b20180a0dafd8b91 -- /bin/bash

检查数据是否存储在 /juicefs-data 目录中。

您应该会看到一个类似于9c3e069a-70d9-4874-bad6-d608979746a0的十六进制字符串,这表示JuiceFS内的数据已成功挂载!

$ cd ..
$ cd juicefs-data
$ ls
9c3e069a-70d9-4874-bad6-d608979746a0
$ cat 9c3e069a-70d9-4874-bad6-d608979746a0

您应该会看到简单任务的序列化输出,该输出可能不易读。它应该包含 pandas ,这表示它与我们执行的简单任务的结果匹配上了!

管理Xorbits集群和调试#

您可以按照 详细教程:在Amazon EKS上部署和运行Xorbits,获取Xorbits命名空间、检查Xorbits Pod的状态,并检查Xorbits UI。

如果一切正常,现在您可以通过在命名空间中添加或删除Pod来轻松扩展和缩减存储资源。