docker容器啓動成功,並不表明容器中的服務就能處理外部的請求。比方說java web項目啓動須要一段時間。
Kubernetes提供了readiness probe來檢測pod中的容器是否能夠接受外部流量。
能夠在java項目中提供一個接口,kubernetes發請求給此接口,當此接口返回數據時,則代表服務準備就緒,能夠接受外部請求了。java
先看一個簡單例子,準備一個spring boot工程,提供一個外部接口。如下服務用的端口號是10012node
@GetMapping("/test02/version")
public String version(){
return "app02/version/v1";
}
在node節點上,編寫Docker配置文件,並打成鏡像web
Dockerfilespring
FROM openjdk:8
ADD *.jar /app/app.jar
ADD entrypoint.sh /app/
# PORT="10012" 是項目端口號
ENV PORT="10012" TIME="Asia/Shanghai" JAVA_OPS="-Xmx256m -Xms256m -XX:+UseConcMarkSweepGC"
RUN set -e \
&& chmod +x /app/entrypoint.sh \
&& ln -snf /usr/share/zoneinfo/$TIME /etc/localtime \
&& echo $TIME > /etc/timezone
ENTRYPOINT ["/app/entrypoint.sh"]
EXPOSE $PORT
STOPSIGNAL SIGTERM
entrypoint.shdocker
#!/bin/sh
exec java ${JAVA_OPS} -jar /app/app.jar
打成鏡像codingsoldier/app02:v1api
docker build -t codingsoldier/app02:v1 .app
在master節點上編寫部署文件curl
k8s-service.yamlui
apiVersion: v1
kind: Service
metadata:
name: service-app02
spec:
selector:
app: app02
ports:
- name: http
port: 10012
targetPort: 10012
k8s-app02.yamlurl
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-app02
spec:
replicas: 2
selector:
matchLabels:
app: app02
template:
metadata:
labels:
app: app02
spec:
containers:
- name: app02
image: codingsoldier/app02:v1
ports:
- name: http
containerPort: 10012
部署服務
kubectl apply -f k8s-service
kubectl apply -f k8s-app02
獲取k8s-service的ip
kubectl get svc
從新開一個終端,循環調用接口,不要關閉這個終端,要一直開着。
while true; \
curl http://10.101.75.203:10012/test02/version; \
echo " "; \
do sleep 1; \
done;
如今就來升級版本吧
一、把/test02/version接口返回值改爲v2
@GetMapping("/test02/version")
public String version(){
return "app02/version/v2";
}
二、打成jar包,上傳到全部node節點
三、生成docker鏡像
docker build -t codingsoldier/app02:v2 .
四、修改k8s-app02.yaml鏡像爲v2
image: codingsoldier/app02:v2
五、從新開一個終端,執行 kubectl get pod -w 動態查看pod狀態
六、從新部署下k8s-app02.yaml
kubectl apply -f k8s-app02.yaml
在循環調用的監控中能夠看到,服務有短暫的時間沒法提供服務。
緣由是:docker容器啓動成功了,k8s就認爲此容器能夠提供服務了。但事實上docker容器啓動成功的時候,java服務還沒啓動完成,暫時沒法給外部提供服務。
解決辦法,使用readiness probe來檢測pod中的容器是否能夠接受外部流量。
一、java工程新增一個服務就緒接口
//服務就緒接口,提供給k8s檢測
@GetMapping("/readiness")
public String readiness(){
return "yes";
}
二、k8s-app02.yaml加上就緒探針
readinessProbe:
httpGet:
port: http
path: /readiness
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe詳細的配置:
initialDelaySeconds:容器啓動後第一次執行探測是須要等待多少秒。
periodSeconds:執行探測的頻率。默認是10秒,最小1秒。
timeoutSeconds:探測超時時間。默認1秒,最小1秒。
successThreshold:探測失敗後,最少連續探測成功多少次才被認定爲成功。默認是1。對於liveness必須是1。最小值是1。
failureThreshold:探測成功後,最少連續探測失敗多少次才被認定爲失敗。默認是3。最小值是1。
httpGet配置項:
host:鏈接的主機名,默認鏈接到pod的IP。你可能想在http header中設置」Host」而不是使用IP。
scheme:鏈接使用的schema,默認HTTP。
path: 訪問的HTTP server的path。
httpHeaders:自定義請求的header。HTTP運行重複的header。
port:訪問的容器的端口名字或者端口號。端口號必須介於1和65525之間。
三、改下 /test02/version ,的返回值 app02/version/v3
四、修改 k8s-app02.yaml中鏡像的版本image: codingsoldier/app02:v3
五、打成jar,上傳
六、打成鏡像
docker build -t codingsoldier/app02:v3 .
七、從新部署服務
kubectl apply -f k8s-app02.yaml
查看循環調用接口的終端,服務一直可用
查看運行了kubectl get pod -w 的終端
一、新pod處於Running狀態,但READY是0/1。pod已經運行,但未就緒,此時不接收外部請求
二、25秒後,新pod處於Running狀態,READY是1/1。pod能夠接收外部請求了
三、新pod可以接收外部請求後,一箇舊pod開始終止
四、因爲pod服務數設置爲2,因此此時另外一個新pod開始建立,過程跟上面的同樣,新pod能就收請求後,舊pod終止。 ---------------------