k8s service详解之东西向网络service详解
东西向网络service详解1. service介绍service主要解决两个问题,一个是pod的ip不固定,一个是pod的负载均衡需求,某种意义上类似微服务的注册中心,用于pod之间的注册与发现。2. hostnames样例实践因consul使用的是head less,没有负载均衡相关能力,故此处的示例通过官方的hostname样例进行说明。#定义serviceapiVersion: v1kin
东西向网络service详解
1. service介绍
service主要解决两个问题,一个是pod的ip不固定,一个是pod的负载均衡需求,某种意义上类似微服务的注册中心,用于pod之间的注册与发现。
2. hostnames样例实践
因consul使用的是head less,没有负载均衡相关能力,故此处的示例通过官方的hostname样例进行说明。
#定义service
apiVersion: v1
kind: Service
metadata:
name: hostnames
spec:
selector:
app: hostnames
ports:
- name: default
port: 80
targetPort: 9376
protocol: TCP
#定义deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostnames
labels:
app: reviews
version: v3
spec:
replicas: 3
selector:
matchLabels:
app: hostnames
template:
metadata:
labels:
app: hostnames
spec:
containers:
- name: hostnames
image: k8s.gcr.io/serve_hostname:latest
ports:
- containerPort: 9376
protocol: TCP
执行kubectl apply -f *.yaml后,hostnames就拉起来了。
可以看到cluster-ip为10.107.205.181,hostnames的endpoints为10.244.2.97:9376,10.244.3.49:9376,10.244.3.50:9376,宿主机上访问vip地址,可以看到能访问到其代理的pod。
[root@k8s-master snap]# kubectl get svc hostnames
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hostnames ClusterIP 10.107.205.181 <none> 80/TCP 8m6s
[root@k8s-master snap]# kubectl get endpoints hostnames
NAME ENDPOINTS AGE
hostnames 10.244.2.97:9376,10.244.3.49:9376,10.244.3.50:9376 21m
[root@k8s-master snap]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostnames-659d5d6f56-bkr69 1/1 Running 0 3m22s 10.244.2.97 k8s-node2 <none> <none>
hostnames-659d5d6f56-j5ptd 1/1 Running 0 3m23s 10.244.3.50 k8s-node3 <none> <none>
hostnames-659d5d6f56-sblg9 1/1 Running 0 3m25s 10.244.3.49 k8s-node3 <none> <none>
[root@k8s-node1 ~]# curl 10.107.205.181:80
hostnames-659d5d6f56-j5ptd
[root@k8s-node1 ~]# curl 10.107.205.181:80
hostnames-659d5d6f56-sblg9
[root@k8s-node1 ~]# curl 10.107.205.181:80
hostnames-659d5d6f56-j5ptd
[root@k8s-node1 ~]# curl 10.107.205.181:80
hostnames-659d5d6f56-bkr69
3. service实现解析
-
service通过kube-proxy组件加linux的iptables实现,hostnames创建时,kube-proxy通过service的Informer机制感知到service对象的添加,然后再宿主机上创建一条iptables规则。
-
10.107.205.181端口为80的ip包会跳到KUBE-SVC-ODX2UBAZM7RQWOIU的iptables链进行处理。可以看到3条链的概率为0.33,0.5,1,因iptables规则匹配是从上往下逐条执行,所以每条链的概率都为1/3。
-
跟踪KUBE-SEP-ESCSO4DZ6QJFDVPZ链,可以看到其实是条DNAT规则,指向10.244.2.97:9376。
[root@k8s-node1 ~]# iptables-save | grep hostnames | grep cluster
-A KUBE-SERVICES -d 10.107.205.181/32 -p tcp -m comment --comment "default/hostnames:default cluster IP" -m tcp --dport 80 -j KUBE-SVC-ODX2UBAZM7RQWOIU
[root@k8s-node1 ~]# iptables-save | grep KUBE-SVC-ODX2UBAZM7RQWOIU
-A KUBE-SVC-ODX2UBAZM7RQWOIU -m comment --comment "default/hostnames:default" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-ESCSO4DZ6QJFDVPZ
-A KUBE-SVC-ODX2UBAZM7RQWOIU -m comment --comment "default/hostnames:default" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-P5WZKF5SFCHMY4QQ
-A KUBE-SVC-ODX2UBAZM7RQWOIU -m comment --comment "default/hostnames:default" -j KUBE-SEP-7ZEX5NM4FNAFXYKX
[root@k8s-node1 ~]# iptables-save | grep KUBE-SEP-ESCSO4DZ6QJFDVPZ
:KUBE-SEP-ESCSO4DZ6QJFDVPZ - [0:0]
-A KUBE-SEP-ESCSO4DZ6QJFDVPZ -s 10.244.2.97/32 -m comment --comment "default/hostnames:default" -j KUBE-MARK-MASQ
-A KUBE-SEP-ESCSO4DZ6QJFDVPZ -p tcp -m comment --comment "default/hostnames:default" -m tcp -j DNAT --to-destination 10.244.2.97:9376
4. 基于iptables实现的弊端
可以看到iptables处理service,需要在宿主机上设置iptables规则,当宿主机存在大量pod时,iptables规则不断被刷新,会大量占用cpu资源。所以该实现不能支撑大量pod的k8s集群。
要解决该问题,一般会通过IPVS模式,IPVS与iptables的实现类似,也是基于netfilter的NAT模式,在转发的性能上看并没有提升,不过IPVS把iptables的规则处理放到了内核态,从而减少了维护这些规则的代价。
5. service的访问方式
除了前面通过VIP的方式,k8s也提供了dns访问pod的能力,在1.18是运行在集群的coredns pod提供dns的能力.
- 对于clusterIP模式的service,,它的dns格式为 m y − s v c . my-svc. my−svc.my-namespace.svc.cluster.local,比如前面提到的hostnames,对应的访问方式为hostnames.default.svc.cluster.local.
- 对于clusterIP=None的headless来说,它的dns格式同样为 m y − s v c . my-svc. my−svc.my-namespace.svc.cluster.local,比如前面章节提到的consul,但其返回的是所有consul pod的IP地址集合,如果客户端未做适配解析该集合,则只会返回第一个pod地址。
- 对于headless来说,它可以直接访问到指定的pod,格式为 m y − p o d . my-pod. my−pod.my-svc.$my-namespace.svc.cluster.local。
更多推荐
所有评论(0)