準備工作
對k8s知識有一定了解掌握佣渴,能夠明白Pod代态、Deployment精刷、Service撼班、Ingress 具體概念
準備一套可用的k8s環(huán)境
準備一個部署的spring boot 應用
構(gòu)建&上傳鏡像
k8s最小單元是Pod, 而Pod 是一組運行的容器,那么容器是怎么運行起來的呢 败许? 就是通過構(gòu)建的鏡像王带。(目前我們使用的容器技術(shù)都是基于docker)
那先讓我們來一起制作個鏡像,
將一個可運行的項目打包成一個jar文件市殷,創(chuàng)建一個文件DockerFile愕撰,DockerFile和jar放到同一個目錄 編寫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
運行鏡像是否正常 9000為宿主機訪問端口
docker run -p 9000:8080 /test/helloworld-server:v1
通過curl或者瀏覽器訪問 localhost:9000 服務是否正常醋寝,如果正常說明鏡像制作成功搞挣,開始準備把鏡像上傳到倉庫, 上傳之前確定是否登錄音羞,如果沒有登錄執(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重啟之后就會有變化舍肠,所以為了能夠固定訪問pod有了service的概念,pod綁定service窘面,我們通過service來訪問pod翠语,service可以理解為集群內(nèi)部的負載均衡流量的控制器,接下來我們開始創(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會默認創(chuàng)建一個nodePort (30000-40000)肌括,然后我們通過node ip 加 nodePort 就可以訪問service。
kubectl apply -f service.yaml
查看nodePort kubectl get svc -o -wide
通過curl node ip : nodePort 查看是否路由到pod的服務酣难,service的路由是針對內(nèi)部使用谍夭,所以對外我們還需要提供另一種訪問方式 那就是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鏡像的時候會失敗,需要手動 docker pull .
配置host nodeIP helloserver.com馋嗜,通過 curl helloserver.com:ingress contoller nodePort 訪問齐板。可以配置HA proxy 解決不用加端口問題
查看ingress contoller nodePort
kubectl get svc -o -wide -n ingress-nginx
到目前為止整個訪問流程就配置完成了葛菇,如果我們配置完之后仍然訪問不了
甘磨,可以一步一步的排除
綁定關(guān)系
- Service selector 應該匹配 Pod 的標簽
- Service targerPort應該匹配在 Pod 內(nèi)容器的containerPort
- Service 端口可以是任意數(shù)字。多個 Service 可以使用同個端口眯停,因為它們已經(jīng)分配了不同的 IP 地址
- Ingress 的servicePort應該匹配在 Service 中的port
- Service 的名稱應該匹配在 Ingress 中的serviceName的字段
故障排查
檢查pod是否正常
kubectl describe pod <pod name>
檢查service 綁定pod配置是否正確 從service 訪問pod Endpoints
kubectl describe service <service-name> | grep Endpoints
一個 endpoint 是一對<ip address:port>济舆,并且當 Service(至少)target 一個 pod 時。至少有一對
檢查Ingress 配置
kubectl describe ingress <ingress-name>
如果你能在 /Backend/ 列中看到 endpoint莺债,但依舊無法訪問應用程序滋觉,那么可能是以下問題:
- 你將 Ingress 暴露于公網(wǎng)的方式
- 你將集群暴露于公網(wǎng)的方式
總結(jié)
如果你毫無頭緒签夭,那么在 Kubernetes 中進行故障排除可能是一項艱巨的任務。
你應該永遠記住以從下至上的順序解決問題:現(xiàn)檢查 Pod椎侠,然后向上移動堆棧至 Service 和 Ingress第租。