K8s 部署 Spring boot 實(shí)踐應(yīng)用指南

準(zhǔn)備工作

對(duì)k8s知識(shí)有一定了解掌握,能夠明白Pod、Deployment、Service、Ingress 具體概念
準(zhǔn)備一套可用的k8s環(huán)境
準(zhǔn)備一個(gè)部署的spring boot 應(yīng)用

構(gòu)建&上傳鏡像

k8s最小單元是Pod, 而Pod 是一組運(yùn)行的容器,那么容器是怎么運(yùn)行起來的呢 ? 就是通過構(gòu)建的鏡像。(目前我們使用的容器技術(shù)都是基于docker)

那先讓我們來一起制作個(gè)鏡像,

將一個(gè)可運(yùn)行的項(xiàng)目打包成一個(gè)jar文件,創(chuàng)建一個(gè)文件DockerFile,DockerFile和jar放到同一個(gè)目錄 編寫DockerFile

FROM java:8 #定義使用環(huán)境信息

WORKDIR /app/spring-boot-hello/ # 創(chuàng)建工作目錄

ADD  spring-boot-hello-1.0.jar /app/spring-boot-hello/ #把jar文件放到工作目錄

EXPOSE  8080 #申明端口,并不是訪問端口

ENTRYPOINT  ["java","-jar","spring-boot-hello-1.0.jar"] #執(zhí)行命令

執(zhí)行生成鏡像命令
docker build -f ./DockerFile -t "/test/helloworld-server:v1" .

查看鏡像 docker images

運(yùn)行鏡像是否正常 9000為宿主機(jī)訪問端口
docker run -p 9000:8080 /test/helloworld-server:v1

通過curl或者瀏覽器訪問 localhost:9000 服務(wù)是否正常,如果正常說明鏡像制作成功,開始準(zhǔn)備把鏡像上傳到倉庫, 上傳之前確定是否登錄,如果沒有登錄執(zhí)行 :docker login 倉庫地址

如果倉庫使用的是harbor tag的名字格式改為:
倉庫地址/倉庫/名稱,
比如 harbor.com/test/helloword-service

修改鏡像 tag
docker tag <imageid> reg.com/test/helloworld-server:v1

上傳鏡像
docker push reg.com/test/helloworld-server:v1
上傳完鏡像可以登錄倉庫查看是否上傳成功。

部署到k8s

創(chuàng)建deployment

創(chuàng)建deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: helloworld-server
  labels:
    app: helloworld-server
spec:
  # 副本數(shù)
  replicas: 2
  selector:
    matchLabels:
      app: helloworld-server
  template:
    metadata:
      labels:
        app: helloworld-server
    spec:
      containers:
      - name: helloworld-server
        image: reg.com/test/helloworld-server:v1
        workingDir: /app/spring-boot-hello
        ports:
        - containerPort: 8080

執(zhí)行 kubectl apply -f deployment.yaml

查看pod 是否創(chuàng)建成功 處于ready 狀態(tài)
kubectl get pod -o wide

如果沒有創(chuàng)建成功,通過log 或者 describe 查看具體原因
kubectl describe pod pod-namexxxxx

pod 的IP重啟之后就會(huì)有變化,所以為了能夠固定訪問pod有了service的概念,pod綁定service,我們通過service來訪問pod,service可以理解為集群內(nèi)部的負(fù)載均衡流量的控制器,接下來我們開始創(chuàng)建service

創(chuàng)建service

創(chuàng)建service.ymal

apiVersion: v1
kind: Service
metadata:
  name: helloworld-server
  labels:
    app: helloworld-server
spec:
  type: NodePort
  selector:
    app: helloworld-server  # pod  app: helloworld-server 
  ports:
    - port: 80 
      targetPort: 8080  # containerPort

我們使用的service type是NodePort,yaml里沒有申明nodePort 所以k8s會(huì)默認(rèn)創(chuàng)建一個(gè)nodePort (30000-40000),然后我們通過node ip 加 nodePort 就可以訪問service。

kubectl apply -f service.yaml

查看nodePort kubectl get svc -o -wide

通過curl node ip : nodePort 查看是否路由到pod的服務(wù),service的路由是針對(duì)內(nèi)部使用,所以對(duì)外我們還需要提供另一種訪問方式 那就是Ingress,(還有其它訪問方式,本章使用Ingress)接下倆就是創(chuàng)建Ingress

創(chuàng)建Ingress

ingress.ymal

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: helloworld-server
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: helloserver.com
    http:
      paths:
      - path: /?(.*)
        backend:
          serviceName: helloworld-server # service name
          servicePort: 80  # service port

kubectl apply -f ingress.ymal

安裝ingress contoller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml

查看ingress contoller pod 是否創(chuàng)建成功,一般情況pull鏡像的時(shí)候會(huì)失敗,需要手動(dòng) docker pull .

配置host nodeIP helloserver.com,通過 curl helloserver.com:ingress contoller nodePort 訪問??梢耘渲肏A proxy 解決不用加端口問題

查看ingress contoller nodePort
kubectl get svc -o -wide -n ingress-nginx

到目前為止整個(gè)訪問流程就配置完成了,如果我們配置完之后仍然訪問不了
,可以一步一步的排除

綁定關(guān)系

  1. Service selector 應(yīng)該匹配 Pod 的標(biāo)簽
  2. Service targerPort應(yīng)該匹配在 Pod 內(nèi)容器的containerPort
  3. Service 端口可以是任意數(shù)字。多個(gè) Service 可以使用同個(gè)端口,因?yàn)樗鼈円呀?jīng)分配了不同的 IP 地址
  4. Ingress 的servicePort應(yīng)該匹配在 Service 中的port
  5. Service 的名稱應(yīng)該匹配在 Ingress 中的serviceName的字段

故障排查

檢查pod是否正常
kubectl describe pod <pod name>

檢查service 綁定pod配置是否正確 從service 訪問pod Endpoints
kubectl describe service <service-name> | grep Endpoints
一個(gè) endpoint 是一對(duì)<ip address:port>,并且當(dāng) Service(至少)target 一個(gè) pod 時(shí)。至少有一對(duì)

檢查Ingress 配置
kubectl describe ingress <ingress-name>

如果你能在 /Backend/ 列中看到 endpoint,但依舊無法訪問應(yīng)用程序,那么可能是以下問題:

  • 你將 Ingress 暴露于公網(wǎng)的方式
  • 你將集群暴露于公網(wǎng)的方式

總結(jié)

如果你毫無頭緒,那么在 Kubernetes 中進(jìn)行故障排除可能是一項(xiàng)艱巨的任務(wù)。
你應(yīng)該永遠(yuǎn)記住以從下至上的順序解決問題:現(xiàn)檢查 Pod,然后向上移動(dòng)堆棧至 Service 和 Ingress。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容