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三种服务发现工具,探讨了最佳的服务发现解决方案,仅供参考. 如果使用预定义的端口,服务越多,发生冲突的可能性越大,毕竟,不可能有两个服务 ...
随机推荐
- Spring定义事物通知tx:advice
<aop:config proxy-target-class="false"> <aop:advisor advice-ref="txAdvice ...
- c#上课总结
private 是完全私有的,只有当前类中的成员能访问到. protected 是受保护的,只有当前类的成员与继承该类的类才能访问. Ctrl+k+c 多行注释Ctrl+k+u 解除注释 e ...
- 我对CSS的认识
花费了一段时间,终于对HTML有了一定的了解,随后又开始进行CSS的战斗感觉自己学起来有一点吃力.我就简单的讲一下我所学到的吧! CSS的概述. 层叠式样式表,用于控制网页样式并允许将样式信息并允许将 ...
- Visible Lattice Points SPOJ - VLATTICE 三维+莫比乌斯反演
#include<bits/stdc++.h> #define ll long long using namespace std; ; int vis[maxn]; int mu[maxn ...
- h3c_7506e引擎主备镜像同步
备份引擎的镜像文件不匹配会导致主引擎无法识别备引擎解决方法:1.备份主引擎上的启动文件同步到备引擎 ftp ip地址 get 在ftp服务器的镜像文件名 为其命名为本地文件(均为源文件名) ...
- docker(基础篇)
http://naotu.baidu.com/file/f02773930afb2d3d9e71621249099d31 centos7安装 https://yq.aliyun.com/articl ...
- MySQL 数据表操作
MySQL 数据表操作 创建MySQL数据表需要以下信息: -表名: -表字段名: -定义每个表字段: 一.创建数据表 1)mysql> create table table_name (c ...
- day-13装饰器
函数的嵌套定义 概念:在一个函数的内部定义另一个函数 为什么要有函数的嵌套定义:1)函数fn2想直接使用fn1函数的局部变量,可以将fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量2 ...
- leetcode中的python学习
list.extend() list1.extend(list2(or string)) 将list2(or string)的所有元素添加到list1中: list1.append(list2(or ...
- IMPALA部署和架构(一)
IMPALA部署和架构(一) 一,概要 因公司业务需求,需要一个查询引擎满足快速查询TB级别的数据,所以我们找到了presto和impala,presto在前面讲过今天只说impala,impala ...