Ingress

    • 节点:Kubernetes 集群中的服务器;
    • 集群:Kubernetes 管理的一组服务器集合;
    • 边界路由器:为局域网和 Internet 路由数据包的路由器,执行防火墙保护局域网络;
    • 集群网络:遵循 Kubernetes网络模型 实现集群内的通信的具体实现,比如 和 OVS
    • 服务:Kubernetes 的服务 (Service) 是使用标签选择器标识的一组 pod 。 除非另有说明,否则服务的虚拟 IP 仅可在集群内部访问。

    通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。如下图所示

    而 Ingress 就是为进入集群的请求提供路由规则的集合,如下图所示

    Ingress 可以给 service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等。为了配置这些 Ingress 规则,集群管理员需要部署一个 Ingress controller,它监听 Ingress 和 service 的变化,并根据规则配置负载均衡并提供访问入口。

    Ingress 格式

    1. kind: Ingress
    2. metadata:
    3. name: test-ingress
    4. spec:
    5. rules:
    6. - http:
    7. paths:
    8. - path: /testpath
    9. backend:
    10. serviceName: test
    11. servicePort: 80

    每个 Ingress 都需要配置 rules,目前 Kubernetes 仅支持 http 规则。上面的示例表示请求 /testpath 时转发到服务 test 的 80 端口。

    Ingress 类型

    根据 Ingress Spec 配置的不同,Ingress 可以分为以下几种类型:

    单服务 Ingress 即该 Ingress 仅指定一个没有任何规则的后端服务。

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

    路由到多服务的 Ingress 即根据请求路径的不同转发到不同的后端服务上,比如

    1. / bar s2:80

    可以通过下面的 Ingress 来定义:

    使用 kubectl create -f 创建完 ingress 后:

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

    虚拟主机 Ingress 即根据名字的不同转发到不同的后端服务上,而他们共用同一个的 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:

    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

    注:没有定义规则的后端服务称为默认后端服务,可以用来方便的处理 404 页面。

    TLS Ingress 通过 Secret 获取 TLS 私钥和证书 (名为 tls.crttls.key),来执行 TLS 终止。如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们将根据通过 SNI TLS 扩展指定的主机名(假如 Ingress controller 支持 SNI)在多个相同端口上进行复用。

    Ingress 中引用 secret:

    1. apiVersion: extensions/v1beta1
    2. kind: Ingress
    3. metadata:
    4. spec:
    5. tls:
    6. - secretName: testsecret
    7. backend:
    8. servicePort: 80

    注意,不同 Ingress controller 支持的 TLS 功能不尽相同。 请参阅有关 nginx, 或任何其他 Ingress controller 的文档,以了解 TLS 的支持情况。

    可以通过 kubectl edit ing name 的方法来更新 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

    这会弹出一个包含已有 IngressSpec yaml 文件的编辑器,修改并保存就会将其更新到 kubernetes API server,进而触发 Ingress Controller 重新配置负载均衡:

    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. ..

    更新后:

    当然,也可以通过 命令来更新,其中 new-ingress.yaml 是修改过的 Ingress yaml。

    Ingress Controller

    Ingress 正常工作需要集群中运行 Ingress Controller。Ingress Controller 与其他作为 kube-controller-manager 中的在集群创建时自动启动的 controller 成员不同,需要用户选择最适合自己集群的 Ingress Controller,或者自己实现一个。

    1. helm install stable/nginx-ingress --name nginx-ingress --set rbac.create=true

    其他 Ingress Controller 还有:

    • 提供了一个 Traefik Ingress Controller 的实践案例
    • kubernetes/ingress-nginx 提供了一个详细的 Nginx Ingress Controller 示例
    • 提供了一个用于 GCE 的 Ingress Controller 示例