配置存活、就緒和啓動探測器
我們平時在使用k8s的時候會面臨到版本升級的問題,我個人開發使用的基本都是java語言,所以也一定會遇到一個問題代碼啓動緩慢.
更新Deployment版本的時候java的延遲啓動會導致請求失敗,爲了解決這種情況可以使用金絲雀發佈.
使用連個Deployment代表兩個版本,兩個Deployment有相同的Label,在新版本的Deployment完全啓動之後,下掉就得Deployment
但是這種方法操作上是相對複雜的,而且違背了k8s的更新規則
使用探測器確保pod處於ready狀態
爲了解決上述的情況Deployment提供了就緒探測器可以知道容器什麼時候準備好了並可以開始接受請求流量,當一個Pod中所有的容器都準備好了,才能吧這個Pod看做就緒.
關於探測器的內容這裏就不多做贅述了,可以直接通過文末的跳轉連接到官網的教程
測試
這裏我吧自己測試的流程展示出來方便大家理解
準備的服務:
- cliden-demo(延遲20秒後啓動):提供一個健康接口返回hello!!
- 對應的ingress、service、deployment
Java代碼
邏輯很簡單一個GET請求,/hello沒有參數,請求後返回 Hello, Spring! 並打印日誌
再啓動的時候
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20; i++) {
System.out.println(i + " seconds late run");
Thread.sleep(1000);
}
SpringApplication.run(DemoApplication.class, args);
}
public Mono<ServerResponse> hello(ServerRequest request) {
log.info("hello!!!");
return ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(BodyInserters.fromObject("Hello, Spring!"));
}
@Bean
public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler) {
return RouterFunctions.route(
RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
greetingHandler::hello);
}
k8s相關yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: client-demo-server
namespace: paas
spec:
replicas: 3
selector:
matchLabels:
run: client-demo-server
template:
metadata:
labels:
run: client-demo-server
spec:
containers:
- name: client-demo-server-containers
image: registry.cn-beijing.aliyuncs.com/spring-cloud-client-demo-image:0.0.2
# 終點是下面兩個配置,指定了請求的端口以及路徑,並且設置了超時時間
readinessProbe:
httpGet:
port: 8083
path: /hello
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 100
# 探活 如果請求返回異常則重啓pod
livenessProbe:
httpGet:
port: 8083
path: /hello
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 20
volumeMounts:
- name: host-time
mountPath: /etc/localtime
ports:
- containerPort: 8083
resources:
requests:
cpu: 1
memory: 1024Mi
limits:
cpu: 1
memory: 1024Mi
imagePullSecrets:
- name: paas
volumes:
- name: host-time
hostPath:
path: /etc/localtime
---
apiVersion: v1
kind: Service
metadata:
name: client-demo-server
namespace: paas
labels:
run: client-demo-server
spec:
type: NodePort
ports:
- port: 8083
selector:
run: client-demo-server
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: client-demo-server
namespace: paas
spec:
rules:
- host: client-demo-server.jbzm.internal.com
http:
paths:
- backend:
serviceName: client-demo-server
servicePort: 8083
測試結果
再次聲明爲了增大服務啓動時間在啓動之前等待了20s
kubectl get pod -n paas
NAME READY STATUS RESTARTS AGE
client-demo-server-57c468986d-2r9lh 1/1 Running 0 14m
client-demo-server-57c468986d-k8xxw 1/1 Running 0 14m
client-demo-server-57c468986d-wmcxf 1/1 Running 0 14m
client-demo-server-767868f74c-gx6df 0/1 Running 0 49s
這裏先將replicas設置爲3,然後更新deployment版本
可以看到沒服務被下掉,但是有一個新的client-demo-server-767868f74c-gx6dfpod出現並且處於Running狀態,但是沒有ready
這裏deployment滾動更新與調度的原理可以去官方文檔查看有很詳細的介紹
查看新擴出來的pod的日誌
kubectl logs -f --tail=100 -n paas client-demo-server-767868f74c-gx6df
0 seconds late run
1 seconds late run
2 seconds late run
3 seconds late run
4 seconds late run
5 seconds late run
6 seconds late run
7 seconds late run
可以看到服務正啓動中,等到倒計時結束並且完成啓動,pod會調用服務的/hello接口,並且在返回狀態碼爲200時認爲服務已經成功的啓動了
kubectl get pod -n paas
NAME READY STATUS RESTARTS AGE
client-demo-server-57c468986d-2r9lh 1/1 Running 0 15m
client-demo-server-57c468986d-k8xxw 0/1 Terminating 0 15m
client-demo-server-57c468986d-wmcxf 1/1 Running 0 15m
client-demo-server-767868f74c-gx6df 1/1 Running 0 74s
client-demo-server-767868f74c-lzwxw 0/1 ContainerCreating 0 17s
這是可以看到已經開始下掉老的pod了
結束
到這裏基本就算是演示結束了