假設我們有一個應用程序,它需要一段時間來初始化并準備好接收流量。我們可以使用就緒探針來確保容器已準備好接收流量后才將其暴露給外部服務。
(相關資料圖)
我們首先創(chuàng)建一個Deployment對象來運行應用程序。Deployment對象將自動創(chuàng)建一個副本集(ReplicaSet),并在其中運行指定數(shù)量的Pod。我們將使用nginx鏡像作為應用程序的示例。
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx-container image: nginx ports: - containerPort: 80 readinessProbe: httpGet: path: / port: 80
在上面的示例中,我們創(chuàng)建了一個名為nginx-deployment的Deployment對象,并指定了需要運行3個Pod副本。每個Pod都運行一個名為nginx-container的容器,該容器使用nginx鏡像,并在80端口上監(jiān)聽流量。我們還將就緒探針配置為使用httpGet方法,向容器的/路徑發(fā)送HTTP GET請求來檢查容器是否已準備好接收流量。
我們可以通過kubectl命令檢查Deployment的狀態(tài):
kubectl get deployment nginx-deployment
輸出應該類似于:
NAME READY UP-TO-DATE AVAILABLE AGEnginx-deployment 3/3 3 3 10s
上面的輸出顯示了Deployment中有3個Pod副本,所有的副本都已準備好,可以接收流量。
接下來,我們可以創(chuàng)建一個Service對象來暴露Deployment中的Pod給外部服務。Service對象將使用負載均衡器將流量分配給Deployment中的Pod。
apiVersion: v1kind: Servicemetadata: name: nginx-servicespec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer
在上面的示例中,我們創(chuàng)建了一個名為nginx-service的Service對象,它將負責將流量分配給Deployment中的Pod。我們將type屬性設置為LoadBalancer,這將自動為Service對象創(chuàng)建一個外部負載均衡器。
我們可以通過kubectl命令檢查Service對象的狀態(tài):
kubectl get service nginx-service
輸出應該類似于:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-service LoadBalancer 10.0.111.157 203.0.113.10 80:30549/TCP 10s
上面的輸出顯示了Service對象的一些基本信息,包括CLUSTER-IP、EXTERNAL-IP和端口信息。
現(xiàn)在,我們可以使用EXTERNAL-IP和端口信息來訪問我們的應用程序。但在我們開始訪問應用程序之前,我們需要確保它已準備好接收流量。我們可以使用kubectl describe命令來檢查Pod的狀態(tài):
kubectl describe pod
輸出應該類似于:
Name: nginx-deployment-7d6ff77df6-f7m6kNamespace: defaultPriority: 0Node: minikube/192.168.99.107Start Time: Mon, 31 May 2021 16:10:53 +0300Labels: app=nginx pod-template-hash=7d6ff77df6Annotations: Status: RunningIP: 172.17.0.4IPs: Controlled By: ReplicaSet/nginx-deployment-7d6ff77df6Containers: nginx-container: Container ID: docker://3d7df1c0d93fc7e97467a35c2e82d26134b6bfbca6f9cb6d82e57e65dcb61990 Image: nginx Image ID: docker-pullable://nginx@sha256:95202e0d007bbd2edcad2b8eae1d2e6966efadfca6b7c6f9e57d71d06ef42b6f Port: 80/TCP Host Port: 0/TCP State: Running Started: Mon, 31 May 2021 16:11:05 +0300 Ready: False Restart Count: 0 Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3 Environment: Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vh2lm (ro)Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: kube-api-access-vh2lm: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: DownwardAPI: trueQoS Class: BestEffortNode-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300sEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 47s default-scheduler Successfully assigned default/nginx-deployment-7d6ff77df6-f7m6k to minikube Normal Pulled 45s kubelet Container image "nginx" already present on machine Normal Created 45s kubelet Created container nginx-container Normal Started 45s kubelet Started container nginx-container
輸出顯示了Pod中的nginx容器的狀態(tài)。我們可以看到,容器的Readiness狀態(tài)為False,這意味著它還沒有準備好接收流量。我們還可以看到,容器的Readiness狀態(tài)為False,這意味著它還沒有準備好接收流量。我們還可以看到Readiness探針的詳細信息,它會定期調(diào)用容器的/healthz端點以檢查容器是否已準備好接收流量。
在這種情況下,我們的Readiness探針定義了一個HTTP GET請求,它將在容器的80端口上調(diào)用/healthz端點。如果該請求成功,則容器被認為是“就緒”的。
現(xiàn)在我們需要添加一個就緒探針來確保容器已準備好接收流量。在Kubernetes中,我們可以使用以下方式定義就緒探針:
HTTP GET探針:向容器發(fā)送一個HTTP GET請求,以檢查容器是否已準備好接收流量。TCP Socket探針:嘗試連接到容器的指定端口,以檢查容器是否已準備好接收流量。Exec探針:在容器中執(zhí)行指定的命令,并檢查命令的退出狀態(tài)以確定容器是否已準備好接收流量。在本例中,我們將使用HTTP GET探針。下面是一個包含就緒探針的更新后的Pod定義:
apiVersion: v1kind: Podmetadata: name: nginx labels: app: nginxspec: containers: - name: nginx image: nginx ports: - containerPort: 80 readinessProbe: httpGet: path: /healthz port: 80 initialDelaySeconds: 5 periodSeconds: 10
在這個更新的Pod定義中,我們添加了一個名為readinessProbe的字段,并在其中定義了HTTP GET探針。探針將在容器的80端口上調(diào)用/healthz端點,并在初始延遲5秒后每10秒執(zhí)行一次。
現(xiàn)在,我們使用kubectl apply命令將更新的Pod定義應用于Kubernetes集群:
kubectl apply -f pod.yaml
如果我們再次運行kubectl describe pod命令,我們應該看到容器的Readiness狀態(tài)已更改為True:
Name: nginxNamespace: defaultPriority: 0Node: minikube/192.168.99.107Start Time: Mon, 31 May 2021 16:10:53 +0300Labels: app=nginxAnnotations: Status: RunningIP: 172.17.0.4IPs: Controlled By: Containers: nginx: Container ID: docker://d96f8e1536c5feca2d79bfb13aebc5e47e5a6c5dd5d5b68a904a8110e32fbaec Image: nginx Image ID: docker-pullable://nginx@sha256:95202e0d007bbd2edcad2b8eae1d2e6966efadfca6bf772bd0eeb695c2d17c5b Port: 80/TCP Host Port: 0/TCP State: Running Started: Mon, 31 May 2021 16:11:04 +0300 Ready: True Restart Count: 0 Readiness: http-get http://:80/healthz delay=5s timeout=1s period=10s #success=1 #failure=3 Environment: Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-x4rrz (ro)Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-x4rrz: Type: Secret (a volume populated by a Secret) SecretName: default-token-x4rrz Optional: falseQoS Class: BestEffortNode-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300sEvents:
現(xiàn)在我們可以確認容器已經(jīng)準備好接收流量,Readiness探針定期調(diào)用/healthz端點以確保容器仍然是就緒的。