k8s服务代理和发现

今天主要学习一下k8s的Service,之前的文章中有介绍过k8s内服务访问的方式,但是自己也没有特别的去了解具体的实现方式,今天就专门再来学习下Service这个非常重要的资源。今天主要是学习官方的文档,文档地址:Service。另外我还是觉得中文文档翻译之后不太好理解,所以最好我觉得还是看英文文档。
k8s中的Service是一个抽象的概念,它定义了一组逻辑的Pod以及访问这些Pod的策略(有时这种模式被称作微服务)。直白点讲Service本身并不提供所谓的服务,它只是告诉你怎么访问你想要访问的服务。通常情况下Service是通过Selector来定位到目标Pod的,当然你也可以通过创建相应的Endpoints定位到具体的服务。

1、虚拟IP和服务代理

在k8s集群中的每个节点上都会运行着一个kube-proxy,由kube-proxy负责为非ExternalName类型的Service实现一种虚拟IP。
之所以k8s选择代理模式将入站流量转发到后端,而不是通过配置多个A值(ipv6为AAAA)0的DNS记录,然后依赖轮询名称解析。主要有几点原因:
1、一直以来DNS都不遵守数据的TTL(Time to live),即使在数据过期后依然会进行缓存;
2、对于某些应用只进行一次DNS查找,但是结果却会永久缓存;
3、即使应用和库进行了适当的重新解析,DNS 记录上的较低的TTL值低或零值可能会给DNS带来高负载,从而使管理变得困难。

1、用户空间代理模式

这种模式下kube-proxy会观察k8s控制节点对Service 对象和 Endpoints对象的添加和删除操作。对于每一个Servicekube-proxy都会在本地的节点上打开一个随机端口,任何连接到这个“代理端口”的请求,都会被转发到该Service对应的后端Pods中的某一个上面。具体使用哪一个Pod,是kube-proxy基于该Service的设置项SessionAffinity来确定的。
最后,kube-proxy会配置iptables规则,捕获到达该ServiceclusterIP(是虚拟 IP)和 port的请求,并重定向到代理端口,然后由代理端口再代理请求到后端Pod
用户空间模式下的kube-proxy默认通过轮转算法选择后端。
用户空间模式见下图:

图-1.png

2、iptables代理模式

和用户空间代理模式,这种模式下kube-proxy也会观察k8s控制节点对Service对象和Endpoints对象的添加和删除操作。 不同的是对每个Servicekube-proxy会通过配置iptables规则,从而捕获到达该ServiceclusterIPport的请求,然后将请求重定向到该Service后端集合中的某个上面。对于每个Endpoints对象,kube-proxy也会配置 iptables规则,这个规则会选择一个后端Pod
iptables模式下kube-proxy默认会随机选择一个后端。
使用iptables处理流量具有较低的系统开销,因为流量由Linux netfilter处理,而无需在用户空间和内核空间之间切换,而且这种方法也可能更可靠。
如果kube-proxyiptables模式下运行,kube-proxy随机选择的Pod没有响应,那么此次连接失败。这点与用户空间模式不同。在用户空间模式情况下,kube-proxy如果检测到与第一个Pod的连接失败,那么它会自动使用其他后端Pod进行重试。
我们可以使用Pod readiness probes 验证后端Pod是否就绪以便iptables模式下的kube-proxy仅看到状态正常且就绪的后端。readiness probes在滚动发布的时候也会用到。
iptables代理模式如下图:

图-2.png

3、IPVS代理模式

ipvs模式下kube-proxy观察k8s的ServicesEndpoints,调用netlink接口相应地创建IPVS规则,并定期将IPVS规则与k8s的ServicesEndpoints同步。该控制循环可确保IPVS状态与所需状态匹配。访问Service时,IPVS将流量定向到后端Pod之一。
IPVS代理模式基于类似于iptables模式的netfilter钩子函数, 但是使用哈希表作为基础数据结构,并且在内核空间中工作。这意味着与iptables模式下的kube-proxy相比,IPVS模式下的kube-proxy重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比IPVS模式还支持更高的网络流量吞吐量。
IPVS提供了更多选项来平衡到达后端Pod的流量。 这些是:
rr:轮替(Round-Robin)
lc:最少链接(Least Connection),即打开链接数量最少者优先
dh:目标地址哈希(Destination Hashing)
sh:源地址哈希(Source Hashing)
sed:最短预期延迟(Shortest Expected Delay)
nq:从不排队(Never Queue)

说明:
要想kube-proxy使用IPVS模式,必须在启动kube-proxy之前保证IPVS在节点上可用。因为当kube-proxyIPVS代理模式启动时,它将验证IPVS内核模块是否可用, 如果未检测到IPVS内核模块,则kube-proxy将会使用iptables代理模式运行。

IPVS代理模式如下图:

图-3.png


在这些代理模式中,在客户端不了解k8s或ServicePod的任何信息的情况下,请求到Serviceip:port的流量最终被代理到具体的后端。
如果要确保每次都将来自特定客户端的连接传递到同一Pod, 则可以通过将service.spec.sessionAffinity设置为ClientIP(默认值是None),来基于客户端的IP地址选择会话关联。 你还可以通过适当设置 service.spec.sessionAffinityConfig.clientIP.timeoutSeconds来设置最大会话停留时间(默认值为 10800 秒,即 3 小时)。

2、服务发现

k8s支持两种基本的服务发现模式——环境变量和DNS

1、环境变量

Pod运行在Node上,kubelet会为每个存活的Service添加一组环境变量。 它同时支持Docker links compatible变量(见makeLinkVariables)和简单的 {SVCNAME}_SERVICE_HOST{SVCNAME}_SERVICE_PORT 变量。 这里Service的名称需大写,横线被转换成下划线。

举个例子,一个名称为 redis-masterService暴露了TCP端口6379, 同时给它分配了ClusterIP地址 10.0.0.11,这个Service生成了如下环境变量:

REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

但是这个环境变量只针对同Namespace下的Service,比如我在namespace A下的Pod的环境变量中是查看到namespace B下的Service的相关信息的。

2、DNS

通常来讲我们的k8s集群都会安装相关的网络插件,比如Calico、Flannel等来设置DNS服务。
支持集群的DNS服务器(例如CoreDNS)会观察k8s API中的新Service,并为每个服务创建一组DNS记录。 如果在整个集群中都启用了DNS,则所有Pod都应该能够通过其DNS名称自动解析服务。
例如,如果你在命名空间 my-ns中有一个名为my-service的服务,则k8s控制面板和DNS服务共同为my-service.my-ns创建DNS记录。my-ns命名空间中的Pod能够通过名称my-service来找到服务(这里可以直接通过环境变量获取my-serviceclusterIpport等),当然也可以通过my-service.my-ns来定位到具体的cluserIp
其他命名空间中的Pod必须将名称限定为my-service.my-ns。这个名称将解析为服务的clusterIP
k8s还支持命名端口的DNS SRV记录。 如果my-service.my-ns服务具有名为http的端口,且协议设置为 TCP,则可以对_http._tcp.my-service.my-ns执行DNS SRV查询,以发现该服务http的端口号以及IP地址。
k8s DNS服务器是唯一的一种能够访问ExternalName类型的Service的方式。 更多关于ExternalName信息可以查看DNS Pod 和 Service

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,322评论 5 465
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,288评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,227评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,015评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,936评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,534评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,995评论 3 389
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,616评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,907评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,923评论 2 315
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,741评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,525评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,016评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,141评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,453评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,054评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,249评论 2 339

推荐阅读更多精彩内容