当前位置: 首页 > 科技观察

照猫画虎把SpringBoot搬到了K8s上,翻船了,体验了Go在云原生的两大优势

时间:2023-03-21 21:46:52 科技观察

这是我们K8s快速入门实战的最后一篇了。从一行代码开始,到在K8s上部署Go服务,需要经过哪些步骤,每一步是怎么做的。今天我们将更新这篇关于如何将SpringBoot应用程序部署到K8s的文章。本来是想偷懒把上节课的图片名改一下。你甚至不能偷懒。具体怎么翻,我们先回顾一下,再在总结的时候再说。我在云原生上有Go和Java相比的优势。好吧,我们先假装大家都是小白,再带大家从头部署一个SpringBoot应用跑在K8s上。SpringBoot应用,运行在K8s上如何部署一个SpringBoot开发的Web应用运行在K8s集群上,需要完成哪些步骤,这里我们先总结一下,然后依次演示各个步骤。这里再重复一下上面理论部分的知识点。分为几个步骤:完成应用代码的编写,将程序打包成容器镜像,使用上一步打包好的镜像,创建应用Pod,使用Deployment调度应用,使用Service对外暴露。该应用程序是通过Ingress代理应用的。你必须记住这六个步骤。下面我们一一展开,详细说说。为了完成应用代码的编写,为了演示,我们简单地创建一个HelloWorld级别的代码。没必要弄得太复杂,复杂项目后面几步的操作都是一样的。首先,让我们构建一个由Maven管理的项目。POM文件中引入了这些依赖关系:POM文件中的依赖关系POM文件中的依赖关系非常简单。我们演示的是一个Web应用,所以在项目依赖中引入SpringMVCstarter即可。至于应用的代码,也很简单。从应用代码可以看出,HelloWorld层面的代码与我们演示的Go程序代码并没有多多少。主要原因是SpringBoot已经为我们做了很多工作。代码写好了,接下来我们将把这个SpringBoot应用做成Docker镜像。将程序打包成容器镜像首先,我们准备好打包镜像的Dockerfile。FROMopenjdk:8-jreADDtarget/*.jar/application.jarENTRYPOINT["java","-jar","/application.jar"]把这个放在项目的根目录下,具体命令我们就不说了Dockerfile话说回来,只有三个命令,可以在网管话bi吧公众号回复docker,得到一份docker命令手册,里面有常用Docker命令的解释。接下来将应用打包成镜像:dockerbuild-tregistry.cn-hangzhou.aliyuncs.com/docker-study-lab/simple-app-java:v0.1上传镜像到远程仓库:dockerpushregistry。cn-hangzhou.aliyuncs.com/docker-study-lab/simple-app-java:v0.1这次我们还是把镜像上传到老好人创建的镜像仓库。练习的时候也可以上传,但是首先你需要在阿里云申请一个免费的镜像云账号,然后使用dockerlogin命令配置你的客户端。阿里云页面上有说明。如果实在不行,可以在公众号问我。创建应用的Deployment,还记得我在之前的文章——K8s面向对象中说过的话吗。Deployment是一个复合控制器,它包装了一个名为ReplicaSet的控制器-副本集。ReplicaSet管理运行的Pod数量,Deployment实现Pod滚动更新,对Pod的健康状况进行健康检查,以及回滚更新的能力。所以,这里我们直接把步骤2和步骤3结合起来。其实也没什么好说的,毕竟我们在Go实践的文章中已经讲过一次了,那么直接上本次使用的YAML配置吧。部署YAML,我这里就翻了一遍。一开始,我完全照抄了Go实践章节中的Deployment配置。部署后,服务不断重启。检查后,是OOM。翻车的截图是因为我们只给Go应用容器分配了50M的内存。这一次,SpringBoot虽然只是一个HelloWorld程序,但是并不能运行,一请求容器就会挂掉。这凸显了Go在云原生中的第一个好处:它占用的内存更少。排查K8s问题的方法可以参考之前的文章:研发群想安装?先学习这些排查K8s问题的方法。上面我直接把容器的可用内存调到了500M。并不是说Java应用占用的内存是Go应用的10倍。我有点懒得尝试了。我直接设置为500M。反正就是100M,试了也不行,哭!使用Service暴露服务创建上述对象后,我们的应用程序只能在K8s集群内部使用。如果我们想从外部访问它,我们必须暴露应用程序。这时候,我们就需要Service对象了。关于Service对象的具体概念解释,我们看之前的文章,这里不再赘述。下面是一个默认的ClusterIP服务,为什么只暴露在集群中?因为我们下面会给Service加一层Ingress,所以不需要使用NodePort类型的Service在节点上开一个端口,然后对外暴露服务。ServiceYAML使用Ingress来代理Service在使用Ingress之前我们应该做什么?是的,您需要先安装IngressController。这里我们使用开源的Ingress-Nginx,本质上就是一个Nginx。很容易理解Ingress是Service对象的代理。想要代理首先得有基础设施支持,但是K8s这里的一切都是面向对象管理的,所以就有了IngressController,它支持不同类型的IngressController,我们用的那个是免费的。请参考下面的链接进行安装。这很简单。上次发了一篇文章,没安装就跑过来问我为什么跑不起来,还去面壁了一会儿。https://kubernetes.github.io/ingress-nginx/deploy/下一步是声明代理我们的Web应用程序的Ingress对象。IngressYAML通过kubctlapply-f命令提交到K8s集群创建Ingress对象。创建Ingress对象后,我们可以通过java-app.example.com访问我们的服务。当然前提是在电脑上配置好我们的hosts文件,把这个域名绑定到127.0.0.1上。来看看我们的访问结果:在K8s上运行应用的效果常用命令这两天的实践,一直在告诉大家如何声明K8s的各种资源对象,以及如何搭配使用。提到了运行期间执行的命令。一张嘴,没有展开说。主要原因是它的命令非常简单。我从头到尾都使用了一个kubectlapply命令。下面我将K8s常用的命令组合放在这里,供大家操作时参考。kubectlapply-fxxx.yaml允许K8s根据配置文件在集群中创建/更新资源对象。kubectl获取pod|部署|服务|ingress查看集群中pod、Deployment、Service、Ingress资源的状态。kubectl描述pod|部署|服务|ingress{$objectName}查看当前特定资源对象的详细信息。kubectl删除pod|部署|服务|ingress{$objectName}删除指定对象。小结这里总结一下K8s常用的入门知识和相关实战操作。只能算是很初级的介绍。还有许多其他非常高级的功能可以让我们控制K8s对应用程序的各种调度动作。