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,如此 herehere 所示。

确保您看过此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 applicationsconfiguring containersmanaging 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的文档分别 herehere确保您查看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功能存在差距。请参阅有关 nginxGCE 或任何其他平台特定的Ingress Controller的文档,以了解TLS在您的环境中的工作原理。

Loadbalancing

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

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

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资源:

原文

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