zoukankan      html  css  js  c++  java
  • k8的service和DNS服务发现机制

    Service介绍

         Kubernetes 之所以需要 Service,一方面是因为 Pod的IP不是固定的,另一方面则是因为一组 Pod 实例之间总会有负载均衡的需求

         Service是由Kube-proxy组件加上iptables来共同实现的

         Service vip(vip 是k8s自动为Service分配的)到Pod的转发

             iptables 对流入的IP包还设置了一个“标志”(–set-xmark)

             只有处于Running状态,且readinessProbe检查通过的Pod,才会出现在Service的Endpoints 列表里.并且,当某一个 Pod 出现问题时,Kubernetes会自动把它从Service里摘除掉

    Service基本原理

           当用户把一个service yaml文件提交给k8s后,kube-proxy组件通过Service的Informer感知到一个Service对象的添加,作为对这个事件的响应它就会在宿主机上创建一条iptables规则 可以通过iptables-save命令来查看

           Service的VIP地址只是一条iptables规则上的配置 并没有真正的网络设备 所以ping这个地址 是不会有任何响应的

           DNAT的作用,就是在PREROUTING检查点之前,也就是在路由之前,将流入IP包的目的地址和端口,改成–to-destination指定的新目的地址和端口

          访问Service VIP的IP包经过上述 iptables 处理之后,就已经变成了访问具体某一个后端Pod的IP包了.

          不难理解,这些 Endpoints 对应的iptables规则,正是kube-proxy通过监听Pod的变化事件,在宿主机上生成并维护的

         

    iptables模式和ipvs模式  

         kube-proxy通过iptables处理Service 的过程,其实需要在宿主机上设置相当多的 iptables 规则 
         当你的宿主机上有大量Pod的时候,成百上千条iptables规则不断地被刷新,会大量占用该宿主机的CPU资源
     
         IPVS 模式
           IPVS 模式的工作原理,其实跟iptables模式类似.当我们创建了前面的 Service 之后,kube-proxy首先会在宿主机上创建一个虚拟网卡(叫作:kube-ipvs0)并为它分配 Service VIP作为 IP 地址 
           

           kube-proxy就会通过Linux的IPVS 模块,为这个IP地址设置三个IPVS 虚拟主机,并设置这三个虚拟主机之间使用轮询模式 (rr) 来作为负载均衡策略

         

        而相比于 iptables,IPVS 在内核中的实现其实也是基于 Netfilter的NAT模式,所以在转发这一层上,理论上 IPVS 并没有显著的性能提升.但是IPVS 并不需要在宿主机上为每个Pod设置 iptables 规则,而是把对这些“规则”的处理放到了内核态,极大地降低了维护这些规则的代价
       不过需要注意的是,IPVS 模块只负责上述的负载均衡和代理功能.而一个完整的 Service 流程正常工作所需要的包过滤,SNAT等操作,还是要靠iptables来实现.只不过,这些辅助性的 iptables 规则数量有限,也不会随着Pod数量的增加而增加

    Service和DNS的关系

            在kubernetes中,所有的Service和Pod都会被分配一条对应的DNS A记录( 通过域名解析到IP地址的记录 )

    clusterIP Service的分配方式
         ClusterIP模式的Service 来说,它的 A 记录的格式是:myservicename.mynamespace.svc.cluster.local 当你访问这条 A 记录的时候,它解析到的就是该Service的VIP 地址
    Headliness Service的分配方式

         ClusterIP=None 的 Headless Service 来说,它的 A 记录的格式也是:myservicename.mynamespace.svc.cluster.local 当你访问这条A记录的时候,它返回的是所有被代理的Pod的IP地址的集合.当然,如果你的客户端没办法解析这个集合的话,它可能会只会拿到第一个Pod的IP地址

    clusterIP Service被代理Pod的分配方式

         对于ClusterIP模式的Service来说,它代理的Pod被自动分配的A记录的格式是:PodIP.mynamespace.pod.cluster.local  这条记录指向Pod的IP地址

    Headliness Service被代理Pod的分配方式
        1.对Headless Service 来说,它代理的Pod被自动分配的A记录的格式是:mypodname.myservicename.mynamespace.svc.cluster.local 这条记录也指向Pod的IP地址
        2. 如果Pod本身声明了hostname和subdomain字段,那么这时候Pod的A记录就会变成:  podhostname.mysubdomain.mynamespace.svc.cluster.local
     
        

        在上面这个Service和Pod被创建之后,你就可以通过busybox-1.default-subdomain.default.svc.cluster.local 解析到这个Pod的IP地址了

        在 Kubernetes 里,/etc/hosts 文件是单独挂载的,这也是为什么kubelet能够对hostname进行修改并且Pod 重建后依然有效的原因这跟 Docke的Init层是一个原理

    用途

          ClusterIP模式的Service为你提供的,就是一个Pod的稳定的IP地址,即 VIP.  并且,这里Pod和Service 的关系是可以通过 Label 确定的 
          Headless Service 为你提供的,则是一个 Pod 的稳定的 DNS 名字,并且,这个名字是可以通过Pod名字和Service名字拼接出来 
          服务发现: 即当我的一个服务(Pod)的IP地址是不固定的且没办法提前获知时,该如何通过一个固定的方式访问到这个Pod 

            

  • 相关阅读:
    zz学习技术的三部曲:WHAT、HOW、WHY
    zz一种理想的在关系数据库中存储树型结构数据的方法
    某外企SQL Server面試題
    C语言中的指针 &与*
    剖析SQL Server执行计划(zz)
    UNICODE,GBK,UTF8区别
    (Part 1Chapter 14) High Performance Linux Clusters with OSCAR, Rocks, OpenMosix, and MPI
    关于GtkTreeView和 MVC的一篇好文章 入木三分
    一个混合 MPI_Init() 和 gtk_init() 的实例序
    (Part 2Chapter 57) High Performance Linux Clusters with OSCAR, Rocks, OpenMosix, and MPI
  • 原文地址:https://www.cnblogs.com/yxh168/p/12243054.html
Copyright © 2011-2022 走看看