<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          簡單幾步把Spring Boot 項(xiàng)目部署到 K8S,步驟來了!

          共 18101字,需瀏覽 37分鐘

           ·

          2021-11-14 02:50

          上一篇:杭州程序員從互聯(lián)網(wǎng)跳央企,曬一天工作和收入,網(wǎng)友:待一年就廢

          作者:qingmu

          qingmu.io/2020/04/08/Spring-Boot-Operator-User-Guide/

          前言

          在Kubernetes中部署spring boot應(yīng)用整體上來說是一件比較繁瑣的事情,而Spring Boot Operator則能帶給你更清爽簡單的體驗(yàn)。
          Spring Boot Operator基于Kubernetes的custom resource definitions (CRDs)擴(kuò)展API進(jìn)行的開發(fā)。

          打包Docker鏡像

          在講部署之前我們需要先將我們的SpringBoot應(yīng)用打包成標(biāo)準(zhǔn)的DockerImage。
          java項(xiàng)目打包鏡像用maven/gradle插件比較多,我的另一篇文章構(gòu)建SpringBoot的Docker鏡像,這里在介紹一個(gè)新的google開源的插件Jib,該插件使用起來比較方便。

          注意:jib打包的鏡像會導(dǎo)致java應(yīng)用的pid=1,在使用SpringBootOperator進(jìn)行發(fā)布時(shí)候,Operator會設(shè)置kubernetes的ShareProcessNamespace參數(shù)為true(v1.10+版本都可使用)來解決該問題。

          下面就來演示一下我們通過https://start.spring.io生成一個(gè)標(biāo)準(zhǔn)的SpringBoot項(xiàng)目operator-demo,然后使用jib插件進(jìn)行鏡像打包
          mvn com.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
          執(zhí)行上面的命令之后我們將得到一個(gè)標(biāo)準(zhǔn)的docker鏡像,該鏡像會被推送到遠(yuǎn)程倉庫。

          Operator快速體驗(yàn)

          完成了鏡像的構(gòu)建之后,我們緊接著來安裝我們的Operator到kubernetes集群,當(dāng)然了首先你需要一套集群,可以參考我之前一篇文章部署高可用kubernetes,雖然版本比較老,但是新版本其實(shí)也差不多的一個(gè)思路。

          https://qingmu.io/2019/05/17/Deploy-a-highly-available-cluster-with-kubeadm/

          快速安裝

          此處快速安裝只是為了快速體驗(yàn)demo

          kubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment.yaml

          apply成功之后控制臺輸出

          namespace/spring-boot-operator-system created
          customresourcedefinition.apiextensions.k8s.io/springbootapplications.springboot.qingmu.io created
          role.rbac.authorization.k8s.io/spring-boot-operator-leader-election-role created
          clusterrole.rbac.authorization.k8s.io/spring-boot-operator-manager-role created
          clusterrole.rbac.authorization.k8s.io/spring-boot-operator-proxy-role created
          clusterrole.rbac.authorization.k8s.io/spring-boot-operator-metrics-reader created
          rolebinding.rbac.authorization.k8s.io/spring-boot-operator-leader-election-rolebinding created
          clusterrolebinding.rbac.authorization.k8s.io/spring-boot-operator-manager-rolebinding created
          clusterrolebinding.rbac.authorization.k8s.io/spring-boot-operator-proxy-rolebinding created
          service/spring-boot-operator-controller-manager-metrics-service created
          deployment.apps/spring-boot-operator-controller-manager created

          稍等片刻查看是否已經(jīng)安裝成功

          kubectl  get po -n spring-boot-operator-system

          成功如下輸出

          NAME                                                       READY   STATUS    RESTARTS   AGE
          spring-boot-operator-controller-manager-7f498596bb-wcwtn   2/2     Running   0          2m15s

          部署OperatorDemo應(yīng)用

          完成了Operator的部署之后,我們來部署我們第一個(gè)應(yīng)用,這里我們就發(fā)布上面我們編寫的springboot應(yīng)用opreator-demo。

          首先我們需要先編寫一個(gè)Spring Boot Application 的CRD部署yaml,如下

          # Demo.yaml
          apiVersion: springboot.qingmu.io/v1alpha1
          kind: SpringBootApplication
          metadata:
            name: operator-demo 
          spec:
            springBoot:
              version: v1.0.0
          #    image: registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0
          細(xì)心的同學(xué)可能發(fā)現(xiàn)了,為啥連Image都沒有?這怎么發(fā)布,就name,version,就能完成發(fā)布?是的沒錯(cuò)!就能完成發(fā)布,后面我講詳細(xì)講到他是如何完成的。
          接著我們apply一下
          kubectl apply -f Demo.yaml

          看到console輸出

          springbootapplication.springboot.qingmu.io/operator-demo created

          驗(yàn)證

          表示創(chuàng)建成功了,接著我們來看下我們部署的第一個(gè)應(yīng)用,這里我們直接用上面的yaml中的name過濾即可。

          查看pod

          ~# kubectl  get po | grep operator-demo
          operator-demo-7574f4789c-mg58m             1/1     Running   0          76s
          operator-demo-7574f4789c-ssr8v             1/1     Running   0          76s
          operator-demo-7574f4789c-sznww             1/1     Running   0          76s

          查看下我們的pid不等于1的設(shè)置是否生效,根據(jù)下面的結(jié)果可以看到通過設(shè)置ShareProcessNamespace該參數(shù)我們可以在Kubernetes層面來解決這個(gè)pid=1的問題。

          kubectl exec -it operator-demo-7574f4789c-mg58m bash
          bash-5.0# ps -ef
          UID        PID  PPID  C STIME TTY          TIME CMD
          root         1     0  0 02:06 ?        00:00:00 /pause
          root         6     0 26 02:06 ?        00:00:09 java --add-opens java.base/sun.nio.ch=ALL-UNNAMED -cp /app/resources:/app/classes:/app/libs/* io.qingmu.operator.operatordemo.Oper...
          root        38     0  0 02:07 pts/0    00:00:00 bash
          root        44    38  0 02:07 pts/0    00:00:00 ps -ef

          查看svc

          ~# kubectl  get svc | grep operator-demo
          operator-demo             ClusterIP   10.101.128.6     <none>        8080/TCP            2m52s

          我們來訪問一下試試。

          root@server1:~# curl -i http://10.101.128.6:8080
          HTTP/1.1 200 
          Content-Type: text/plain;charset=UTF-8
          Content-Length: 9
          Date: Wed, 08 Apr 2020 08:45:46 GMT

          hello !!!

          我們來試著縮減他的副本數(shù)到1個(gè)

          編輯我們的Demo.yaml,加入一個(gè)新的屬性replicas

          # Demo.yaml
          apiVersion: springboot.qingmu.io/v1alpha1
          kind: SpringBootApplication
          metadata:
            name: operator-demo 
          spec:
            springBoot:
              version: v1.0.0
              replicas: 1

          應(yīng)用一下

          root@server1:~# kubectl apply -f Demo.yaml 
          springbootapplication.springboot.qingmu.io/operator-demo configured

          再次查看pod,你會發(fā)現(xiàn)我們的pod已經(jīng)縮放為一個(gè)副本了

          ~# kubectl  get po | grep operator-demo
          operator-demo-7574f4789c-sznww             1/1     Running   0          8m29s

          清理operator-demo

          要?jiǎng)h除該pod 我們只需要執(zhí)行delete即可

          ~# kubectl delete -f Demo.yaml 
          springbootapplication.springboot.qingmu.io "operator-demodeleted

          再次查看pod,已經(jīng)沒了

          kubectl  get po | grep operator-demo

          部署自己的應(yīng)用

          部署自己私有倉庫的應(yīng)用需要需要先創(chuàng)建secret(如果已經(jīng)創(chuàng)建跳過即可)

          創(chuàng)建docker-registry的secret

          kubectl create  \
          secret docker-registry aliyun-registry-secret \
          --docker-server=registry-vpc.cn-hangzhou.aliyuncs.com \
          --docker-username=*** \
          --docker-password=*** \
          --docker-email=***

          自己應(yīng)用的crd Yaml

          apiVersion: springboot.qingmu.io/v1alpha1
          kind: SpringBootApplication
          metadata:
            name: 你的應(yīng)用的名稱
          spec:
            springBoot:
              version: v1.0.0
              replicas: 1 
              image: 你的image地址
              imagePullSecrets: 
                - 上面創(chuàng)建的secret

          一個(gè)完整的Spring Boot Application Yaml

          下面是一個(gè)完整的yaml屬性結(jié)構(gòu),大部分屬性我們都可以用默認(rèn)配置的即可。推薦:一百期Java面試題匯總

          不設(shè)置屬性,默認(rèn)使用Operator中設(shè)置的通用值詳見后面的自定義安裝Operator。

          apiVersion: springboot.qingmu.io/v1alpha1
          kind: SpringBootApplication
          metadata:
            name: operator-demo
            namespacedefault
          spec:
            springBoot:
              # image 可以不設(shè)置,如果不設(shè)置默認(rèn)使用 IMAGE_REPOSITORY+/+mate.name+:+spec.springBoot.version
              # registry.cn-shanghai.aliyuncs.com/qingmuio + / + operator-demo + : + v1.0.0
              image: registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo:v1.0.0
              clusterIp: "" 
              version: v1.0.0 
              replicas: 1 
              resource:
                cpu:
                  request: 50m
                  limit: "" 
                memory:
                  request: 1Gi
                  limit: 1Gi 
              path:
                liveness: /actuator/health 
                readiness: /actuator/health 
                hostLog: /var/applog 
                shutdown: /spring/shutdown 
              imagePullSecrets: 
                - aliyun-docker-registry-secret
              env: 
                - name: EUREKA_SERVERS
                  value: 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"

          優(yōu)雅停機(jī)的路徑

          由于優(yōu)雅停機(jī)默認(rèn)是關(guān)閉的并且并不支持Get請求所以我們需要開啟和搭個(gè)橋

          首先在application.yml中啟用

          management:
            endpoints:
              web:
                exposure:
                  include"*"
            endpoint:
              shutdown:
                enabled: true

          然后橋接一個(gè)Get方法

          @RestController
          public class ShutdownController {
              @Autowired
              private ShutdownEndpoint shutdownEndpoint;

              @GetMapping("/spring/shutdown")
              public Map<String, String> shutdown(HttpServletRequest request) {
                  return shutdownEndpoint.shutdown();
              }
          }

          node親和的使用

          舉一個(gè)列子 我們有一個(gè)springboot應(yīng)用 user-service 希望他能分布到3個(gè)可用區(qū)的6個(gè)節(jié)點(diǎn)上:

          首先我們把機(jī)器劃分多個(gè)可用區(qū)

          cn-i區(qū)(node-i1,node-i02)
          cn-h區(qū)(node-g1,node-g02)
          cn-g區(qū)(node-h1,node-h02)
          現(xiàn)在我們有三個(gè)可以區(qū) 每個(gè)區(qū)有2臺workload,一共6臺。然后我們需要給這些機(jī)器分別打上label。
          將全部的i區(qū)機(jī)器標(biāo)注為cn-i
          kubectl label node node-i1 failure-domain.beta.kubernetes.io/zone=cn-i
          kubectl label node node-i2 failure-domain.beta.kubernetes.io/zone=cn-i

          同理將h區(qū)的標(biāo)注為h,g區(qū)同理

          kubectl label node node-h1 failure-domain.beta.kubernetes.io/zone=cn-i
          kubectl label node node-ih2 failure-domain.beta.kubernetes.io/zone=cn-i

          現(xiàn)在準(zhǔn)備工作我們就緒了,現(xiàn)在我們來設(shè)置讓它達(dá)到我們的調(diào)度效果,像如下編寫即可。

          spec:
            springBoot:
              nodeAffinity: #可以不設(shè)置 節(jié)點(diǎn)親和 這里演示的是盡量將pod分散到 i h g 三個(gè)可用區(qū),默認(rèn)設(shè)置了pod反親和
                key"failure-domain.beta.kubernetes.io/zone"
                operator"In"
                values:
                  - "cn-i"
                  - "cn-h"
                  - "cn-g"

          Operator 自定義安裝

          上面我們快速的安裝了好了,接著我們來講解下如何自定義安裝,以及有哪些自定義的參數(shù),可以個(gè)性化的參數(shù)我們用環(huán)境變量的方式注入。

          下面來修改Deployment完成自己個(gè)性化的配置部署,從我提供的部署yaml中拉倒最后,找到name是spring-boot-operator-controller-manager的Deployment,我們將修改它。

          apiVersion: apps/v1
          kind: Deployment
          metadata:
            labels:
              control-plane: controller-manager
            name: spring-boot-operator-controller-manager
            namespace: spring-boot-operator-system
          .....

                  #注意:一下配置針對通用全局的spring boot默認(rèn)配置,對crd的spring boot生效,這里不配置也可以在部署的yaml中指定

                  # 私有倉庫的地址,比如我的最終打包的鏡像地址是 registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo/operator-demo:v1.0.0
                  # 那么配置的值是 registry.cn-shanghai.aliyuncs.com/qingmuio/operator-demo
                  # 配置這個(gè)值之后,我們我們?nèi)绻诎l(fā)布的yaml中不寫image,那么使用的image就是 IMAGE_REPOSITORY+"/"+mate.name+spec.springBoot.version
                  - name: IMAGE_REPOSITORY
                    value: registry.cn-shanghai.aliyuncs.com/qingmuio
                  # 請求CPU限制
                  - name: REQUEST_CPU
                    value: 50m
                  # 限制最大能用最大CPU java應(yīng)用可以不用限制,限制不合理會導(dǎo)致啟動異常緩慢
                  - name: LIMIT_CPU
                    value: ""
                  # 請求內(nèi)存大小
                  - name: REQUEST_MEMORY
                    value: 500Mi
                  # 限制最大內(nèi)存大小 一般和request一樣大即可
                  - name: LIMIT_MEMORY
                    value: 500Mi
                  # 就緒檢查Path,spring boot actuator 默認(rèn)Path
                  - name: READINESS_PATH
                    value: /actuator/health
                  # 就緒存活Path,spring boot actuator 默認(rèn)Path
                  - name: LIVENESS_PATH
                    value: /actuator/health
                  # 就緒存活Path,優(yōu)雅停機(jī)Path
                  - name: SHUTDOWN_PATH
                    value: /spring/shutdown
                  # 復(fù)制級 即副本數(shù)
                  - name: REPLICAS
                    value: "3"
                  # 將日志外掛到主機(jī)磁盤Path,默認(rèn)兩者相同
                  - name: HOST_LOG_PATH
                    value: /var/applog
                  # 用于pull 鏡像的secrets
                  - name: IMAGE_PULL_SECRETS
                    value: ""
                  # 用于pull 鏡像的secrets
                  - name: SPRING_BOOT_DEFAULT_PORT
                    value: "8080"
                  # node親和,比如我可以設(shè)置pod盡量分散在不同可用區(qū)cn-i,cn-g,cn-h區(qū)
                  - name: NODE_AFFINITY_KEY
                    value: ""
                  - name: NODE_AFFINITY_OPERATOR
                    value: ""
                  - name: NODE_AFFINITY_VALUES
                    value: ""
                  # 全局的環(huán)境變量,會追加到每個(gè)spring boot的每個(gè)pod中,格式 k=v;k1=v2,
                  # 如 EUREKA_SERVERS=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/,http://eureka3:8761/eureka/;k=v
                  - name: SPRING_BOOT_ENV
                    value: ""
                  image: registry.cn-shanghai.aliyuncs.com/qingmuio/spring-boot-operator-controller:latest

          .....

          自定義安裝之后部署

          yaml可以簡化為如下。

          apiVersion: springboot.qingmu.io/v1alpha1
          kind: SpringBootApplication
          metadata:
            name: 你的應(yīng)用的名稱
          spec:
            springBoot:
              version: v1.0.0

          附錄

          環(huán)境變量表格

          Github倉庫

          SpringBootOperator: https://github.com/goudai/spring-boot-operator

          感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!

          小編到你上高速。


              · END ·
          最后,關(guān)注公眾號互聯(lián)網(wǎng)架構(gòu)師,在后臺回復(fù):2T,可以獲取我整理的 Java 系列面試題和答案,非常齊全


          正文結(jié)束


          推薦閱讀 ↓↓↓

          1.不認(rèn)命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵(lì)志故事

          2.如何才能成為優(yōu)秀的架構(gòu)師?

          3.從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧

          4.程序員一般可以從什么平臺接私活?

          5.37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...

          6.IntelliJ IDEA 2019.3 首個(gè)最新訪問版本發(fā)布,新特性搶先看

          7.這封“領(lǐng)導(dǎo)痛批95后下屬”的郵件,句句扎心!

          8.15張圖看懂瞎忙和高效的區(qū)別!


          瀏覽 48
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产美女被鸡巴操 | 欧美性爱天天操 | www.4438AV | 久久亚洲色免费视频 | 一本道一区二区三区四区 |