Service是分布式集群架构的核心
- 拥有唯一指定的名称(比如mysql-server)
- 拥有一个虚拟IP地址(ClusterIP地址)和端口号
- 能够提供某种远程服务能力
- 能够将客户端对服务的访问请求转发到一组容器应用上
Service的服务进程通常基于Socket通信方式对外提供服务
一个Service通常由多个相关的服务进程提供服务,每个服务进程都有一个独立的Endpoint(IP+Port)访问点,但 Kubernetes能够让我们通过Service(ClusterIP+Service Port)连接指定的服务。
为了建立Service和Pod间的关联关系,
Kubernetes首先给 每个Pod都贴上一个标签(Label),比如给运行MySQL的Pod贴上 name=mysql标签,给运行PHP的Pod贴上name=php标签,然后给相应的 Service定义标签选择器(Label Selector),
例如,MySQL Service的标 签选择器的选择条件为name=mysql,意为该Service要作用于所有包含 name=mysql标签的Pod。这样一来,就巧妙解决了Service与Pod的关联 问题。
ClusterIP
Service一旦被创建,Kubernetes就会自动为它分配一个全 局唯一的虚拟IP地址——ClusterIP地址,而且在Service的整个生命周期内,其ClusterIP地址不会发生改变,这样一来,每个服务就变成了具备唯一IP地址的通信节点,远程服务之间的通信问题就变成了基础的TCP 网络通信问题。
ClusterIP地址是一种虚拟IP地址,原因有以下几点。
◎ ClusterIP地址仅仅作用于Kubernetes Service这个对象,并由 Kubernetes管理和分配IP地址(来源于ClusterIP地址池),与Node和 Master所在的物理网络完全无关。
◎ 因为没有一个“实体网络对象”来响应,所以ClusterIP地址无法 被Ping通。ClusterIP地址只能与Service Port组成一个具体的服务访问端 点,单独的ClusterIP不具备TCP/IP通信的基础。
◎ ClusterIP属于Kubernetes集群这个封闭的空间,集群外的节点 要访问这个通信端口,则需要做一些额外的工作。
Service的外网访问
Kubernetes的三种IP,这三种IP分别如下。
◎ Node IP:Node的IP地址。
◎ Pod IP:Pod的IP地址。
◎ Service IP:Service的IP地址。
Node IP是Kubernetes集群中每个节点的物理网卡的IP地址, 是一个真实存在的物理网络,所有属于这个网络的服务器都能通过这个 网络直接通信,不管其中是否有部分节点不属于这个Kubernetes集群。 这也表明Kubernetes集群之外的节点访问Kubernetes集群内的某个节点或 者TCP/IP服务时,都必须通过Node IP通信。
Pod IP是每个Pod的IP地址,在使用Docker作为容器支持引擎 的情况下,它是Docker Engine根据docker0网桥的IP地址段进行分配的, 通常是一个虚拟二层网络。前面说过,Kubernetes要求位于不同Node上 的Pod都能够彼此直接通信,所以Kubernetes中一个Pod里的容器访问另 外一个Pod里的容器时,就是通过Pod IP所在的虚拟二层网络进行通信 的,而真实的TCP/IP流量是通过Node IP所在的物理网卡流出的。
Service的ClusterIP地址属于集群内的地址, 无法在集群外直接使用这个地址。为了解决这个问题,Kubernetes首先 引入了NodePort这个概念,NodePort也是解决集群外的应用访问集群内 服务的直接、有效的常见做法。
Service的负载均衡机制 当一个Service对象在Kubernetes集群中被定义出来时,集群内的客 户端应用就可以通过服务IP访问到具体的Pod容器提供的服务了。从服 务IP到后端Pod的负载均衡机制,则是由每个Node上的kube-proxy负责 实现的。
kube-proxy的代理模式、会话保持机制和基于拓扑感知 的服务路由机制(EndpointSlices)进行说明。
ipvs模式:
kubeproxy通过设置Linux Kernel的netlink接口设置IPVS规则,转发效率和支 持的吞吐率都是最高的。ipvs模式要求Linux Kernel启用IPVS模块,如果 操作系统未启用IPVS内核模块,kube-proxy则会自动切换至iptables模 式。同时,ipvs模式支持更多的负载均衡策略,
rr:round-robin,轮询。
lc:least connection,最小连接数。
dh:destination hashing,目的地址哈希。
sh:source hashing,源地址哈希。
sed:shortest expected delay,最短期望延时。
nq:never queue,永不排队
iptables模式:kube-proxy通过设置Linux Kernel的iptables规则, 实现从Service到后端Endpoint列表的负载分发规则,效率很高。但是, 如果某个后端Endpoint在转发时不可用,此次客户端请求就会得到失败 的响应,相对于userspace模式来说更不可靠。此时应该通过为Pod设置 readinessprobe(服务可用性健康检查)来保证只有达到ready状态的 Endpoint才会被设置为Service的后端Endpoint。