Loading

Kubernetes:Ingress

概述

在集群外部,我们可以通过NodePort类型的ServiceLoadBalancer类型的Service来访问集群内部的Pod。由于它们的实现均基于IP地址和端口并通常使用TCP协议,因此属于四层网络模型。

Ingress则基于七层网络模型,可以向集群外部提供可访问的URL并将发往Ingress负载均衡器的外部HTTP或HTTPS请求转发到集群内部的Service。一个将所有流量都发送到同一Service下Pod的简单Ingress示意图如下:

demo.001.jpeg.001

如图所示,集群外的客户端向Ingress负载均衡器发送HTTP(s)请求,流量将被转发到节点的80(443)端口上。同时,集群内部的Ingress对象监听节点的80(443)端口,因此流量将被其接收。Ingress对象将请求的URL和目标主机名与其配置的规则进行匹配,并将流量转发到对应的Service。最后由Service将流量转发到后端的Pod。

通常由Ingress Controller负责创建Ingress负载均衡器,因此在创建Ingress对象之前,集群中必须拥有Ingress Controller。Kubernetes目前支持和维护AWSGCEnginx三种Ingress Controller。

配置

一个最简单的Ingress对象配置如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress                                # 必须是合法的DNS子域名名称
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /      # 注解的配置取决于Ingress Controller
spec:
rules:
- http:
    paths:
    - path: /testpath
    pathType: Prefix
    backend:
        service:
        name: test
        port:
            number: 80

Ingress对象的spec.rules字段中规定了所有传入请求(incoming request)应匹配的规则列表,且仅支持转发HTTP或HTTPS流量的规则。每个HTTP(s)规则都应包含以下信息:

  • host:可使用通配符来指定请求的目标主机名格式。若未指定,则该规则适用于指向Ingress IP地址的所有入站HTTP流量;
  • paths:路径列表,其中的每个路径都有一个与之关联的后端(backend);
  • pathType:每个路径必须指定其类型,Kubernetes中支持的类型有以下三种:
    • ImplementationSpecific:匹配规则取决于IngressClass,可以将其视为单独的pathType或与PrefixExact路径类型相同。
    • Exact:精确匹配URL路径,且区分大小写;
    • Prefix:根据以/分隔的URL路径前缀进行匹配,且区分大小写。如path字段值为/aaa/bbb,则请求路径/aaa/bbb/ccc与之匹配,而/aaa/bbbccc不匹配。
  • backend:由service.nameservice.port.number(或service.port.name)定义的Service对象,只有从与规则匹配的hostpath发出的入站请求才会被Ingress转发到后段的Service中。通常在Ingress Controller中会配置defaultBackend(默认后端)字段,以处理任何不匹配规则列表的传入请求。

另外,backend还可以是一个对象引用(ObjectRef),指向Ingress对象所处Namespace下的另一个Kubernetes资源。此时配置中的字段变为backend.resource,其常见用法是将入站数据通过Ingress导入到存放静态资产(static assets)的对象存储中:

...
rules:
- http:
    paths:
        - path: /icons
        pathType: ImplementationSpecific
        backend:
            resource:                       # resource与service的配置互斥,若二者均被设置会无法通过检查
            apiGroup: k8s.example.com
            kind: StorageBucket
            name: icon-assets

IngressClass

Ingress可以由不同的Ingress Controller创建,通常使用不同的配置。 每个Ingress应当指定一个类,即对IngressClass资源的引用。

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: external-lb
spec:
  controller: example.com/ingress-controller    # 实现IngressClass的Controller名称
  parameters:                                   # 可选字段,为IngressClass引用的额外配置
    apiGroup: k8s.example.com
    kind: IngressParameters
    name: external-lb

根据请求的URI路由

配置扇出(Fanout)可以根据HTTP(S)请求的URI,将来自同一IP地址的流量路由到多个后端Service。我们可以配置以下Ingress完成这一效果:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 4200
      - path: /bar
        pathType: Prefix
        backend:
          service:
            name: service2
            port:
              number: 8080

查看已创建的Ingress配置,可以在Address字段中看到Ingress负载均衡器的IP地址:

kubectl describe ingress simple-fanout-example

Name:             simple-fanout-example
Namespace:        default
Address:          178.91.123.132
Default backend:  default-http-backend:80 (10.8.2.3:8080)
Rules:
  Host         Path  Backends
  ----         ----  --------
  foo.bar.com
               /foo   service1:4200 (10.8.0.90:4200)
               /bar   service2:8080 (10.8.0.91:8080)
Annotations:
  nginx.ingress.kubernetes.io/rewrite-target:  /
Events:
  Type     Reason  Age                From                     Message
  ----     ------  ----               ----                     -------
  Normal   ADD     22s                loadbalancer-controller  default/test

该Ingress处理入站请求的示意图如下:

195698510203044522

根据请求的目标主机名路由

配置Ingress实现将指向同一IP地址、不同主机名的HTTP(S)请求的流量路由到不同的多个后端Service,不过前提条件是已将目标主机域名解析为Ingress的IP地址。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: name-virtual-host-ingress-no-third-host
spec:
  rules:
  - host: first.bar.com                        # 指向主机名first.bar.com的请求将被转发到service1
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: service1
            port:
              number: 80
  - host: second.bar.com                       # 指向主机名second.bar.com的请求将被转发到service2
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: service2
            port:
              number: 80
  - http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: service3                     # 未指定主机名但指向Ingress IP的请求将被转发到servic3
            port:
              number: 80

该Ingress处理入站请求的示意图如下:

235255507323325313

posted @ 2021-03-12 00:57  koktlzz  阅读(407)  评论(0编辑  收藏  举报