• service连通k8s外部


    外界连通Service

            Service 的访问信息在Kubernetes集群之外,其实是无效的 
            如何从外部(Kubernetes 集群之外),访问到 Kubernetes 里创建的Service
    方式1(NodePort)

            创建一个NodePort类型的service

            不显式地声明nodePort字段,Kubernetes就会为你分配随机的可用端口来设置代理.这个端口的范围默认是30000-32767

            ClusterIP模式的Service和NodePort类型的Service定义格式

            

           在NodePort 方式下,Kubernetes 会在 IP 包离开宿主机发往目的 Pod 时,对这个 IP 包做一次 SNAT 操作 .
           这条规则设置在 POSTROUTING 检查点,也就是它给即将离开这台主机的 IP 包,进行了一次 SNAT 操作 .将这个IP包的源地址替换成了这台宿主机上的 CNI 网桥地址或者宿主机本身的 IP 地址(如果 CNI 网桥不存在的话) .当然,这个SNAT 操作只需要对 Service 转发出来的 IP 包进行(否则普通的IP包就被影响了)而 iptables 做这个判断的依据,就是查看该IP包是否有一个“0x4000”的“标志
          

        当一个外部的 client 通过 node 2 的地址访问一个 Service 的时候,node 2 上的负载均衡规则,就可能把这个 IP 包转发给一个在 node 1 上的 Pod.而当 node1上的这个Pod处理完请求之后,它就会按照这个IP包的源地址发出回复.可是,如果没有做 SNAT 操作的话,这时候,被转发来的IP包的源地址就是 client 的 IP 地址.所以此时Pod 就会直接将回复发给client.对于 client 来说,它的请求明明发给了node2,收到的回复却来自node1 这个client很可能会报错

        所以,在上图中,当IP包离开node2之后,它的源IP地址就会被SNAT改成 node2的CNI网桥地址或者 node2自己的地址.这样Pod 在处理完成之后就会先回复给node2(而不是 client)然后再由node2发送给client.这也就意味着这个Pod只知道该IP包来自于node2,而不是外部的 client

       如果Pod需要明确知道所有请求的来源情况   就必须把Service的spec.externalTrafficPolicy字段设置为local,这就保证了所有Pod通过Service收到请求之后,一定可以看到真正的,外部 client 的源地址

       这个机制的实现原理也非常简单:这时候,一台宿主机上的iptables规则,会设置为只将IP包转发给运行在这台宿主机上的 Pod.所以这时候Pod 就可以直接使用源地址将回复包发出,不需要事先进行 SNAT
         

         这就意味着如果在一台宿主机上,没有任何一个被代理的Pod存在,比如上图中的node2那么你使用node2 的IP地址访问这个Service就是无效的.此时请求会直接被DROP掉

    方式2(LoadBalancer)

           适合公有云上的kubernetes的服务

          公有云提供的Kubernetes服务里,都使用了一个叫作CloudProvider的转接层,来跟公有云本身的API进行对接.所以,在上述LoadBalancer类型的Service被提交后Kubernetes 就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端

           创建负载均衡的功能交给集群外部的系统来实现 这是和普通service的区别 普通service负载均衡的功能都是由集群内部的组件来实现的

         

     方式3(ExternalName)

         

         这种类型的Service不需要指定selector 因为响应请求的不会是集群中的Pod,而是把用户请求转发到公网中(集群外部)的某个服务器上由它进行响应

         通过Service的DNS名字访问它的时候如访问my-service.default.svc.cluster.local.那么k8s返回的就是my.database.example.com
        ExternalName类型的 Service,其实是在 kube-dns里为你添加了一条CNAME记录.这时,访问my-service.default.svc.cluster.local 就和访问 my.database.example.com 这个域名是一个效果了 
     方式4(ExternalIPs)

           Kubernetes的Service还允许你为Service分配公有IP地址

           当用户向公网(集群外的节点)中的指定的主机和端口发起请求的时候 会把请求转发到k8s由集群中的Pod对用户的请求进行响应 所以定义有selector选择相关Pod

         

        在上述 Service 中,我为它指定的 externalIPs=80.11.12.10那么此时,你就可以通过访问 80.11.12.10:80 访问到被代理的Pod了.不过,在这里Kubernetes要求externalIP必须是至少能够路由到一个Kubernetes的节点 
     

    Service总结

           在理解了Kubernetes Service 机制的工作原理之后很多与Service相关的问题,其实都可以通过分析Service在宿主机上对应的 iptables 规则(或者IPVS配置)得到解决
           Kubernetes里面的Service和DNS 机制,也都不具备强多租户能力.比如,在多租户情况下,每个租户应该拥有一套独立的 Service 规则(Service 只应该看到和代理同一个租户下的 Pod)再比如DNS,在多租户情况下,每个租户应该拥有自己的kube-dns(kube-dns 只应该为同一个租户下的 Service 和 Pod 创建 DNS Entry)
  • 相关阅读:
    Python
    Python
    Python
    #2035:人见人爱A^B
    #2030:汉字统计--统计给定文本文件中汉字的个数
    #2028:Lowest Common Multiple Plus(n个数的最小公倍数)
    幂次方的四种快速取法(不使用pow函数)
    爬楼梯:经典动态规划+递归法
    最小生成树算法【图解】:一文带你理解什么是Prim算法和Kruskal算法
    KMP算法-从头到尾彻底理解KMP
  • 原文地址:https://www.cnblogs.com/yxh168/p/12245450.html
Copyright © 2020-2023  润新知