After a new Pod is created, Service can select it immediately and forward the request to the Pod. Then the problem comes. Usually a Pod takes time to start. If the Pod is not ready yet (it may take time to load the configuration) Or data, or you may need to perform a warm-up procedure or the like). If the request is transferred to the Pod at this time, the Pod cannot process it, causing the request to fail.
The way Kubernetes solves this problem is to add a business readiness probe to the Pod, and only allow the Service to transfer the request to the Pod when it detects that the Pod is ready.
The Readiness Probe also periodically detects the Pod and then determines whether the Pod is ready based on the response. Same as the Liveness Probe, the Readiness Probe also supports the following three types.
Exec: Probe executes the command in the container and checks the status code of the command exit. If the status code is 0, it means it is ready.
HTTP GET: Send an HTTP GET request to the IP:Port of the container. If Probe receives 2xx or 3xx, it is ready.
TCP Socket: Try to establish a TCP connection with the container. If the connection can be established, it is ready.
How Readiness Probe works
The effect of Readiness Probe can be achieved through Endpoints. When the Pod is not ready, delete the Pod's IP: Port from Endpoints, and then add the Pod to Endpoints when it is ready, as shown in the following figure.
Figure 1 The realization principle of Readiness Probe
Exec
The Exec method is consistent with the HTTP GET method. As shown below, this probe executes the ls /ready command. If the file exists, it returns 0, indicating that the Pod is ready, otherwise it returns other status codes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:alpine
name: container-0
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
readinessProbe: # Readiness Probe
exec: # 定义 ls /ready 命令
command:
- ls
- /ready
imagePullSecrets:
- name: default-secret
Save the definition of the above Deployment to the deploy-read.yaml file, delete the previously created Deployment, and use deploy-read.yaml to create this Deployment.
# kubectl delete deploy nginx
deployment.apps "nginx" deleted
# kubectl create -f deploy-read.yaml
deployment.apps/nginx created
Here, because the nginx image does not contain the file /ready, the container is not in the Ready state after the creation is completed, as shown below, note that the value of the READY column is 0/1, which means the container is not Ready.
# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-7955fd7786-686hp 0/1 Running 0 7s
nginx-7955fd7786-9tgwq 0/1 Running 0 7s
nginx-7955fd7786-bqsbj 0/1 Running 0 7s
Create Service.
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- name: service0
targetPort: 80
port: 8080
protocol: TCP
type: ClusterIP
Looking at the Service, it is found that the value of the Endpoints line is empty, indicating that there is no Endpoints.
$ kubectl describe svc nginx
Name: nginx
......
Endpoints:
......
If you create a /ready file in the container at this time and let the Readiness Probe succeed, the container will be in the Ready state. Looking at Pod and Endpoints again, I found that the container where the /ready file was created is Ready, and Endpoints have also been added.
# kubectl exec nginx-7955fd7786-686hp -- touch /ready
# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP
nginx-7955fd7786-686hp 1/1 Running 0 10m 192.168.93.169
nginx-7955fd7786-9tgwq 0/1 Running 0 10m 192.168.166.130
nginx-7955fd7786-bqsbj 0/1 Running 0 10m 192.168.252.160
# kubectl get endpoints
NAME ENDPOINTS AGE
nginx 192.168.93.169:80 14d
HTTP GET
The configuration of the Readiness Probe is the same as the livness probe. It is in the containers of the Pod Template. As shown below, this Readiness Probe sends an HTTP request to the Pod. When the Probe receives 2xx or 3xx, it means that the Pod is ready. .
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:alpine
name: container-0
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
readinessProbe: # readinessProbe
httpGet: # HTTP GET定义
path: /read
port: 80
imagePullSecrets:
- name: default-secret
TCP Socket
Similarly, the TCP Socket type probe is shown below.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:alpine
name: container-0
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
readinessProbe: # readinessProbe
tcpSocket: # TCP Socket定义
port: 80
imagePullSecrets:
- name: default-secret
Advanced configuration of Readiness Probe
Same as Liveness Probe, Readiness Probe also has the same advanced configuration options. The describe command of nginx Pod above has the following line in the echo.
Readiness: exec [ls /var/ready] delay=0s timeout=1s period=10s #success=1 #failure=3
This line represents the specific parameter configuration of Readiness Probe, and its meaning is as follows:
- delay=0s means the detection starts immediately after the container is started, there is no delay time
- timeout=1s means that the container must give corresponding feedback to probe within 1s, otherwise it will be regarded as a detection failure
- period=10s means to detect once every 10s
- #success=1 means that the detection is successful for 1 consecutive time, indicating success
- #failure=3 means that the container will be restarted after the probe fails three times in a row.
These are the default settings when they are created, and you can also configure them manually, as shown below.
readinessProbe: # Readiness Probe
exec: # 定义 ls /readiness/ready 命令
command:
- ls
- /readiness/ready
initialDelaySeconds: 10 # 容器启动后多久开始探测
timeoutSeconds: 2 # 表示容器必须在2s内做出相应反馈给probe,否则视为探测失败
periodSeconds: 30 # 探测周期,每30s探测一次
successThreshold: 1 # 连续探测1次成功表示成功
failureThreshold: 3 # 连续探测3次失败表示失败