1.1. Kubernetes应用开发实践
1.1.1. 通用开发者建议
1.为应用添加健康检查
应用开发者应该为每个独立启动的服务均添加基于HTTP协议的健康检查接口,例如可以使用Spring Boot Actuator来添加健康检查。通常URL为/health,访问该URL可以显示服务的健康状态,具体如何判定为健康,由应用开发者自行处理,例如该接口可以执行以下检查:
- 检查数据库连接是否正常。
- 检查核心功能是否正常。
该健康检查可以提供给运维人员,在进行Kubernetes工作负载创建时,用于配置健康检查的探针,确保服务异常时,Kubernetes可以正确的处理。
2.为应用添加监控接口
应用开发者应该为每个独立启动的服务添加监控接口,以Prometheus为例,可以将指标以Prometheus的Exporter的方式进行暴露。例如可以使用Spring Boot Actuator来添加监控接口,示例图如下:
3.使用ServiceName进行服务间访问
应用开发者需要使用Service Name进行服务间访问,不要使用Pod IP或者Service的Cluster IP,Service Name在Kubernetes内部是可以解析到Cluster IP。
4.Pod可以随时被杀死,应用需要自己处理突然关闭的问题。
Pod在Kubernetes中可能因为节点压力被驱逐、可能因为运维人员手工驱逐,也可能因为节点故障,在新的主机上启动,所以Pod可以随时被杀死重建,复杂的应用程序在处理逻辑时,需要考虑到这个因素,并进行正确的处理。
5.遵守云原生规范,不要把Pod当成虚拟机。
很多开发人员从传统的虚拟机迁移到Kubernetes环境,最容易犯的问题就是,使用原有的思想,指导新的环境。毕竟习惯的改变需要时间,以下时常见的不规范的操作,尽可能的避免。
- 避免在Pod中调试代码,避免在Pod上传和下载文件,遵循不可变基础设施的理论,不要试图修改一个Pod。
- 避免将Pod的代码挂载出来。很多PHP工程师喜欢这么干,遵循不可变基础设施的理论,版本更新就需要重新构建镜像,进行升级。
- 避免使用Pod的IP地址或者主机名,因为Pod的生命周期可能很短,IP地址和名称重启后均可能发生变化。
- 避免使用kubectl edit去修改一个工作负载,可以使用Helm,或者修改YAML文件,提交到Git,使用kubectl apply进行变更。
1.1.2. Spring Cloud迁移至Kubernetes
如果你需要将急于Spring Cloud的应用系统迁移至Kubernetes,再了解了Kubernetes的运行方式后,有以下两种方案:
- 直接将Spring Cloud迁移至Kubernetes,不改动任何内容。
- 引入Spring Cloud Kubernetes对原有的Spring Cloud进行改造,更好的融合Kubernetes。
Srping Cloud直接迁移至Kubernetes
如果将Spring CLoud框架开发的应用直接原封不动的迁移至Kubernetes相对于传统虚拟化的模式遇到的最大的不同就是网络,如果有Kubernetes集群外的Client需要访问集群内就面临以下问题:
- POD的IP段是独立的IP段,对于集群外的机器是不可访问。
- Spring Cloud的服务做服务注册的时候,注册的是POD的IP
- Spring Cloud的客户端从Eureka上获取服务的IP是POD的IP,从而造成集群外机器访问该POD的IP是不通的。
如果迁移后有类似的访问问题,通常以下几种解决方案:
方案一: Host network(不推荐) 部署的时候,以host network的方式部署Spring Cloud的服务应用。这个方式虽然简单,但是其利用的是port mapping的方式,在同一个node节点部署多个实例时,容易造成端口冲突的问题,在kubernetes环境下,一般不建议使用
方案二:Bridge network/Macvlan/Vlan(复杂) 利用CNI的bridge/Macvlan网络模式,或者是网络插件的Vlan模式(如Contiv),将POD的IP段设置成与主机IP段在同一个段内 ,通过配置交换机的路由,使其能够互访。 但是这里面有一定的局限性,特别是在公有云上,是无法在虚拟网络里再构建这些二层网络的。
方案三:将集群外的机器也纳入集群内管理,但是不运行POD(建议) 依然是将POD的IP段设置为独立的IP段,和主机IP段隔离。但是将集群外的机器,也纳入集群内:安装对应的kubectl, kubeproxy。这样在这台机器是可以直接访问POD的IP的。为了不让这些机器接受调度请求而运行对应的POD,需要认为将这些机器设置为非容器调度节点。
kubectl cordon <node-name> --ignore-daemonsets
Spring Cloud与Kubernetes集成
Spring Cloud可以和Kubernetes进行深度融合,因为在架构上它们之间有很多的交集.
Spring Cloud和Kubernetes对比
下图是Spring Cloud和Kubernetes在一些功能上的对比,可以看到在一些功能上,是完全重复的。
Spring Cloud Kubernetes框架
除了众所周知的Spring Cloud Netflix全家桶,其实还有很多对标的选择,例如微软推出的Spring Cloud Azure、阿里推出的spring-cloud-alibaba、Spring官方推出的Spring Cloud Kubernetes,都是用于Spring Cloud框架与不同生态的融合。 Spring Cloud Kubernetes(https://spring.io/projects/spring-cloud-kubernetes),是Spring Cloud官方提供的一个通用服务接口实现,允许开发者在Kubernetes上构建和运行Spring Cloud应用。
- 配置管理:从Kubernetes ConfigMap 和 Secret 加载应用 application properties。当 ConfigMap 或 Secret 发生变化时,重新加载 application properties。
- 服务发现:Discovery Client 实现,将服务名称(service name)解析为 Kubernetes服务。