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

简单几步将SpringBoot项目部署到K8S,步骤如下!

时间:2023-03-21 22:09:26 科技观察

前言在Kubernetes中部署springboot应用通常是一项繁琐的工作,但是SpringBootOperator可以给你带来更清爽简单的体验。SpringBootOperator是基于Kubernetes的自定义资源定义(CRD)扩展API开发的。打包Docker镜像在我们讨论部署之前,我们需要将我们的SpringBoot应用程序打包到一个标准的DockerImage中。java项目打包镜像的maven/gradle插件有很多。我的另一篇文章构建了SpringBoot的Docker镜像。这里介绍一个新的google开源插件Jib,使用起来更加方便。注意:jib打包的镜像会导致java应用的pid=1。使用SpringBootOperator发布时,Operator会将kubernetes的ShareProcessNamespace参数设置为true(可以使用v1.10+版本)来解决这个问题。下面演示一下我们通过https://start.spring.io生成一个标准的SpringBoot项目operator-demo,然后使用jib插件镜像打包mvncom.google.cloud.tools:jib-maven-plugin:build\-Djib.to.auth.username=${{secrets.MY_USERNAME}}\-Djib.to.auth.password=${{secrets.MY_PASSWORD}}\-Djib.container.jvmFlags=--add-opens,java.base/sun.nio.ch=ALL-UNNAMED\-Djib.from.image=freemanliu/oprenjre:11.0.5\-Dimage=registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0执行以上命令后,我们会得到一个标准的docker镜像,将其推送到远程仓库。完成镜像的构建后,我们将我们的Operator安装到kubernetes集群中。当然,你首先需要一个集群。可以参考我之前的文章部署高可用kubernetes。虽然版本比较旧,但是是新的。该版本实际上是类似的想法。https://qingmu.io/2019/05/17/Deploy-a-highly-available-cluster-with-kubeadm/快速安装这里快速安装只是为了快速体验demokubectlapply-fhttps://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment.yamlapply成功后控制平台输出namespace/spring-boot-operator-systemcreatedcustomresourcedefinition.apiextensions.k8s.io/springbootapplications.springboot.qingmu.iocreatedrole.rbac.authorization.k8s。io/spring-boot-operator-leader-election-rolecreatedclusterrole.rbac.authorization.k8s.io/spring-boot-operator-manager-rolecreatedclusterrole.rbac.authorization.k8s.io/spring-boot-operator-proxy-rolecreatedclusterrole。rbac.authorization.k8s.io/spring-boot-operator-metrics-readercreatedrolebinding.rbac.authorization.k8s.io/spring-boot-operator-leader-election-rolebindingcreatedclusterrolebinding.rbac.authorization.k8s.io/spring-boot-operator-manager-rolebindingcreatedclusterrolebinding.rbac.authorization.k8s.io/spring-boot-operator-proxy-rolebindingcreatedservice/spring-boot-operator-controller-manager-metrics-servicecreateddeployment.apps/spring-boot-operator-controller-managercreated稍等片刻查看是否安装成功kubectlgetpo-nspring-boot-operator-system成功如下输出NAMEREADYSTATUSRESTARTSAGEspring-boot-operator-controller-manager-7f498596bb-wcwtn2/2Running02m15s部署OperatorDemo应用程序完成Operator的部署后,让我们部署我们的第一个应用程序。这里发布我们上面写的springboot应用opreator-demo。首先,我们需要写一个SpringBootApplication的CRD部署yaml如下#Demo.yamlapiVersion:springboot.qingmu.io/v1alpha1kind:SpringBootApplicationmetadata:name:operator-demospec:springBoot:version:v1.0.0#image:registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0细心的同学可能发现了,为什么没有图像?这个怎么发布,只要名字,版本,就可以完成发布了?恩,那就对了!发布就可以完成了,具体是怎么做的,后面会详细说。然后我们应用kubectlapply-fDemo.yaml,查看控制台输出springbootapplication.springboot.qingmu.io/operator-democreated,验证是否创建成功。然后让我们看看我们部署的第一个应用程序。这里我们直接使用上面yaml里面的名字就可以过滤了。检查pod~#kubectlgetpo|grepopoperator-demooperator-demo-7574f4789c-mg58m1/1Running076soperator-demo-7574f4789c-ssr8v1/1Running076soperator-demo-7574f4789c-sznww1/1Running076s,看看我们的pid是否不等于1。设置参数ShareProcessNamespace,我们可以在Kubernetes层面解决pid=1的问题。kubectlexec-itoperator-demo-7574f4789c-mg58mbashbash-5.0#ps-efUIDPIDPPIDCSTIMETTYTIMECMDroot10002:06?00:00:00/pauseroot602602:06?00:00:09java--add-opensjava.base/sun.nio.ch=ALL-UNNAMED-cp/app/resources:/app/classes:/app/libs/*io.qingmu.operator.operatordemo.Oper...root380002:07pts/000:00:00bashroot4438002:07pts/000:00:00ps-efViewsvc~#kubectlgetsvc|grepoperator-demoperator-demoClusterIP10.101.128.68080/TCP2m52s访问试试吧。root@server1:~#curl-ihttp://10.101.128.6:8080HTTP/1.1200Content-Type:text/plain;charset=UTF-8Content-Length:9Date:Wed,08Apr202008:45:46GMThello!!!让我们试试减少副本数为1,编辑我们的Demo.yaml,添加一个新的属性replicas#Demo.yamlapiVersion:springboot.qingmu.io/v1alpha1kind:SpringBootApplicationmetadata:name:operator-demospec:springBoot:version:v1.0.0replicas:1应用root@server1:~#kubectlapply-fDemo.yamlspringbootapplication.springboot.qingmu.io/operator-democonfigured再次查看pod,你会发现我们的pod已经缩放为replica~#kubectlgetpo|grepoperator-demoperator-demo-7574f4789c-sznww1/1Running08m29s清理operator-demo删除pod,我们只需要执行delete~#kubectldelete-fDemo.yamlspringbootapplication.springboot.qingmu.io"operator-demo"deleted再次查看pod,kubectlgetpo不见了|grpopoperator-demo部署自己的应用部署自己的私有仓库应用,需要先创建一个secret(如果已经创建,请跳过)创建docker-registrysecretkubectlcreate\secretdocker-registryaliyun-registry-secret\--docker-server=registry-vpc.cn-hangzhou.aliyuncs.com\--docker-username=***\--docker-password=***\--docker-email=***crdofyourownapplicationYamlapiVersion:springboot.qingmu.io/v1alpha1kind:SpringBootApplicationmetadata:name:你的应用的名字spec:springBoot:version:v1.0.0replicas:1image:你的镜像地址imagePullSecrets:-上面创建的秘密是一个完整的SpringBoot应用程序Yaml。下面是一个完整的yaml属性结构。大部分属性我们可以默认配置,常用值见后面的自定义安装算子。apiVersion:springboot.qingmu.io/v1alpha1kind:SpringBootApplicationmetadata:name:operator-demonamespace:defaultspec:springBoot:#image不能设置,如果不设置,使用IMAGE_REPOSITORY+/+mate.name+:+spec.springBoot.version#registry。cn默认-shanghai.aliyuncs.com/qingmuio+/+operator-demo+:+v1.0.0image:registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo:v1.0.0clusterIp:""version:v1.0.0replicas:1resource:cpu:request:50mlimit:""memory:request:1Gilimit:1Gipath:liveness:/actuator/healthreadiness:/actuator/healthhostLog:/var/applogshutdown:/spring/shutdownimagePullSecrets:-aliyun-docker-registry-secretenv:-名称:EUREKA_SERVERS值:http://eureka1:8761/eureka/,http://eureka2:8761/eureka/,http://eureka3:8761/eureka/nodeAffinity:key:"failure-domain.beta.kubernetes.io/zone"operator:"in"values:-"cn-i"-"cn-h"-"cn-g"优雅关机的路径由于优雅关机默认是关闭的,不支持Get请求,我们需要启用和搭建桥梁,首先启用管理:endpoints:web:exposure:in在application.yml中包括:“*”endpoint:shutdown:enabled:true然后桥接一个Get方法@RestControllerpublicclassShutdownController{@AutowiredprivateShutdownEndpointshutdownEndpoint;@GetMapping("/spring/shutdown")publicMapshutdown(HttpServletRequestrequest){returnshutdownEndpoint.shutdown();}}节点亲和性的使用举个例子,我们有一个springboot应用user-service,希望它可以分布到3个可用区的6个节点上:首先我们把机器分成多个可用区cn-i区(节点-i1,node-i02)cn-harea(node-g1,node-g02)cn-garea(node-h1,node-h02)现在我们有3个可能的区域,每个区域有2个workload,一共6个工作负载然后我们这些机器需要单独标记。将zonei中的所有机器标记为cn-ikubectllabelnodenode-i1failure-domain.beta.kubernetes.io/zone=cn-ikubectlllabelnodenodenode-i2failure-domain.beta.kubernetes.io/zone=cn-i同理,标记zoneh相同的是true为h和g区设置它来实现我们的调度效果,只需要这样写。spec:springBoot:nodeAffinity:#不能设置节点亲和性。这里的演示是尝试将pod分散到ihg的三个可用区。默认情况下,pod反亲和键设置为:"failure-domain.beta.kubernetes.io/zone"operator:"In"values:-"cn-i"-"cn-h"-"cn-g"运营商自定义安装上面我们已经快速安装好了,接下来我们会讲解如何自定义安装以及有哪些自定义参数可以是我们以环境变量的形式注入的个性化参数。接下来修改Deployment,完成自己的个性化配置部署。从我提供的deploymentyaml下拉到最后,找到名称为spring-boot-operator-controller-manager的Deployment,我们修改一下。apiVersion:apps/v1kind:Deploymentmetadata:labels:control-plane:controller-managername:spring-boot-operator-controller-managernamespace:spring-boot-operator-system.....#注意:下面的配置是针对generalglobalspringboot默认配置对crd的springboot有效。如果这里不配置,也可以在部署的yaml中指定#private仓库的地址。比如我最后打包的镜像地址是registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0#配置的值为registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo#配置这个值后,如果我们在发布的yaml中不写image,则使用image为IMAGE_REPOSITORY+"/"+mate.name+spec.springBoot.version-name:IMAGE_REPOSITORYvalue:registry.cn-shanghai。aliyuncs.com/qingmuio#RequestCPUlimit-name:REQUEST_CPUvalue:50m#limitthemaximumavailablemaximumCPUjavaapplication不需要限制,不合理的限制会导致启动异常慢Path,springbootactuatordefaultPath-name:READINESS_PATHvalue:/actuator/health#readysurvivalPath,springbootactuatordefaultPath-name:LIVENESS_PATHvalue:/actuator/health#readysurvivalPath,gracefulshutdownPath-name:SHUTDOWN_PAThvalue:/spring/shutdown#replicationlevel为副本数-name:REPLICASvalue:"3"#外部日志到宿主机磁盘路径,默认相同-name:HOST_LOG_PATHvalue:/var/applog#拉取镜像的秘密-name:IMAGE_PULL_SECRETSvalue:""#拉取镜像的Secrets-name:SPRING_BOOT_DEFAULT_PORTvalue:"8080"#nodeaffinity,比如我可以设置pod分散在不同可用区cn-i,cn-g,cn-h区-name:NODE_AFFINITY_KEYvalue:""-name:NODE_AFFINITY_OPERATORvalue:""-name:NODE_AFFINITY_VALUESvalue:""#每个springboot的每个pod都会添加全局环境变量,格式k=v;k1=v2,#比如EUREKA_SERVERS=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/,http://eureka3:8761/eureka/;k=v-name:SPRING_BOOT_ENVvalue:""image:registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:latest.....自定义安装后部署yaml可以简化为如下apiVersion:springboot.qingmu.io/v1alpha1kind:SpringBootApplicationmetadata:name:yourapplicationNamespec:springBoot:version:v1.0.0附录环境变量形式Github仓库SpringBootOperator:https://github.com/goudai/spring-boot-operator