• 详解K8S入口Ingerss


    1 缘起

    学习K8S的过程中,先学习使用,了解K8S正常工作需要哪些模块,
    然后,学习各个模块,
    之前,学习了K8S的Pod、Service,完成K8S内部服务部署和访问,
    当需要将服务暴露给外部(K8S之外的机器集群)调用时,需要设计一个路由分发的组件,
    匹配不同的Service,Ingerss即完成该工作的模块,官方文档
    本文围绕Ingress展开,
    帮助读者了解和学习Ingerss的设计。
    回顾知识:Pod和Service的相关文档如下:
    详解K8S的Pod
    详解K8S网络模型(包含Service讲解)

    2 Ingress

    2.1 相关术语

    序号术语描述
    1节点(Node)Kubernetes集群中的某台工作的机器
    2集群(Cluster)由Kubernetes管理运行容器应用的一组节点
    3边缘路由器(Edge router)强制防火墙策略的集群路由器,可以是由云服务商或者物理机提供的网关
    4集群网络(Cluster network)根据Kubernetes网络模型,一组逻辑或物理链路,帮助集群内通信
    5服务(Service)使用标签选择器识别一组Pod的Kubernetes服务。除非另外说明,否则假定服务只有虚拟IP才能在集群网络中路由

    2.2 是什么

    Ingress是集群中管理外部接入Service的接口(API)对象。
    Ingress可提供负载均衡、SSL终端和基于名称虚拟主机等功能。
    Ingress将外部集群的HTTP和HTTPS暴露给集群内部的Service,示意图如下图所示,
    由图可知,Ingress将集群外部的请求通过路由规则(routing rule)转发给Servcie,
    然后由Service匹配到最终的Pod。

    在这里插入图片描述

    Ingress将外部集群的HTTP和HTTPS暴露给集群内部的Service,示意图如下图所示。
    Ingress可以通过配置为Service提供可访问的URL,流量负载均衡,终端SSL/TLS以及基于名称的的虚拟主机。
    Ingress控制器提供入口功能,通常使用负载均衡器,也可以通过配置边缘路由器或其他前端辅助处理流量。
    Ingress不会暴露任何端口或协议。向Internet暴露HTTP和HTTPS以外的服务通常使用service的Type:如NodePort或LoadBalancer。

    2.3 配置Ingress

    Ingress需要apiVersion、kind、metadata和spec属性。Ingress对象的名称必须是有效的DNS子域名。
    Ingress经常使用注解配置Ingress控制器的依赖,如rewrite-target注解。不同的Ingress控制器支持不同的注解。Ingress属性spec拥有配置负载均衡或代理服务的所有信息。最重要地是包含请求的规则匹配列表。Ingress资源仅支持定向的HTTP(s)流量路由。
    如果省略ingressClassname,需要定义默认的Ingress类。
    Ingress配置最小单元如下:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: minimal-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx-example
      rules:
      - http:
          paths:
          - path: /testpath
            pathType: Prefix
            backend:
              service:
                name: test
                port:
                  number: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.4 Ingress规则

    每个HTTP规则包含如下信息:

    • 可选主机。当前例子中没有配置host,因此规则适用于通过指定IP地址入站的所有HTTP流量。如果配置host,规则适用于配置的host,如foo.bar.com。
    • 路径列表。路径关联后台服务,这些服务通过servcie.name、service.port.name或者service.port.number定义。host和path必须在负载均衡定向流量到Service前匹配请求内容,以分发流量到Service。
    • 后台服务是Service和端口名称的组合。HTTP(或HTTPS)请求到Ingress后,会将请求发送到与host和path匹配的后台服务中。
      Ingress控制器中通常配置默认的后台来服务没有匹配到path的请求。

    2.5 默认后端

    没有配置规则的Ingress将所有流量发送到某个默认的后端,.spec.defaultBackend即处理请求的后端。defaultBackend通常是Ingress控制的可选属性,Ingress资源中并未指定。如果没有指定的.spec.rules,则必须指定.spec.defaultBackend。如果没有配置defaultBackend,不符合任何规则的请求的处理由Ingress控制器决定。
    Ingress对象中没有host和path与HTTP请求相匹配,流量会被路由到默认后端。

    2.6 资源后端

    资源后端是对象引用到另一个Kubernetes资源中有相同命名空间的Ingress对象。
    资源与服务是互斥的,如果两者同时指定,会导致验证失败。资源后端通用场景是使用静态资产将数据输入到对象存储后端。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-resource-backend
    spec:
      defaultBackend:
        resource:
          apiGroup: k8s.example.com
          kind: StorageBucket
          name: static-assets
      rules:
        - http:
            paths:
              - path: /icons
                pathType: ImplementationSpecific
                backend:
                  resource:
                    apiGroup: k8s.example.com
                    kind: StorageBucket
                    name: icon-assets
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 查看Ingress
    kubectl describe ingress ingress-resource-backend
    
    • 1
    • 结果
    Name:             ingress-resource-backend
    Namespace:        default
    Address:
    Default backend:  APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets
    Rules:
      Host        Path  Backends
      ----        ----  --------
      *
                  /icons   APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets
    Annotations:  
    Events:       
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.8 路径类型

    Ingress中的每个路径需要有对应的路径类型。路径不包括具体的pathType会校验失败。
    支持的三种路径类型:

    • ImplementationSpecific:该路径类型的匹配取决于IngressClass。实现可将其视为单独的pathType,亦可以等同于Exact或Prefix路径类型。
    • Exact:精确匹配URL并且区分大小写(大小写敏感)。
    • Prefix:基于以/分割的URL路径前缀匹配。匹配区分大小写,并以路径元素为基础进行。路径元素指由/分隔符分割的路径中的标签列表。

    匹配样例:

    序号路径类型路径请求路径是否配置
    1Prefix/所有路径匹配,即只有一个/分隔符匹配所有路径
    2Prefix/foo/foo或/foo/匹配
    3Prefix/aaa/bb/aaa/bbb或/aaa/bbxyz不匹配
    4Prefix/aaa/bbb/aaa/bbb或/aaa/bbb/匹配
    5Prefix/,/aaa/aaa/ccc匹配,通过/aaa匹配,因为ccc已经使用/分隔了
    6Exact/foo/foo匹配
    7Exact/foo/foo/不匹配
    8Exact/foo//foo不匹配
    9Exact/foo/bar不匹配
    10Mixed/foo(Prefix),/foo(Exact)/foo匹配

    2.9 主机名通配符

    主机可以精确匹配(如foo.bar.com)或通配符匹配(如*.foo.com)。精确匹配需要HTTP主机头匹配主机属性。通配符匹配需要HTTP主机头与通配符规则的后缀相同。
    匹配样例:

    序号主机主机头是否配置
    *.foo.combar.foo.com匹配,后缀相同
    *.foo.combaz.bar.foo.com不匹配,通配符只覆盖单个DNS标签
    *.foo.comfoo.com不匹配,通配符只覆盖单个DNS标签

    配置样例:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-wildcard-host
    spec:
      rules:
      - host: "foo.bar.com"
        http:
          paths:
          - pathType: Prefix
            path: "/bar"
            backend:
              service:
                name: service1
                port:
                  number: 80
      - host: "*.foo.com"
        http:
          paths:
          - pathType: Prefix
            path: "/foo"
            backend:
              service:
                name: service2
                port:
                  number: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.10 Ingress类

    Ingress可以通过不同的控制器实现,配置通常也不相同。
    每个Ingress应该指定一个类,引用IngressClass的资源配置包括控制器名称(应该实现的类)。
    IngressClass配置样例,
    IngressClass的属性.spec.parameters允许引用另一个资源,为IngressClass提供相关的配置。
    指定的参数类型的使用依赖于Ingress控制器,即指定的.spec.controller。

    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      name: external-lb
    spec:
      controller: example.com/ingress-controller
      parameters:
        apiGroup: k8s.example.com
        kind: IngressParameters
        name: external-lb
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.10.1 IngressClass作用域

    IngressClass作用域依赖于Ingress控制器,可以使用参数配置为集群范围(cluster-wide)或者只配置一个命名空间。

    2.10.1.1 集群(Cluster)

    IngressClass参数的默认属性为集群范围(cluster-wide)。
    如果配置.spec.paramters属性时没有设置.spec.paramters.scope,或者配置.spec.parameters.scope为Cluster,IngressClass指向集群范围的资源。kind参数指向集群范围的API(组合apiGroup),name参数标识该API的特定集群资源。
    配置样例:

    ---
    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      name: external-lb-1
    spec:
      controller: example.com/ingress-controller
      parameters:
        # The parameters for this IngressClass are specified in a
        # ClusterIngressParameter (API group k8s.example.net) named
        # "external-config-1". This definition tells Kubernetes to
        # look for a cluster-scoped parameter resource.
        scope: Cluster
        apiGroup: k8s.example.net
        kind: ClusterIngressParameter
        name: external-config-1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    2.10.1.2 命名空间(Namespace)

    如果配置.spec.paramters属性时,将.spec.parameters.scope设定为Namespace,IngressClass指向命名空间资源。必须设置.spece.parameters的namespace属性来指定需要使用的命名空间。
    kind参数(组合apiGroup)指向命名空间API(如ConfigMap),name参数标识指定命名空间的资源。
    命名空间参数有助于集群操作员通过用于工作负载的配置代理控制(如负载均衡配置、API网关定义)。

    配置样例:

    ---
    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      name: external-lb-2
    spec:
      controller: example.com/ingress-controller
      parameters:
        # The parameters for this IngressClass are specified in an
        # IngressParameter (API group k8s.example.com) named "external-config",
        # that's in the "external-configuration" namespace.
        scope: Namespace
        apiGroup: k8s.example.com
        kind: IngressParameter
        namespace: external-configuration
        name: external-config
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    2.10.1.3 默认IngressClass

    可以为集群指定一个特定的默认IngressClass。在IngressClass资源中将ingressclass.kubernetes.io/is-default-class注解设置为true,可保证在不指定ingressClassName时使用默认的IngressClass。

    2.11 Ingress类型

    2.11.1 Ingress由单一服务支持

    现存的Kubernetes概念允许暴露单个服务,Ingress可以通过无规则的默认后端实现。
    配置样例如下:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test-ingress
    spec:
      defaultBackend:
        service:
          name: test
          port:
            number: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.11.2 简单扇出

    扇出配置将流量从一个IP地址路由到多个Service,基于HTTP URI请求,
    示意图如下图所示。
    在这里插入图片描述
    配置样例如下:

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.11.3 基于名称的虚拟主机

    基于名称的虚拟主机在相同的IP地址支持路由HTTP流量到多个主机名称,
    示意图如下图所示。

    在这里插入图片描述
    配置样例如下:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: name-virtual-host-ingress
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: service1
                port:
                  number: 80
      - host: bar.foo.com
        http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: service2
                port:
                  number: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    当创建Ingress资源时没有定义主机规则,
    可以匹配进入到Ingress控制器IP地址的任何web流量,无需基于名称的虚拟主机。
    比如,Ingress将请求first.bar.com的流量路由到service1,second.bar.com路由到service2,
    不匹配first.bar.com和second.bar.com的流量路由到service3。
    配置样例如下:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: name-virtual-host-ingress-no-third-host
    spec:
      rules:
      - host: first.bar.com
        http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: service1
                port:
                  number: 80
      - host: second.bar.com
        http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: service2
                port:
                  number: 80
      - http:
          paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: service3
                port:
                  number: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.12 TLS

    通过指定包含TLS私有密钥和认证的Secret加密Ingress。
    Ingress资源仅支持单个TLS端口:443,并假定TLS在入口点终止(到服务及Pods的流量为明文)。
    Ingress的TLS配置指定不同的主机,通过SNI TLS扩展指定的主机名在同一端口多路复用(前提是Ingress控制器支持SNI)。TLS密钥必须包含的键名:tls.crt和tls.key,用于指定TLS认证和私有密钥。
    配置样例如下:

    apiVersion: v1
    kind: Secret
    metadata:
      name: testsecret-tls
      namespace: default
    data:
      tls.crt: base64 encoded cert
      tls.key: base64 encoded key
    type: kubernetes.io/tls
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    配置密钥后,Ingress需要引用配置的密钥,Ingress配置样例如下:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: tls-example-ingress
    spec:
      tls:
      - hosts:
          - https-example.foo.com
        secretName: testsecret-tls
      rules:
      - host: https-example.foo.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.13 负载均衡

    Ingress控制器启动时会加载负载均衡策略配置应用到所有Ingress,比如负载均衡算法、后端权重方案等。
    高级的负载均衡概念Ingress尚未公开(如持久会话、动态权重)。

    2.14 更新Ingress

    将新的主机添加到Ingress,可以通过编辑资源更新:

    # 查看ingerss
    kubectl describe ingress test
    
    • 1
    • 2
    Name:             test
    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:80 (10.8.0.90:80)
    Annotations:
      nginx.ingress.kubernetes.io/rewrite-target:  /
    Events:
      Type     Reason  Age                From                     Message
      ----     ------  ----               ----                     -------
      Normal   ADD     35s                loadbalancer-controller  default/test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    修改Ingress

    # 编辑ingress
    kubectl edit ingress test
    
    • 1
    • 2

    添加service2

    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - backend:
              service:
                name: service1
                port:
                  number: 80
            path: /foo
            pathType: Prefix
      - host: bar.baz.com
        http:
          paths:
          - backend:
              service:
                name: service2
                port:
                  number: 80
            path: /foo
            pathType: Prefix
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    更新并保存文档,再查看Ingress:

    kubectl describe ingress test
    
    • 1

    完成服务添加,结果如下:

    Name:             test
    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:80 (10.8.0.90:80)
      bar.baz.com
                   /foo   service2:80 (10.8.0.91:80)
    Annotations:
      nginx.ingress.kubernetes.io/rewrite-target:  /
    Events:
      Type     Reason  Age                From                     Message
      ----     ------  ----               ----                     -------
      Normal   ADD     45s                loadbalancer-controller  default/test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3 小结

    (1)Ingress是集群中管理外部接入Service的接口(API)对象。
    (2)Ingress可提供负载均衡、SSL终端和基于名称虚拟主机等功能。
    (3)Ingress中的每个路径需要有对应的路径类型。支持的三种路径类型:ImplementationSpecific、Exact和Prefix。
    (4)Ingress可路由一个或多个Service,并且可动态更新Service路由关系。通过kubectl edit ingress ingress-name。

  • 相关阅读:
    数据安全与个人隐私:美国人的焦虑与变化
    基于DTU储油罐在线监测系统,防患于未然
    近期部分航院部分消息(主要是长长见识摘录的)
    正厚软件干货|redis key键
    【JAVA数据结构】包装类与认识泛型
    ESP8266-Arduino编程实例-BME680环境传感器驱动
    电脑文件数据恢复有哪些方法?电脑怎么恢复已删除的文件数据?
    前端架构师之01_JavaScript_Ajax
    数仓数据同步策略
    localhost知识
  • 原文地址:https://blog.csdn.net/Xin_101/article/details/126966613