前面我们学习了通过控制器去批量创建和管理pod,有了pod就可以创造一个虚拟ip配合负载均衡对外提供服务了。现在新的问题又来了,如何在多个pod副本之间形成负载均衡?坏的pod被自动替换掉却有了新的ip,又该如何将新ip加入负载均衡?如何将pod提供的服务暴露给外网客户端?这些问题都需要k8s中一个叫做Service的东西来解答,这一节我们就一起来学习下Service。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。
文章目录
Service的定义
Service就是k8s集群中的一群具有某种共性的pod,这些pod通过service的组织对外统一提供服务,service也被叫做微服务。
每个service有自己的一套label选择器,符合这些label选择器的pod就被认为属于该service,而被该service管理。service会自动获取其管理pod的ip并制定负载均衡,pod的ip有变化也会自动同步到service中。
这里说的负载均衡都是基于IP的4层负载均衡
下面这个图可以很好地说明这个关系
图中有一个叫Frontend的Service通过两个标签app=webapp,role=frontend
去选择符合条件的pod,只要pod的标签中包含这两个标签即认为符合条件,标签可多不可缺。同时Service的定义中将Service的IP的443端口映射到后端pod的443端口。之后外界访问Service的443端口就会自动负载均衡到后端的3个pod中的一个。
Service的类型
k8s中的Service有如下几种类型,对应着定义Service的yaml文件的type字段
- ClusterIP
默认类型,该Service的虚拟IP仅为集群内部访问 - NodePort
在ClusterIP的基础上,在每个Node的物理网卡上都为该Service建立一个相同的端口映射,例如上图中将每个Node的8443端口都映射到Frontend这个Service的443端口,这样不管外部访问哪个Node的IP:8443都可以访问到该Service。如果要对集群外提供服务采用该方式,并且通常在Node的前面加上针对Node物理网卡IP的负载均衡 - LoadBalancer
在NodePort的基础上,借助第三方的云服务提供Node物理网卡IP的负载均衡。企业中用的不多,因为第三方云服务要额外收费,并且完全可以用免费方案代替 - ExternalName
相当于给集群外部的一个第三方服务加了一个DNS的CNAME记录,将外部流量引入集群内部
Service实现机制演进
Service的表象就是每个Node的kube-proxy进程为Service创造了一个虚拟IP,也就是VIP,到后端pod的映射关系。但是为了达到这个目的,k8s一直在改进实现机制。
了解这些实现机制,有助于我们去验证和排查Service到后端的负载均衡问题。
- k8s 1.0版本,采用userspace方式,已经被完全弃用
- k8s 1.1版本,增加了iptables方式,并在k8s 1.2版本变为默认方式
iptables会将负载均衡的规则写入NAT表中,可以通过iptabels -nvL -t nat
来查看规则 - k8s 1.8版本,增加了ipvs方式,并在k8s 1.14版本变为默认方式
ipvs有自己的管理工具ipvsadm,可以通过ipvsadm -Ln
来查看规则
不使用DNS做负载均衡,因为DNS会被缓存,往往达不到均衡的效果
IPVS因为远高于iptables的性能,而在新版本中被优先采用。但是如果没有安装IPVS的模块,即使配置了IPVS方式,k8s还是会回退到iptables的方式。
修改iptables模式为ipvs模式
如果因为某些原因发现安装的1.15版本的k8s还是使用的iptables模式,按照以下方式修改为ipvs模式。
编辑kube-proxy的配置文件
kubectl edit configmap kube-proxy -n kube-system
将其中的mode ""
改为mode: ipvs
,然后:wq
保存退出
删除现有的kube-proxy,让k8s自动替换新的
kubectl delete pod -n kube-system <pod-name>
之后查看新的kube-poxy的log,见到如下字样表示成功启用ipvs模式
Using ipvs Proxier
例如
[root@k8s-master k8s-test]# kubectl logs kube-proxy-4fw7f -n kube-system
I0506 15:56:08.640887 1 server_others.go:170] Using ipvs Proxier.
W0506 15:56:08.664133 1 proxier.go:401] IPVS scheduler not specified, use rr by default
I0506 15:56:08.664714 1 server.go:534] Version: v1.15.0
I0506 15:56:08.693167 1 conntrack.go:52] Setting nf_conntrack_max to 131072
I0506 15:56:08.693460 1 config.go:96] Starting endpoints config controller
I0506 15:56:08.