云上 K8s 集群数据持久化方案之 JuiceFS

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000次 1年
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 第一次成功部署 Kubernetes 集群以后,除了排除万难后的兴奋,是否也有这样的疑惑:应用容器跑起来了,数据该存在哪儿?

作为最流行的容器编排系统,Kubernetes 解决以下问题:

  • 服务发现和负载均衡
  • 存储编排
  • 自动部署和回滚
  • 自动完成装箱计算
  • 自我修复
  • 密钥与配置管理

毫无疑问,这些特性覆盖了容器化技术的方方面面,每个特性都是 Kubernetes 的核心主题。

现在请大家回想,在你第一次成功部署 Kubernetes 集群以后,除了排除万难后的兴奋,是否也有这样的疑惑:

应用容器跑起来了,数据该存在哪儿?

在使用 Docker 时,我们几乎不用操心数据存储(持久化)的问题,直接把本地存储映射到容器就 OK。而 Kubernetes 起步就是由多节计算点组成的集群,单纯地将节点上的的存储映射给容器,存储会受限于所在节点的健康状态,这显然是不可靠的。

我们知道,Kubernetes 本身不提供存储,它的存储编排能力主要解决的是简化容器与存储之间的连接,让我们可以轻松的实现本地存储和云存储的挂载和使用。

而在 K8s 集群中,常用的存储不外乎基于本地网络的 NAS 存储,比如 SMB、NFS、iSCSI 等,以及基于云的块存储和对象存储。存储类型之间并无优劣之分,每种存储都有其擅长的应用场景。比如,使用云平台托管的 Kubernetes 集群服务与使用跨云平台自建的集群在存储选型上就有很大差别,后者的节点分布在不同平台,无法公用某一特定云平台的 NAS 存储服务。而使用平台无关的云存储服务,就能同时满足前面两种场景的需求。

在本文中,我们就来分享一种平台无关的云的存储方案 —— JuiceFS。

什么是 JuiceFS

JuiceFS 是一个云原生的分布式文件系统,由对象存储和数据库共同驱动。任何存入 JuiceFS 的文件都会按照特定的规则被拆分成数据块存入对象存储,相对应的元数据则会存储在独立的数据库。相比于直接使用对象存储,JuiceFS 可以实现几十倍甚至上百倍的性能提升。

通过架构图可以了解,JuiceFS 的底层是数据库和对象存储,通过 JuiceFS 客户端,向上提供丰富的接口满足不同应用的存储需求,比如面向 Kubernetes 提供了 CSI 驱动,面向 Hadoop 提供了 Java API,而面向常规操作系统环境则通过 FUSE 提供了 POSIX 文件系统接口,可以挂载 JuiceFS 像本地磁盘一样使用。

juicefs-arch.png

使用 JuiceFS 的优势

  • 十倍以上对象存储性能提升
  • 简单易用
  • 弹性存储
  • 跨平台,数据自由迁移。
  • 开源软件,安全透明。

在 Kubernetes 上使用 JuiceFS

前面已经提到,JuiceFS 是一套平台无关的存储方案,既能应用在自建的 Kubernetes 集群,也能应用在平台托管的 Kubernetes 集群,而且二者的安装和使用方法基本一致。本文我们以阿里云上的容器服务 ACK 托管版为例,介绍如何安装和使用 JuiceFS 持久化数据。

资源准备

我们需要准备以下资源:

  • JuiceFS 文件系统
  • Kubernetes 集群

1. 准备 JuiceFS 文件系统

JuiceFS 文件系统的创建非常简单,不论你是否使用阿里云的服务,都可以参照《在阿里云上安装和使用 JuiceFS 存储》这篇文章创建文件系统。

2. 准备 Kubernetes 集群

这里我们使用阿里云的 Kubernetes 容器托管服务 ACK 进行演示,它的特点是只需创建 worker 节点,master 节点由平台统一提供。我们创建的集群配置如下:

  • 阿里云 ACK 托管版
  • Kubernetes 版本:1.20.4-aliyun.1
  • 容器运行时:Containerd 1.4.8
  • workder 节点数:2

worker 节点即 ECS 云服务器,数量和配置可以按需调整,这里我创建了2个节点,配置为:

  • CPU:4 核
  • 内存:8 GB
  • 硬盘:40 GB ESSD

访问集群

我们通常使用 kubectl 访问和管理集群,如未安装,请参考官方文档。将集群的访问凭据拷贝到用于控制集群的主机上,通常拷贝到 $HOME/.kube/config 配置文件中。

在 ACK 集群信息页面,「连接信息」选项卡查看「集群访问凭证」,根据需要选择公网或内网凭证。如果要通过阿里云上其他的 ECS 访问集群,则可以使用内网凭证。在本地计算机上远程控制集群,则需要使用公网凭证。

本文我们会在本地电脑上远程控制 ACK 集群,因此要将公网凭证复制到本地主机的 $HOME/.kube/config 文件中。访问凭据添加完成以后,在本地使用 kubectl 可以看到 ACK 集群的节点状态:

$ kubectl get nodes
NAME                     STATUS   ROLES    AGE     VERSION
cn-shanghai.10.0.2.11    Ready    <none>   8m53s   v1.20.4-aliyun.1
cn-shanghai.10.0.4.209   Ready    <none>   8m53s   v1.20.4-aliyun.1

安装 JuiceFS CSI Driver

集群配置妥当了,现在开始安装 JuiceFS CSI Driver。根据你使用 Kubernetes 版本,选择执行以下命令。

本文使用的版本是 1.20.4,应执行第一条安装命令。

Kubernetes v1.18 及以上版本

$ kubectl apply -f https://raw.githubusercontent.com/juicedata/juicefs-csi-driver/master/deploy/k8s.yaml

Kubernetes v1.18 以下版本

$ kubectl apply -f https://raw.githubusercontent.com/juicedata/juicefs-csi-driver/master/deploy/k8s_before_v1_18.yaml

集群节点位于国内数据中心时,可能会因为链接被重置而无法应用配置的问题:

Unable to connect to the server: read tcp 192.168.3.88:64971->185.199.111.133:443: read: connection reset by peer

这时可以先将配置文件保存到本地,然后直接通过本地的配置文件进行部署,例如:

$ kubectl apply -f k8s.yaml

该命令会在集群上创建一系列必要的资源,执行成功会返回类似下面的结果,

serviceaccount/juicefs-csi-controller-sa created
serviceaccount/juicefs-csi-node-sa created
clusterrole.rbac.authorization.k8s.io/juicefs-csi-external-node-service-role created
clusterrole.rbac.authorization.k8s.io/juicefs-external-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/juicefs-csi-node-service-binding created
clusterrolebinding.rbac.authorization.k8s.io/juicefs-csi-provisioner-binding created
priorityclass.scheduling.k8s.io/juicefs-mount-critical created
statefulset.apps/juicefs-csi-controller created
daemonset.apps/juicefs-csi-node created
csidriver.storage.k8s.io/csi.juicefs.com created

JuiceFS CSI Driver 的相关资源均创建在 kube-system 命名空间。

namespace.png

其中包括一个 DaemonSet 守护进程,在每个节点上都有一个实例。

daemonset.png

创建存储类

现在就可以通过 JuiceFS CSI Driver 创建存储类了。创建一个配置文件,例如:juicefs-sc.yaml,参照并调整以下配置信息。在以下示例配置中声明了 SecretStorageClass 两种资源,请注意两种资源之间的名称对应关系。

Secret 部分, stringData 段落用来设置 JuiceFS 存储的信息,包括文件系统名称、元数据链接以及对象存储相关的信息。如果使用已经创建好的文件系统,那么直接填写 namemetaurl 这两项就可以了。其他不需要的设置项可以删除或将它的值留空。

apiVersion: v1
kind: Secret
metadata:
  name: juicefs-sc-secret
  namespace: kube-system
type: Opaque
stringData:
  name: "test"
  metaurl: "redis://juicefs.afyq4z.0001.use1.cache.amazonaws.com/3"
  storage: "s3"
  bucket: "https://juicefs-test.s3.us-east-1.amazonaws.com"
  access-key: ""
  secret-key: ""
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: juicefs-sc
provisioner: csi.juicefs.com
reclaimPolicy: Retain
volumeBindingMode: Immediate
parameters:
  csi.storage.k8s.io/node-publish-secret-name: juicefs-sc-secret
  csi.storage.k8s.io/node-publish-secret-namespace: kube-system
  csi.storage.k8s.io/provisioner-secret-name: juicefs-sc-secret
  csi.storage.k8s.io/provisioner-secret-namespace: kube-system

应用配置:

$ kubectl apply -f juicefs-sc.yaml
secret/juicefs-sc-secret created
storageclass.storage.k8s.io/juicefs-sc created

storageclass.png

不难发现,一个存储类中关联了一个 JuiceFS 文件系统。存储类的数量没有限制,你可以根据需要创建任意多个 JuiceFS 存储类。创建多个存储类时,注意配置文件中的名称及资源间的对应关系。

使用 JuiceFS 存储

成功创建了存储类,接下来我们创建一个 Nginx 应用并为它挂载声明的 JuiceFS 存储。创建配置文件 nginx.yaml`,添加以下配置:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Pi
  storageClassName: juicefs-sc
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-run
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: linuxserver/nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /config
              name: web-data
      volumes:
        - name: web-data
          persistentVolumeClaim:
            claimName: nginx-pvc

执行命令部署应用:

$ kubectl apply -f nginx.yaml

persistentvolumeclaim/nginx-pvc created
deployment.apps/nginx-run created

应用部署成功以后,在存储声明列表中会看到我们在配置文件中声明的 nginx-pvc

pvc.png

紧接着在 ACK 控制台为应用创建 service 和 ingress,然后使用平台提供的临时域名即可访问 Nginx 的欢迎页面。

说明:由于每个集群选择路由方案和设置方法各不相同,具体的设置步骤不做展开。

index.png

我们可以在本地计算机上挂载同一个 JuiceFS 文件系统,里面是所有已经创建的 PVC 数据目录。如下图,红框标注的是我们刚刚声明的 PVC 的目录。

pvdir.png

进一步查看它的目录结构,可以看到 Nginx 已经在里面建立所需的目录和文件。

$ tree pvc-30873eae-58a1-4722-9911-8e5f2f061347
pvc-30873eae-58a1-4722-9911-8e5f2f061347
├── custom-cont-init.d
├── custom-services.d
├── geoip2db
├── keys
│   ├── cert.crt
│   └── cert.key
├── log
│   ├── nginx
│   │   ├── access.log
│   │   └── error.log
│   └── php
│       └── error.log
├── nginx
│   ├── nginx.conf
│   └── site-confs
│       └── default
├── php
│   ├── php-local.ini
│   └── www2.conf
└── www
    └── index.html

11 directories, 10 files

我们尝试在 www 目录中添加一个新网页 hello.html,页面内容如下:

Hello JuiceFS!

将访问链接指向新添加的文件,浏览器中成功显示出了我们新添加的页面!

hello.png

至此,我们就完成了 JuiceFS 在 Kubernetes 集群上的安装和应用测试。

写在最后

本文介绍了如何使用 JuiceFS 为平台托管的 Kubernetes 集群提供数据持久化存储,以阿里云 ACK 容器服务为蓝本进行了实例演示。大家可以举一反三,参照本文的内容,可以很容易的实现在其他云平台托管的 Kubernetes 集群上安装和使用 JuiceFS。

有关于 JuiceFS CSI Driver 的更多技术细节,请查看项目主页:https://github.com/juicedata/juicefs-csi-driver

如果你有其他疑问,欢迎在评论区给我留言。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
15天前
|
弹性计算 人工智能 Serverless
阿里云ACK One:注册集群云上节点池(CPU/GPU)自动弹性伸缩,助力企业业务高效扩展
在当今数字化时代,企业业务的快速增长对IT基础设施提出了更高要求。然而,传统IDC数据中心却在业务存在扩容慢、缩容难等问题。为此,阿里云推出ACK One注册集群架构,通过云上节点池(CPU/GPU)自动弹性伸缩等特性,为企业带来全新突破。
|
22天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
23天前
|
Kubernetes 持续交付 开发工具
ACK One GitOps:ApplicationSet UI简化多集群GitOps应用管理
ACK One GitOps新发布了多集群应用控制台,支持管理Argo CD ApplicationSet,提升大规模应用和集群的多集群GitOps应用分发管理体验。
|
1月前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
146 0
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
1月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
461 1
|
1月前
|
Kubernetes Cloud Native 微服务
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
105 1
|
1月前
|
负载均衡 应用服务中间件 nginx
基于Ubuntu-22.04安装K8s-v1.28.2实验(二)使用kube-vip实现集群VIP访问
基于Ubuntu-22.04安装K8s-v1.28.2实验(二)使用kube-vip实现集群VIP访问
51 1
|
1月前
|
Kubernetes Ubuntu Linux
Centos7 搭建 kubernetes集群
本文介绍了如何搭建一个三节点的Kubernetes集群,包括一个主节点和两个工作节点。各节点运行CentOS 7系统,最低配置为2核CPU、2GB内存和15GB硬盘。详细步骤包括环境配置、安装Docker、关闭防火墙和SELinux、禁用交换分区、安装kubeadm、kubelet、kubectl,以及初始化Kubernetes集群和安装网络插件Calico或Flannel。
141 0
|
1月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
73 0
|
1月前
|
弹性计算 Kubernetes Linux
如何使用minikube搭建k8s集群
如何使用minikube搭建k8s集群