Kubernetes Ingress 只是 Kubernetes 中的一个普通资源对象,须要一个对应的 Ingress 控制器来解析 Ingress 的规则,暴露服务到外部,好比 ingress-nginx
,本质上来讲它只是一个 Nginx Pod,而后将请求重定向到其余内部(ClusterIP)服务去,这个 Pod 自己也是经过 Kubernetes 服务暴露出去,最多见的方式是经过 LoadBalancer 来实现的。一样本文咱们但愿用一个简单清晰的概述,让你来了解 Kubernetes Ingress 背后的东西,让你更容易理解使用的 Ingress。html
咱们可使用 Ingress 来使内部服务暴露到集群外部去,它为你节省了宝贵的静态 IP,由于你不须要声明多个 LoadBalancer 服务了,这次,它还能够进行更多的额外配置。下面咱们经过一个简单的示例来对 Ingress 进行一些说明吧。python
简单 HTTP server
首先,咱们先回到容器、Kubernetes 以前的时代。nginx
以前咱们更多会使用一个(Nginx)HTTP server 来托管咱们的服务,它能够经过 HTTP 协议接收到一个特定文件路径的请求,而后在文件系统中检查这个文件路径,若是存在则就返回便可。git

例如,在 Nginx 中,咱们能够经过下面的配置来实现这个功能。github
location /folder {
root /var/www/;
index index.html;
}
除了上面提到的功能以外,咱们能够当 HTTP server 接收到请求后,将该请求重定向到另外一个服务器(意味着它做为代理)去,而后将该服务器的响应重定向到客户端去。对于客户端来讲,什么都没有改变,接收到的结果仍然仍是请求的文件(若是存在的话)。web

一样若是在 Nginx 中,重定向能够配置成下面的样子:api
location /folder {
proxy_pass http://second-nginx-server:8000;
}
这意味着 Nginx 能够从文件系统中提供文件,或者经过代理将响应重定向到其余服务器并返回它们的响应。浏览器
简单的 Kubernetes 示例
使用 ClusterIP 服务
在 Kubernetes 中部署应用后,咱们应该先去了解 Kubernetes Service 服务(前文中讲解的)。好比咱们有两个 worker 节点,有两个服务 service-nginx 和 service-python,它们指向不一样的 pods。这两个服务没有被调度到任何特定的节点上,也就是在任何节点上都有可能,以下图所示:缓存

在集群内部咱们能够经过他们的 Service 服务来请求到 Nginx pods 和 Python pods 上去,如今咱们想让这些服务也能从集群外部进行访问,按照前文提到的咱们就须要将这些服务转换为 LoadBalancer 服务。安全
使用 LoadBalancer 服务
固然使用 LoadBalancer 服务的前提是咱们的 Kubernetes 集群的托管服务商要能支持才行,若是支持咱们能够将上面的 ClusterIP 服务转换为 LoadBalancer 服务,能够建立两个外部负载均衡器,将请求重定向到咱们的节点 IP,而后重定向到内部的 ClusterIP 服务。

咱们能够看到两个 LoadBalancers 都有本身的 IP,若是咱们向 LoadBalancer 22.33.44.55
发送请求,它请被重定向到咱们的内部的 service-nginx 服务去。若是发送请求到 77.66.55.44,它将被重定向到咱们的内部的 service-python 服务。
这个确实很方便,可是要知道 IP 地址是比较稀有的,并且价格可不便宜。想象下咱们 Kubernetes 集群中不仅是两个服务,有不少的话,咱们为这些服务建立 LoadBalancers 成本是否是就成倍增长了。
那么是否有另外一种解决方案可让咱们只使用一个 LoadBalancer 就能够把请求转发给咱们的内部服务呢?咱们先经过手动(非 Kubernetes)的方式来探讨下这个问题。
手动配置 Nginx 代理服务
咱们知道 Nginx 能够做为一个代理使用,因此咱们能够很容易想到运行一个 Nginx 来代理咱们的服务。以下图所示,咱们新增了一个名为 service-nginx-proxy 的新服务,它其实是咱们惟一的一个 LoadBalancer 服务。service-nginx-proxy 仍然会指向一个或多个 Nginx-pod-endpoints(为了简单没有在图上标识),以前的另外两个服务转换为简单的 ClusterIP 服务了。

能够看到咱们只分配了一个 IP 地址为 11.22.33.44
的负载均衡器,对于不一样的 http 请求路径咱们用黄色来进行标记,他们的目标是一致的,只是包含的不一样的请求 URL。
service-nginx-proxy 服务会根据请求的 URL 来决定他们应该将请求重定向到哪一个服务去。
在上图中咱们有两个背后的服务,分别用红色和蓝色进行了标记,红色会重定向到 service-nginx 服务,蓝色重定向到 service-python 服务。对应的 Nginx 代理配置以下所示:
location /folder {
proxy_pass http://service-nginx:3001;
}
location /other {
proxy_pass http://service-python:3002;
}
只是目前咱们须要去手动配置 service-nginx-proxy 服务,好比新增了一个请求路径须要路由到其余服务去,咱们就须要去从新配置 Nginx 的配置让其生效,可是这个确实是一个可行的解决方案,只是有点麻烦而已。
而 Kubernetes Ingress 就是为了让咱们的配置更加容易、更加智能、更容易管理出现的,因此在 Kubernetes 集群中咱们会用 Ingress 来代替上面的手动配置的方式将服务暴露到集群外去。
使用 Kubernetes Ingress
如今咱们将上面手动配置代理的方式转换为 Kubernetes Ingress 的方式,以下图所示,咱们只是使用了一个预先配置好的 Nginx(Ingress),它已经为咱们作了全部的代理重定向工做,这为咱们节省了大量的手动配置工做了。

这其实就已经说明了 Kubernetes Ingress 是什么,下面让咱们来看看一些配置实例吧。
安装 Ingress 控制器
Ingress 只是 Kubernetes 的一种资源对象而已,在这个资源中咱们能够去配置咱们的服务路由规则,可是要真正去实现识别这个 Ingress 并提供代理路由功能,还须要安装一个对应的控制器才能实现。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml
使用下面的命令,能够看到安装在命名空间 ingress-nginx 中的 k8s 资源。

咱们能够看到一个正常的 LoadBalancer 服务,有一个外部 IP 和一个所属的 pod,咱们可使用命令 kubectl exec
进入该 pod,里面包含一个预配置的 Nginx 服务器。

其中的 nginx.conf
文件就包含各类代理重定向设置和其余相关配置。
Ingress 配置示例
咱们所使用的 Ingress yaml 例子能够是这样的。
# just example, not tested
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: default
name: test-ingress
spec:
rules:
- http:
paths:
- path: /folder
backend:
serviceName: service-nginx
servicePort: 3001
- http:
paths:
- path: /other
backend:
serviceName: service-python
servicePort: 3002
和其余资源对象同样,经过 kubectl create -f ingress.yaml
来建立这个资源对象便可,建立完成后这个 Ingress 对象会被上面安装的 Ingress 控制器转换为对应的 Nginx 配置。
若是你的一个内部服务,即 Ingress 应该重定向到的服务,是在不一样的命名空间里,怎么办?由于咱们定义的 Ingress 资源是命名空间级别的。在 Ingress 配置中,只能重定向到同一命名空间的服务。
若是你定义了多个 Ingress yaml 配置,那么这些配置会被一个单一的Ingress 控制器合并成一个 Nginx 配置。也就是说全部的人都在使用同一个 LoadBalancer IP。
配置 Ingress Nginx
有时候咱们须要对 Ingress Nginx 进行一些微调配置,咱们能够经过 Ingress 资源对象中的 annotations 注解来实现,好比咱们能够配置各类平时直接在 Nginx 中的配置选项。
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-connect-timeout: '30'
nginx.ingress.kubernetes.io/proxy-send-timeout: '500'
nginx.ingress.kubernetes.io/proxy-read-timeout: '500'
nginx.ingress.kubernetes.io/send-timeout: "500"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "*"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
...
此外也能够作更细粒度的规则配置,以下所示:
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'www.qikqiak.com' ) {
rewrite ^ https://qikqiak.com$request_uri permanent;
}
这些注释都将被转换成 Nginx 配置,你能够经过手动链接(kubectl exec
)到 nginx pod 中检查这些配置。
关于 ingress-nginx 更多的配置使用能够参考官方文档相关说明:
-
https://github.com/kubernetes/ingress-nginx/tree/master/docs/user-guide/nginx-configuration -
https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#lua-resty-waf
查看 ingress-nginx 日志
要排查问题,经过查看 Ingress 控制器的日志很是有帮助。

使用 Curl 测试
若是咱们想测试 Ingress 重定向规则,最好使用 curl -v [yourhost.com](http://yourhost.com)
来代替浏览器,能够避免缓存等带来的问题。
重定向规则
在本文的示例中咱们使用 /folder
和 /other/directory
等路径来重定向到不一样的服务,此外咱们也能够经过主机名来区分请求,好比将 api.myurl.com 和 site.myurl.com 重定向到不一样的内部 ClusterIP 服务去。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: api.myurl.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
- host: website.myurl.com
http:
paths:
- path: /
backend:
serviceName: service3
servicePort: 3333
SSL/HTTPS
可能咱们想让网站使用安全的 HTTPS 服务,Kubernetes Ingress 也提供了简单的 TLS 校验,这意味着它会处理全部的 SSL 通讯、解密/校验 SSL 请求,而后将这些解密后的请求发送到内部服务去。
若是你的多个内部服务使用相同(多是通配符)的 SSL 证书,这样咱们就只须要在 Ingress 上配置一次,而不须要在内部服务上去配置,Ingress 可使用配置的 TLS Kubernetes Secret 来配置 SSL 证书。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
不过须要注意的是若是你在不一样的命名空间有多个 Ingress 资源,那么你的 TLS secret 也须要在你使用的 Ingress 资源的全部命名空间中可用。
总结
这里咱们简单介绍了 Kubernetes Ingress 的原理,简单来讲:它不过是一种轻松配置 Nginx 服务器的方法,它能够将请求重定向到其余内部服务去。这为咱们节省了宝贵的静态 IP 和 LoadBalancers 资源。
另外须要注意的是还有其余的 Kubernetes Ingress 类型,它们内部没有设置 Nginx 服务,但可能使用其余代理技术,同样也能够实现上面的全部功能。
原文: https://codeburst.io/kubernetes-ingress-simply-visually-explained-d9cad44e4419
翻译: 感谢阳明老师的翻译与分享。
你可能还喜欢
点击下方图片便可阅读
本文分享自微信公众号 - 云原生生态圈(CloudNativeEcoSystem)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。