原创 吴就业 160 0 2023-05-27
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/19553f0725bf45bf92a014aa4c071de7
作者:吴就业
链接:https://wujiuye.com/article/19553f0725bf45bf92a014aa4c071de7
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
中间件容器化部署是为了实现GitOps模式的持续交付,实现部署即代码。痛点在于大多数中间件都是有状态的,本篇介绍如何实现有状态中间件的容器化部署。
常见中间件要实现容器化部署,需要解决以下问题:
Ingress是k8s提供将集群内部服务(Service)暴露外部访问的定义http路由规则的资源,Ingress资源本身只是定义http路由策略,需要依赖Ingress Controller实现Ingress资源的路由策略。
Ingress Controller本身也是一个Service,通过设置Service的类型为NodePort(使用节点IP)或者ExternalIP、云服务提供商提供的LoadBalancer暴露给外部访问。
BFE Ingress Controller是基于BFE实现的Ingress Controller,用于支持在Kubernetes中部署使用BFE进行七层流量代理转发,并能使用Ingress进行流量接入。
BFE Ingress Controller通过监听Service、Endpoints、Secrets、Namespace资源实现服务发现,TLS证书配置;通过监听Ingress资源触发生成新的配置文件并Reload,将Ingress资源定义的http/https路由规则转为bfe的路由配置,并通过调用bfe暴露的基于http协议的local reload接口通知bfe进程刷新配置。
示例:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-http-ingress
annotations:
kubernetes.io/ingress.class: bfe
spec:
tls:
- hosts:
- test.com
secretName: test-com-tls-secret
rules:
- host: test.com
http:
paths:
- path: /api/user
pathType: Prefix
backend:
service:
name: test-user
port:
number: 8080
此示例的意思是,配置一个Ingress资源,名称为test-http-ingress,ingress类型是bfe(标识该Ingress由BFE Ingress Controller处理),配置了一个host路由规则,将通过test.com域名访问,且路径前缀为/api/user的http请求转发给test-user服务的8080端口。还为test.com配置了tls证书,对应的secret资源名称为test-com-tls-secret。
Nginx Ingress Controller是基于Nginx实现的Ingress Controller,用于支持在Kubernetes中部署使用Nginx进行流量代理转发,并能使用Ingress进行流量接入。原理同前面介绍的BFE Ingress Controller。
示例:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-http-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- test.com
secretName: test-com-tls-secret
rules:
- host: test.com
http:
paths:
- path: /api/user
pathType: Prefix
backend:
service:
name: test-user
port:
number: 8080
此示例的意思是,配置一个Ingress资源,名称为test-http-ingress,ingress类型是nginx(标识该Ingress由Nginx Ingress Controller处理),配置了一个host路由规则,将通过test.com域名访问,且路径前缀为/api/user的http请求转发给test-user服务的8080端口。同样还为test.com配置了tls证书,对应的secret资源名称为test-com-tls-secret。
使用Ingress实现流量入口是k8s的推荐方案,只需要为域名配置tls secret资源、ingress资源,配置路由规则,就可以由Ingress Controller将流量转发给后端服务。每新增一个微服务只需要创建一个Ingress资源。
Ingress Controller只是让网关实现Ingress资源描述的能力,真是解决将网关暴露给外网访问,解决静态IP问题的,是将Ingress Controller的Service的类型配置为LoadBalancer,利用云服务提供商实现的LoadBalancer解决静态IP问题。或是将Ingress Controller的Service的类型配置为NodePort,可使用任意一个Pod所在的Node的IP访问;如果是ExternalIP,则使用ExternalIP访问。如果是私有云,可自己实现LoadBalancer。
Ingress Controller本质也是CRD(自定义资源定义)+ 自定义Controller(即Operator),只不过这是k8s官方提供的资源定义(Ingress),并将实现Ingress资源描述的功能的自定义控制器称为Ingress Controller,因此不叫Operator。目前istio、nginx、bfe、kong、haproxy等流量网关都提供了Ingress Controller的实现。
数据存储中间件才涉及到数据的持久化存储,因此持久化存储解决方案,就是解决数据存储中间件容器化的方案。
通常需要持久化存储且对数据一致性0容忍的应用都是有状态应用。k8s提供StatefulSet控制器用来部署有状态应用,它管理具有唯一身份标识的多个pod(每个pod都有一个持久化的、唯一的ID),每个 pod 可以有自己的持久化存储卷。即便StatefulSet中的单个pod发生故障,持久化的pod标识符能够将现有的Volume(卷)与Kubernetes新启的pod进行匹配,以取代发生故障的pod。
K8S支持静态PV和动态PV:
可以利用rdb、cephfs的k8s StorageClass,将mysql、kafka的数据存储到远程块存储/分布式文件系统。
CephFS-Provisioner
cephfs-provisioner是kubernetes官方社区提供的Cephfs的StorageClass支持,主要watch kubernetes中PVC资源的 CURD事件,然后创建PV。
RBD-Provisioner
rbd-provisioner是kubernetes官方社区提供的Ceph RBD的StorageClass支持,主要watch kubernetes中PVC资源的 CURD事件,然后创建PV。
在申请资源的时候,按照虚拟机部署的规格去购买虚拟机,满足CPU、内存、硬盘的要求,将购买的节点加入k8s集群,并为这些节点打标签。
例如,部署mysql的节点,标签设置为mysql-node,这样编写mysql的StatefulSet时,通过配置节点亲和性,将pod部署到mysql-node节点上。
但是该方案无法实现计算存储分离,动态扩缩容显的无能为力。另外要求其它pod不能部署到这几个节点。
使用PV+PVC方式,实际就是挂载一个远程文件系统/块存储设备,存在网络I/O性能开销,具体性能影响,要看远程文件系统/块存储设备的实现原理,可能会利用本地磁盘暂存+内存缓存减少一些网络I/O的开销,但肯定比不上使用节点本地磁盘,并且出现问题较难排查,需要有这方面的专家才敢这么去做。因此对于Mysql这类有状态的中间件,我们目前还是当成IaC资源申请使用,不考虑容器化部署。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
新的云原生中间件很难短时间内覆盖到企业项目中,企业走云原生这条道路,还需要考虑传统中间件如何上云的问题。最需要解决的是如何容器化部署,以及自动化运维。这就不得不借助Operator了。
在实战的过程中,我自己做了很多笔记,从模糊到清晰,逐渐了解云原生架构,不仅参与了中间件容器化架构改造与自动化部署Operator开发,还参与了IaC基础设施即代码的开发,kubevela terraform Addon插件开发,从应用层到中间件到基础设施都有参与,整条链路的一些核心原理都非常清晰。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。