- 一、四层负载均衡Service概述
- 1.1、为什么要有Service?
- 1.2、Service是什么?
- 1.3、Service实现原理
- 1.4、kube-proxy负载均衡方式
- 二、kubernets中三类IP地址
- 2.1、Node Network(节点网络)
- 2.2、Pod network(pod 网络)
- 2.3、Cluster Network
- 三、Service四种类型
- 3.1、ExternalName
- 3.2、ClusterIP
- 3.3、NodePort
- 3.4、LoadBalancer
- 总结:整理不易,如果对你有帮助,可否点赞关注一下?
一、四层负载均衡Service概述 1.1、为什么要有Service?
在kubernetes中,pod是有生命周期的,如果pod重启ip地址有可能会发生变化,如果服务中定义的是pod的ip地址的话,那么该pod的ip地址发生变化后该服务会找不到之前定义的ip地址从而发生报错。 为了解决这个问题,在kubernetes中定义了service资源对象。Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service是一组Pod的逻辑集合,这一组Pod能够被Service访问到,通常是通过Label Selector(标签选择器)实现的。
总结:
1、pod ip经常发生变化,service是pod的代理,客户端访问,只需要访问service,service就会把请求代理到后端Pod。
2、pod ip在k8s集群之外是无法访问,所以需要创建service,这个service可以在k8s集群外访问的。
1.2、Service是什么?
在Kubernetes平台上,Pod是有生命周期,为了可以给客户端一个固定的访问端点,因此需要在客户端和Pod之间添加一个中间层,这个中间层称之为Service。
在Kubernetes中,每个节点都安装了kube-proxy,kube-proxy通过kubernetes中固有的watch请求方法持续监听apiserver。一旦有service资源发生变动(增删改查)kube-proxy可以及时转化为能够调度到后端Pod节点上的规则,这个规则可以是iptables也可以是ipvs,取决于service实现方式。
1.3、Service实现原理
k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象,当Pod地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到那个Pod进行访问的地址。至于转发到哪个节点的Pod,由kube-proxy负载均衡来决定。如下图所示:
总结:
1、endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。
2、只有当service配置selector(选择器),endpoint controller才会自动创建对应的endpoint对象,否则,不会生成endpoint对象。
3、在k8s集群中创建kubernetes的service,就会生成一个同名的endpoint对象,endpoint就是service关联的Pod的ip地址和端口。
4、访问Service的请求,不论是Cluster IP+TargetPort的方式;还是用Node节点IP+NodePort的方式,都被Node节点的Iptables规则重定向到Kube-proxy监听Service服务代理端口。kube-proxy接收到Service的访问请求后,根据负载策略,转发到后端的Pod。
1.4、kube-proxy负载均衡方式
kube-proxy负载均衡方式
二、kubernets中三类IP地址 2.1、Node Network(节点网络)
Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址。
ens33: flags=4163mtu 1500 inet 192.168.1.16 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::556d:553b:fe97:ab7b prefixlen 64 scopeid 0x20 ether 00:0c:29:43:a9:f0 txqueuelen 1000 (Ethernet) RX packets 14026340 bytes 3605525779 (3.3 GiB) RX errors 0 dropped 246096 overruns 0 frame 0 TX packets 4652141 bytes 663629292 (632.8 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.2、Pod network(pod 网络)
Pod network(pod 网络):创建的Pod具有的IP地址。
[root@k8s-client-17 state]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sts-nginx-0 1/1 Running 0 2d4h 10.244.27.43 k8s-worker-21sts-nginx-1 1/1 Running 0 2d4h 10.244.115.60 k8s-worker-16 sts-nginx-2 1/1 Running 0 2d4h 10.244.27.44 k8s-worker-21
2.3、Cluster Network
Cluster Network(集群地址,也称为service network):这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。
#查看mpmt-calculate-svc服务cluster ip地址 [root@k8s-master-111 jms]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP 323d mpmt-calculate-svc NodePort 10.96.155.70 8092:31092/TCP 9d #通过ifconfig过滤10.96.155.70这个ip发现不存在 [root@k8s-worker-112 jms]# ifconfig | grep 10.96.155.70 #通过查看ipvs规则信息找到了10.96.155.70这个ip地址 [root@k8s-worker-112 jms]# ipvsadm -Ln --stats |grep -A 10 10.96.155.70 TCP 10.96.155.70:8092 0 0 0 0 0 -> 10.48.1.194:8092 0 0 0 0 0 -> 10.48.2.206:8092 0 0 0 0 0
总结:Node Network配置在节点接口之上,pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的。但是Cluster Network是虚拟的地址,没有配置在某个接口上,只是出现在service的规则当中。
三、Service四种类型
K8S官网:Service四种类型,如下图所示:
3.2、ClusterIP
ClusterIP:暴露集群内部IP上的服务。选择此值将使服务只能从集群内部访问。这是默认的ServiceType。
示例如下:
---
apiVersion: v1
kind: Service
metadata:
name: test-nginx
labels:
app: test-nginx
namespace: default
spec:
selector:
app: test-nginx
type: ClusterIP
ports:
- port: 8088
protocol: TCP
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: test-nginx
replicas: 3
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80 #pod中的容器需要暴露的端口
---
在集群内部(master节点和worker节点)可以通过service的cluster ip:port访问。
在集群外部(非master节点和非worker节点)不可以通过service的cluster ip:port访问。
3.3、NodePort
通过每个Node节点上的IP和静态端口暴露k8s集群内部的服务,请求访问:Client ==> NodeIP:NodePort ==> Service Ip:ServicePort ==> PodIP:ContainerPort
如果不记得k8s对外暴露端口范围,可参考如下命令:
示例如下::
---
apiVersion: v1
kind: Service
metadata:
name: test-nginx
labels:
app: test-nginx
namespace: default
spec:
selector:
app: test-nginx
type: NodePort
ports:
- port: 8088
protocol: TCP
targetPort: 80
nodePort: 33000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: test-nginx
replicas: 3
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80 #pod中的容器需要暴露的端口
---
在集群内部(master节点和worker节点)可以通过service的cluster ip:port访问。
在集群外部(非master节点和非worker节点)可以通过每个Node节点上的IP和静态端口暴露k8s集群内部的服务。
3.4、LoadBalancer
总结:整理不易,如果对你有帮助,可否点赞关注一下?
更多详细内容请参考:企业级K8s集群运维实战



