參考:https://qingmu.io/2020/04/08/Spring-Boot-Operator-User-Guide/
在Kubernetes中部署spring boot應用整體上來說是一件比較繁瑣的事情,而Spring Boot Operator則能帶給你更清爽簡單的體驗。
Spring Boot Operator基於Kubernetes的custom resource definitions (CRDs)擴展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插件進行鏡像打包
script
1 |
mvn com.google.cloud.tools:jib-maven-plugin:build \ |
執行上面的命令之后我們將得到一個標准的docker鏡像,該鏡像會被推送到遠程倉庫。
Operator快速體驗
完成了鏡像的構建之后,我們緊接着來安裝我們的Operator到kubernetes集群,當然了首先你需要一套集群,可以參考我之前一篇文章部署高可用kubernetes,雖然版本比較老,但是新版本其實也差不多的一個思路。
快速安裝
此處快速安裝只是為了快速體驗demo
script
1 |
kubectl apply -f https://raw.githubusercontent.com/goudai/spring-boot-operator/master/manifests/deployment.yaml |
apply成功之后控制台輸出
1 |
namespace/spring-boot-operator-system created |
稍等片刻查看是否已經安裝成功
script
1 |
kubectl get po -n spring-boot-operator-system |
成功如下輸出
1 |
NAME READY STATUS RESTARTS AGE |
部署OperatorDemo應用
完成了Operator的部署之后,我們來部署我們第一個應用,這里我們就發布上面我們編寫的springboot應用opreator-demo。
首先我們需要先編寫一個Spring Boot Application 的CRD部署yaml,如下
1 |
# Demo.yaml |
細心的同學可能發現了,為啥連Image
都沒有?這怎么發布,就name,version,就能完成發布?是的沒錯!就能完成發布,后面我講詳細講到他是如何完成的。
接着我們apply一下
script
1 |
kubectl apply -f Demo.yaml |
看到console輸出
1 |
springbootapplication.springboot.qingmu.io/operator-demo created |
驗證
表示創建成功了,接着我們來看下我們部署的第一個應用,這里我們直接用上面的yaml中的name過濾即可。
查看pod
script
1 |
~# kubectl get po | grep operator-demo |
查看下我們的pid不等於1的設置是否生效,根據下面的結果可以看到通過設置ShareProcessNamespace該參數我們可以在Kubernetes層面來解決這個pid=1的問題。
script
1 |
kubectl exec -it operator-demo-7574f4789c-mg58m bash |
查看svc
script
1 |
~# kubectl get svc | grep operator-demo |
我們來訪問一下試試。
script
1 |
root@server1:~# curl -i http://10.101.128.6:8080 |
我們來試着縮減他的副本數到1個
編輯我們的Demo.yaml,加入一個新的屬性replicas
1 |
# Demo.yaml |
應用一下
script
1 |
root@server1:~# kubectl apply -f Demo.yaml |
再次查看pod,你會發現我們的pod已經縮放為一個副本了
script
1 |
~# kubectl get po | grep operator-demo |
清理operator-demo
要刪除該pod 我們只需要執行delete即可
script
1 |
~# kubectl delete -f Demo.yaml |
再次查看pod,已經沒了
script
1 |
kubectl get po | grep operator-demo |
部署自己的應用
部署自己私有倉庫的應用需要需要先創建secret(如果已經創建跳過即可)
創建docker-registry的secret
script
1 |
kubectl create \ |
自己應用的crd Yaml
1 |
|
一個完整的Spring Boot Application Yaml
下面是一個完整的yaml屬性結構,大部分屬性我們都可以用默認配置的即可。
不設置屬性,默認使用Operator中設置的通用值詳見后面的自定義安裝Operator。
1 |
|
優雅停機的路徑
由於優雅停機默認是關閉的並且並不支持Get請求所以我們需要開啟和搭個橋
首先在application.yml
中啟用
1 |
management: |
然后橋接一個Get方法
1 |
|
node親和的使用
舉一個列子 我們有一個springboot應用 user-service 希望他能分布到3個可用區的6個節點上:
首先我們把機器划分多個可用區
1 |
cn-i區(node-i1,node-i02) |
現在我們有三個可以區 每個區有2台workload,一共6台。然后我們需要給這些機器分別打上label。
將全部的i區機器標注為cn-i
script
1 |
kubectl label node node-i1 failure-domain.beta.kubernetes.io/zone=cn-i |
同理將h區的標注為h,g區同理
script
1 |
kubectl label node node-h1 failure-domain.beta.kubernetes.io/zone=cn-i |
現在准備工作我們就緒了,現在我們來設置讓它達到我們的調度效果,像如下編寫即可。
1 |
spec: |
Operator 自定義安裝
上面我們快速的安裝了好了,接着我們來講解下如何自定義安裝,以及有哪些自定義的參數,可以個性化的參數我們用環境變量的方式注入。
下面來修改Deployment
完成自己個性化的配置部署,從我提供的部署yaml中拉倒最后,找到name是spring-boot-operator-controller-manager
的Deployment,我們將修改它。
1 |
|
自定義安裝之后部署
yaml可以簡化為如下。
1 |
|
附錄
環境變量表格
環境變量名 | 是否可以空 | 默認值 | 說明 |
---|---|---|---|
IMAGE_REPOSITORY | true | “” | 私有倉庫的地址 |
REQUEST_CPU | true | 50m | 請求CPU限制 |
LIMIT_CPU | true | “” | 限制最大能用最大CPU java應用可以不用限制,限制不合理會導致啟動異常緩慢 |
REQUEST_MEMORY | true | 2Gi | 請求內存大小 |
LIMIT_MEMORY | true | 2Gi | 限制最大內存大小 一般和request一樣大即可 |
READINESS_PATH | true | /actuator/health | 就緒檢查Path,spring boot actuator 默認Path |
LIVENESS_PATH | true | /actuator/health | 存活檢查Path,spring boot actuator 默認Path |
SHUTDOWN_PATH | true | /spring/shutdown | 就緒存活Path,優雅停機Path |
REPLICAS | true | 3 | 副本數 |
HOST_LOG_PATH | true | /var/applog | 將日志外掛到主機磁盤Path,默認兩者相同 |
IMAGE_PULL_SECRETS | true | 無 | 用於pull 鏡像的secrets |
SPRING_BOOT_DEFAULT_PORT | true | 8080 | 用於pull 鏡像的secrets |
NODE_AFFINITY_KEY | true | “” | node親和key,比如我可以設置pod盡量分散在不同可用區cn-i,cn-g,cn-h區 |
NODE_AFFINITY_OPERATOR | true | “” | node親和操作符 |
NODE_AFFINITY_VALUES | true | “” | node親和value |
SPRING_BOOT_ENV | true | “” | 全局的環境變量,會追加到每個spring boot的每個pod中,格式 k=v;k1=v2 |