编者按:云原生背景下,本地存储相比分布式存储,在易用性、可维护性、IO 性能上都更胜一筹,但应用本地存储任然有诸多问题。那么 open-local 会带来什么不一样的体验呢?来看看作者怎么说。本文整顿自龙蜥大讲堂第 30 期,精彩分享视频回放已上传至龙蜥官网(首页 - 动静 - 视频),欢送查看!
云原生背景下,有状态利用须要借助一套存储计划进行数据长久化保留。本地存储相比分布式存储,在易用性、可维护性、IO 性能上都更胜一筹,但应用本地存储作为目前低成本交付 Kubernetes 集群,仍然存在许多问题:
- 本地存储管理能力无限:应用本地存储须要肯定的人力老本,如通过为节点打标来限度 Pod 调度、人工治理不同机型的磁盘、人工通过 Hostpath 形式挂载指定磁盘到容器等;同时还有一些现场交付问题,如绑定了谬误的宿主机门路使得故障无奈及时发现,这些都重大影响了 K8s 交付效率以及利用运行时稳定性。
- 本地存储空间隔离能力缺失:利用挂载不适当的宿主机目录(如挂载到宿主机根门路)导致宿主机故障,如因利用数据写满磁盘导致容器运行时无响应、触发 Pod 驱赶等问题。
- K8s 原生本地存储能力无限。通过 Hostpath 无奈做到节点放弃,使得 Pod 漂移后利用数据失落;而应用半自动动态 Local PV 可保障节点放弃,然而无奈实现全自动,依然须要为人为参加(如创立文件夹门路,为节点打标等);无奈应用一些高级存储能力(例如快照)。
针对以上问题,open-local 利用而生,接下来一起来看看 open-local 都有哪些性能?
open-local 介绍
开源地址:https://github.com/alibaba/op…
open-local 是阿里巴巴开源的一款本地存储管理零碎。通过 open-local,在 Kubernetes 上应用本地存储就像应用集中式存储一样简略。
目前 open-local 反对以下存储个性:本地存储池治理、存储卷动态分配、存储调度算法扩大、存储卷扩容、存储卷快照、存储卷监控、存储卷 IO 限流、原生块设施及长期卷。
1、use case
- 利用自身已反对多正本高可用,心愿应用本地盘以进步存储资源利用率,进步数据读写性能,如 HBase、MinIO 等。
- 利用冀望数据卷具备容量隔离能力,避免出现诸如日志打满系统盘的状况。
- 利用须要大量本地存储并依赖节点放弃,如 etcd、zookeeper、Elasticsearch 等。
- 集群本地磁盘数量泛滥,心愿通过调度器实现有状态利用的自动化部署。
- 通过存储快照能力为数据库类利用备份刹时数据等。
2、架构
┌─────────────────────────────────────────────────────────────────────────────┐
│ Master │
│ ┌───┬───┐ ┌────────────────┐ │
│ │Pod│PVC│ │ API-Server │ │
│ └───┴┬──┘ └────────────────┘ │
│ │ bound ▲ │
│ ▼ │ watch │
│ ┌────┐ ┌───────┴────────┐ │
│ │ PV │ │ Kube-Scheduler │ │
│ └────┘ ┌─┴────────────────┴─┐ │
│ ▲ │ open-local │ │
│ │ │ scheduler-extender │ │
│ │ ┌────►└────────────────────┘◄───┐ │
│ ┌──────────────────┐ │ │ ▲ │ │
│ │ NodeLocalStorage │ │create│ │ │ callback │
│ │ InitConfig │ ┌┴──────┴─────┐ ┌──────┴───────┐ ┌────┴────────┐ │
│ └──────────────────┘ │ External │ │ External │ │ External │ │
│ ▲ │ Provisioner │ │ Resizer │ │ Snapshotter │ │
│ │ watch ├─────────────┤ ├──────────────┤ ├─────────────┤ │
│ ┌─────┴──────┐ ├─────────────┴──┴──────────────┴──┴─────────────┤GRPC│
│ │ open-local │ │ open-local │ │
│ │ controller │ │ CSI ControllerServer │ │
│ └─────┬──────┘ └────────────────────────────────────────────────┘ │
│ │ create │
└──────────┼──────────────────────────────────────────────────────────────────┘
│
┌──────────┼──────────────────────────────────────────────────────────────────┐
│ Worker │ │
│ │ │
│ ▼ ┌───────────┐ │
│ ┌──────────────────┐ │ Kubelet │ │
│ │ NodeLocalStorage │ └─────┬─────┘ │
│ └──────────────────┘ │ GRPC Shared Disks │
│ ▲ ▼ ┌───┐ ┌───┐ │
│ │ ┌────────────────┐ │sdb│ │sdc│ │
│ │ │ open-local │ create volume └───┘ └───┘ │
│ │ │ CSI NodeServer ├───────────────► VolumeGroup │
│ │ └────────────────┘ │
│ │ │
│ │ Exclusive Disks │
│ │ ┌─────────────┐ ┌───┐ │
│ │ update │ open-local │ init device │sdd│ │
│ └────────────────┤ agent ├────────────────► └───┘ │
│ └─────────────┘ Block Device │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
2.1 open-local 蕴含四个组件:
1)scheduler-extender:作为 Kube-Scheduler 的扩大组件,通过 Extender 形式实现,新增本地存储调度算法。
2)CSI 插件:依照 CSI(Container Storage Interface) 规范实现本地磁盘治理能力,蕴含创立 / 删除 / 扩容存储卷、创立 / 删除快照、裸露存储卷 metrics 等能力。
3)agent:运行在集群中的每个节点,依据配置清单初始化存储设备,并通过上报集群中本地存储设备信息以供 Scheduler-Extender 决策调度。
4)controller:获取集群存储初始化配置,并向运行在各个节点的 Agent 下发具体的资源配置清单。
2.2 open-local 蕴含两个 CRD
1)NodeLocalStorage:open-local 通过 NodeLocalStorage 资源上报每个节点上的存储设备信息,该资源由 controller 创立,由每个节点的 agent 组件更新其 status。该 CRD 属于全局范畴的资源。2)NodeLocalStorageInitConfig:open-local controller 可通过 NodeLocalStorageInitConfig 资源创立每个 NodeLocalStorage 资源。NodeLocalStorageInitConfig 资源中蕴含全局默认节点配置和特定节点配置,若节点的 node label 满足表达式则应用特定节点配置,否则应用默认配置。
如何在 ack-distro 中应用 open-local
1、初始化配置
前置条件:环境中曾经装置 lvm 工具
ack-distro 部署时会默认装置 open-local。编辑 NodeLocalStorageInitConfig 资源,进行存储初始化配置。
# kubectl edit nlsc open-local
应用 open-local 要求环境中有 VG(VolumeGroup),若用户环境中已存在 VG 且有残余空间,则能够配置在白名单;若环境中没有 VG,用户需提供一个块设施名称供 open-local 创立 VG。
apiVersion: csi.aliyun.com/v1alpha1
kind: NodeLocalStorageInitConfig
metadata:
name: open-local
spec:
globalConfig: # 全局默认节点配置,初始化创立 NodeLocalStorage 时会填充到其 Spec 中
listConfig:
vgs:
include: # VolumeGroup 白名单,反对正则表达式
- open-local-pool-[0-9]+
- your-vg-name # 若环境中已有 VG,能够写入白名单由 open-local 纳管
resourceToBeInited:
vgs:
- devices:
- /dev/vdc # 若环境中没有 VG,用户需提供一个块设施
name: open-local-pool-0 # 将块设施 /dev/vdc 初始化为名叫 open-local-pool-0 的 VG
NodeLocalStorageInitConfig 资源编辑结束后,controller 和 agent 会更新所有节点的 NodeLocalStorage 资源。
2、存储卷动静供给
open-local 默认在集群中部署了一些存储类模板,咱们以 open-local-lvm、open-local-lvm-xfs 和 open-local-lvm-io-throttling 举例:
# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
open-local-lvm local.csi.aliyun.com Delete WaitForFirstConsumer true 8d
open-local-lvm-xfs local.csi.aliyun.com Delete WaitForFirstConsumer true 6h56m
open-local-lvm-io-throttling local.csi.aliyun.com Delete WaitForFirstConsumer true
创立一个 Statefulset,该 Statefulset 应用 open-local-lvm 存储类模板。此时创立的存储卷文件系统为 ext4。若用户指定 open-local-lvm-xfs 存储模板,则存储卷文件系统为 xfs。
# kubectl apply -f https://raw.githubusercontent.com/alibaba/open-local/main/example/lvm/sts-nginx.yaml
查看 Pod/PVC/PV 状态,可看到存储卷创立胜利:
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-lvm-0 1/1 Running 0 3m5s
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
html-nginx-lvm-0 Bound local-52f1bab4-d39b-4cde-abad-6c5963b47761 5Gi RWO open-local-lvm 104s
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS AGE
local-52f1bab4-d39b-4cde-abad-6c5963b47761 5Gi RWO Delete Bound default/html-nginx-lvm-0 open-local-lvm 2m4s
kubectl describe pvc html-nginx-lvm-0
3、存储卷扩容
编辑对应 PVC 的 spec.resources.requests.storage 字段,将 PVC 申明的存储大小从 5Gi 扩容到 20 Gi。
# kubectl patch pvc html-nginx-lvm-0 -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
查看 PVC/PV 状态:
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
html-nginx-lvm-0 Bound local-52f1bab4-d39b-4cde-abad-6c5963b47761 20Gi RWO open-local-lvm 7h4m
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
local-52f1bab4-d39b-4cde-abad-6c5963b47761 20Gi RWO Delete Bound default/html-nginx-lvm-0 open-local-lvm 7h4m
4、存储卷快照
open-local 有如下快照类:
# kubectl get volumesnapshotclass
NAME DRIVER DELETIONPOLICY AGE
open-local-lvm local.csi.aliyun.com Delete 20m
创立 VolumeSnapshot 资源:
# kubectl apply -f https://raw.githubusercontent.com/alibaba/open-local/main/example/lvm/snapshot.yaml
volumesnapshot.snapshot.storage.k8s.io/new-snapshot-test created
# kubectl get volumesnapshot
NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE
new-snapshot-test true html-nginx-lvm-0 1863 open-local-lvm snapcontent-815def28-8979-408e-86de-1e408033de65 19s 19s
# kubectl get volumesnapshotcontent
NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT AGE
snapcontent-815def28-8979-408e-86de-1e408033de65 true 1863 Delete local.csi.aliyun.com open-local-lvm new-snapshot-test 48s
创立一个新 Pod,该 Pod 对应的存储卷数据与之前快照点时刻的数据统一:
# kubectl apply -f https://raw.githubusercontent.com/alibaba/open-local/main/example/lvm/sts-nginx-snap.yaml
service/nginx-lvm-snap created
statefulset.apps/nginx-lvm-snap created
# kubectl get po -l app=nginx-lvm-snap
NAME READY STATUS RESTARTS AGE
nginx-lvm-snap-0 1/1 Running 0 46s
# kubectl get pvc -l app=nginx-lvm-snap
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
html-nginx-lvm-snap-0 Bound local-1c69455d-c50b-422d-a5c0-2eb5c7d0d21b 4Gi RWO open-local-lvm 2m11s
5、原生块设施
open-local 反对创立的存储卷将以块设施模式挂载在容器中(本例中块设施在容器 /dev/sdd 门路):
# kubectl apply -f https://raw.githubusercontent.com/alibaba/open-local/main/example/lvm/sts-block.yaml
查看 Pod/PVC/PV 状态:
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-lvm-block-0 1/1 Running 0 25s
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
html-nginx-lvm-block-0 Bound local-b048c19a-fe0b-455d-9f25-b23fdef03d8c 5Gi RWO open-local-lvm 36s
# kubectl describe pvc html-nginx-lvm-block-0
Name: html-nginx-lvm-block-0
Namespace: default
StorageClass: open-local-lvm
...
Access Modes: RWO
VolumeMode: Block # 以块设施模式挂载入容器
Mounted By: nginx-lvm-block-0
...
6、IO 限流
open-local 反对为 PV 设置 IO 限流,反对 IO 限流的存储类模板如下:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: open-local-lvm-io-throttling
provisioner: local.csi.aliyun.com
parameters:
csi.storage.k8s.io/fstype: ext4
volumeType: "LVM"
bps: "1048576" # 读写吞吐量限度在 1024KiB/s 高低
iops: "1024" # IOPS 限度在 1024 高低
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
创立一个 Statefulset,该 Statefulset 应用 open-local-lvm-io-throttling 存储类模板。
# kubectl apply -f https://raw.githubusercontent.com/alibaba/open-local/main/example/lvm/sts-io-throttling.yaml
Pod 处于 Running 状态后,进入 Pod 容器中:
# kubectl exec -it test-io-throttling-0 sh
此时存储卷是以原生块设施挂载在 /dev/sdd 上,执行 fio 命令:
# fio -name=test -filename=/dev/sdd -ioengine=psync -direct=1 -iodepth=1 -thread -bs=16k -rw=readwrite -numjobs=32 -size=1G -runtime=60 -time_based -group_reporting
后果如下所示,可见读写吞吐量限度在 1024KiB/s 高低:
......
Run status group 0 (all jobs):
READ: bw=1024KiB/s (1049kB/s), 1024KiB/s-1024KiB/s (1049kB/s-1049kB/s), io=60.4MiB (63.3MB), run=60406-60406msec
WRITE: bw=993KiB/s (1017kB/s), 993KiB/s-993KiB/s (1017kB/s-1017kB/s), io=58.6MiB (61.4MB), run=60406-60406msec
Disk stats (read/write):
dm-1: ios=3869/3749, merge=0/0, ticks=4848/17833, in_queue=22681, util=6.68%, aggrios=3112/3221, aggrmerge=774/631, aggrticks=3921/13598, aggrin_queue=17396, aggrutil=6.75%
vdb: ios=3112/3221, merge=774/631, ticks=3921/13598, in_queue=17396, util=6.75%
7、长期卷
open-local 反对为 Pod 创立长期卷,其中长期卷生命周期与 Pod 统一,即 Pod 删除后长期卷也随之删除。此处可了解为 open-local 版本的 emptydir。
# kubectl apply -f ./example/lvm/ephemeral.yaml
后果如下:
# kubectl describe po file-server
Name: file-server
Namespace: default
......
Containers:
file-server:
......
Mounts:
/srv from webroot (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-dns4c (ro)
Volumes:
webroot: # 此为 CSI 长期卷
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: local.csi.aliyun.com
FSType:
ReadOnly: false
VolumeAttributes: size=2Gi
vgName=open-local-pool-0
default-token-dns4c:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-dns4c
Optional: false
8、监控大盘
open-local 自带了监控大盘,用户可通过 Grafana 查看集群本地存储信息,蕴含存储设备和存储卷信息。
总而言之,借助 open-local,在运维方面可缩小人力老本,进步集群运行时的稳定性;性能方面,将本地存储的劣势最大化,使用户不仅能体验到本地盘的高性能,同时各种高级存储个性丰盛了利用场景,让宽广开发者体验云原生带来的红利,实现利用上云尤其是有状态利用云原生部署要害一步。
对于视频回放和课件获取
【视频回放】:视频回访已上传至龙蜥官网:https://openanolis.cn/video 查看。
【PPT 课件获取】:关注微信公众号(OpenAnolis),回复“龙蜥课件”即可获取。有任何疑问请随时征询龙蜥助手—小龙(微信:openanolis_assis)。
—— 完 ——