基于 ACK Fluid 的混合云优化数据访问(二):搭建弹性计算实例与第三方存储的桥梁

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 基于 ACK Fluid 的混合云优化数据访问(二):搭建弹性计算实例与第三方存储的桥梁

作者:车漾

前文回顾:

本系列将介绍如何基于 ACK Fluid 支持和优化混合云的数据访问场景,相关文章请参考:

基于 ACK Fluid 的混合云优化数据访问(一):场景与架构


在前文《场景与架构》中,重点介绍 ACK Fluid 支持混合云数据访问适用的不同应用场景和架构实现。在本文中会重点介绍如何通过 ACK Fluid 实现公共云的弹性计算实例访问云下存储系统的能力。



概述


ACK(阿里云容器服务 Kubernetes)即开即用的弹性能力可以很好做自建IDC的弹性能力补充。特别是随着 AIGC 的流行,算力推动创新的理念深入人心,许多原本抵制计算上云的客户也开始在评估公共云。他们通常会选择使用 ECI(弹性计算实例)作为技术验证的第一步。但是,如何将自建存储与云上弹性资源对接,特别是 ECI 资源对接,就成了混合云客户使用阿里云的门槛。比如,用户想快速比较通过云上 ASK 和云下自建机房运行训练任务的成本,传统的做法需要把数据搬到云上,这就会涉及数据隐私问题,还有迁移的时间和金钱成本,无法做快速验证。甚至有些客户短期内无法通过内部安全评审,导致整个创新节奏受到严重的影响。


可以看到许多企业的数据都是存在线下,并且使用的存储类型多样,包括各种开源存储(Ceph,lustrure,JuiceFS,CubeFS)和自建存储。在使用公共云计算资源的时候,也存在挑战:


  • 数据迁云安全性和成本评估时间长:对于数据迁移到云存储上,需要安全和存储团队的长时间评估,这会延缓整个上云过程。
  • 数据访问适配性差:比如公共云对于弹性计算实例(ECI)支持的分布式存储类型有限(比如 NAS,OSS,CPFS),但是对于第三方存储缺乏支持。
  • 接入云平台周期长和难度高:需要开发和维护云原生兼容的 CSI 插件,一方面需要相关的专家和开发适配工程量,同时要维护版本的升级,同时支持的场景有限。比如自建 CSI 无法适配弹性计算实例(ECI)。
  • 缺乏可信透明的数据接入方式:如何在 Serverless 容器的黑盒系统访问数据过程中规避泄露,如何确保数据在传输、访问过程中安全,透明,可靠。
  • 避免业务修改的需求:如何确保业务用户不感知基础设施层面的差异,避免对现有应用本身进行任何修改。


ACK Fluid 通过提供 ThinRuntime 扩展机制支持将基于 FUSE 实现第三方存储客户端以容器化的方式接入 Kubernetes 中,可以支持阿里云上标准 Kubernetes,边缘 Kubernetes,Serverless Kubernetes 多种形态。


  1. 简单的开发接入模式,易扩展: 基于 ThinRuntime 方案,只需要了解 Dockerfile 构建就可以完成,一般开发工作 2-3 小时左右,从而显著降低了接入第三方存储的工作成本。同时基于开源 Fluid 标准对于 ThinRuntime 提供了完整的支持,只要满足开源要求就可以适配。
  2. 安全可控的数据访问:以容器化的方式支持自定义方式实现数据访问。整个数据访问过程云平台无侵入,无需提供实现细节。
  3. 无降低改造适配的成本:只需要在 PVC 中添加特定 label 即可,满足了业务用户无需感知基础设施层面的差异的需求,能将存储适配时间缩短为原计划的十分之一。
  4. 存储客户端的自适应部署:Fluid 同时支持 CSI 和 FUSE Sidecar 两种客户端部署模式,根据所在运行平台选择合适的部署模式,将 PVC 协议转换成 Sidecar 模式,无需最终用户感知。
  5. 增强可观测性和可控制性:第三方存储客户端只需要实现自身的容器化,就可以转化为 Fluid 管理的 Pod,无缝接入 Kubernetes 体系,并获得可观测性和计算资源可控制性。


总结:ACK Fluid 为云上计算访问云下数据提供了扩展性好,安全可控,低适配成本和与云平台实现无关的好处,应用案例参见小米[1]


演示


以开源 MinIO 为例,展示如何通过 Fluid 将第三方存储接入阿里云弹性计算资源(ECI)。


1. 前提条件

  • 已创建 ACK Pro 版集群,且集群版本为 1.18 及以上。具体操作,请参见创建 ACK Pro 版集群[2]
  • 已安装云原生 AI 套件并部署 ack-fluid 组件。重要:若您已安装开源 Fluid,请卸载后再部署 ack-fluid 组件。
  • 未安装云原生 AI 套件:安装时开启 Fluid 数据加速。具体操作,请参见安装云原生 AI 套件[3]
  • 已安装云原生 AI 套件:在容器服务管理控制台的云原生 AI 套件页面部署 ack-fluid。
  • 已部署 ACK 虚拟节点(Virtual Node)。具体操作,请参见通过部署 ACK 虚拟节点组件创建 ECI Pod[4]
  • 已通过 kubectl 连接 ACK 集群。具体操作,请参见通过 kubectl 工具连接集群[5]


2. 准备MinIO环境

部署 Minio 存储到 ACK 集群中。

如下 YAML 文件 minio.yaml:


apiVersion: v1
kind: Service
metadata:
  name: minio
spec:
  type: ClusterIP
  ports:
    - port: 9000
      targetPort: 9000
      protocol: TCP
  selector:
    app: minio
---
apiVersion: apps/v1 #  for k8s versions before 1.9.0 use apps/v1beta2  and before 1.8.0 use extensions/v1beta1
kind: Deployment
metadata:
  # This name uniquely identifies the Deployment
  name: minio
spec:
  selector:
    matchLabels:
      app: minio
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        # Label is used as selector in the service.
        app: minio
    spec:
      containers:
      - name: minio
        # Pulls the default Minio image from Docker Hub
        image: bitnami/minio
        env:
        # Minio access key and secret key
        - name: MINIO_ROOT_USER
          value: "minioadmin"
        - name: MINIO_ROOT_PASSWORD
          value: "minioadmin"
        - name: MINIO_DEFAULT_BUCKETS
          value: "my-first-bucket:public"
        ports:
        - containerPort: 9000
          hostPort: 9000


部署上述资源到 ACK 集群:


$ kubectl create -f minio.yaml


部署成功后,ACK 集群内的其他 Pod 即可通过 http://minio:9000的Minio API 端点访问 Minio 存储系统中的数据。上述 YAML 配置中,我们设置 Minio 的用户名与密码均为 minioadmin,并在启动 Minio 存储时默认创建一个名为 my-first-bucket 的存储桶,在接下来的示例中,我们将会访问 my-first-bucket 这个存储桶中的数据。在执行以下步骤前,首先执行以下命令,在 my-first-bucket 中存储示例文件:


$ kubectl exec -it minio-69c555f4cf-np59j -- bash -c "echo fluid-minio-test > testfile"
$ kubectl exec -it minio-69c555f4cf-np59j -- bash -c "mc cp ./testfile local/my-first-bucket/" 
$ kubectl exec -it  minio-69c555f4cf-np59j -- bash -c "mc cat local/my-first-bucket/testfile"
fluid-minio-test


3. 集群管理员将 MinIO 接入 Fluid 的开发和部署过程

作为一个 MinIO 存储管理员,接入 Fluid 的工作主要是三个步骤,以下调试过程可以在开源 Kubernetes 中完成:

  1. 开发和构建 MinIO 容器镜像
  2. 开发和部署 MinIO 的 RuntimeProfile
  3. 创建访问 MinIO 的 Fluid 数据集,并且生成对应的数据卷


3.1. 容器镜像的开发和构建

Fluid 将会把 ThinRuntime 中 FUSE 所需的运行参数、Dataset 中描述数据路径的挂载点等参数传入到 ThinRuntime FUSE Pod 容器中。在容器内部,需要执行参数解析脚本,并将解析完的运行时参数传递给 FUSE 客户端程序,由客户端程序完成 Fuse 文件系统在容器内的挂载。


因此,使用 ThinRuntime CRD 描述存储系统时,需要使用特制的容器镜像,镜像中需要包括以下两个程序:

  • FUSE 客户端程序
  • FUSE 客户端程序所需的运行时参数解析脚本


对于 FUSE 客户端程序,在本示例中选择 S3 协议兼容的 goofys 客户端连接并挂载 minio 存储系统。


对于运行时所需的参数解析脚本,定义如下 python 脚本 fluid-config-parse.py:


import json
with open("/etc/fluid/config.json", "r") as f:
    lines = f.readlines()
rawStr = lines[0]
print(rawStr)
script = """
#!/bin/sh
set -ex
export AWS_ACCESS_KEY_ID=`cat $akId`
export AWS_SECRET_ACCESS_KEY=`cat $akSecret`
mkdir -p $targetPath
exec goofys -f --endpoint "$url" "$bucket" $targetPath
"""
obj = json.loads(rawStr)
with open("mount-minio.sh", "w") as f:
    f.write("targetPath=\"%s\"\n" % obj['targetPath'])
    f.write("url=\"%s\"\n" % obj['mounts'][0]['options']['minio-url'])
    if obj['mounts'][0]['mountPoint'].startswith("minio://"):
      f.write("bucket=\"%s\"\n" % obj['mounts'][0]['mountPoint'][len("minio://"):])
    else:
      f.write("bucket=\"%s\"\n" % obj['mounts'][0]['mountPoint'])
    f.write("akId=\"%s\"\n" % obj['mounts'][0]['options']['minio-access-key'])
    f.write("akSecret=\"%s\"\n" % obj['mounts'][0]['options']['minio-access-secret'])
    f.write(script)


上述 python 脚本按以下步骤执行:


  1. 读取 /etc/fluid/config.json 文件中的 json 字符串,Fluid 会将 Fuse 客户端挂载所需的参数存储并挂载到 Fuse 容器的 /etc/fluid/config.json 文件。
  2. 解析 json 字符串,从中提取 Fuse 客户端挂载所需的参数。例如,上述示例中的 url、bucket、minio-access-key、minio-access-secret 等参数。
  3. 提取出所需参数后,输出挂载脚本到文件 mount-minio.sh。


⚠️注意:在 Fluid 中,/etc/fluid/config.json 文件中仅会提供各个加密参数具体值的存储路径,因此需要参数解析脚本额外执行文件读取操作(例如:上述示例中的 "export AWS_ACCESS_KEY_ID=`cat $akId`")。


接着,使用如下 Dockerfile 制作镜像,这里我们直接选择包含 goofys 客户端程序的镜像(i.e. cloudposse/goofys)作为 Dockerfile 的基镜像:


FROM cloudposse/goofys
RUN apk add python3 bash
COPY ./fluid-config-parse.py /fluid-config-parse.py


使用以下命令构建并推送镜像到镜像仓库:


$ IMG_REPO=<your image repo>
$ docker build -t $IMG_REPO/fluid-minio-goofys:demo .
$ docker push $IMG_REPO/fluid-minio-goofys:demo


3.2. 开发和部署 MinIO 的 ThinRuntimeProfile

在创建 Fluid Dataset 和 ThinRuntime 挂载 Minio 存储系统前,首先需要开发 ThinRuntimeProfile CR 资源。ThinRuntimeProfile 是一种 Kubernetes 集群级别的 Fluid CRD 资源,它描述了一类需要与 Fluid 对接的存储系统的基础配置(例如:容器、计算资源描述信息等)。集群管理员需提前在集群中定义若干 ThinRuntimeProfile CR 资源,在这之后,集群用户需要显示声明引用一个 ThinRuntimeProfile CR 来创建 ThinRuntime,从而完成对应存储系统的挂载。


以下为 MinIO 存储系统的 ThinRuntimeProfile CR 示例(profile.yaml):


apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntimeProfile
metadata:
  name: minio
spec:
  fileSystemType: fuse
  fuse:
    image: $IMG_REPO/fluid-minio-goofys
    imageTag: demo
    imagePullPolicy: IfNotPresent
    command:
    - sh
    - -c
    - "python3 /fluid-config-parse.py && chmod u+x ./mount-minio.sh && ./mount-minio.sh"


在上述 CR 示例中:

  • fileSystemType 描述了 ThinRuntime FUSE 所挂载的文件系统类型 (fsType)。需要根据使用的存储系统 Fuse 客户端程序填写,例如,goofys 挂载的挂载点 fsType为fuse,s3fs 挂载的挂载点 fsType 为 fuse.s3fs)
  • fuse 描述了 ThinRuntime FUSE 的容器信息,包括镜像信息 (image、imageTag、imagePullPolicy) 以及容器启动命令 (command) 等。


创建 ThinRuntimeProfile CR minio 并且部署到 ACK 集群。


3.3. 创建 Dataset 和 ThinRuntime CR 来挂载访问 Minio 存储系统中的数据。

创建访问 minio 所需的凭证 Secret:


$ kubectl create secret generic minio-secret \                                                                                   
  --from-literal=minio-access-key=minioadmin \ 
  --from-literal=minio-access-secret=minioadmin


创建 Dataset 和 ThinRuntime CR 的示例(dataset.yaml),目的是生成用户可用的存储数据卷:


apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: minio-demo
spec:
  mounts:
  - mountPoint: minio://my-first-bucket   # minio://<bucket name>
    name: minio
    options:
      minio-url: http://minio:9000  # minio service <url>:<port>
    encryptOptions:
      - name: minio-access-key
        valueFrom:
          secretKeyRef:
            name: minio-secret
            key: minio-access-key
      - name: minio-access-secret
        valueFrom:
          secretKeyRef:
            name: minio-secret
            key: minio-access-secret
---
apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntime
metadata:
  name: minio-demo
spec:
  profileName: minio


  • Dataset.spec.mounts[*].mountPoint 指定所需访问的数据桶 (e.g. my-frist-bucket)
  • Dataset.spec.mounts[*].options.minio-url 指定 minio 在集群可访问的 URL(e.g. http://minio:9000)
  • ThinRuntime.spec.profileName 指定已创建的 ThinRuntimeProfile(e.g. minio-profile)


创建 Dataset 和 ThinRuntime CR:


$ kubectl create -f dataset.yaml


检查 Dataset 状态,一段时间后,可发现 Dataset 和 Phase 状态变为 Bound,Dataset 可正常挂载使用:


$ kubectl get dataset minio-demo
NAME         UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
minio-demo                    N/A      N/A              N/A                 Bound   2m18s


4. 最终用户使用 ECI(弹性容器实例)直接通过 PVC(数据卷申请)直接访问 MinIO

对于最终用户来说,访问 MinIO 的过程是非常简单的。以下为示例 Pod Spec 的 YAML 文件(pod.yaml),用户只需要使用和 Dataset 同名的 PVC:


apiVersion: v1
kind: Pod
metadata:
  name: test-minio
  labels:
    alibabacloud.com/fluid-sidecar-target: eci
    alibabacloud.com/eci: "true"
spec:
  restartPolicy: Never
  containers:
    - name: app
      image: nginx:latest
      command: ["bash"]
      args:
      - -c
      - ls -lh /data && cat /data/testfile && sleep 180
      volumeMounts:
        - mountPath: /data
          name: data-vol
  volumes:
    - name: data-vol
      persistentVolumeClaim:
        claimName: minio-demo


  • alibabacloud.com/fluid-sidecar-target=eci 标识了需要启用 ACK Fluid 对于 ECI 的特定支持
  • alibabacloud.com/eci 表示在 ACK 中调度到 ECI 对应的虚拟节点


创建数据访问Pod:


$ kubectl create -f pod.yaml


查看数据访问 Pod 结果:


$ kubectl logs test-minio -c app
total 512
-rw-r--r-- 1 root root 6 Aug 15 12:32 testfile
fluid-minio-test


可以看到,Pod test-minio 可正常访问 Minio 存储系统中的数据。


5. 环境清理


$ kubectl delete -f pod.yaml
$ kubectl delete -f dataset.yaml
$ kubectl delete -f profile.yaml
$ kubectl delete -f minio.yaml


⚠️注意

本示例用于展示整个数据接入流程,相关的 MinIO 环境配置仅作为演示目的。


相关链接:

[1] 小米

https://www.infoq.cn/article/kco7hi5TcVE08ySwNIw7

[2] 创建 ACK Pro 版集群

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/create-an-ack-managed-cluster-2#task-skz-qwk-qfb

[3] 安装云原生 AI 套件

https://help.aliyun.com/zh/ack/cloud-native-ai-suite/user-guide/deploy-the-cloud-native-ai-suite#task-2038811

[4] 通过部署 ACK 虚拟节点组件创建 ECI Pod

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/deploy-the-virtual-node-controller-and-use-it-to-create-elastic-container-instance-based-pods#task-1443354

[5] 通过 kubectl 工具连接集群

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/obtain-the-kubeconfig-file-of-a-cluster-and-use-kubectl-to-connect-to-the-cluster#task-ubf-lhg-vdb

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4月前
|
存储 Kubernetes 容器
Kubernetes 存储选项:持久化卷与存储类
【8月更文第29天】随着容器化的普及,越来越多的应用程序需要持久化数据以保持状态信息。Kubernetes 提供了一套完整的解决方案来管理和配置持久化存储,包括持久卷 (Persistent Volume, PV)、持久卷声明 (Persistent Volume Claim, PVC) 和存储类 (StorageClass)。本文将详细介绍这些概念,并通过实际示例来演示如何在 Kubernetes 中配置存储。
401 1
|
6天前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
21 2
|
18天前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
2月前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
257 0
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
2月前
|
存储 Kubernetes 负载均衡
基于Ubuntu-22.04安装K8s-v1.28.2实验(四)使用域名访问网站应用
基于Ubuntu-22.04安装K8s-v1.28.2实验(四)使用域名访问网站应用
44 1
|
2月前
|
负载均衡 应用服务中间件 nginx
基于Ubuntu-22.04安装K8s-v1.28.2实验(二)使用kube-vip实现集群VIP访问
基于Ubuntu-22.04安装K8s-v1.28.2实验(二)使用kube-vip实现集群VIP访问
76 1
|
2月前
|
存储 Kubernetes 监控
深度解析Kubernetes在微服务架构中的应用与优化
【10月更文挑战第18天】深度解析Kubernetes在微服务架构中的应用与优化
139 0
|
3月前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
|
4月前
|
存储 Kubernetes 容器
k8s创建NFS动态存储
k8s创建NFS动态存储
|
4月前
|
存储 Kubernetes Cloud Native
告别数据丢失的噩梦!PersistentVolume全攻略,让你轻松玩转Kubernetes数据持久化秘籍!
【8月更文挑战第25天】随着容器技术的发展,Kubernetes已成为云原生应用的主流部署平台。然而,数据持久化成为一个亟待解决的问题。Kubernetes通过PersistentVolume(PV)提供了解决方案。PV是一种存储资源对象,它抽象出底层存储技术(例如Ceph、GlusterFS或NFS),让用户仅需关注存储容量和访问模式等属性。PV由管理员创建与维护,Pod通过PersistentVolumeClaim(PVC)请求存储资源。本文详细介绍了PV的工作原理、配置方法及示例,帮助读者更好地理解和应用此功能。
153 2

相关产品

  • 容器服务Kubernetes版