范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringBoot应用在kubernetes的sidecar设计与实战

  前言
  基于 Spring Boot 框架的应用如何在 kubernetes 环境部署,是沿用 Docker 容器的做法还是另有其他?接下来咱们从理论到设计再到实战,一起来感受传统后台应用在容器环境的微妙变化;  Spring Boot 应用基于 Spring Boot 框架的应用,通常会构建成 XXX.jar 文件,执行   java -jar XXX.jar   来运行该应用;  Docker 下的 Spring Boot 应用镜像Docker 环境下,通常用 Maven 的 docker-maven-plugin 插件将应用打包成镜像,例如以   java:8u111-jdk   作为基础镜像再加入 jar 文件,这样容器启动的时候执行   java -jar XXX.jar   就能将应用运行起来了;  传统思路Spring Boot 应用镜像在 kubernetes 声明为 Pod,即可正常运行;  但是,这是合适的做法么?去 K8S 官网需要一些理论上的指导吧;  寻找官方的理论依据官方文档地址:https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/  其中对 Pod 多个容器的关系描述如下:
  上图红框中提到一个容器基于共享资源对外提供服务,另一个"sidecar"容器负责更新这些共享资源;  在 Kubernetes 中文社区的文档中也对此作了阐述,地址是:http://docs.kubernetes.org.cn/312.html
  在提到 Pod 中的 sidecar 模式时,官方文档用到"relatively advanced"来形容,进一步证实了当下该模式的正确性,如下图:
  具体的实现模型如下图:
  Spring Boot 应用的 sidecar 设计根据 kubernetes 官方文档的指导,再结合 SpringBoot 应用的特点,我设计出的 sidecar 部署方式如下:
  该应用的业务服务被封装在一个 Pod 定义中,该 Pod 由两个容器组成;  绿色容器是来自 OpenJDK 官方镜像:   openjdk:8u181-jre-alpine3.8   ,用 docker history 命令查看体积,几十兆不算大:  [root@localhost work]# docker history openjdk:8u181-jre-alpine3.8 IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT 2e01f547f003        12 days ago         /bin/sh -c set -x  && apk add --no-cache  ...   78.6 MB                         12 days ago         /bin/sh -c #(nop)  ENV JAVA_ALPINE_VERSION...   0 B                             12 days ago         /bin/sh -c #(nop)  ENV JAVA_VERSION=8u181       0 B                             7 weeks ago         /bin/sh -c #(nop)  ENV PATH=/usr/local/sbi...   0 B                             7 weeks ago         /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/lib/...   0 B                             7 weeks ago         /bin/sh -c {   echo "#!/bin/sh";   echo "s...   87 B                            7 weeks ago         /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0 B                             7 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0 B                             7 weeks ago         /bin/sh -c #(nop) ADD file:25c10b1d1b41d46...   4.41 MB
  复制代码之所以要用 jre-alpine 版本,是因为   8u181-jdk   版本相比之下大了很多,如下所示:  [root@localhost work]# docker history openjdk:8u181-jdk IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT 954739b8bdfb        7 days ago          /bin/sh -c /var/lib/dpkg/info/ca-certifica...   355 kB                          7 days ago          /bin/sh -c set -ex;   if [ ! -d /usr/share...   348 MB                          7 days ago          /bin/sh -c #(nop)  ENV CA_CERTIFICATES_JAV...   0 B                             7 days ago          /bin/sh -c #(nop)  ENV JAVA_DEBIAN_VERSION...   0 B                             3 weeks ago         /bin/sh -c #(nop)  ENV JAVA_VERSION=8u181       0 B                             3 weeks ago         /bin/sh -c #(nop)  ENV JAVA_HOME=/docker-j...   0 B                             3 weeks ago         /bin/sh -c ln -svT "/usr/lib/jvm/java-8-op...   33 B                            3 weeks ago         /bin/sh -c {   echo "#!/bin/sh";   echo "s...   87 B                            3 weeks ago         /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0 B                             3 weeks ago         /bin/sh -c apt-get update && apt-get insta...   2.21 MB                         3 weeks ago         /bin/sh -c apt-get update && apt-get insta...   142 MB                          3 weeks ago         /bin/sh -c set -ex;  if ! command -v gpg >...   7.8 MB                          3 weeks ago         /bin/sh -c apt-get update && apt-get insta...   23.2 MB                         3 weeks ago         /bin/sh -c #(nop)  CMD ["bash"]                 0 B                             3 weeks ago         /bin/sh -c #(nop) ADD file:b3598c18dc39584...   101 MB
  复制代码红色容器的镜像使用 Spring Boot 应用构建出来的,稍后再详细整个过程;  在 kubernetes 环境,这两个容器会挂载同一个 Volume,红色容器将 jar 放在此处,绿色容器使用此处的 jar;  红色容器用来提供 jar,没有进程需要保持运行状态,很适合设置为 Init Container 类型;  绿色容器的 java 进程是长久运行的;  以上就是整体设计思路,接下来咱们就来实战吧,分三步完成:  实战步骤列举本次实战分为以下几部分组成:  开发 Spring Boot 应用;  制作 Docker 镜像,做两个版本,以便验证升级;  编写 yaml 文件;  在 kubernetes 环境部署,验证;  升级版本,验证;  环境和版本信息编译构建的 jdk 和运行的 jre 都用 1.8 版本;  maven:3.3.3;  spring boot:2.1.0.RELEASE;  docker:1.13.1;  kubernetes:1.12.2;  本次实战一共有四台 CentOS7 机器,基本信息如下:
  kubernetes 环境优 localhost、node1、node2 三台机器组成,maven 负责编译构建、生成镜像、上传到镜像仓库等操作;  开发 Spring Boot 应用这是个简单的 Spring Boot 应用,对外提供一个 http 接口,返回一个字符串;  您可以选择直接从 GitHub 下载这个工程的源码,地址和链接信息如下表所示:
  这个 git 项目中有多个文件夹,本章源码在 springbootsidecardemo 这个文件夹下,如下图红框所示:
  您也可以随本文一起来开发这个应用:  应用名为 springbootsidecardemo,是用 maven 构建的,JDK 使用 1.8,Spring Boot 版本 2.1.0.RELEASE;  应用的 pom.xml 如下,为了构建 Docker 镜像使用了 docker-maven-plugin 插件,该插件具体的配置请参照下面的注释:  <?xml version="1.0" encoding="UTF-8"?>      4.0.0       com.bolingcavalry     springbootsidecardemo     0.0.1     jar       springbootsidecardemo     Demo project for Spring Boot sidecard demo in K8S                org.springframework.boot         spring-boot-starter-parent         2.1.0.RELEASE                               UTF-8         UTF-8         1.8                                  org.springframework.boot             spring-boot-starter-web                                 org.springframework.boot             spring-boot-starter-test             test                              app                                       org.springframework.boot                 spring-boot-maven-plugin                                                          com.spotify                 docker-maven-plugin                 0.4.12                                                                            bolingcavalry/${project.artifactId}                                                                   ${project.version}                                                               busybox                                                                                                /                             ${project.build.directory}                             app.jar                                                                                           
  复制代码上面的配置有一处需要注意,就是基础镜像的选择(就是 baseImage 节点中的内容),我用了   busybox   ,用它是因为够小,来看 docker 镜像仓库中的描述,地址是 https://hub.docker.com/_/busybox/:
  看到这里,可能会有朋友问"为什么不用 scratch?它比 busybox 更小",scratch 虽小,但不带基本的 shell 命令,例如 cp 命令,而后容器启动时要用 cp 命令对文件做复制操作,因此只能选择 busybox 了;  Controller 类的代码也很简单:  package com.bolingcavalry.springbootsidecardemo.controller;   import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;   import java.util.Date;   /**  * @Description: 一个最普通的Controller,hello接口返回一个字符串并带上当前时间  * @author: willzhao E-mail: zq2599@gmail.com  * @date: 2018/11/6 14:15  */ @RestController public class HelloController {       @RequestMapping(value = "/hello")     public String hello(){         return "Hello version 1.0 " + new Date();     } }
  复制代码制作应用的 Docker 镜像请确保您当前环境的 maven 和 Docker 都已经 OK 了;  在应用的 pom.xml 所在目录执行如下命令即可构建 Docker 镜像:  mvn clean package -U -DskipTests docker:build
  复制代码构建成功的控制台输出如下:  [INFO] Building image bolingcavalry/springbootsidecardemo [INFO] Building image bolingcavalry/springbootsidecardemo Step 1/2 : FROM busybox  ---> 59788edf1f3e Step 2/2 : ADD /app.jar //  ---> 8105c9ac033b Removing intermediate container fdc62513abf6 Successfully built 8105c9ac033b [INFO] Built bolingcavalry/springbootsidecardemo [INFO] Tagging bolingcavalry/springbootsidecardemo with 0.0.1 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5.354 s [INFO] Finished at: 2018-11-06T05:07:08-08:00 [INFO] Final Memory: 42M/225M [INFO] ------------------------------------------------------------------------
  复制代码构建成功后用 docker history 命令查看镜像,如下,三个 layer 组成:  root@maven:~# docker history bolingcavalry/springbootsidecardemo:0.0.1 IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT 8105c9ac033b        46 minutes ago      /bin/sh -c #(nop) ADD file:909ca8e9c8898cd...   16.6 MB              59788edf1f3e        4 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0 B                             4 weeks ago         /bin/sh -c #(nop) ADD file:63eebd629a5f755...   1.15 MB
  复制代码去工程的 target 目录下看看构建的 app.jar 文件,如下所示,也是 16 兆,所以这个镜像已经被做到最小了,相对于以前那种 JAVA 环境+jar 文件的镜像,这个镜像更易于下载和上传:  root@maven:/usr/local/work/github/blog_demos/springbootsidecardemo/target# ls -al total 16276 drwxr-xr-x 9 root root     4096 Nov  6 05:08 . drwxr-xr-x 5 root root     4096 Nov  6 05:29 .. -rw-r--r-- 1 root root 16621351 Nov  6 05:08 app.jar -rw-r--r-- 1 root root     4432 Nov  6 05:08 app.jar.original drwxr-xr-x 3 root root     4096 Nov  6 05:08 classes drwxr-xr-x 2 root root     4096 Nov  6 05:08 docker drwxr-xr-x 3 root root     4096 Nov  6 05:08 generated-sources drwxr-xr-x 3 root root     4096 Nov  6 05:08 generated-test-sources drwxr-xr-x 2 root root     4096 Nov  6 05:08 maven-archiver drwxr-xr-x 3 root root     4096 Nov  6 05:08 maven-status drwxr-xr-x 3 root root     4096 Nov  6 05:08 test-classes
  复制代码执行 docker push 命令,将镜像推送到镜像仓库中,我这里是推送到了 hub.docker.com,您可以根据实际情况来执行,例如私有仓库、阿里云等都可以,当然了,如果当前机器就是 K8S 的机器就不用推送了,毕竟此镜像就是在 K8S 环境用的;  如果觉得推送到仓库太慢,或者从仓库下载太慢,也可以使用文件导入导出的方式,具体操作如下:  #将镜像导出为tar文件 docker save 2e01f547f003 > 1.tar   ###将tar文件还原为镜像 docker load < 1.tar   ###还原后的镜像的名称和tag都不对,要用tag命令来设置 docker tag 8105c9ac033b bolingcavalry/springbootsidecardemo:0.0.1
  复制代码制作应用升级版的 Docker 镜像为了验证 K8S 下的应用升级,做好 tag 为   0.0.1   的镜像之后,我们改动应用代码,把 pom.xml 中的版本改成 0.0.2,然后再做个镜像,这样稍后在 K8S 就能验证 Pod 升级了;  修改 HelloController.java 的源码,hello 方法返回的字符串,之前是   Hello version 1.0   ,现在改成   Hello version 2.0   ;  修改 pom.xml 中的 version 节点,之前是   0.0.1   ,现在改成   0.0.2   ,由于我们已配置了镜像 tag 就是工程版本,因此新构建的镜像 tag 会是 0.0.2;  再次执行 maven 命令构建,然后推送到镜像仓库;  此时我们有两个镜像了:  root@maven:~# docker images | grep sidecar bolingcavalry/springbootsidecardemo                                 0.0.2        f6ba01c33388        11 hours ago        17.8 MB bolingcavalry/springbootsidecardemo                                 0.0.1        8105c9ac033b        11 hours ago        17.8 MB
  复制代码现在镜像已经 OK,该准备部署到 kubernetes 环境了;  编写 yaml 文件在可以执行 kubectl 命令的机器上编写配置文件,Pod 的配置 javaweb-deploy.yaml 文件内容如下:  apiVersion: extensions/v1beta1 kind: Deployment metadata:   name: javaweb spec:   replicas: 1   template:     metadata:      labels:       name: javaweb     spec:      initContainers:      - image: bolingcavalry/springbootsidecardemo:0.0.1        name: appjar        command: ["cp", "/app.jar", "/app"]        volumeMounts:        - mountPath: /app          name: app-volume      containers:      - image: openjdk:8u181-jre-alpine3.8        name: openjdk8u181        command: ["java","-jar","/webapp/app.jar"]        volumeMounts:        - mountPath: /webapp          name: app-volume        ports:        - containerPort: 8080      volumes:      - name: app-volume        emptyDir: {}
  复制代码从上述配置中,有两处需要注意:  第一,应用镜像被设置为 initConteiners 类型的容器,被设置执行 cp 命令将自己的 app.jar 文件复制到共享的 Volume;  第二,一直运行用于提供服务的容器,来自 openjdk 镜像的 java 进程,该进程加载的 jar 文件就是共享的 Volume 中的 app.jar;  为了能在浏览器上访问该应用,再部署个 service,其配置文件 javaweb-svc.yaml 的内容如下:  apiVersion: v1 kind: Service metadata:   name: javaweb spec:   type: NodePort   ports:        - port: 8080          nodePort: 30008   selector:     name: javaweb
  复制代码启动 pod 和 service,在前面的 yaml 文件所在目录执行命令如下:  kubectl create -f javaweb-deploy.yaml  && kubectl create -f javaweb-svc.yaml
  复制代码service 的类型是 NodePort,因此可以通过 Node 节点的 IP 地址访问服务,我这边 Node 地址为 192.168.119.159,因此访问地址就是:http://192.168.119.159:30008/hello ,在浏览器访问返回如下内容:
  符合预期,证明主容器加 sidecar 容器的组合方式是可以正常工作的,接下来试试升级;  升级版本接下来模拟生产环境的应用升级,前面准好了两个版本的应用镜像:0.0.1 和 0.0.2,现在 K8S 环境运行的是 0.0.1,咱们将其升级为 0.0.2:  修改 javaweb-deploy.yaml 文件中镜像的 tag,从 0.0.1 改成 0.0.2,如下图红框所示:
  在 javaweb-deploy.yaml 文件所在目录执行如下命令即可完成升级:  kubectl apply -f javaweb-deploy.yaml
  复制代码在浏览器访问 http://192.168.119.159:30008/hello,返回如下内容,可见的确是修改后的应用逻辑:
  升级成功,符合预期;  小结sidecar 模式下,仅需更新应用 jar 打包的镜像,这个镜像可以做到极小;  提供 java 进程的镜像是固定的,在 K8S 环境下,一个 Node 上实际运行着多种 pod,如果他们的 java 进程都由一个镜像提供,其好处是不言而喻的;  Spring Boot 应用的运行,是由 java 进程与应用 jar 文件组成的,很适合 sidecar 模式,通过容器解耦,通过 pod 对外服务;  至此,Spring Boot 应用在 kubernetes 的 sidecar 设计与实战就全部完成了,希望此文能助您将应用以 sidecar 模式部署在 kubernetes,如果您发现我对官网的指导内容理解有误或有偏差,欢迎您的热心指正,谢谢!

励志让你看了很有感悟的句子1。少年有梦不应止于心动更应付诸行动2。无效的社交的摧毁有趣的灵魂,我的孤独永远骄傲3。能控制早晨的人方可控制一生4。有些事你现在不做,明天也可能不会做,一辈子都可能不做。那就选择百读不厌的好句子有关令你印象深刻的文案百读不厌的好句子分享!1。生命只是如此前行,不必说给别人听,只在心里最幽微的地方,时时点着一盏灯,灯上写着两行字今日踽踽独行,他日化蝶飞去。2。一个人不想攀高判断一个人过得好不好看脸人都说,苦瓜脸的人就是吃苦的命,是有一定道理的。因为人的第一眼,都是看对方的脸。有的人天生嘴巴向下,容易给别人造成一种不开心的错觉。毕竟,人人都喜欢笑着的人。这样的人更加有亲和力,常吃洋葱能消散甲状腺结节吗?提醒养护甲功,建议多喝6水常吃洋葱能消散甲状腺结节吗?像洋葱具有消炎杀菌的功效,而且还具有起到利尿的作用,能够帮助为身体补充所需的维生素以及微量元素,有利于个人的健康,但是对于甲状腺结节患者来说就不建议多吃喝水后一直小便的人,和半天不去厕所的人,谁的身体更健康呢?有科学专家进行过科学实验,发现一个人在不食用任何食物的情况之下,平均可以维持七天左右的寿命。正常人的饮水量?正常的成年人,一天的饮水量通常是25003000ml,日常的饮用水还包括你每天做的4件事,很可能成为心脏杀手,最伤害你的心脏您甚至可能不知道自己正在这样做,但它同样会损害您的心脏健康。如果你做一些简单的生活方式改变,你患心脏病的风险就会大大降低。这是你现在对你的心脏做的最糟糕的四件事,需要停止。过着久坐想要延年益寿的几个养生方法长寿一直都是是古今中外所有人类的共同愿望,但是生老病死的自然规律我们无法打破,因此只能在现有环境下,采取一些健康的保健手段来保持我们的身体健康,从而达到延年益寿的目的。那么想要保持血压高了,头部会先知道吗?出现这3种情况,建议大家要提高警惕现在社会,经济发展迅速,人们生活水平都提高了,由于不良的饮食习惯,以及不规律的生活习惯,三高人群变得越来越多。因为三高导致死亡的案例也越来越多了。高血压的发病比较慢,大部分的人早期到2030年,磷酸铁锂将主导全球3TWh锂离子电池市场能源人都在看,点击右上角加关注据WoodMackenziePowerRenewables发布的对锂离子电池制造业的新分析,预计到2028年,磷酸铁锂(LFP)将成为超过镍锰钴(NMVR设备商STEPVR创始人郭成用9年时间打开虚拟现实的大门经济观察网记者周应梅我们对于VR和元宇宙的想象力,在于我们用整个五感,用我们的身体,用我们感受现实世界的方法去获取信息或输出信息,实际上就是我们每一个人变成了互联网上的每一个节点。养生小知识五脏六腑时间排表十二时辰养生表微风肺经凌晨300500(深睡)微风大肠经500700(排便)微风胃经700900(吃早餐)微风脾经9001100(造血喝水)微风心经11001300(午饭午睡)微风
国乒太励志!坐经济舱打世乒赛累惨,对比国足包机住豪华酒店扎心北京时间11月18日消息,参加休斯顿世乒赛的国乒将士们已经抵达当地酒店,全程花去了将近2天时间。对于光环耀眼的国乒来说,此番他们却是坐经济舱前往。对比国足包机前往海外比赛,住五星级声称天赋碾压往届,本届的状元真的是10年来最强吗?在篮球运动里,天赋决定了上限。无论再努力,没有篮球天赋,成就注定有限。末节之王小托马斯,受限于身高,在当打之年被球队交易。原因何在?175的身高决定了球队对他的未来不抱期望。历史中新赛季段位重置规则来了!海克斯能量清零,黄金段位不掉段英雄联盟手游作为一款完美复刻端游的游戏,在上线之初就吸引了一大批的情怀玩家,在这款游戏中不仅仅打法跟端游相似,就连英雄的技能以及人物模型都相差无几,在国服上线的时候官方也是第一时间不是很懂?这勇士咋回事儿,一下子就又这么猛?湖人却崩盘了上赛季和这赛季有哪些变化?除了库里,连个全明星都没有,把老四吊起来打,这防守也太好了吧,看不懂球了,我已经你说阵容强度吧,我感觉各个位置除了一号位,其他也就那样,为啥这么强。上赛季篮网惨败勇士后,美国杨毅发声库里是帅才,杜兰特只是将才本赛季虽然开打的时间并不算太长,但是很多的球队的表现却让球迷们出人意料。比如谁都不会想到,今年的东西部第一分别被勇士队和奇才队占据。湖人队因为各种问题暂列西部第七,东部更是乱成了一17年勇士vs96年公牛,谁的赢面更大?罗德曼勇士很难得到30分17年的勇士可以说是非常强悍的,因为杜兰特的加入,让勇士变成了四巨头,96年的公牛也是非常不错的阵容,那么问题来了,17年勇士大战96年公牛,谁的赢面更大,罗德曼给予了回应现在的防先胜勇士再胜奇才,两战拿下东西部第一篮网四人20擒拿骑士黄蜂真强队,先胜勇士再胜奇才两战拿下东西部第一篮网四人20擒拿骑士!什么样的球队算强队,连续两战分别拿下东西部第一算不算?黄蜂居然做到了,乔老板的球队终于硬气了!1。黄蜂队布里奇斯玩家将AppleWatch改装成了宝可梦晶灿钻石明亮珍珠的宝可表宝可表(Poketch)是宝可梦虚拟世界神奥地区的一种电子产品,它可以通过搭载各种应用增加新功能,这些应用可以从神奥地区的各处获得。最近,玩家uIdreesInc在现实借助Appl库里臀部又受伤,湖人宣布詹姆斯复出时间,瓦妮莎替科比泪目喊话乐极生悲啊,11月18日对阵勇士队的比赛,小学生库里玩得倒是很开心,首节12分,全场比赛9个三分,砍下了37分7篮板5助攻2抢断,库里命中了自己常规赛生涯的第2900个三分球。除了NBA2122赛季勇士11799篮网,库里37分,如何看待这场比赛?妙手回春,行云流水,那支勇士的魔力回来了吗?近几个赛季的挣扎,人们关于勇士辉煌过往的记忆逐渐褪去。就算上个赛季,库里康复后表现惊艳,勇士球迷们其实并不十分满意。因为单人转固然有足够搞笑!勇士格林和对手夹胳膊纠缠,队友裁判都分不开,较上劲了NBA常规赛一场焦点战,金州勇士队客场挑战克利夫兰骑士。最终,勇士队以10489战胜对手。本场比赛第四节,发生了很搞笑的一幕,德雷蒙德格林和加兰相互夹胳膊纠缠,队友裁判都分不开,两