文章目录
1.service是什么?
service是kubernetes中最核心的资源对象之一,service和pod之间是通过Label串起来,相同的Service的pod的Label是一样的. 同一个service下的所有pod是通过kube-proxy
实现负载均衡.而每个service都会分配一个全局唯一的虚拟ip,也就cluster ip.
在该service整个生命周期内,cluster ip保持不变,而在kubernetes中还有一个dns服务,它会把service的name解析为cluster ip。
Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。(可以通过Ingress实现)
service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)
2.service的类型
ClusterIP
:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。NodePort
:将Service通过指定的Node上的端口暴露给外部,访问任意NodeIP:nodePort都将路由到ClusterIP。LoadBalancer
:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到:NodePort,此模式只能在云服务器上使用。ExternalName
:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。
2.1VIP和Service代理
在Kubernetes集群中,每个Node运行一个kube-proxy进程。kube-proxy负责为Service实现了一种VIP(虚拟IP)的形式,而不是ExternalName的形式。在Kubernetes v1.0版本,代理完全在userspace。在Kubernetes v1.1版本,新增了iptables代理,但并不是默认的运行模式。从Kubernetes v1.2起,默认就是iptables代理。
在Kubernetes v1.0版本,Service是“4层”(TCP/UDP over IP)概念。在Kubernetes v1.1版本,新增了 Ingress API(beta版),用来表示“7层”(HTTP)服务。
2.2没有selector的Service
Service抽象了该如何访问Kubernetes Pod,但也能抽象其他类型的backend,例如:
- 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
- 希望服务指向另一个Namespace中或其他集群中的服务。
- 正在将工作负载转移到Kubernetes集群,和运行在Kubernetes集群之外的backend。
在任何这些场景中,都能够定义没有selector 的 Service :
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
由于这个Service没有selector,就不会创建相关的Endpoints对象。可以手动将Service映射到指定的Endpoints:
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 1.2.3.4
ports:
- port: 9376
- 注意:Endpoint IP地址不能loopback(127.0.0.0/8),link-local(169.254.0.0/16),或者link-local多播(224.0.0.0/24)。
访问没有selector的Service,与selector的Service的原理相同。请求被路由到用户定义的Endpoint(该示例中为1.2.3.4:9376)
ExternalName service是Service的特别,它没有selector,也没有定义任何的端口和Endpoint。相反地,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
当查询主机 my-service.prod.svc.CLUSTER时,集群的DNS服务将返回一个值为my.database.example.com的CNAME记录,访问这个服务的功能方式与其他的相同,唯一不同的是重定向发生的DNS层,而且不会进行代理或转发。如果后续决定要将数据库迁移到Kubetnetes中,可以启动对应的Pod,增加合适的Selector或Endpoint,修改service的typt。
3. service的三种工作模式
第一种: 是Userspace方式
这种模式,kube-proxy
会监视Kubernetes master对service对象和Endpoints对象的添加和移除。对每个Service,它会在本地Node上打开一个端口(随机选择)。任何连接到“代理端口”的请求,都会被代理到Service的backend Pods中的某一个上面。使用哪个backend Pod,是基于Service的SessionAffinity来确定的。最后,它安装iptables规则,捕获到达该Service的clusterIP(是虚拟IP)和Port的请求,并重定向到代理端口,代理端口再代理请求到backend Pod。
网络返回的结果是,任何到达Service的IP:Port的请求,都会被代理到一个合适的backend,不需要客户端知道关于Kubernetes,service或pod的任何信息。
默认的策略是,通过round-robin算法
来选择backend Pod。实现基于客户端IP的会话亲和性,可以通过设置service.spec.sessionAffinity的值为“ClientIP”(默认值为“None”);
如下图描述,
Client Pod要访问Server Pod时,它先将请求发给本机内核空间中的service规则,由它再将请求,
转给监听在指定套接字上的kube-proxy,kube-proxy处理完请求,并分发请求到指定Server Pod后,再将请求
递交给内核空间中的service,由service将请求转给指定的Server Pod。
由于其需要来回在用户空间和内核空间交互通信,因此效率很差,接着就有了第二种方式.
第二种: iptables模型
此工作方式是直接由内核中的iptables规则
,接受Client Pod的请求,并处理完成后,直接转发给指定ServerPod.
这种模式,kube-proxy会监视Kubernetes master对象和Endpoinnts对象的添加和移除。对每个Service,它会安装iptables规则,从而捕获到达该Service的clusterIP(虚拟IP)和端口的请求,进而将请求重定向到Service的一组backend中某个上面。对于每个Endpoints对象,它也会安装iptables规则,这个规则会选择一个backend Pod。
默认的策略是,随机选择一个backend。实现基于客户端IP的会话亲和性,可以将service.spec.sessionAffinity的值设置为“ClientIP”(默认值为“None”)
和userspace代理类似,网络返回的结果是,任何到达Service的IP:Port的请求,都会被代理到一个合适的backend,不需要客户端知道关于Kubernetes,service或Pod的任何信息。这应该比userspace代理更快,更可靠。然而,不想userspace代理,如果始出选择的Pod没有响应,iptables代理不能自动地重试另一个Pod,所以它需要依赖readiness probes;
第三种: ipvs模型
它是直接有内核中的ipvs规则
来接受Client Pod请求,并处理该请求,再有内核封包后,直接发给指定的Server Pod。
这种模式,kube-proxy会