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.7、3.8、3.9 和 3.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 构建。
如果你希望从源码制作一个镜像,可以参考我们的 Dockerfile 和 Docker 构建文档 进行制作。
一旦你的镜像构建完成,需要将其上传至一个你的 Kubernetes 集群能够访问到的仓库,例如,你自己的 Dockerhub 命名空间。
最后,使用部署接口 xorbits.deploy.kubernetes.client.new_cluster() 中的 image 选项去指定你的镜像即可。
安装 Python 包#
Xorbits 的发布镜像中已经包含了一些 Python 包,参考 Dockerfile 中安装内容。如果你想安装额外的 Python 包或者改变其中某些包的版本,使用 xorbits.deploy.kubernetes.client.new_cluster() 接口中的 pip 和 conda 选项即可。
注意,使用 pip 和 conda 选项时,请确保你的 Kubernetes 集群能够访问 PyPi 和 conda对应的通道。
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来轻松扩展和缩减存储资源。