適合ingress-nginx接入外部負載均衡的部署 一文主要介紹瞭如何透過ingress-nginx對外暴露服務,以及與外部負載均衡的結合,下面我們透過將SpringBoot專案遷入K8S中,來完整了解下從一個Java專案的整體流程。
環境準備
1.名稱空間
K8S透過namespace劃分叢集資源。因此我們透過prod、test、develop來劃分生產環境、測試環境、開發環境。
在此我們主要以test進行演示。
2. 映象倉庫
我們透過harbor倉庫來儲存springboot專案的映象,可參考Docker部署spring boot體驗來了解helloworld專案從打包到上傳harbor倉庫的過程。
部署
1.建立名稱空間
kubectl create ns test
2.新增harbor認證
透過secret 可以實現類似docker login登入harbor倉庫認證過程。
#在對應的namespace下建立secretkubectl create secret docker-registry harbor ——namespace test ——docker-server=harbor。test。cn ——docker-username=admin ——docker-password=admin ——docker-email=test@test。cn
注意:
一定要在對應的namespace下建立secret,否則會導致從harbor倉庫pull映象認證不透過。
3.定義Deployment
通常Deployment、service、ingress 寫在一份yaml檔案中,為方便演示我們都進行單獨分解。
# 1。vim deployment。yamlapiVersion: apps/v1kind: Deploymentmetadata: name: helloworld namespace: testspec: replicas: 1 selector: matchLabels: app: helloworld template: metadata: name: helloworld labels: app: helloworld spec: hostAliases: - ip: “10。11。10。11” hostnames: - “api1。test。cn” - “api2。test。cn” - ip: “10。11。10。12” hostnames: - “api3。test。cn” containers: - name: helloworld env: - name: JAVA_OPTS value: “-Xmx128m -Xms128m -Dspring。profiles。active=test” image: harbor。test。cn/helloworld/helloworld:1311c4520122dfa67bb60e0103c9519fcb370e50 imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 200 timeoutSeconds: 5 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 180 timeoutSeconds: 5 ports: - containerPort: 8080 resources: limits: cpu: “0。5” memory: “500Mi” requests: cpu: “0。5” memory: “500Mi” volumeMounts: - name: logdir mountPath: /logs - name: localtime mountPath: /etc/localtime - name: timezone mountPath: /etc/timezone imagePullSecrets: - name: harbor volumes: - name: logdir emptyDir: {} - name: localtime hostPath: path: /etc/localtime - name: timezone hostPath: path: /etc/timezone# 2。應用配置檔案kubectl apply -f deployment。yaml# 3。檢視# kubectl get pod -n testNAME READY STATUS RESTARTS AGEhelloworld-6f78bd8668-j6hmp 1/1 Running 0 3d18h
要點:
hostAliases:
用於指定適用於該專案的hosts解析,可根據實際情況進行新增。
env:
jvm啟動引數透過環境變數env傳遞,而args只適用於dockder build階段,因此不能使用。
resources:
容器預設會無限制佔用宿主機資源,因此需要進行限制。對於java 專案 xms xmx只是堆記憶體,實際程序所佔記憶體比這還大,例如某專案預設Xms Xmx都是128M,但是pod的資源限制為200M、300M都會導致OOM,
因此調整的資源需要比Xmx還要大
。
hostPath:
將宿主機節點檔案系統中的檔案或目錄掛載到叢集中,
由於基於宿主機的目錄,多副本跨節點必須保證目錄存在,否則可能導致失敗
。
emptyDir:
當pod被分配給節點時,首先建立emptyDir卷,並且只要該pod在該節點上執行,該卷就會存在。正如卷的名字所述,它最初是空的。pod中的容器可以讀取和寫入emptyDir卷中的相同檔案。儘管該卷可以掛在到每個容器中的相同或不同路徑上。當出於任何原因從節點中刪除pod時,emptyDir中的資料將被永久刪除。
容器時區:
掛在宿主機的localtime和timezone,保證專案日誌時間正常。
livenessProbe:
透過探針livenessProbe進行檢測,httpGet獲取的狀態碼等於200或小於400則正常。檢測失敗後,將根據使用restartPolicy策略。restartPolicy預設為always。
readinessProbe:
透過探針readinessProbe進行檢測,httpGet獲取的狀態碼等於200或小於400則正常。指示容器是否準備好服務請求。如果就緒探針失敗,則端點控制器將從與Pod匹配的所有服務的端點中刪除Pod的IP地址。預設每10秒檢測一次,連續失敗數為3,連續成功數為1。
initialDelaySeconds:
如果啟動時間超過initialDelaySeconds會導致livenessProbe、readinessProbe檢測不成功。readinessProbe 失敗導致無法接受請求,livenessProbe失敗導致容器不斷重啟。
因此initialDelaySeconds要大於實際啟動時間
。
注意:
對於SpringBoot專案的日誌檔案,我們並沒有進行持久化儲存,而是透過emptyDir臨時儲存,然後透過寫入ELK做長期儲存。
對於SpringBoot專案的資料檔案,無論透過hostPath還是emptyDir都不合適,需透過PVC進行持久化儲存。
4.定義service
# 1。vim service。yamlapiVersion: v1kind: Servicemetadata: name: helloworld namespace: testspec: type: NodePort selector: app: helloworld ports: - port: 8080 targetPort: 8080# 2。應用配置檔案kubectl apply -f service。yaml# 3。檢視狀態# kubectl get svc -n testNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhelloworld NodePort 10。1。139。205
對於NodePort型別的service,透過叢集所有節點的IP都可以訪問服務。
# curl 192。168。3。218:30949 Hello,world!# curl 192。168。3。219:30949 Hello,world!# curl 192。168。3。217:30949 Hello,world!# 原因:# 所有節點lvs資訊都有對service 30949埠的轉發,因此叢集內所有節點都可透過service訪問服務ipvsadm -l -n |grep -A 2 -B 2 30949TCP 192。168。3。217:30949 rr -> 10。244。2。100:8080
5.定義ingress-ingress
此部分細節可參考適合ingress-nginx接入外部負載均衡的部署 選擇適合自己的部署方式,本文我們使用預設的Deployment+NodePort進行部署。
# 1。vim ingress。yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: helloworld namespace: testspec: rules: - host: hello。test。cn http: paths: - path: / backend: serviceName: helloworld servicePort: 8080# 2。應用kubectl apply -f ingress。yaml# 3。檢視# kubectl get ing -n testNAME CLASS HOSTS ADDRESS PORTS AGEhelloworld
注意:
預設ingress-nginx部署並不能讓我們從外部透過80埠訪問到服務,只能透過NodePort暴露的埠訪問。
總結
以上是整個SpringBoot專案的部署過程及需要注意的地方,個人認為K8S部署SpringBoot專案最主要的應該是資源限制、健康檢查及儲存這三點。
資源限制保證叢集內容器合理佔用宿主機資源,避免資源無限佔用導致叢集問題;
健康檢查保證叢集內容器正常執行,合理摘除不健康的節點,保證請求的轉發到健康節點;
選擇合適的儲存方式,保證專案的執行時資料、日誌檔案合理儲存;