微服务交付至kubernetes流程
1、微服务简介
微服务优点
- 服务组件化
每个服务独立开发、部署,有效避免一个服务的修改引起整个系统重新部署 - 技术栈灵活
约定通信方式,是得服务本身功能实现对技术要求不再那么铭感 - 独立部署
每个微服务独立部署,加快部署速度,方便扩展 - 扩展性强
每个微服务可以部署多个,并且有负载均衡能力 - 独立数据
每个微服务有独立的基本组件,例如数据库、缓存等
微服务缺点
- 沟通成本
- 数据一致性
- 运维成本
- 内部架构复杂性
微服务和单体应用
单体应用,易于部署、测试,但是会使得代码膨胀,难以维护,构建和部署成本大,新人上手难
适用于微服务的框架:Spring Boots、Spring Cloud、Dubbo、Go-micro .....
2、K8s部署微服务考虑的问题
微服务架构图
微服务间如何通信?
REST API、RPC、MQ(后两者主流)。
微服务如何发现彼此?
通过注册中心进行服务的注册与发现。
组件之间怎么个调用关系?
微服务内部处理逻辑。
那个服务作为整个网站入口?
网关,即gateway(也是单独的一个微服务)。
那些微服务需要对外访问?
只需要网关gateway入口对外即可,
一般都是先为gateway创建svc,然后由Ingress指定到该svc。
微服务怎么部署?更新?扩容?
基于Kubernetes就可以轻易实现,
Kubernetes生来就是为了这些。
如何区分有状态应用和无状态应用?
无状态应用:不考虑存储,不维护有状态信息,也不考虑和其它服务副本是否有关系。
有状态应用:有固定存储,维护集群状态信息,例如:mysql、mongodb,有状态应用不建议部署到kubernetes。
为什么要用注册中心?
微服务太多面临的问题:
- 怎么记录一个微服务多个副本接口地址?
- 怎么实现一个微服务多个副本负载均衡?
- 怎么判断一个微服务副本是否可用?
主流注册中心:Eureka,Nacos,Etcd;
注册中心可基于statefulset部署到k8s集群中,也可以部署在集群外。
不同环境如何区分配置文件?
- configmap:通过不同的环境去挂载不同的配置文件
- entrypoint.sh:通过启动脚本区分
- java -jar --spring.profiles.active=dev xxx.jar:基于启动命令区分
- 统一配置中心,例如:Apollo,Disconf
3、项目迁移到k8s流程
-
制作镜像(应用程序、运行环境、文件系统)
基础镜像:Debian 或 应用程序的运行环境镜像
应用程序:Go,Java,Python ....
运行环境:不同的语言都需要有特定的运行环境(例如java需要jdk)
文件系统:忽略 -
控制器管理Pod
Deployment:无状态部署
StatefulSet:有状态部署(MySQL、Mongodb、Redis ...)
DaemonSet:守护进程部署
Job & CronJob:批处理 -
暴露应用
Service定义了Pod的逻辑集合和访问这个集合的策略,
Service引入为了解决Pod的动态变化,提供服务发现和负载均衡,
支持Cluster IP,NodePort以及LocalBalancer三种类型,
Service的底层实现主要实现有iptables和ipvs两种网络模式,推荐ipvs,
使用CoreDNS解析Service名称,
通过Label关联Pod。 -
对外发布应用(ingress)
通过Service关联Pod,
基于域名访问,
通过Ingress Controller实现Pod的负载均衡(支持TCP/UDP 4层和HTTP 7层)。
最后在Ingress前面部署外网用户统一入口实现七层代理/四层转发(Nginx、HaProxy...) -
日志采集
Pod在运行的时候会产生应用日志,需要将其日志文件信息采集到统一的数据库中存储,然后从一个平台中展示
易给开发查阅日志信息和错误日志信息,易于排查问题
主流方案:FileBeat + ELK(高性能和解耦:+kafka) -
监控
不管是k8s集群Master还是Node,以及Pod,我们需要知道它们运行的具体状况,
占用多少资源,剩余多少资源,就得通过监控的方式去实现。
主流方案:Prometheus + Grafana + ...Export