環境準備
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 [email protected]
注意:一定要在對應的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 <none> 8080:30949/TCP 6d# 4.訪問# curl 10.1.138.205:8080Hello,world
對於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
# 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 <none> hello.test.cn 10.1.217.16 80 4d18h# kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx NodePort 10.1.217.16 <none> 80:30687/TCP,443:31826/TCP 15h# kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx NodePort 10.1.217.16 <none> 80:30687/TCP,443:31826/TCP 15h# 4.訪問# curl -x 192.168.3.218:30687 hello.test.cnHello,world!
注意: 預設ingress-nginx部署並不能讓我們從外部通過80埠訪問到服務,只能通過NodePort暴露的埠訪問。
總結以上是整個SpringBoot專案的部署過程及需要注意的地方,個人認為K8S部署SpringBoot專案最主要的應該是資源限制、健康檢查及儲存這三點。
資源限制保證叢集內容器合理佔用宿主機資源,避免資源無限佔用導致叢集問題;健康檢查保證叢集內容器正常執行,合理摘除不健康的節點,保證請求的轉發到健康節點;選擇合適的儲存方式,保證專案的執行時資料、日誌檔案合理儲存;
最新評論