# Kubernetes 1.18 中 Ingress 的增强

作者：[Rob Scott (Google)](https://www.linkedin.com/in/robertjscott1) [Christopher M Luciano (IBM)](https://www.linkedin.com/in/cmluciano)

原文：[Improvements to the Ingress API in Kubernetes 1.18](https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/)

Kubernetes 的 Ingress API 是大量 Ingress 控制器的基础，它们通过这一 API，用方便强大的方式为 Kubernetes 提供入站流量的支持。在 Kubernetes 1.18 中，这个 API 有了三个显著的变化：

- 新的 `pathType` 字段可以用来匹配 Ingress 路径。
- `IngressClass` 资源能够指定控制器实现 Ingress 的方法。
- 主机名中可以使用通配符。

## 使用 Path Type 改进路径匹配

Path Type 的新概念让用户可以指定路径的匹配方式，目前有三种：

- `ImplementationSpecific`（缺省）：这种匹配方式的行为取决于 `IngressClass` 控制器的实现。
- `Extract`：以区分大小写的方式精确匹配整个 URL 路径。
- `Prefix`：区分大消息，根据以 `/` 分割的 URL 元素进行前缀匹配。

## 使用 Ingress Class 扩展配置

Ingress 资源的设计初衷就是易用性，尝试使用简单的字段为所有应用提供支持。随着应用场景的不断增加，为了适应更广泛的需求，越来越多的 Ingress 控制器要靠大量的自定义注解来完成更复杂的配置。`IngressClass` 资源提供了一种替换部分注解的思路。

每个 `IngressClass` 中都指明了用于实现 Ingress 的控制器类型，并且可以引用自定义资源来使用更多参数。

~~~yaml
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
  name: external-lb
spec:
  controller: example.com/ingress-controller
  parameters:
    apiGroup: k8s.example.com/v1alpha
    kind: IngressParameters
    name: external-lb
~~~

### 指定 Ingess 的 Class

Ingress 规范中加入了 `ingressClassName` 字段，用来指定实现这个 Ingress 资源的的 `IngressClass`。

### 淘汰 Ingress 注解

在 1.18 加入 `IngressClass` 之前，需要在 Ingess 资源中使用 `kubernetes.io/ingress.class` 注解来指定 Ingress 控制器。在没有官方定义的情况下，这个注解被大量的 Ingress 控制器所支持。现在是时候淘汰他了。

### 设置缺省的 IngressClass

可以使用 `ingressclass.kubernetes.io/is-default-class` 注解，将其设置为 `True`，就代表所在的 `IngressClass` 为缺省控制器。没有显示指定 `IngressClassName` 的新的 Ingress 资源都会使用该控制器。

## 主机名通配符

很多 Ingress 控制器都支持通配符，例如 `*.foo.com` 可以匹配 `app1.foo.com`，但是直到目前为止，规范还是假设使用完全匹配的 FQDN。主机名现在也可以使用通配符了。

|Host|Host Header|匹配?|
|---|---|---|
|`*.foo.com`|`*.foo.com`|根据后缀匹配|
|`*.foo.com`|`*.foo.com`|不匹配，通配符只能对应一个 DNS 项|
|`*.foo.com`|`foo.com`|不匹配，通配符只能对应一个 DNS 项|

## 总结一下

新的 Ingress 功能扩展了配置能力，下面是一个例子，其中用到了上面提到的三个新特性：

~~~yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  ingressClassName: external-lb
  rules:
  - host: *.example.com
    http:
      paths:
      - path: /example
        pathType: Prefix
        backend:
          serviceName: example-service
          servicePort: 80
~~~

### Ingress 控制器支持

这个功能是 Kubernetes 1.18 中新增的，因此各种控制器都需要一段时间才能提供支持。请关注相关产品的官方文档。

## Ingress 的未来

Ingress API 将在 1.19 进入稳定阶段。它会持续使用简单的方式为 Kubernetes 入站流量提供支持。这个 API 的设计重心就在于轻量和简单，但是更好的配置能力和更广泛的案例支持也是一个持续的努力方向。

目前还在开发一组高配置能力的 API。被称为 `Service API` 的新 API 会提供一种 Ingress 的替代方案。它的存在目的不是替代 Ingress，而是提供一种更具配置能力的新方案。请查看 Github 上的 [Service API](http://github.com/kubernetes-sigs/service-apis) 项目。
