创建一个Service资源后,他会自动创建出一个同名的Endpoint资源。因为Service并不直接匹配其后端的标签,而是交由Endpoint进行匹配,而匹配过程是由Endpoint控制器完成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看系统上存在的SVC
root@k8s-master01:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp NodePort 10.111.8.128 <none> 80:31156/TCP 7d
demoapp-externalip-svc ClusterIP 10.96.141.139 172.16.11.75 80/TCP 12h
demoapp-loadbalancer-svc LoadBalancer 10.98.79.128 <pending> 80:30373/TCP 12h
demoapp-service-nodeport NodePort 10.97.56.1 <none> 80:31398/TCP 15h
demoapp-svc ClusterIP 10.97.72.1 <none> 80/TCP 16h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d14h

# 查看EP
root@k8s-master01:~# kubectl get ep
NAME ENDPOINTS AGE
demoapp 10.244.1.4:80,10.244.2.3:80,10.244.3.2:80 + 1 more... 7d
demoapp-externalip-svc 10.244.1.4:80,10.244.2.3:80,10.244.3.2:80 + 1 more... 12h
demoapp-loadbalancer-svc 10.244.1.4:80,10.244.2.3:80,10.244.3.2:80 + 1 more... 12h
demoapp-service-nodeport 10.244.1.4:80,10.244.2.3:80,10.244.3.2:80 + 1 more... 15h
demoapp-svc 10.244.1.4:80,10.244.2.3:80,10.244.3.2:80 + 1 more... 16h
kubernetes 172.16.11.71:6443 7d14h

# 对比SVC和EP可以发现他们的名字相同

Endpoint资源还与就绪探针存在关联关系,只有就绪后,才会被Endpoint捕获并添加为可用的后端端点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@k8s-master01:~# kubectl describe ep demoapp-svc
Name: demoapp-svc
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2021-07-05T09:35:54Z
Subsets:
Addresses: 10.244.1.4,10.244.2.3,10.244.3.2,172.16.11.81 # 此处为已经就绪的端点
NotReadyAddresses: <none> # 此处为未就绪的端点。
Ports:
Name Port Protocol
---- ---- --------
http 80 TCP

Events: <none>

# 所有未就绪的后端端点不会被Service接受流量。

未就绪状态演示

1.编写配置清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: v1
kind: Service
metadata:
name: service-readiness-demo
namespace: default
spec:
selector:
app: demoapp-with-readiness
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp2
spec:
replicas: 2
selector:
matchLabels:
app: demoapp-with-readiness
template:
metadata:
labels:
app: demoapp-with-readiness
spec:
containers:
- name: demoapp
image: ikubernetes/demoapp:v1.0
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
path: '/readyz'
port: 80
initialDelaySeconds: 15
periodSeconds: 10

2.应用配置清单

1
2
3
4
5
6
7
8
root@k8s-master01:~# kubectl apply -f service-readiness-demo.yaml 
service/service-readiness-demo created
deployment.apps/demoapp2 created

root@k8s-master01:~# kubectl get pods -l app=demoapp-with-readiness -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demoapp2-5b5dc85587-p6l58 1/1 Running 0 8m21s 10.244.3.27 k8s-node03 <none> <none>
demoapp2-5b5dc85587-wtht9 1/1 Running 0 8m21s 10.244.3.26 k8s-node03 <none> <none>

3.查看endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@k8s-master01:~# kubectl describe ep service-readiness-demo 
Name: service-readiness-demo
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2021-07-06T02:25:54Z
Subsets:
Addresses: 10.244.3.26,10.244.3.27
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
http 80 TCP

Events: <none>

# 两个后端端点已经就绪

4.手动的将其中一个pod改为非ready状态

1
2
3
root@k8s-master01:~# curl -XPOST -d 'readyz=FAIL' 10.244.3.26/readyz
root@k8s-master01:~# curl 10.244.3.26/readyz
FAIL

5.再次查看endpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@k8s-master01:~# kubectl describe ep service-readiness-demo 
Name: service-readiness-demo
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2021-07-06T02:37:44Z
Subsets:
Addresses: 10.244.3.27
NotReadyAddresses: 10.244.3.26
Ports:
Name Port Protocol
---- ---- --------
http 80 TCP

Events: <none>

# 此时10.244.3.26已经成为notReady状态。流量不会被Service引入

6.对Service进行请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取service地址
root@k8s-master01:~# kubectl get svc service-readiness-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service-readiness-demo ClusterIP 10.97.181.65 <none> 80/TCP 14m

# 对Service进行访问,只会被调度到10.244.3.27
root@k8s-master01:~# curl 10.97.181.65
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp2-5b5dc85587-p6l58, ServerIP: 10.244.3.27!
root@k8s-master01:~# curl 10.97.181.65
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp2-5b5dc85587-p6l58, ServerIP: 10.244.3.27!
root@k8s-master01:~# curl 10.97.181.65
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp2-5b5dc85587-p6l58, ServerIP: 10.244.3.27!
root@k8s-master01:~# curl 10.97.181.65
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp2-5b5dc85587-p6l58, ServerIP: 10.244.3.27!

7.让后端端点变为就绪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@k8s-master01:~# curl -XPOST -d 'readyz=OK' 10.244.3.26/readyz

# 再次查看ep的详细信息,所由端点都已经就绪
root@k8s-master01:~# kubectl describe ep service-readiness-demo
Name: service-readiness-demo
Namespace: default
Labels: <none>
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2021-07-06T02:49:54Z
Subsets:
Addresses: 10.244.3.26,10.244.3.27
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
http 80 TCP

Events: <none>

8.访问SVC

1
2
3
4
5
# 后端端点可以被轮询调度
root@k8s-master01:~# curl 10.97.181.65
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp2-5b5dc85587-wtht9, ServerIP: 10.244.3.26!
root@k8s-master01:~# curl 10.97.181.65
iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: demoapp2-5b5dc85587-p6l58, ServerIP: 10.244.3.27!