• Ingress Resources
    • What is Ingress?
    • Prerequisites(先决条件)
    • The Ingress Resource
    • Ingress controllers
    • Before you begin
    • Types of Ingress
      • Single Service Ingress
      • Simple fanout
      • Name based virtual hosting(基于名称的虚拟主机)
      • TLS
      • Loadbalancing
    • Updating an Ingress
    • Failing across availability zones(跨可用区的故障)
    • Future Work
    • Alternatives(备选方案)
    • 原文

    Ingress Resources

    术语

    在本文中,您将看到有些术语,这些术语在其他地方往往被交叉使用。这可能会导致混淆。本节试图澄清它们。

    • Node:Kubernetes集群中的单个虚拟机或物理机。
    • Cluster:一组位于互联网防火墙之后的Node,这是Kubernetes管理的主要计算资源。
    • Edge router:为集群强制执行防火墙策略的路由器。这可能是由cloud provider或物理硬件管理的网关。
    • Cluster network:一组逻辑或物理链接,可根据 Kubernetes networking model 实现集群内的通信。集群网络的示例包括诸如 flannel 的Overlay网络或诸如 OVS 的SDN网络。
    • Service:Kubernetes Service 使用Label Selector识别一组Pod。除非另有说明,否则Service假定在集群网络内仅可通过虚拟IP进行路由。

    What is Ingress?

    通常,Service和Pod的IP只能在集群网络内部访问。所有到达edge router的所有流量会被丢弃或转发到其他地方。在概念上,这可能看起来像:

    1. internet
    2. |
    3. ------------
    4. [ Services ]

    Ingress是允许入站连接到达集群Service的规则的集合。

    1. internet
    2. |
    3. [ Ingress ]
    4. --|-----|--
    5. [ Services ]

    可配置Ingress,从而提供外部可访问的URL、负载均衡流量、SSL、提供基于名称的虚拟主机等。用户通过POST Ingress资源到API Server的方式来请求Ingress。 Ingress controller 负责实现Ingress,通常使用负载均衡器,也可配置edge router或其他前端,这有助于以HA方式处理流量。

    Prerequisites(先决条件)

    在开始使用Ingress资源之前,您应该了解一些事情。 Ingress是一个Beta资源,在1.1之前的任何Kubernetes版本中都不可用。您需要一个Ingress Controller才能满足Ingress,单纯创建Ingress不起作用。

    GCE/GKE会在Master上部署一个Ingress Controller。您可以在Pod中部署任意数量的自定义Ingress Controller。您必须使用适当的类去为每个Ingress添加Annotation,如此 here 和 here 所示。

    确保您看过此Controller的 beta limitations 。在GCE/GKE以外的环境中,您需要 deploy a controller 为pod。

    The Ingress Resource

    最简单的Ingress可能如下所示:

    1. apiVersion: extensions/v1beta1
    2. kind: Ingress
    3. metadata:
    4. name: test-ingress
    5. annotations:
    6. ingress.kubernetes.io/rewrite-target: /
    7. spec:
    8. rules:
    9. - http:
    10. paths:
    11. - path: /testpath
    12. backend:
    13. serviceName: test
    14. servicePort: 80

    如果您尚未配置Ingress Controller,那么将其发送到API Server将不起作用。

    1-6行 :与所有其他Kubernetes配置一样,Ingress需要 apiVersionkindmetadata 字段。有关使用配置文件的信息,请参阅 deploying applications 、 configuring containers 、 managing resources 以及 ingress configuration rewrite 。

    7-9行 :Ingress spec 有配置负载均衡器或代理服务器所需的所有信息。 最重要的是,它包含了一个匹配所有入站请求的rule列表。 目前,Ingress资源只支持http rule。

    10-11行 :每个http rule包含以下信息:host(例如:foo.bar.com,本例中默认为*);path列表(例如:/ testpath),每个path都有关联的backend(比如test:80)。 在负载均衡器将流量导入到backend之前,host和path都必须都与入站请求的内容匹配。

    行12-14 :backend是 services doc 描述的 service:port 组合。 Ingress流量通常直接发送到与backend匹配的端点。

    全局参数 :简单起见,Ingress示例没有全局参数,要查看资源的完整定义,请阅读 API reference 。可指定全局缺省backend,在所有请求都无法与spec中path匹配的情况下,会发送给缺省backend。

    Ingress controllers

    为使Ingress资源正常工作,集群必须运行Ingress Controller。这与其他类型的Controller不同,它们通常作为kube-controller-manager 二进制文件的一部分运行,通常作为集群创建的一部分自动启动。 您需要选择最适合您集群的Ingress Controller实现,或自己实现一个。我们目前支持和维护 GCE 和 nginx Controller。

    Before you begin

    以下文档描述了通过Ingress资源暴露的一组跨平台功能。 理想情况下,所有Ingress Controller都应符合此规范,但还没有实现。 GCE和nginx Controller的文档分别 here 和 here 。确保您查看Controller的文档,以便您了解每个文档的注意事项

    Types of Ingress

    Single Service Ingress

    现有的Kubernetes概念允许您暴露单个Service(请参阅 alternatives ),但是您也可通过Ingress来暴露,通过指定不带rule的默认backend来实现。

    1. apiVersion: extensions/v1beta1
    2. kind: Ingress
    3. metadata:
    4. name: test-ingress
    5. spec:
    6. backend:
    7. serviceName: testsvc
    8. servicePort: 80

    使用 kubectl create -f创建它,即可看到:

    1. $ kubectl get ing
    2. NAME RULE BACKEND ADDRESS
    3. test-ingress - testsvc:80 107.178.254.228

    其中, 107.178.254.228是由Ingress Controller为此Ingress分配的IP。 RULE 列显示发送到IP的所有流量都被转发到在BACKEND列所列出的Kubernetes服务。

    Simple fanout

    如上文所述,kubernetes Pod的IP只能在集群网络可见,所以我们需要一些边缘组件,边缘接受Ingress流量并将其代理到正确的端点。 该组件通常是高可用的负载均衡器。 Ingress允许您将负载均衡器的数量降至最低,例如:如果你想创建类似如下的配置:

    1. foo.bar.com -> 178.91.123.132 -> / foo s1:80
    2. / bar s2:80

    那么将需要一个Ingress,例如:

    1. apiVersion: extensions/v1beta1
    2. kind: Ingress
    3. metadata:
    4. name: test
    5. annotations:
    6. ingress.kubernetes.io/rewrite-target: /
    7. spec:
    8. rules:
    9. - host: foo.bar.com
    10. http:
    11. paths:
    12. - path: /foo
    13. backend:
    14. serviceName: s1
    15. servicePort: 80
    16. - path: /bar
    17. backend:
    18. serviceName: s2
    19. servicePort: 80

    当您使用 kubectl create -f 创建Ingress时:

    1. $ kubectl get ing
    2. NAME RULE BACKEND ADDRESS
    3. test -
    4. foo.bar.com
    5. /foo s1:80
    6. /bar s2:80

    只要存在Service(s1,s2),Ingress Controller就会提供满足Ingress的特定负载均衡器的实现。完成这个步骤后,您将在Ingress的最后一列看到负载均衡器的地址。

    Name based virtual hosting(基于名称的虚拟主机)

    Name-based virtual hosts为相同IP使用多个主机名。

    1. foo.bar.com --| |-> foo.bar.com s1:80
    2. | 178.91.123.132 |
    3. bar.foo.com --| |-> bar.foo.com s2:80

    以下Ingress告诉后端负载均衡器根据 Host header 进行路由请求。

    1. apiVersion: extensions/v1beta1
    2. kind: Ingress
    3. metadata:
    4. name: test
    5. spec:
    6. rules:
    7. - host: foo.bar.com
    8. http:
    9. paths:
    10. - backend:
    11. serviceName: s1
    12. servicePort: 80
    13. - host: bar.foo.com
    14. http:
    15. paths:
    16. - backend:
    17. serviceName: s2
    18. servicePort: 80

    默认后端 :一个没有rule的Ingress,如上一节所示,所有流量都会发送到一个默认的backend。您可以使用相同的技术,通过指定一组rule和默认backend,来告诉负载均衡器找到您网站的404页面。如果您的Ingress中的所有Host都无法与请求头中的Host匹配,或者,没有path与请求的URL匹配,则流量将路由到您的默认backend。

    TLS

    您可以通过指定包含TLS私钥和证书的 secret 来加密Ingress。目前,Ingress仅支持单个TLS端口443,并假定TLS termination(TLS终止)。如果Ingress中的TLS配置部分指定了不同的host,那么它们将根据通过SNI TLS扩展指定的主机名复用同一端口(如果你提供的Ingress Controller支持SNI)。TLS secret必须包含名为 tls.crttls.key 的密钥,其中包含用于TLS的证书和私钥,例如:

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

    在Ingress中引用这个secret会告诉Ingress Controller,使用TLS加密从客户端到负载均衡器器的channel:

    1. apiVersion: extensions/v1beta1
    2. kind: Ingress
    3. metadata:
    4. name: no-rules-map
    5. spec:
    6. tls:
    7. - secretName: testsecret
    8. backend:
    9. serviceName: s1
    10. servicePort: 80

    请注意,不同Ingress Controller支持的TLS功能存在差距。请参阅有关 nginx 、 GCE 或任何其他平台特定的Ingress Controller的文档,以了解TLS在您的环境中的工作原理。

    Loadbalancing

    Ingress Controller启动时,会带上适用于所有Ingress的负载均衡策略设置,例如负载均衡算法、后端权重方案等。 更高级的负载均衡概念(例如:持续会话、动态权重)尚未通过Ingress公开。您仍然可以通过 service loadbalancer 获得这些功能。随着时间的推移,我们计划将跨平台适用的负载均衡模式提取到Ingress资源中。

    另外,尽管健康检查不直接通过Ingress暴露,但是在Kubernetes中存在parallel(并行)的概念,例如 readiness probes ,可让您实现相同的最终结果。请查看特定Controller的文档,以了解他们如何处理健康检查( nginx 、 GCE )。

    Updating an Ingress

    如果您想将新的Host添加到现有Ingress中,可通过编辑资源进行更新:

    1. $ kubectl get ing
    2. NAME RULE BACKEND ADDRESS
    3. test - 178.91.123.132
    4. foo.bar.com
    5. /foo s1:80
    6. $ kubectl edit ing test

    将会弹出一个编辑器,让你修改现有yaml,修改它,添加新的Host:

    1. spec:
    2. rules:
    3. - host: foo.bar.com
    4. http:
    5. paths:
    6. - backend:
    7. serviceName: s1
    8. servicePort: 80
    9. path: /foo
    10. - host: bar.baz.com
    11. http:
    12. paths:
    13. - backend:
    14. serviceName: s2
    15. servicePort: 80
    16. path: /foo
    17. ..

    保存yaml,就会更新API Server中的资源,这将会告诉Ingress Controller重新配置负载均衡器。

    1. $ kubectl get ing
    2. NAME RULE BACKEND ADDRESS
    3. test - 178.91.123.132
    4. foo.bar.com
    5. /foo s1:80
    6. bar.baz.com
    7. /foo s2:80

    在一个被修改过的Ingress yaml文件上,调用 kubectl replace -f 也可实现相同的效果。

    Failing across availability zones(跨可用区的故障)

    不同cloud provider之间,跨故障域的流量传播技术有所不同。有关详细信息,请查看Ingress Controller相关的文档。 有关在federated cluster中部署Ingress的详细信息,请参阅federation doc 。

    Future Work

    • 各种模式的HTTPS/TLS支持(例如:SNI、re-encryption)
    • 通过声明请求IP或主机名
    • 结合L4和L7 Ingress
    • 更多Ingress Controllers

    请追踪 L7 and Ingress proposal (L7和Ingress提案),了解有关资源演进的更多细节,以及 Ingress repository ,了解有关各种Ingress Controller演进的更多细节。

    Alternatives(备选方案)

    有多种方式暴露Service,而无需直接涉及Ingress资源:

    • 使用 Service.Type=LoadBalancer
    • 使用 Service.Type=NodePort
    • 使用 Port Proxy
    • 部署 Service loadbalancer 。这允许您在多个Service之间共享一个IP,并通过Service Annotation实现更高级的负载均衡。

    原文

    https://kubernetes.io/docs/concepts/services-networking/ingress/