【摘要】
原生的K8S集群系统架构优化——无服务器化优化,针对集群Serverless能力,进行梳理优化。
【案例正文】
【背景】
K8S云原生系统架构优化_xuyijing0103的博客-CSDN博客https://blog.csdn.net/weixin_53439529/article/details/132565188
【问题】
【过程与结果】
【初步解决思路】
无服务化应该是一种思路和方法,而不是一种固定的产品。
【Serverless原理】
- 全托管的计算服务,客户只需要编写代码构建应用,无需关注同质化的、负担繁重的基于服务器等基础设施的开发、运维、安全、高可用等工作;
- 通用性,结合云 BaaS API 的能力,能够支撑云上所有重要类型的应用;
- 自动的弹性伸缩,让用户无需为资源使用提前进行容量规划;
- 按量计费,让企业使用成本得有效降低,无需为闲置资源付费。
也就是说,在 Serverless 计算中可以有不同形式的服务形态。个人理解在实际使用中可以划分为以下三类:
1)并不是完全的没有服务器,但是尽可能地把基础设施层的服务放到云上。比如无状态计算(计算、网络、大数据等)委托给云;有状态存储(数据库、文件、对象存储等)委托给云;有状态中间件如redis、kafka、rabbitmq、nacos等以有状态+持久化的方式委托给云。
总的来说,这种形式是按照Serverless 的思路来架构,但是距离Serverless的理想形式还有距离。
2)和容器技术进行融合创新,通过良好的可移植性,容器化的应用能够无差别地运行在开发机、自建机房以及公有云环境中。典型的服务就是弹性容器实例,如阿里云ECI,华为云CCI,Google 提供了 CloudRun,此外 Google 也开源了基于 Kubernetes 的 Serverless 应用框架 Knative。
这种形式提供给用户的是一个没有节点的云容器平台,(并不是真的没有服务器)用户不用关心服务器,且容器平台随时可以弹性到CCE,用户只需要关注容器化应用构建即可。
3)函数计算(Function as a Service,即FAAS),是 Serverless 中最具代表性的产品形态。它通过把应用逻辑拆分多个函数,每个函数都通过事件驱动的方式触发执行,例如当对象存储(OSS)中产生的上传 / 删除对象等事件,能够自动、可靠地触发 FaaS 函数处理,且每个环节都是弹性和高可用的,客户能够快速实现大规模数据的实时并行处理。同样的,通过消息中间件和函数计算的集成,客户可以快速实现大规模消息的实时处理。
- 函数编程以事件驱动方式执行,这在应用架构、开发习惯方面,以及研发交付流程上都会有比较大的改变;
- 函数编程的生态仍不够成熟,应用开发者和企业内部的研发流程需要重新适配;
- 细颗粒度的函数运行也引发了新技术挑战,比如冷启动会导致应用响应延迟,按需建立数据库连接成本高等。
所以在种种限制下,FAAS在实际中并不常见,在政务信息化应用圈里大概是1/100的概率。CCI这种形式也不常用,用户更偏向于使用轻量化的云容器平台,如浪潮云CNP,灵雀云ACP,利用了它的轻量和可移植性,但是总归还需要服务器的。
在实践中更常用的是第一种 Serverless 形式,也就是把原来安装到服务器中的应用以脱离服务器的形式委托给云,或者使用云上的数据库RDS等基础设施。在云服务不满足的条件下,介绍一下如何尽可能地把基础设施和中间件层资源上云,使之不受服务器宕机等意外的影响。
【解决方案】
1.无状态计算委托给云:已实现;
2.中间件委托给云:集群用到的中间件有redis、rabbitmq、nacos、minio,都已部署为有状态负载
3.有状态存储委托给云
之前考虑过提升serverless能力,把数据库用有状态负载+持久化存储的方式部署,但是不太现实,于是抛弃这个方案;
K8S云原生系统架构优化(一)可用性_xuyijing0103的博客-CSDN博客https://blog.csdn.net/weixin_53439529/article/details/132575756除了数据库集群还使用了另一种存储,就是文件存储做了共享目录,很多服务都挂载nfs存储卷。
可观测实现后,发现node、pod甚至整个集群的资源都可以监控到,但是文件存储还没有。因为共享目录只是一个服务器上的文件夹,并不是集群的资源,所以考虑把文件存储放到云上。
K8S云原生系统架构优化(二)可观测_xuyijing0103的博客-CSDN博客https://blog.csdn.net/weixin_53439529/article/details/132595874文件存储无论共享与否(最好共享)、块存储也就是云硬盘都可以部署为存储类和存储卷。PV和PVC是Kubernetes持久化存储体系里重要的分类,有时间详细介绍下。yaml参考:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-yun
namespace: yun
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 1Gi
persistentVolumeReclaimPolicy: Retain
nfs:
server: XX.XX
path: /opt/sdb/nfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-yun
namespace: yun
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
volumeName: pv-yun
以上yaml将服务器的共享文件目录创建为持久化存储卷。
kubectl apply -f pv-pvc-yun.yaml部署即可创建存储类和存储卷,要挂载到pod只需要修改对应负载的spec.volumns字段,如
volumes:
- name: vol
persistentVolumeClaim:
claimName: pvc-yun
同时在容器里要配置挂载点,对应spec.containers.volumeMounts 如
volumeMounts:
- mountPath: /cloud
name: vol
subPath: logs/dataanalysis
意思是容器挂载到vol存储卷的/cloud目录,子路径是/logs/dataanalysis用来放日志的。
pv挂载后发现kuboard可视化界面还是不能监控到,原因是缺少一个套件pv-brower,是用来展示存储卷的浏览器,如图:
在浏览器外也可以看到整个存储卷的状态和使用量,只要挂载了pod即可:
由于集群部署在政务云行政域网段,与互联网隔离,所以基本在线安装任何软件都不可能。kuboard上提示离线安装的方式,即:Kuboard 用户中心https://uc.kuboard.cn/public/addons/pv-browser.addons.kuboard.cn
实测该教程有一个最大的问题,就是离线安装的yaml不对,前面的参考步骤倒是可以,主要是把镜像拉到环境的仓库里面,剩下的就是yaml配置的问题,网上搜并没有可参考的正确yaml:
---
apiVersion: kuboard.cn/v1
kind: KuboardAddon
metadata:
name: pv-browser.addons.kuboard.cn
namespace: kube-system
spec:
scope: Cluster
extensions: []
info:
name: 存储卷浏览器
id: pv-browser.addons.kuboard.cn
version: v1.0.1
lastUpdate: '2020-09-11'
maintainer: shaohq@foxmail.com
scope: Cluster
description: 在集群概览页显示存储卷的利用率,查看存储卷内文件内容
document: 'https://addons.kuboard.cn/kuboard-pv-browser/v1.0.1/README.md'
addonUrl: 'https://addons.kuboard.cn/kuboard-pv-browser/v1.0.1/addon.yaml'
addonResourceUrl: 'https://addons.kuboard.cn/kuboard-pv-browser/v1.0.1/addonResource.yaml'
status:
status: LOADED
---
apiVersion: kuboard.cn/v1
k8sYamls:
kuboard-pv-browser: |-
apiVersion: apps/v1
kind: DaemonSet
metadata:
annotations:
k8s.kuboard.cn/ingress: 'false'
k8s.kuboard.cn/service: none
k8s.kuboard.cn/workload: kuboard-pv-browser
labels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: kuboard-pv-browser
name: kuboard-pv-browser
namespace: kube-system
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: kuboard-pv-browser
template:
metadata:
labels:
k8s.kuboard.cn/layer: monitor
k8s.kuboard.cn/name: kuboard-pv-browser
spec:
containers:
- image: '10.210.56.201/library/eipwork/kuboard-pv-browser:v1.0.1'
imagePullPolicy: IfNotPresent
name: delegator
volumeMounts:
- mountPath: /var/lib/kubelet
name: kubelet
- mountPath: /run/mount
name: mounts
- command:
- sleep
- '360000'
image: 'IP/library/eipwork/kuboard-pv-browser:v1.0.1'
imagePullPolicy: IfNotPresent
name: pv-browser
volumeMounts:
- mountPath: /var/lib/kubelet
name: kubelet
- mountPath: /run/mount
name: mounts
dnsPolicy: ClusterFirst
tolerations:
- effect: ''
key: node-role.kubernetes.io/master
operator: Exists
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /var/lib/kubelet
type: DirectoryOrCreate
name: kubelet
- hostPath:
path: /run/mount
type: DirectoryOrCreate
name: mounts
kind: KuboardAddonResource
lifecycleHandler:
additionalStep: >-
<div style="font-size: 14px; color: red; font-weight: 500">请确认您的 Kuboard
版本不低于 v2.0.5-beta.4</div>
beforeUninstall: JavaScriptToExecuteBeforeUninstall
disable: JavaScriptToExecuteBeforeDisable
initialize: >
import { startInitTasks, completeInitTask, failInitTask, KuboardProxy }
from '/addon-api/index.js'
export function initializeKuboardAddon (initContext) {
startInitTasks([
{name: 'pvbrowser', description: '初始化任务 pv-browser', descriptionEn: 'init task: pv-browser' },
])
setTimeout(_ => {
completeInitTask('pvbrowser')
}, 1000)
console.log('finished')
}
install:
- kuboard-pv-browser
metadata:
namespace: kube-system
name: pv-browser.addons.kuboard.cn
这个yaml是kuboard可视化界面整个安装的步骤,部署完成之后会有安装提示,按步骤操作即可。
安装pv-browser之后,文件存储即可监控和界面化浏览。