diff --git a/addons/glusterfs/dev-guide/glusterfs-zh_CN.md b/addons/glusterfs/dev-guide/glusterfs-zh_CN.md new file mode 100644 index 000000000..5cc72b4b0 --- /dev/null +++ b/addons/glusterfs/dev-guide/glusterfs-zh_CN.md @@ -0,0 +1,141 @@ +# GlusterFS 接入 ThinRuntime 的简单示例 + +## 前期准备 +glusterfs 接入 ThinRuntime 需要构造 GlusterFS-FUSE 客户端,本实例使用 [该项目](https://github.com/gluster/gluster-containers) 为基础构建 FUSE 镜像。 + +## 准备 GlusterFS-FUSE 客户端镜像 +1. 挂载远程文件系统脚本 + +在 FUSE 容器内需要提取相关的 **ThinRuntimeProfile、Dataset、ThinRuntime**资源中对远程文件系统的配置信息,相关信息以 JSON 字符串的方式保存到 FUSE 容器的 **/etc/fluid/config.json** 文件内。 + +```python +import json +import os +import subprocess + +obj = json.load(open("/etc/fluid/config.json")) + +mount_point = obj["mounts"][0]["mountPoint"] +target_path = obj["targetPath"] + +os.makedirs(target_path, exist_ok=True) + +if len(mount_point.split(":")) != 2: + print( + f"The mountPoint format [{mount_point}] is wrong, should be server:volumeId") + exit(1) + +server, volume_id = mount_point.split(":") +args = ["glusterfs", "--volfile-server", server, "--volfile-id", + volume_id, target_path, "--no-daemon", "--log-file", "/dev/stdout"] + +# Available options are described in the following pages: +# https://manpages.ubuntu.com/manpages/trusty/en/man8/mount.glusterfs.8.html +# https://manpages.ubuntu.com/manpages/trusty/en/man8/glusterfs.8.html +if "options" in obj["mounts"][0]: + options = obj["mounts"][0]["options"] + for option in options: + if option[0] == "ro": + option[0] = "read-only" + elif option[0] == "transport": + option[0] = "volfile-server-transport" + + if option[1].lower() == "true": + args.append(f'--{option[0]}') + elif option[1].lower() == "false": + continue + else: + args.append(f"--{option[0]}={option[1]}") + +subprocess.run(args) +``` +该 shell 脚本创建挂载的文件夹并将远程文件系统挂载到目标位置(targetPath)。 + +2. 创建 FUSE 客户端镜像 + + +将脚本打包入镜像。 + +```dockerfile +FROM gluster/glusterfs-client@sha256:66b1d51d327ab1c4c1d81e6bad28444e13e1746c2d6f009f9874dad2fba9836e + +ADD entrypoint.py / + +CMD ["python3", "/entrypoint.py"] +``` + +## 使用示例 +### 创建并部署 ThinRuntimeProfile 资源 +```shell +$ cat < profile.yaml +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntimeProfile +metadata: + name: glusterfs +spec: + fileSystemType: mount.glusterfs + + fuse: + image: + imageTag: + imagePullPolicy: IfNotPresent +EOF + +$ kubectl apply -f profile.yaml +``` +将上述 改为您制作的镜像的仓库名称, 修改为该镜像的 TAG。 +### 创建并部署 Dataset 和 ThinRuntime 资源 +```shell +$ cat < data.yaml +apiVersion: data.fluid.io/v1alpha1 +kind: Dataset +metadata: + name: glusterfs-demo +spec: + mounts: + - mountPoint: + name: glusterfs-demo +--- +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntime +metadata: + name: glusterfs-demo +spec: + profileName: glusterfs +EOF + +$ kubectl apply -f data.yaml +``` +将上述 mountPoint(HOST_IP:PATH) 修改为您需要使用的远程 glusterfs 的地址。 + +### 部署应用 +```shell +$ cat < app.yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /data + name: glusterfs-demo + volumes: + - name: glusterfs-demo + persistentVolumeClaim: + claimName: glusterfs-demo +EOF + +$ kubectl apply -f app.yaml +``` +在将使用该远程文件系统的应用部署后,相应的 FUSE pod 也被调度到相同节点。 + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +glusterfs-demo-fuse-wx7ns 1/1 Running 0 12s +nginx 1/1 Running 0 26s +``` +远程的文件系统被挂载到 nginx pod 的 /data 目录下。 \ No newline at end of file diff --git a/addons/glusterfs/dev-guide/glusterfs.md b/addons/glusterfs/dev-guide/glusterfs.md new file mode 100644 index 000000000..e50bab316 --- /dev/null +++ b/addons/glusterfs/dev-guide/glusterfs.md @@ -0,0 +1,142 @@ +# Simple example of GlusterFS access to ThinRuntime + +## Prerequisites +GlusterFS access to ThinRuntime needs to construct an GlusterFS-fuse client. This demo uses [this repository](https://github.com/gluster/gluster-containers) to build a FUSE image. + +## Prepare GlusterFS-FUSE Client Image +1. Parameter Resolution Script + +In the FUSE container, you need to extract the configuration information of the remote file system from the relevant **ThinRuntimeProfile, Dataset, and ThinRuntime** resources. The relevant information is saved to the FUSE container in the form of JSON strings in **/etc/fluid/config.json** file. + +```python +import json +import os +import subprocess + +obj = json.load(open("/etc/fluid/config.json")) + +mount_point = obj["mounts"][0]["mountPoint"] +target_path = obj["targetPath"] + +os.makedirs(target_path, exist_ok=True) + +if len(mount_point.split(":")) != 2: + print( + f"The mountPoint format [{mount_point}] is wrong, should be server:volumeId") + exit(1) + +server, volume_id = mount_point.split(":") +args = ["glusterfs", "--volfile-server", server, "--volfile-id", + volume_id, target_path, "--no-daemon", "--log-file", "/dev/stdout"] + +# Available options are described in the following pages: +# https://manpages.ubuntu.com/manpages/trusty/en/man8/mount.glusterfs.8.html +# https://manpages.ubuntu.com/manpages/trusty/en/man8/glusterfs.8.html +if "options" in obj["mounts"][0]: + options = obj["mounts"][0]["options"] + for option in options: + if option[0] == "ro": + option[0] = "read-only" + elif option[0] == "transport": + option[0] = "volfile-server-transport" + + if option[1].lower() == "true": + args.append(f'--{option[0]}') + elif option[1].lower() == "false": + continue + else: + args.append(f"--{option[0]}={option[1]}") + +subprocess.run(args) +``` +The shell script creates the mounted folder and mounts the remote file system to the target location. + +2. Build FUSE Client Image + + +Package parameter resolution scripts, mount scripts, and related libraries into the image. + +```dockerfile +FROM gluster/glusterfs-client@sha256:66b1d51d327ab1c4c1d81e6bad28444e13e1746c2d6f009f9874dad2fba9836e + +ADD entrypoint.py / + +CMD ["python3", "/entrypoint.py"] +``` + +## Demo +### Create and Deploy ThinRuntimeProfile Resource +```shell +$ cat < profile.yaml +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntimeProfile +metadata: + name: glusterfs +spec: + fileSystemType: mount.glusterfs + + fuse: + image: + imageTag: + imagePullPolicy: IfNotPresent +EOF + +$ kubectl apply -f profile.yaml +``` +Replace the above to the repository name of the image you created, is modified to the TAG of your image. + +### Create and Deploy Dataset and ThinRuntime Resource +```shell +$ cat < data.yaml +apiVersion: data.fluid.io/v1alpha1 +kind: Dataset +metadata: + name: glusterfs-demo +spec: + mounts: + - mountPoint: + name: glusterfs-demo +--- +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntime +metadata: + name: glusterfs-demo +spec: + profileName: glusterfs +EOF + +$ kubectl apply -f data.yaml +``` +Modify the above mountPoint(HOST_IP:PATH) to the address of the remote glusterfs you want to use. + +### Deploy Application +```shell +$ cat < app.yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /data + name: glusterfs-demo + volumes: + - name: glusterfs-demo + persistentVolumeClaim: + claimName: glusterfs-demo +EOF + +$ kubectl apply -f app.yaml +``` +After the application using the remote file system is deployed, the corresponding FUSE pod is also scheduled to the same node. + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +glusterfs-demo-fuse-wx7ns 1/1 Running 0 12s +nginx 1/1 Running 0 26s +``` +The remote file system is mounted to the /data directory of nginx pod. \ No newline at end of file diff --git a/addons/glusterfs/docker/Dockerfile b/addons/glusterfs/docker/Dockerfile new file mode 100644 index 000000000..9bec09897 --- /dev/null +++ b/addons/glusterfs/docker/Dockerfile @@ -0,0 +1,5 @@ +FROM gluster/glusterfs-client@sha256:66b1d51d327ab1c4c1d81e6bad28444e13e1746c2d6f009f9874dad2fba9836e + +ADD entrypoint.py / + +CMD ["python3", "/entrypoint.py"] \ No newline at end of file diff --git a/addons/glusterfs/docker/build.sh b/addons/glusterfs/docker/build.sh new file mode 100644 index 000000000..679d3c56f --- /dev/null +++ b/addons/glusterfs/docker/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set +x + +docker build . --network=host -f Dockerfile -t fluidcloudnative/glusterfs:v0.1 + +docker push fluidcloudnative/glusterfs:v0.1 \ No newline at end of file diff --git a/addons/glusterfs/docker/entrypoint.py b/addons/glusterfs/docker/entrypoint.py new file mode 100644 index 000000000..ab557a829 --- /dev/null +++ b/addons/glusterfs/docker/entrypoint.py @@ -0,0 +1,39 @@ +import json +import os +import subprocess + +obj = json.load(open("/etc/fluid/config.json")) + +mount_point = obj["mounts"][0]["mountPoint"] +target_path = obj["targetPath"] + +os.makedirs(target_path, exist_ok=True) + +if len(mount_point.split(":")) != 2: + print( + f"The mountPoint format [{mount_point}] is wrong, should be server:volumeId") + exit(1) + +server, volume_id = mount_point.split(":") +args = ["glusterfs", "--volfile-server", server, "--volfile-id", + volume_id, target_path, "--no-daemon", "--log-file", "/dev/stdout"] + +# Available options are described in the following pages: +# https://manpages.ubuntu.com/manpages/trusty/en/man8/mount.glusterfs.8.html +# https://manpages.ubuntu.com/manpages/trusty/en/man8/glusterfs.8.html +if "options" in obj["mounts"][0]: + options = obj["mounts"][0]["options"] + for option in options: + if option[0] == "ro": + option[0] = "read-only" + elif option[0] == "transport": + option[0] = "volfile-server-transport" + + if option[1].lower() == "true": + args.append(f'--{option[0]}') + elif option[1].lower() == "false": + continue + else: + args.append(f"--{option[0]}={option[1]}") + +subprocess.run(args) diff --git a/addons/glusterfs/readme-zh_CN.md b/addons/glusterfs/readme-zh_CN.md new file mode 100644 index 000000000..5192fd013 --- /dev/null +++ b/addons/glusterfs/readme-zh_CN.md @@ -0,0 +1,72 @@ +# GlusterFS + +该插件用于 [GlusterFS](https://www.gluster.org/). + +## 安装 + +```shell +kubectl apply -f runtime-profile.yaml +``` + +## 使用 + +### 创建 Dataset 和 ThinRuntime +```shell +$ cat < dataset.yaml +apiVersion: data.fluid.io/v1alpha1 +kind: Dataset +metadata: + name: glusterfs-demo +spec: + mounts: + - mountPoint: + name: glusterfs-demo +--- +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntime +metadata: + name: glusterfs-demo +spec: + profileName: glusterfs +EOF + +$ kubectl apply -f dataset.yaml +``` +将上述`mountPoint`修改为实际挂载的glusterfs地址 + +### 运行Pod,并且使用Fluid PVC + +```shell +$ cat < app.yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /data + name: glusterfs-demo + volumes: + - name: glusterfs-demo + persistentVolumeClaim: + claimName: glusterfs-demo +EOF + +$ kubectl apply -f app.yaml +``` +使用远程文件系统的应用部署完成后,对应的FUSE pod也会被调度到同一个节点上。 + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +glusterfs-demo-fuse-wx7ns 1/1 Running 0 12s +nginx 1/1 Running 0 26s +``` +远程文件系统被挂载到nginx容器的`/data`目录下 + + +## 如何开发 +请参考 [doc](dev-guide/glusterfs-zh_CN.md) diff --git a/addons/glusterfs/readme.md b/addons/glusterfs/readme.md new file mode 100644 index 000000000..60c9cab4f --- /dev/null +++ b/addons/glusterfs/readme.md @@ -0,0 +1,72 @@ +# GlusterFS + +该插件用于 [GlusterFS](https://www.gluster.org/). + +## Install + +```shell +kubectl apply -f runtime-profile.yaml +``` + +## How to use + +### Create and Deploy Dataset and ThinRuntime Resource +```shell +$ cat < dataset.yaml +apiVersion: data.fluid.io/v1alpha1 +kind: Dataset +metadata: + name: glusterfs-demo +spec: + mounts: + - mountPoint: + name: glusterfs-demo +--- +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntime +metadata: + name: glusterfs-demo +spec: + profileName: glusterfs +EOF + +$ kubectl apply -f dataset.yaml +``` +Modify the above mountPoint to the address of the remote glusterfs you want to use. + +### Run pod with Fluid PVC + +```shell +$ cat < app.yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - mountPath: /data + name: glusterfs-demo + volumes: + - name: glusterfs-demo + persistentVolumeClaim: + claimName: glusterfs-demo +EOF + +$ kubectl apply -f app.yaml +``` +After the application using the remote file system is deployed, the corresponding FUSE pod is also scheduled to the same node. + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +glusterfs-demo-fuse-wx7ns 1/1 Running 0 12s +nginx 1/1 Running 0 26s +``` +The remote file system is mounted to the /data directory of nginx pod. + +## How to develop + +Please check [doc](dev-guide/glusterfs.md) diff --git a/addons/glusterfs/runtime-profile.yaml b/addons/glusterfs/runtime-profile.yaml new file mode 100644 index 000000000..7d00fed4b --- /dev/null +++ b/addons/glusterfs/runtime-profile.yaml @@ -0,0 +1,10 @@ +apiVersion: data.fluid.io/v1alpha1 +kind: ThinRuntimeProfile +metadata: + name: glusterfs +spec: + fileSystemType: fuse.glusterfs + fuse: + image: fluidcloudnative/glusterfs + imageTag: v0.1 + imagePullPolicy: IfNotPresent \ No newline at end of file