开发者学堂课程【云原生实践公开课:存储配置的最佳实践】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/698/detail/12274
存储配置的最佳实践
内容介绍:
一、 容器存储概述
二、 云原生数据库实践
三、 共享存储多租户实践
四、 典型场景介绍
一、容器存储概述
1.容器存储―云原生应用的基石
云原生应用场景中使用的存储服务,具备︰敏捷、弹性、高性能、自运维、声明式API等云原生特征。
存储&无状态服务&有状态服务︰
有状态∶实例序号、稳定的存储、稳定的网络;
无状态︰多个副本完全等价、可替换;
PV:持久化存储卷,在 K8S 中代表一个具体存储类型的卷,其对象中定义了具体存储类型和卷参数。
PVC:存储卷声明,是 k8s 中一种抽象的存储卷类型,代表了某个具体类型存储的数据卷表达。
StorageClass:存储类,是 K8S 动态创建PV卷的模板。
2.容器存储的特征
(1)自运维:
批量存储卷的全生命周期管理;
(2)高密度:
单节点挂载批量存储卷
(3)多租户:
共享存储如何满足多租户需求?
(4)场景多:
共享存储、独享存储、静态存储、动态存储;
(5)高性能:
大数据、Al计算高吞吐要求;
(6)智能化:
实际场景,存储需要调度、运维、规划多角度融合;
(7)安全合规:
数据防误删、防恶意篡改、数据加密、元数据加密;
3. Kubernetes存储架构
(1)架构思想:
- 统一接口声明(CSI);
- 容量规划(调度器)·
- 运维管理(Operator)
(2)架构组成:
- 管控侧–CSI Controller
- 管控侧–存储调度·
- 管控侧–运维管控
- 节点侧-CSI NodeServer
- 节点侧–存储管理
二、云原生数据库实践
场景∶
在 ACK 环境构建云原生数据库,实现数据库的快速构建、更新、发布逻辑等,本方案着重关注数据库的存储方案,介绍容器场景中不同存储方案提供的不同特性;
方案:
使用临时存储卷:
使用本地存储卷:
使用云盘存储卷:
多副本高可用方案:
扩展:
配置存储监控;
配置存储备份:
配置数据恢复;
1.数据库存储方案:EmptyDir
特点:
临时存储不具备高可用性,实例重启数据会丢失;
使用 Kubelet 工作目录的存储空间,默认没有容量、IO 限制;
配置:
使用 K8S EmptyDir 卷作为 mysql 存储服务;使用 StatefulSet 作为 mysql 的编排方案;
演示:
重启pod,数据库存储将丢失,数据库变成最初状态;
场景∶
由于数据不具备持久性,一般不推荐使用此方案;
在临时数据库场景,例如:每次数据库启动时都重新初始化库,可以考虑这个方案;
代码示例:
apiVersion: v1
kind: Service
metadata:
name: mysql-empty
labels:
app: mysql
speC:
ports:
- port: 8o
name: mysql
clusterlP: None
selector
app: mysql
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql-empty
spec:
serviceName:"mysql“
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env;
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort 3306
name: mysql
volumeMounts:
- name: mysql-storage
mountPath:Narliblmysql
volumes:
- name: mysql-storage
emptyDir:{}
2.数据库存储方案∶LocalVolume
特点∶
LocalVolume 卷包含节点信息,可理解为:HostPath + NodeSelector;LocalVolume具备一定的高可用性,重启实例后可实现数据持久化;节点宕机时,数据无法迁移到其他节点,无法实现服务的高可用;
配置:
使用K8S LocalVolume 作为 mysql 存储服务;
在 LocalVolume 卷中配置某个节点作为 NodeAffinity;
演示:
重启 Pod,数据库存储将延续,保持数据持久性;
节点宕机,数据库无法在其他节点启动,需要手动介入;
场景∶
实例重启时,数据可以实现持久化,本方案推荐在无分布式存储场景使用;由于节点宕机时数据不可以迁移,可以使用数据库的多副本方案实现服务高可用;
代码示例:
apiVersion: v1
kind: Persistentvolume
metadata:
name: mysql-localvolume
spec:
capacity:
storage:100Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mysql
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key. kubermetes.io/hostname
operator: In
values:
- cn-shenzhen.192.168.7.174
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-localvolume
spec;
accessModes:
- ReadWriteOnce
storageClassName: local-storage
resources:
requests:
storage:100Gi
3. 数据库存储方案︰云盘数据卷
特点︰
云盘存储卷具备高可用性,重启实例后可实现数据持久化;节点宕机时,Pod 启动迁移到其他节点,同时将数据迁移过去;
阿里云提供多种云盘类型:提供不同级别的服务能力;ESSD 类型云盘,可提供高吞吐、低延迟高性能块存储服务;
配置:
使用 ACK 云盘数据卷作为 mysql 存储服务﹔
由于可用区限制,需要节点和云盘处于相同可用区;
演示:
重启 Pod,数据库存储将延续,保持数据持久性;节点宕机,数据库在其他节点启动,数据保持持久性;
场景:
本方案实现数据的持久化,且节点宕机时实现数据的可迁移,推荐使用;ACK 集群默认集成了云盘数据卷方案,可以根据需求选择使用各种类型的云盘类型,满足不同的性能需求;
代码示例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-ebsspec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: alicloud-disk-topology
apiVersion: v1
kind: Persistentvolume
metadata:
name: d-wz906w11kl1m6pskcj9m
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 20Gi
csi:
driver: diskplugin.csialibabacloud.com
fsType: ext4
volumeAttributes
:type: available
volumeHandle: d-wz906w11kl1m6pskcj9m
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key:topology.diskplugin.csi.alibabacloud.com/zone
operator: In
values:
- cn-shenzhen-e
persistentVolumeReclaimPolicy:Delete
storageClassName: alicloud-d sk-topology
4. 数据库存储方案:云盘的备份、恢复
特点:
云盘具备数据的持久性,可以节点的迁移能力,即实现了数据库的高可用;在数据库容灾方面,通过云盘的备份、恢复方案来实现;
配置:
使用 ACK 提供的 VolumeSnapshot 能力实现云盘卷的备份功能;通过 PVC 的DataSource 功能,实现云盘数据的恢复能力;
演示:
启动数据库实例,通过 VolumeSnapshot 实现云盘快照备份;
删除老的数据库实例和存储卷,通过 PVC DataSource 恢复数据库;
场景:
本方案实现数据库存储的备份、恢复方案,在存储卷高可用的基础上,通过定时备
份,保证数据意外删除时数据可恢复。推荐使用;
案例分析:
apliversion: snapshot.storage.k8s.iov1beta1
kind: VolumeSnapshotClass
metadata:
name: default-snapclass
driver: diskplugin.csi.alibabacloud.com
parameters:
forceDellete: "true
-deletionPolicy: Delete
apiversion: snapshot.storage.k8s.iolv1beta1
kind: VolumeSnapshot
metadata:
name: msyql-ebs
spec
volumeSnapshotClassName: default-snapclass
source:
persistentVolumeClaimName: mysql-ebs
apiversion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-ebs-restore
spec:
accessModes:- ReadWriteOnce
storageClassName: alicloud-disk-topology
resources:
requests:
storage: 20Gi
datasource:
name: msyql-ebs
kind: volumeSnapshot
apiGroup: snapshot.storage.k8s.io
5. 数据库存储方案:多副本
背景:
云盘的备份、恢复功能只能恢复过去某个时间点的数据,不能提供实时的备份功能;
数据库的主备多副本方案,可实现数据的实时备份能力;
配置:
下载 Chart 包
(https://artifacthub.iolpackages/helm/bitnami/mysql);配置数据库使用多副本方案,使用阿里云云盘实现存储持久化;配置多可用区打散模式,使多个mysql Pod运行在不同可用区;
使用云盘数据卷拓扑感知功能,配合多可用区特性,实现数据库高可用;
演示:
重启 Pod,数据库存储将延续,保持数据持久性;Master 节点宕机,可以将 Master Pod 迁移到其他节点;
Master 数据卷丢失,可以从 Slave 数据库恢复实时数据,可从快照中恢复某个时刻数据;
场景:
本方案实现数据的持久化,且实现了数据库的实时备份能力,推荐使用;通过数据库的主从多副本、云盘的高可用、备份恢复等能力,多个维度实现云原生数据库的高可用特性;
代码示例:
修改 values.yaml,实现数据库持久化(云盘-延迟郝定)
:persistence:
enabled: true
siorageClass: "alicloud-disk-topology“
accessModes:
- ReadWriteOnce
size: 20Gi
修改 mysql 模板(templates/statefulset yam)(多可用区打散)∶
affinity:
podAntiAffinity.
preferredDuringSchedulinglgnoredDuringExecution:
- welight: 100
podAffinityTerm:labelSelector:
matchExpressions:
- key: app
operator:
Invalues:
-{{template "fullname”. }}
topoliogyKey:
failure-domain.beta.kubernetes.io/zone
6.数据库存储方案–存储监控
可展示每个数据库 PV 卷的详情:容量、可用量、IOPS、延迟等;
CSI 监控数据+ Kubelet 监控数据+Operator 监控数据;
通过 Promethus 收集数据并展示;
具体展示框架
整个集群内部使用pv pvc总量上的统计
关于每一个pv容量、趋势上的展示
三、共享存储多租户实践
1.共享文件存储―多租虚拟机
示例场景:
管理员为团队每个成员提供独立开发环境:
独立的运行环境、独立的用户账号、独立受限的存储空间;
方案∶
通过 ACK 平台为每个用户提供运行 Centos 镜像的 Pod 作为虚机;
每个用户通过 PSP(SecurityContext)定义其用户ID/组ID;
为每个用户分配隔离的共享文件存储;
动态NAS卷:
通过动态 nas 卷为每个用户提供一个 NAS PV;
配置 NAS PV 的使用权限,限制只有特定用户使用特定的 NAS 卷;
配置 NAS PV 的存储容量,限制用户使用存储空间大小,以免超额;
实现 NAS PV 的容量可扩展;
2. 共享文件存储–访问权限
场景:
用户1:配置用户 ID/组 ID 为900/900,通过动态 NAS 卷创建 PV1,所有用户1创建的应用均有权限使用 pv1存储卷;
用户2:配置用户 ID/组 ID为800/800,通过动态 NAS 卷创建 PV2,所有用户2创建的应用均有权限使用 pv2存储卷;
权限限制:
用户2创建的应用,引用用户1的创建的数据卷(PV1),报权限不足;
使用配置;
volumeAs:定义使用哪种动态卷类型,subpath/filesystem;
server:子目录类型卷定义的挂载点地址,可用"∵隔开多个;
archiveOnDelete:删除 pvc、pv 的时候是否清理后端数据;
securityContext:表示创建pv使用权限管理功能,只有和创建者(pod)相同 uid/gid 的pod才可以使用该 PV;
volumeCapacity:表示创建pv使用容量限制,存储超过限制容量将写失败;
通过 K8S 的 SecurityContext 定义用户 ID 和组 ID;实际生产中可以配合 PSP 的权限管理能力实现更为复杂的应用、名词空间、资源的使用限制;
代码示例:
allowVolumeExpansion: true
apiversion: storage.k8s.lio/v1
kind: StorageClass
metadata:
name: alicloud-nas-sp-aut
hmountOptions:
- nolock.tcp,noresvport
- vers=3
parameters:
archiveOnDelete:"true“
-securityContext"true”
server: 2564f49129-ysu87.cn-shenzhen.nas.allyuncs.com:/root/
volumeAs: subpath
volumeCapacity :"true"
provisioner: nasplugin.csi.alibabacloud.com
recla mPolicy: Delete
---
apiversion: v1
kind PersistentVolumeClaim
metadata:
name: vm-pvc-1
spec:
accessModes:
-ReadWriteOnce
storageClassName: alicloud-nas-sp-auth
resources:
requests:
storage: 2Gi
apiversion: apps/v1beta1
kind: Deployment
metadata:
name: vm-1
spec:
spec:
securityContext
runAsGroup:900
runAsUser:900
containers:
- name: centos
image: centos:7.7.1908
command: [sh"."-c]
args: [while true; do sleep 1000: done"]
volumeMounts:
- mountPath "/data”
name: vm-storage
volumes:
- name: vm-storage
persistentVolumeClaim:
ciaimName: vm-pvc-1
3.共享文件存储―容量限制
背景:
NAS 动态存储卷使用一个子目录模拟一个卷;
NAS 存储的每个目录默认没有容量限制(整个文件系统的容量)﹔
业务往往需要对每个用户限制其使用量,即对目录限制存储容量;'
配置:
通过在 StorageClass 中配置 volumeCapacity 为 true,声明nas卷需要容量限制;
通过在 StorageClass 中配置 allowVolumeExpansion 为 true,声明 NAS 卷可扩容;
实践:
通过动态 NAS 创建 PV 并挂载使用,写入数据到容量限额(PV 的大小);
待几分钟后(NAS 目录容量感知延迟),继续写入数据报错 Disk Quota Exceeded";
修改 PVC 的容量大小,实现 NAS 卷容量扩容;
由于容量限额导致写入失败的卷,扩容后写操作恢复;
代码示例:
[root@i2wz9fipj2sjwfirgiiap4z vm]# kubectl get pvc lgrep vm-pvc-1
vm-pvc-1Bound
nas-0391b177-885a-422f-966b-7582129930683Gi RW
0alicloud-nas-sp-auth82m
[root@izwz9fipj2sjnfirgi1qo42 vm]# kubectl patch pvc vm-1pvc
ests":{"storage":-"4Gi"}}}}"
persistentvolumeclaim/m-pvc-1 patched
[root@izwz9fipjzsjwfirgiiqo4z vm]# kubectl get pvclgrep_im-puc-1
vm-pvc-1Boundnas-0391b177-885a-422f-966b-7
4Gi RW
0oalicloud-nas-sp-auth86m
[root@izwz9fipj2sjwfirgi1qp42 vm]#
[rooteizwz9c694cocz7ihdoaienz mountj= cp /usr/bin/kaubelet kubelet. " date + %s”
cp: failed to close " leubelet.1602156589' : Disk quota exceeded
[root@izwz9e694cocz7ihdoaenz
mount]#cp/usr/bin/kubeletkubelet. [root@izwz9e694cocz7ihdoaenzmount]# cp /usr/bin/kubelet kubelet.
[root@izwz9e694cocz7ihdoaenzmount]# cp /usr/bin/kubelet kubelet.
[root@izwz9e694cocz7ihdoaenzmount]# cp /usr/bin/kubelet kubelet.
[root@izwz9e694cocz7ihdoaenzmount]# cp /usr/bin/kubelet kubelet.
当以上代码重复五次后,会发现处于无法写入的状态,因为 NAS 存在延迟,在超过1G后两到三分钟才能提醒
四、 典型场景介绍
日志存储
应用在运行中会保存日志数据或状态数据,这个场景一般每个 pod 都有写需求,且所有 pod 写日志会存储在一个存储卷中通常使用 NAS 共享存储来保存日志;有时为了实现不同 pod 写入不同目录,可以配合 subPathExpr 使用。
中间件业务
对于数据库、中间件之类有状态服务,推荐云盘存储卷来保证服务的低延迟需求,且使用 StatefulSet 提供稳定编排服务典型例子:Mysql、ElasticSearch、etcd、kafka 等。
大数据业务
对于有数据高并发需求的服务,其存储需求主要有高吞吐、高并发、数据共享,推荐使用高性能 NAS、CPFS 文件存储;典型例子:大数据计算、Al 训练、基因计算等。
临时存储业务
对于业务自身高可用,或数据缓存场景,可以使用本地盘(LVM卷)方式,通过卷隔
离可以实现本地存储生命周期管理典型例子:Mysql、Spark 等。





