8.1 Service存在的意义

  • 防止Pod失联(服务发现)

  • 定义一组Pod的访问策略(负载均衡)

8.2 为什么要使用Service

Kubernetes Pod`是平凡的,由`Deployment`等控制器管理的`Pod`对象都是有生命周期的,它们会被创建,也会意外挂掉。虽然它们可以由控制器自动重建或者滚动更新,但是重建或更新之后的`Pod`对象的IP地址等都会发生新的变化。这样就会导致一个问题,如果一组`Pod`(称为`backend`)为其它`Pod`(称为 `frontend`)提供服务,那么那些`frontend`该如何发现,并连接到这组`Pod`中的哪些`backend`呢? 这时候就用到了:`Service

示例说明为什么要使用Service

如下图所示,当Nginx Pod作为客户端访问Tomcat Pod中的应用时,IP的变动或应用规模的缩减会导致客户端访问错误。而Pod规模的扩容又会使得客户端无法有效的使用新增的Pod对象,从而影响达成规模扩展之目的。为此,Kubernetes特地设计了Service资源来解决此类问题。

8.3 Service实现原理

Service资源基于标签选择器将一组Pod定义成一个逻辑组合,并通过自己的IP地址和端口调度代理请求至组内的Pod对象之上,如下图所示,它向客户端隐藏了真实的、处理用户请求的Pod资源,使得客户端的请求看上去就像是由Service直接处理并响应一样。

Service对象的IP地址也称为Cluster IP,它位于Kubernetes集群配置指定专用IP地址的范围之内,是一种虚拟IP地址,它在Service对象创建后既保持不变,并且能够被同一集群中的Pod资源所访问。Service端口用于接收客户端请求并将其转发至其后端的Pod中的相应端口之上,因此,这种代理机构也称为“端口代理”(port proxy)或四层代理,工作于TCP/IP协议栈的传输层。

Service资源会通过API Server持续监视着(watch)标签选择器匹配到的后端Pod对象,并实时跟踪各对象的变动,例如,IP地址变动、对象增加或减少等。Service并不直接链接至Pod对象,它们之间还有一个中间层——Endpoints资源对象,它是一个由IP地址和端口组成的列表,这些IP地址和端口则来自由Service的标签选择器匹配到的Pod资源。当创建service对象时,其关联的Endpoints对象会自动创建。

8.4 虚拟IP和服务代理

一个Service对象就是工作节点上的一些iptablesipvs规则,用于将到达Service对象IP地址的流量调度转发至相应的Endpoints对象指定的IP地址和端口之上。kube-proxy组件通过API Server持续监控着各Service及其关联的Pod对象,并将其创建或变动实时反映到当前工作节点上的iptables规则或ipvs规则上。

ipvs是借助于Netfilter实现的网络请求报文调度框架,支持rrwrrlcwlcshsednq等十余种调度算法,用户空间的命令行工具是ipvsadm,用于管理工作与ipvs之上的调度规则。

Service IP事实上是用于生成iptablesipvs规则时使用的IP地址,仅用于实现Kubernetes集群网络的内部通信,并且能够将规则中定义的转发服务的请求作为目标地址予以相应,这也是将其称为虚拟IP的原因之一。

kube-proxy将请求代理至相应端点的方式有三种:userspace(用户空间)iptablesipvs。因userspace传输效率太低,不推荐使用,在1.1版本之前是默认转发策略,现在默认是iptables。

8.5 iptables代理模式

iptables代理模式中,kube-proxy负责跟踪API ServerServiceEndpoints对象的变动(创建或移除),并据此作出Service资源定义的变动。同时,对于每个Service对象,它都会创建iptables规则直接捕获到达Cluster IP(虚拟IP)和Port的流量,并将其重定向至当前Service的后端。对于每个Endpoints对象,Service资源会为其创建iptables规则并关联至挑选的后端Pod资源,默认的调度算法是随机调度(random)。实现基于客户端IP的会话亲和性(来自同一个用户的请求始终调度到后端固定的一个Pod),可将service.spec.sessionAffinity的值设置为“ClientIP”(默认值为“None”)。

其代理过程是:请求到达service后,其请求被相关service上的iptables规则进行调度和目标地址转换(DNAT)后再转发至集群内的Pod对象之上。

Iptables:

  • 灵活,功能强大

  • 规则遍历匹配和更新,呈线性时延

8.6 ipvs代理模式

kube-proxy跟踪API ServerServiceEndpoints对象的变动,据此来调用netlink接口创建ipvs规则,并确保与API Server中的变动保持同步,其请求流量的调度功能由ipvs实现,其余的功能由iptables实现。ipvs支持众多调度算法,如rrlcdhshsednq等。

IPVS:

  • 工作在内核态,有更好的性能

  • 调度算法丰富:rr,wrr,lc,wlc,ip hash...

8.7 Pod与Service的关系

  • 通过label-selector相关联

  • 通过Service实现Pod的负载均衡( TCP/UDP 4层)

8.8 Service三种类型

ServiceIP地址只能够在集群内部可访问,对一些应用(如frontend)的某些部分,可能希望通过外部(kubernetes集群外部)IP地址暴露Service,这时候就需要使用到NodePortkubernetes ServiceTypes支持四种类型:ClusterIPNodePortLoadBalancer、其默认是Cluster IP类型。

  • ClusterIP:默认策略,分配一个稳定的IP地址,即VIP,只能在集群内部访问(同Namespace内的Pod)。
    pod ---> ClusterIP:ServicePort --> (iptables、ipvs)DNAT --> PodIP:containePort

  • NodePort:在每个节点上启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群IP地址。

    访问地址:<NodeIP>:<NodePort>
    clietn --> <NodeIp>:<NodePort> --> (iptables、ipvs)DNAT --> <PodIP>:<ContainerPort>

  • LoadBalancer:与NodePort类似,在每个节点上启用一个端口来暴露服务。除此之外,Kubernetes会请求底层云平台上的负载均衡器,将每个Node([NodeIP]:[NodePort])作为后端添加进去。

8.9 将service代理模式改为IPVS

1 验证所有node节点是否启用了ipvs
# lsmod | grep ip_vs
ip_vs_sh               12688 0
ip_vs_wrr             12697 0
ip_vs_rr               12600 0
ip_vs                 141432 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack         133053 7 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4
libcrc32c             12644 4 xfs,ip_vs,nf_nat,nf_conntrack

2 修改kube-proxy配置文件
[root@k8s-admin ~]# kubectl edit configmap kube-proxy -n kube-system
mode: "ipvs"

3 重建kube-proxy
[root@k8s-admin ~]# kubectl get pod -n kube-system -o wide

[root@k8s-admin ~]# kubectl delete pod kube-proxy-2n5j5 -n kube-system
[root@k8s-admin ~]# kubectl delete pod kube-proxy-mwgw2 -n kube-system
[root@k8s-admin ~]# kubectl delete pod kube-proxy-nq9jb -n kube-system
[root@k8s-admin ~]# kubectl get pod -n kube-system -o wide

4 验证
在k8s-node1,k8s-node2节点上进行验证
# grep ipvs /var/log/messages

# yum install ipvsadm -y
[root@k8s-admin ~]# kubectl get deploy,pod,svc,ep -o wide

# 访问nginx
http://172.16.1.71:31522/
http://172.16.1.72:31522/

[root@k8s-node1 ~]# ipvsadm -L -n # 会出现很多的ipvs规则,kube-proxy把pod的路由规则绑定到ip上
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
......
TCP 172.16.1.71:31522 rr
-> 10.244.2.6:80               Masq   1     2         0   
TCP 10.96.116.184:80 rr
-> 10.244.2.6:80               Masq   1     0         0 
......

[root@k8s-node2 ~]# ipvsadm -L -n # 会出现很多的ipvs规则,kube-proxy把pod的路由规则绑定到ip上
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
......
TCP 172.16.1.72:31522 rr
-> 10.244.2.6:80               Masq   1     2         0   
TCP 10.96.116.184:80 rr
-> 10.244.2.6:80               Masq   1     0         0 
......

8.10 Service DNS名称

DNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。

ClusterIP A记录格式:<service-name>.<namespace-name>.svc.cluster.local

示例:my-svc.my-namespace.svc.cluster.local

# cat busybox.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: busybox
name: busybox
namespace: default
spec:
containers:
- image: busybox:1.28.4
name: bs
command:
- "ping"
- "baidu.com"

​# kubectl apply -f busybox.yaml
# kubectl get pod
NAME                     READY   STATUS   RESTARTS   AGE
busybox                 1/1     Running   1         7m7s

# kubectl get svc
NAME         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)       AGE
kubernetes   ClusterIP   10.96.0.1       <none>       443/TCP       9d
nginx       NodePort   10.96.116.184   <none>       80:31522/TCP   9d

# kubectl exec -it busybox sh
/ # nslookup kubernetes
Server:   10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:     kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ # nslookup nginx
Server:   10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:     nginx
Address 1: 10.96.116.184 nginx.default.svc.cluster.local
/ #

8.11 小结

  1. 采用NodePort对外暴露应用,前面加一个LB实现统一访问入口

  2. 优先使用IPVS代理模式

  3. 集群内应用采用DNS名称访问

  4. service只支持四层负载均衡
    四层:OSI中的传输层,TCP/UDP,四元组,只负责IP数据包转发。
    七层:OSI中的应用层,HTTP、FTP、SNMP协议,可以拿到这些协议头部信息,那就可以实现基于协议层面的处理。

  5. NodePort访问流程
    user -> 域名(公网IP)-> node ip:port -> iptables/ipvs -> pod

    一般生产环境 node 都是部署在内网,那30008这个端口怎么让互联网用户访问呢
    (1) 找一台有公网IP的服务器,装一个nginx,反向代理 -> node ip:port
    (2) 只用你们外部负载均衡器 (Nginx、LVS、HAProxy) -> node ip:port

  6. LoadBalancer 访问流程
    user -> 域名(公网IP) -> 公有云上的负载均衡器(自动配置,控制器去完成) -> node ip:port

  7. kube-proxy工作
    (1) 实现pod数据包转发
    (2) 将service相关路由规则落地实现

第8章:深入理解Service的更多相关文章

  1. [深入理解Android卷一全文-第三章]深入理解init

    因为<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...

  2. [深入理解Android卷一全文-第四章]深入理解zygote

    由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的所有内容. ...

  3. 《深入理解Android 卷III》第二章 深入理解Java Binder和MessageQueue

    <深入理解Android 卷III>即将公布.作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...

  4. 《深入理解Android 卷III》第七章 深入理解SystemUI

    <深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...

  5. 《深入理解Android 卷III》第四章 深入理解WindowManagerService

    <深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白.即Android Framework中和UI相关的部分. ...

  6. 《深入理解Android 卷III》第六章 深入理解控件(ViewRoot)系统

    <深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...

  7. Objective-C 基础教程第七章,深入理解Xcode

    目录 Object-C 基础教程第七章,深入理解Xcode 0x00 前言 0x01 创建工程界面 0x02 主程序界面 ①顶部 Top Test(测试) Profile(动态分析) Analyze( ...

  8. [深入理解Android卷一全文-第七章]深入理解Audio系统

    由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...

  9. 《深入理解Android 卷III》第五章 深入理解Android输入系统

    <深入理解Android 卷III>即将公布.作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白.即Android Framework中和UI相关的部分. ...

随机推荐

  1. vmware安装ubuntu ,一直处于end kernel panic - not syncing : corrupted stack end detected inside scheduler

    vmware安装ubuntu ,一直处于end kernel panic - not syncing : corrupted stack end detected inside scheduler y ...

  2. Python菜鸟100例

    题目地址 #-*- codeing = utf-8 -*- #@Time : 2021/3/18 21:17 #@Author : HUGBOY #@File : 1.py #@Software: P ...

  3. 单片机编程时易错总结 20181015 项目:3060-A

    3060-A的调试过程中: 20181015 V1.30 A.遇到问题: RS232与LY3023的通信总是自己停止  主程序依旧执行 此版本进行如下修改: 1.RS232用的串口1关闭DMA传送   ...

  4. SUSE12 操作系统安装

    今天开发同事需要一个客户的SUSE环境,原来没有安装过这个操作系统,网络配置方面有些问题见下一篇 镜像:SLE-12-SP3-Server-DVD-x86_64-GM-DVD1.iso 安装过程: 选 ...

  5. 使用Selenium从IEEE与谷歌学术批量爬取BibTex文献引用

    搞科研的小伙伴总是会被期刊严苛的引用文献格式搞的很头疼.虽然常用的文献软件可以一键导出BibTex,但由于很多论文在投稿之前都会先发上Arxiv占坑,软件就很可能会把文献引出为来自Arxiv.我用的是 ...

  6. typora的一些使用

    1.介绍typora 支持markdown语法的一款写作app 真的足够简洁高效 2. typora和其他工具配合实现功能 如插入图片 截图 gif等等图库 smms图库的使用 需要使用PicGo和s ...

  7. ReentrantLock修饰类文件,实现按类获取锁的逻辑

    1.ReentrantLock 给类文件加锁,实现类似synchronized(class)的功能 核心是类文件中,使用static修饰的reentrantLock对象 public class So ...

  8. 常用深度学习框——Caffe/ TensorFlow / Keras/ PyTorch/MXNet

    常用深度学习框--Caffe/ TensorFlow / Keras/ PyTorch/MXNet 一.概述 近几年来,深度学习的研究和应用的热潮持续高涨,各种开源深度学习框架层出不穷,包括Tenso ...

  9. 如何为应用选择最佳的FPGA(上)

    如何为应用选择最佳的FPGA(上) How To Select The Best FPGA For Your Application 在项目规划阶段,为任何一个项目选择一个FPGA部件是最关键的决策之 ...

  10. CountDownLatch原理详解

    介绍 当你看到这篇文章的时候需要先了解AQS的原理,因为本文不涉及到AQS内部原理的讲解. CountDownLatch是一种同步辅助,让我们多个线程执行任务时,需要等待线程执行完成后,才能执行下面的 ...