Service代理模式分类

Service的概念

k8s service定义了这样一个抽象:一个Pod的逻辑文组,一个可以访问它们的策略-----通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector

Service能够提供负载均衡的能力,但是在使用上有以下限制:

  ·只提供4层负载均衡能力,而没有七层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。

Service的类型

Service在k8s中有以下四种类型

  ·ClusterIP:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP

  ·NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort来访问该服务

  ·LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到<NodeIP>:NodePort

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

 

 

 VIP和Service代理

在k8s集群中,每个Node运行一个kube-proxy进程。kube-proxy负责为Service实现了一个VIP(虚拟IP)的形式,而不是ExternalName的形式。在k8s v1.0版本,代理完全在userspace。在k8s1.1版本,新增了iptables代理,但并不是默认的运行模式。从k8s v1.2起,默认就是iptables代理。在k8s v1.8.0-beta.0中,添加了ipvs代理

在k8s 1.14版本开始默认使用ipvs代理

在k8s v1.0版本,Service是4层(TCP/UDP over IP)概念。在K8S v1.1版本,新增了Ingress API(beta版),用来表示七层(HTTP)服务

代理模式的分类

Ⅰ、userspace代理模式

 

 

 Ⅱ、iptables代理模式

 

Ⅲ、ipvs模式

这种模式,kube-proxy会监视Kubernetes Service对象和Endpoints,调用netlink接口以响应地创建ipvs规则并定期与Kubernetes Service对象和Endpoints对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将被重定向到其中一个后端Pod

与iptables类似,ipvs与netfilter的hook功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着ipvs可以更快地重定向流量,并且在同步代理规则时具有更好地性能。此外,ipvs为负载均衡算法提供了更多选项,例如:

  ·rr:轮询调度

  ·lc:最小连接数

  ·dh:目标哈希

  ·sh:源哈希

  ·sed:最短期望延迟

  ·nq:不排队调度

 

 ClusterIP

clusterIP主要在每个node节点使用ipvs(如果使用iptables那就是iptables),将发向clusterIP对应端口地数据,转发到kube-proxy中,然后kube-proxy自己内部实现由负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据抓发给对应的pod的地址和端口

 

为了实现图上的功能,主要需要以下几个组件的协同工作:

  ·apiserver用户通过kubelet命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储到etcd中

  ·kube-proxy kubernetes的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的ipvs(iptables)规则中

  ·ipvs(iptables)使用NAT等基数将virtualIP的流量转至endpoint中

 创建myapp-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: stabel
  template:
    metadata:
      labels:
        app: myapp
        release: stabel
        env: test
    spec:
      containers:
      - name: myapp
        image: wangyanglinux/myapp:v2
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

创建Service信息

vim myapp-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: stabel
  ports:
  - name: http
    port: 80
    targetPort: 80

 

 

Headless Service

有时不需要或不想要负载均衡,以及单独的Service IP。遇到这类情况,可以通过指定ClusterIP(spec.clusterIP)的值为“None”来创建Headless Service。这类Service并不会分配Cluster IP,kube-proxy不会处理它们,而且平台也不会为他们进行负载均衡和路由

vim myapp-svc-headless.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  selector:
    app: myapp
  clusterIP: "None"
  ports:
  - port: 80
    targetPort: 80

 

 

 NodePort

nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步到给对应的pod

vim myapp-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: default
spec:
  type: NodePort
  selector:
    app: myapp
    release: stabel
  ports:
  - port: 80
    targetPort: 80

LoadBalancer

loadBalancer和nodePort其实是同一种方式,区别在于loadBalancer比nodePort多了一步,就是可以调用cloud provider去创建LB来向节点导流

ExternalName

这种类型的Service通过返回CNAME和它的值,可以将服务器映射到externameName字段的内容(例如:hub.atguigu.com)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。

vim externalname.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-service-1
  namespace: default
spec:
  type: ExternalName
  externalName: www.baidu.com

 

 

posted @ 2019-12-11 10:42  BachrRR  阅读(906)  评论(0)    收藏  举报