Kubernetes集群有四种类型的服务,分别是ClusterIP、NodePort、LoadBalancer以及ExternalName。
ClusterIP类型的服务只能在集群内访问,而NodePort和LoadBalancer两种类型的服务都可以从集群外部访问。这三种服务有一个共同特点,就是理论上只能通过四层协议来访问。LoadBalancer类型的服务虽然也可以配置对应负载均衡的HTTP/HTTPS属性,但也只提供了简单的代理,无法应对复杂的七层的策略路由场景。
Ingress的存在,正是为了解决以上问题。Ingress的职责是将不同URL的请求转发给不同的服务,以实现复杂路由策略。典型的Ingress组件,是基于Nginx七层代理实现的Nginx Ingress Controller。如图11-1所示,这是一个典型的七层路由的例子。

图11-1 七层路由典型示例
访问www.b**k.com/bookinfo相关的信息需要路由到Bookinfo这个服务进行处理,而访问www.b**k.com/subscription相关的信息需要路由到Subscription这个服务进行处理。
我们需要定义Ingress模板去实现上一节中的功能。前面的内容中分别定义了Ingress的API版本、对象类型以及元数据,而具体的路由规则在Spec中指定。


上一节中的定义,实现了一个HTTP协议的站点路由。然而HTTP协议是明文在网络上传输的,容易被窃取信息。大多数情况下,我们需要部署一个安全的站点,采用HTTPS协议访问。本节将讲述如何部署安全路由。
如果是测试环境,通常只需要自签名证书即可,具体操作有以下几个步骤。
(1)使用openssl工具生成私钥和证书文件。

(2)创建Secret,并将私钥和证书存放到其中。

(3)修改Ingress模板文件,添加spec.tls配置。


创建或者更新Ingress-example后,证书就会被Ingress控制器配置到对应的七层代理中。
如果是在正式环境中,通常需要去CA申请证书,并拿到私钥文件(tls. key)和证书链文件(tls.pem),这时可以跳过上面的第1步,只执行第2步和第3步即可。
关于安全路由的配置,需要注意以下几点:
● tls.key和tls.crt字段名称不能修改。
● Secret必须和Ingress在同一个命名空间,否则证书配置会失败。
● tls.key、tls.crt存放的其实是key和crt的Base64编码文件,在Linux环境中可以用Base64命令解码对比证书信息。
有些场景下,我们需要对Ingress做更复杂的配置,例如让访问日志打印出响应时长以统计Web性能,或将URL重定向到根路径。
对于常规的Nginx来说,我们只需要修改nginx.conf文件即可。然而对Kubernetes来说,因为Nginx Ingress Controller封装了Nginx,所以我们不能直接修改Nginx的配置。
正确的做法是,通过在Ingress的编排文件中添加Annotation的方式配置局部参数,或者通过修改nginx-configuration这个ConfigMap的方式来配置全局参数。
在Ingress的使用过程中,常常会遇到一些问题,比如客户端访问偶尔报“502”或“504”错误、域名证书配置不生效、获取不到客户端真实IP地址等。
了解Ingress路由的实现原理,对于解决Ingress各种问题十分有帮助。本节将讲解Ingress是如何实现复杂的七层路由策略的。
以阿里云的Ingress组件为例,Ingress可以分为三个部分,分别是入口SLB(由nginx-ingress-lb这个Service创建)、控制器以及Nginx代理,如图11-2所示。

图11-2 基于Nginx实现的Ingress
Ingress的实现包含了两部分内容,一个是Controller,即Ingress控制器,另一个是Nginx代理。当创建一个Ingress对象的时候,控制器会作为Ingress对象和Nginx之间的翻译官,把Ingress中定义的路由配置转换成Nginx的配置。
如果Ingress定义有错误,翻译工作会失败,导致最新的规则没有办法下发到Nginx里。控制器日志和Nginx的Access/Error日志,都会汇总到Nginx Ingress Controller这个Pod的标准输出,可以从Pod的标准输出查看控制器的日志或者Nginx的访问日志。
一般情况下,如果需要查看生效的Nginx配置,我们可以登录到Nginx Ingress Controller容器里,查看配置文件/etc/nginx/nginx.conf。
值得一提的是,为了减少对Nginx配置高频率加载这样的操作,Nginx Ingress Controller引入了Lua模块。Lua模块可以协助Nginx低“成本”地更新Upstream,以避免此类操作对业务的影响。
在Ingress控制器里获取Lua配置的方法如下。
(1)进入Pod。

(2)查看配置。
