kube-proxy 是集群中每个节点(node)上所运行的网络代理, 是实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
一次请求过程中需要kube-proxy参与吗?
做个实验:在kube-proxy正常工作的情况下使用上面的yaml文件创建Service,发现服务能正常访问。关闭kube-proxy发现服务也能正常访问。
关闭kube-proxy重新创建Service然后你会发现服务不能访问。这里可以先得出一个结论: kube-proxy只会在Service创建时创建一些规则(iptables/ipvs),
然后在Service在被访问的过程,kube-proxy并不参与。
使用下面的yaml文件创建Service1
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# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-curl
spec:
replicas: 1
selector:
matchLabels:
app: my-curl
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: my-curl
spec:
containers:
- name: my-curl
image: hysyeah/my-curl:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
apiVersion: v1
kind: Service
metadata:
name: my-curl
spec:
selector:
app: my-curl
ports:
- name: http
port: 8080
targetPort: 8080
type: NodePort
iptables的每条链下面的规则处理顺序都是从上往下逐条遍历,除非遇到DROP,REJECT,RETURN。如果链下面是自定义链,则跳转到
对应的自定义链执行链下的所有规则,然后跳转回来执行原来那条链后面的规则。
1 |
|
在Chain PREROUTING中的规则执行顺序如下:KUBE-SERVICES我们只关注我们创建的Service这条链KUBE-SVC-W7DCC3F5ZN5NE3KW
KUBE-SERVICES —> KUBE-SERVICES —> KUBE-SVC-W7DCC3F5ZN5NE3KW —> KUBE-MARK-MASQ —> KUBE-SEP-SZ5GI3C7S6AQLVNR
—> KUBE-MARK-MASQ —> DNAT —> KUBE-NODEPORTS —> KUBE-EXT-W7DCC3F5ZN5NE3KW —> KUBE-MARK-MASQ —>KUBE-SVC-W7DCC3F5ZN5NE3KW —> KUBE-MARK-MASQ —> KUBE-SEP-SZ5GI3C7S6AQLVNR
—> KUBE-MARK-MASQ —> DNAT(10.244.0.221:8080)
最终会把请求转发到pod内。
在链KUBE-SERVICES下每一个Service都会有一条自定义链,在一次请求过程中需要一个一个遍历执行,如果Service过多则有很大的性能消耗。
这些iptables规则是怎么生成的呢?
kube-proxy会监听以下资源:
Endpoints:kube-proxy会监听Service和Endpoints之间的变化。当Service的Endpoint发生变化时,kube-proxy会更新相应的iptables规则或IPVS规则,以确保流量正确地路由到新的Endpoints。
Service:kube-proxy会监听Service的创建、更新和删除。当Service发生变化时,kube-proxy会相应地更新相应的iptables规则或IPVS规则。
Node:kube-proxy会监听Node的变化,例如节点的加入或离开集群。当节点发生变化时,kube-proxy会相应地更新iptables规则或IPVS规则,以确保流量正确地路由到可用的节点。
通过监听这些资源的变化,kube-proxy能够动态地更新网络规则,以确保流量能够正确地路由到集群中的Pod
下篇文章我们将讲下kube-proxy的具体实现。