• kube-proxy 原理


    kube-proxy & service必要说明

    kube-proxy其实就是管理service的访问入口,包括集群内Pod到Service的访问和集群外访问service。 kube-proxy管理sevice的Endpoints,该service对外暴露一个Virtual IP,也成为Cluster IP, 集群内通过访问这个Cluster IP:Port就能访问到集群内对应的serivce下的Pod。 service是通过Selector选择的一组Pods的服务抽象,其实就是一个微服务,提供了服务的LB和反向代理的能力,而kube-proxy的主要作用就是负责service的实现。 service另外一个重要作用是,一个服务后端的Pods可能会随着生存灭亡而发生IP的改变,service的出现,给服务提供了一个固定的IP,而无视后端Endpoint的变化。

    暴露服务
    1、ClusterIP:这是k8s默认的ServiceType。通过集群内的ClusterIP在内部发布服务。

    apiVersion: v1
    kind: Service
    metadata:
      name: service-python
    spec:
      ports:
      - port: 3000
        protocol: TCP
        targetPort: 443
      selector:
        run: pod-python
      type: ClusterIP
    

    使用 kuebctl get svc :

    类型为ClusterIP的service,这个service有一个Cluster-IP,其实就一个VIP。具体实现原理依靠kubeproxy组件,通过iptables或是ipvs实现。这种类型的service 只能在集群内访问。

    2、NodePort:这种方式是常用的,用来对集群外暴露Service,你可以通过访问集群内的每个NodeIP:NodePort的方式,访问到对应Service后端的Endpoint。

    apiVersion: v1
    kind: Service
    metadata:
      name: service-python
    spec:
      ports:
      - port: 3000
        protocol: TCP
        targetPort: 443
        nodePort: 30080
      selector:
        run: pod-python
      type: NodePort
    

    使用 kuebctl get svc :

    此时我们可以通过http://4.4.4.1:30080http://4.4.4.2:30080 对pod-python访问。该端口有一定的范围,比如默认Kubernetes 控制平面将在--service-node-port-range标志指定的范围内分配端口(默认值:30000-32767)。

    3、LoadBalancer: 这也是用来对集群外暴露服务的,不同的是这需要Cloud Provider的支持,比如AWS等。 ExternalName:这个也是在集群内发布服务用的,需要借助KubeDNS(version >= 1.7)的支持,就是用KubeDNS将该service和ExternalName做一个Map,KubeDNS返回一个CNAME记录。

    apiVersion: v1
    kind: Service
    metadata:
      name: service-python
    spec:
      ports:
      - port: 3000
        protocol: TCP
        targetPort: 443
        nodePort: 30080
      selector:
        run: pod-python
      type: LoadBalancer
    

    使用 kuebctl get svc :

    可以看到external-ip。我们就可以通过该ip来访问了。

    4、ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理被创建。只有k8s1.7版本或者更高版本的kube-dns才支持

    kind: Service
    apiVersion: v1
    metadata:
      name: service-python
    spec:
      ports:
      - port: 3000
        protocol: TCP
        targetPort: 443
      type: ExternalName
      externalName: remote.server.url.com
    

    当查找主机 service-python.default.svc.cluster.local时,集群DNS服务返回CNAME记录,其值为my.database.example.com。 访问service-python的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发。

    kube-proxy转发的三种模式

    Kubernetes以Pod作为应用部署的最小单位。kubernetes会根据Pod的声明对其进行调度,包括创建、销毁、迁移、水平伸缩等,因此Pod 的IP地址不是固定的,不方便直接采用Pod IP对服务进行访问。Kube-proxy是一个运行在每个节点上的go应用程序。kube-proxy在转发时主要有两种模式Userspace和Iptables,另一种不经常用:IPVS模式

    1、userspace 模式 (userspace是在用户空间,通过kuber-proxy实现LB的代理服务。)
    该模式下kube-proxy会为每一个Service创建一个监听端口。发向Cluster IP的请求被Iptables规则重定向到Kube-proxy监听的端口上,Kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。
    该模式下,Kube-proxy充当了一个四层Load balancer的角色。由于kube-proxy运行在userspace中,在进行转发处理时会增加两次内核和用户空间之间的数据拷贝,效率较另外两种模式低一些;好处是当后端的Pod不可用时,kube-proxy可以重试其他Pod。

    2、iptables 模式 (iptables的方式则是利用了linux的iptables的nat转发进行实现。)
    为了避免增加内核和用户空间的数据拷贝操作,提高转发效率,Kube-proxy提供了iptables模式。在该模式下,Kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向Cluster IP的请求重定向到一个Pod IP。
    该模式下Kube-proxy不承担四层代理的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。

    3、ipvs 模式 (ipvs 的设计就是用来为大规模服务进行负载均衡的)
    该模式和iptables类似,kube-proxy监控Pod的变化并创建相应的ipvs rules。ipvs也是在kernel模式下通过netfilter实现的,但采用了hash table来存储规则,因此在规则较多的情况下,Ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。如果要设置kube-proxy为ipvs模式,必须在操作系统中安装IPVS内核模块。

    IPVS负载均衡方式:
    NAT
    TUN
    DR

    k8s服务发现

    • 环境变量: 当你创建一个Pod的时候,kubelet会在该Pod中注入集群内所有Service的相关环境变量。需要注意的是,要想一个Pod中注入某个Service的环境变量,则必须Service要先比该Pod创建。这一点,几乎使得这种方式进行服务发现不可用。

    • DNS:这也是k8s官方强烈推荐的方式。可以通过cluster add-on的方式轻松的创建KubeDNS来对集群内的Service进行服务发现。

    每创建一个service,需要定义三个变量:clusterIP port targetPort nodePort

    • clusterIP + port是内部pod访问service用的,随即分配

    • targetPort是容器的port

    • nodePort是外部访问service对应的后端pod用的,任何以节点的nodePort都可以访问到

  • 相关阅读:
    一提黄金肯定就是西方的货币史
    封装QtCore(在非Qt项目里使用QString,QJson,QFileInfo,QFile等类)
    Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)
    MAC 设置环境变量path的几种方法
    深入Qt 学习 -- 反射机制(比较简单清楚)
    排序
    寄存器,cache、伙伴系统、内存碎片、段式页式存储管理
    NET Core项目
    消息队列
    RedisHelper
  • 原文地址:https://www.cnblogs.com/lfl17718347843/p/14537309.html
Copyright © 2020-2023  润新知