kubenetes服务发现
一、基于 iptables 的 Service 实现
Pod的ip地址不是固定了。Service通过selector属性和后端Pod关联,被selector选中的Pod被称为Service的Endpoint。通过该Service的VIP地址就可以访问到它所代理的Pod。VIP地址是kubernetes自动为Service分配的。
Service 是由 kube-proxy 组件,加上iptables 来共同实现的。
一旦创建了Service,那么kube-proxy就可以通过Service的Informer感知到Service的添加,而作为这个事件的响应,他就会在宿主机上创建一条iptables规则,为这个Service设置一个固定的入口地址。由于它只是一条iptables规则上的配置,并没有真正的网络设备,所以ping这个地址,是没有任何反应的。
上面会路由到一组规则的集合,它实际上是一组随机模式的iptables链。转发的最终目的地就是Service代理的Pod,所以这组规则就是Service实现负载均衡的位置。
这组规则实际上是DNAT规则。DNAT规则的作用是在路由之前将流入的ip地址的目标地址和端口转为-to0destination所指定的新的目的地址和端口,这个目的地址和端口正是被代理的pod的ip地址和端口。
所以,访问Service VIP的ip包经过上述的iptables处理之后,就已经变成了访问具体某一个后端pod的ip包了。这些endpoint对应的iptables规则,正是kube-proxy通过监听pod的变化事件在宿主机上生成并维护的。
缺点:会产生大量的iptables规则,而且这些iptables规则需要被不断的刷新
二、IPVS 模式的 Service
IPVS 模式的工作原理,其实跟 iptables 模式类似。当我们创建了前面的 Service 之后,kube-proxy 首先会在宿主机上创建一个虚拟网卡(叫作:kube-ipvs0),并为它分配 Service VIP 作为 IP 地址,如下所示:
而接下来,kube-proxy 就会通过 Linux 的 IPVS 模块,为这个 IP 地址设置三个 IPVS 虚拟主机(实际上就是被代理的pod,这里的例子是三个),并设置这三个虚拟主机之间使用轮询模式 (rr) 来作为负载均衡策略。我们可以通过 ipvsadm 查看到这个设置,如下所示:
可以看到,这三个 IPVS 虚拟主机的 IP 地址和端口,对应的正是三个被代理的 Pod。
这时候,任何发往 10.102.128.4:80 的请求,就都会被 IPVS 模块转发到某一个后端 Pod 上了。
而相比于 iptables,IPVS 在内核中的实现其实也是基于 Netfilter 的 NAT 模式,所以在转发这一层上,理论上 IPVS 并没有显著的性能提升。但是,IPVS 并不需要在宿主机上为每个 Pod 设置 iptables 规则,而是把对这些“规则”的处理放到了内核态,从而极大地降低了维护这些规则的代价。“将重要操作放入内核态”是提高性能的重要手段。
不过需要注意的是,IPVS 模块只负责上述的负载均衡和代理功能。而一个完整的 Service 流程正常工作所需要的包过滤、SNAT 等操作,还是要靠 iptables 来实现。只不过,这些辅助性的 iptables 规则数量有限,也不会随着 Pod 数量的增加而增加。
三、Service 与 DNS 的关系
在 Kubernetes 中,Service 和 Pod 都会被分配对应的 DNS A 记录(从域名解析 IP 的记录)。
对于 ClusterIP 模式的 Service 来说(比如我们上面的例子),它的 A 记录的格式是:..svc.cluster.local。当你访问这条 A 记录的时候,它解析到的就是该 Service 的 VIP 地址。
而对于指定了 clusterIP=None 的 Headless Service 来说,它的 A 记录的格式也是:..svc.cluster.local。但是,当你访问这条 A 记录的时候,它返回的是所有被代理的 Pod 的 IP 地址的集合。当然,如果你的客户端没办法解析这个集合的话,它可能会只会拿到第一个 Pod 的 IP 地址。
此外,对于 ClusterIP 模式的 Service 来说,它代理的 Pod 被自动分配的 A 记录的格式是:..pod.cluster.local。这条记录指向 Pod的ip地址。
而对 Headless Service 来说,它代理的 Pod 被自动分配的 A 记录的格式是:...svc.cluster.local。这条记录也指向 Pod的ip地址。
四、外部访问Service的三种方式
NodePort:访问宿主机的ip:端口,就能访问到pod。kuberbetes会在ip发往目的pod时,对ip包做一次SNAT操作
LoadBalancer:会创建一个负载均衡服务,把pod的ip配置给负载均衡服务
External Name:不需要制定selector。还可以为Service分配公有的ip
Service,其实就是 Kubernetes 为 Pod 分配的、固定的、基于 iptables(或者 IPVS)的访问入口。而这些访问入口代理的 Pod 信息,则来自于 Etcd,由 kube-proxy 通过控制循环来维护。
kubenetes服务发现的更多相关文章
- Consul 服务注册与服务发现
上一篇:Mac OS.Ubuntu 安装及使用 Consul 1. 服务注册 对 Consul 进行服务注册之前,需要先部署一个服务站点,我们可以使用 ASP.NET Core 创建 Web 应用程序 ...
- etcd:用于服务发现的键值存储系统
etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现.etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理 ...
- 我是服务的执政官-服务发现和注册工具consul简介
服务发现和注册 我们有了两个服务.服务A的IP地址是192.168.0.1,端口9001,服务B的IP地址192.168.0.2,端口9002.我们的客户端需要调用服务A和服务B,我们只需要在配置文件 ...
- k8s DNS 服务发现的一个坑
按照官当文档,以及大家的实践进行k8s dns 服务发现搭建还是比较简单的,但是会有一个因为系统默认dns 配置造成的一个问题 1. linux 默认dns 配置在 /etc/resolv.conf ...
- Kubernetes如何使用kube-dns实现服务发现
大纲: • Kubernetes中如何发现服务 • 如何发现Pod提供的服务 • 如何使用Service发现服务 • 如何使用kube-dns发现服务 ...
- Consul 服务发现和配置
Service discovery and configuration made easy. Distributed, highly available, and datacenter-aware. ...
- 服务发现之 Etcd VS Consul
抄自这里 *********************************************************************************************** ...
- SpringCloud+Consul 服务注册与服务发现
SpringCloud+Consul 服务注册与服务发现 1. 服务注册: 在Spring.factories有一段: # Discovery Client Configuration org.spr ...
- 服务发现:Zookeeper vs etcd vs Consul
[编者的话]本文对比了Zookeeper.etcd和Consul三种服务发现工具,探讨了最佳的服务发现解决方案,仅供参考. 如果使用预定义的端口,服务越多,发生冲突的可能性越大,毕竟,不可能有两个服务 ...
随机推荐
- 30天代码day4 Class vs. Instance
Class A blueprint defining the charactaristics and behaviors of an object of that class type. Class ...
- 用python给邮箱发邮件,问题,以及解决方法。
模版 import smtplib #导入相关模块 from email.mime.text import MIMEText from email.utils import formataddr de ...
- L1-046 整除光棍
这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数整除.比如,111111就可以被13整除. 现在,你的程序 ...
- 7 种 join
DROP TABLE IF EXISTS `test_student`; CREATE TABLE `test_student` ( `id` ) NOT NULL COMMENT '学号', `se ...
- Python 限制线程的最大数量(Semaphore)
import threadingimport time sem = threading.Semaphore(4) # 限制线程的最大数量为4个 def gothread(): with sem: # ...
- ubutu16.04 安装Tenda u12无线网卡驱动
ubutu16.04 安装Tenda u12无线网卡驱动 一些问题: 1) Tenda u12 linux版本的驱动支持 kernel 2.6 到 4.4,而前系统内版本核为4.10,所以编译不过去啦 ...
- c#死锁示例代码
void Main() { object obj1 = new object(); object obj2 = new object(); var t1 = new Thread(delegate(o ...
- 在<canvas>上绘制img(drawImage())时需要注意的事
<canvas>标签相当于是一个画布,css决定画布的样式(这块画布的背景颜色.大小等),脚本(一般使用JavaScript)就是画笔,我们可以在这个画布上绘制线条.形状.文字.图片等. ...
- Pytho条件判断
def health_status(): height = float(input("请输入身高(单位:米) :")) weight = float(input("请输入 ...
- Win10无法访问网上邻居电脑共享的文件夹怎么办
Win10无法访问网上邻居电脑共享的文件夹怎么办 现在许多电脑上装的都是Win系统,Win10无法访问网上邻居电脑共享的文件夹怎么办呢?下面小编为大家介绍下解决的方法吧! 1点击桌面上的“此电脑”图标 ...