<1> Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应 用可以方便地实现服务发现和负载均衡。
<2> service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)
<3> service的类型:
ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。
NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个 NodeIP:nodePort都将路由到ClusterIP。
LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均 衡器,并将请求转发到 <NodeIP>:NodePort,此模式只能在云服务器上使用。
ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)
<4> Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。
<5> kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU 资源。
<6> IPVS模式的service,可以使K8s集群支持更多量级的Pod。
默认设置的service是ClusterIP类型,他只允许集群内部访问,集群外不能访问。
kubectl edit svc myservice ##编辑myservice服务配置
kubectl describe svc myservice ##查看myservice服务的详细信息
这样service使用NodePort类型的,外部可以通过访问任何一个NodeIP:nodePort都将路由到ClusterIP。
kube-proxy通过iptables处理service,需要在宿主机上设置相当多的iptables规则,如果宿主机有大量的pod,不断刷新iptables规则,会消耗大量的cpu资源。而ipvs模式的service,可以使k8s集群支持更多量级的pod。
yum install -y ipvsadm ##在各节点上安装ipvsadm
lsmod |grep ip_vs ##过滤出ip_vs
kubectl -n kube-system edit cm kube-proxy ##修改ipvs模式
kubectl -n kube-system get pod ##查看一下
kubectk -n kube-system get pod | grep kube-proxy ##过滤出kube-proxy
kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}' ##删除掉kube-proxy pod ,他会自动再次新建,所以这样一步是在更新kube-proxy pod
在ipvs模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP。
kube-proxy通过linux的ipvs模块,以rr轮询的方式调度service中的pod
vim pod2.yml ##我们来添加几个pod,看ipvs是否改变
ipvsadm -ln
只要服务创建,他就有解析。
当我们访问service的IP时,可以直接访问ip,也可以通过域名来访问,当service删除又重新创建时,他的ip会发生改变,但是域名不会变,这就是k8s的dns域名解析,很方便。
Headless service无头服务:
<1> Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理Pod 的IP地址。
<2> 域名格式: ( s e r v i c e n a m e ) . (servicename). (servicename).(namespace).svc.cluster.local
vim service.yml
(1)NodePort方式
这种方式是将Service通过指定的Node上的端口(这个端口是随机的)暴露给外部,外部访问任意一个节点ip:暴露的端口都可以都将路由到ClusterIP。
kubectl edit svc myservice
(2)LoadBalancer: 从外部访问service的第二种方式,适用于公有云上的k8s服务
kubectl delete -f service.yml
vim service.yml
在service提交后,Kubernetes就会调用 CloudProvider 在公有云上为你创建 一个负载均衡服务,并且把被代理的 Pod 的 IP地址配置给负载均衡服务做后端。工作流程就是:
(3)ExternalName:从外部访问service的第三种方法
这种方式适用的场景是pod集群内部去访问集群外部的资源,外部的资源不是咱能控制的,当外部的域名改变时,我们通过使用k8s的cname 别名方式,使得访问myservice.default.svc相当于访问www.westos.com。
kubectl delete -f service.yml
vim service.yml
kubectl delete -f service.yml
vim service.yml
(4)service允许为其分配一个公有IP。
这里的共有ip一定是可以被外界直接访问的ip。
kubectl delete -f service.yml
vim service.yml
能看到上面访问的时候有些访问是很慢的,这是由于vxlan模式的工作原理所致。
每个节点在启动的时候,他会把子网的分配放在/run/flannel/subnet.env里面
当俩个不在同一个节点的pod通信时,即跨主机通信。
flannel是一个网络插件,他支持的后端应用有很多,vxlan是其中的一种。这里我们来介绍一下host-gw(主机网关类型)、vxlan+Directrouting(直连路由)
host-gw:
这种host-gw类型他不再走flannel隧道,而是直接使用主机网关。
我们再来外部访问测试一下:
vim pod2.yml ##多设置几个pod
kubectl delete -f service.yml
vim service.yml
从以上可以看出来flannel使用host-gw主机网关类型他能减少访问的损耗量。
host-gw的工作模型是:直接访问目标主机的主机网关。但这个模型他有使用条件,二层必须是连通的,就是节点能够通信。但是在实际中,大多数需要三层的,二层网络互通这很难满足。
vxlan+Directrouting:
默认使用vxlan,他是没有打开Directrouting(直连路由的),这种vxlan+直连路由的模式他工作是当是二层网络是直接使用直连路由,相当于host-gw,当是三层网络时,他走隧道模式。
设置方法如下:
访问一下,能看到访问不卡顿。