在上一篇中,通过NodePort模式,其实我们已经可以将一系列Pod暴露给集群外。但Service最多只能做好OSI 4层的负载均衡。而OSI 7层的负载均衡需要交给Ingress。
简单解释一下,2层的负载均衡就是虚拟MAC地址接收请求;3层的负载均衡就是虚拟IP地址;4层就是基于IP + 端口;7层就涉及URI等应用层。
以下文会提到的Traefik官方的一张图来说明,Ingress的作用就是根据不同的域名,正确找到对应的后台的Service:
在Service接到请求后,再负责转交给Pod:
要使用Ingress需要先安装一个Ingress Controller。一般比较常用的有两个:Nginx Ingress Controller和Traefik Ingress Controller。在我做POC的过程中一开始选择Nginx Ingress Controller,但总是curl调不通,于是最终选择了Traefik。Traefik还多带了一个UI不错的后台管理admin dashboard。而Nginx的不少功能需要用Nginx Plus版的才有。虽然也很理解,毕竟Nginx也是要恰饭的。。。
需要说明一点:虽然Nginx本身可以同时担任静态网站web server和反向代理两种职责,但Nginx Ingress Controller只负责反向代理。
Ingress Controller除了这两个之外,还是有F5的、Kong的和Voyager等等。从这里就可以看到Kubernetes的一大特点:指定了方向,让各厂家和开源开发者发挥自己的特长来做实现。
1. Traefik Ingress安装
安装按照官方文档一步步做就行了。
先配置RBAC(关于RBAC我们之后详细介绍):
1 | kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml |
然后配置Ingress Controller和对应的Service,对外暴露http的80端口和admin的8080端口。
Ingress Controller有两种部署方式:Deployment和DaemonSet。DaemonSet是一种特殊的Pod:
- 在每个节点上有且仅有一个Pod实例
- 当有新Worker节点加入时,自动在新节点上创建;旧节点被删除后,上面的DaemonSet Pod会被自动回收
两种方式各有各的好处。官方文档上都有详细比较,并在最后很贴心地对选择困难症给了建议:遇事不决先用DaemonSet试试。那么作为POC我就却之不恭选择DaemonSet了。反正要吃后悔药也就是几个命令的事情。
最后部署一个Traefik Dashboard的UI。配置的时候需要注意根据自己的情况调整host域名,然后我们就能通过域名访问admin Dashboard了。
2. Ingress YAML定义
对于Ingress来说,最关键的就是定义找服务的规则:IngressRule。
下面是最简单的Ingress模板:
1 | piVersion: extensions/v1beta1 |
如果配置过Nginx的话就很容易理解这个配置文件了。
需要注意的是:Nginx的server_name可以是ip,但Ingress的spec.rules.host必须是一个域名格式(FQDN),不能是ip。
我们的POC项目按照这个模板配置一下:
1 | apiVersion: extensions/v1beta1 |
然后配置一个DNS指向任何一个Worker节点的ip,或修改本地的hosts,就可以访问我们的静态网站了。
如果是本机测试没有域名,可以将YAML简化为:
1 | apiVersion: extensions/v1beta1 |
3. Ingress Controller高可用
我们在上文使用的DNS指定节点的方式会有不少弊端。虽然我们可以给每个域名都配置所有Worker节点的ip,即Round-robin DNS方式。但Round-robin本身就不是一个故障转移方案。在Kubernetes官方的Service章节就有提到其他缺陷。
一般有两种方式:
3.1 Deployment方式部署Ingress Controller,Service类型指定为LoadBalancer
如果使用公有云,或私有服务器有自己的LoadBalancer,一般就使用该方案了。云会给每个LoadBalancer类型的Service分配公网ip地址。但公有云的LoadBalancer服务是要收费的,而自己很难部署。
3.2 DaemonSet方式在边缘节点部署Ingress Controller,外部通过虚拟ip和keepalived访问边缘节点
首先我们可以通过label命令,选定几台服务器作为边缘节点:
1 | kubectl label node docker-5 node=edge |
然后修改traefik-ds.yaml,将通过nodeSelector,限定Ingress Controller部署在边缘节点上:
1 | spec: |
在重新apply后,可以看到traefik-ingress-controller的Pod数量降低到了2个。
然后参考这篇部署keepalived即可:边缘节点配置
4. 参考资料
Kubernetes Ingress Controller的使用介绍及高可用落地 · Service Mesh|服务网格中文社区
http://www.servicemesher.com/blog/kubernetes-ingress-controller-deployment-and-ha/
Traefik Ingress Controller的安装和使用官方文档
Kubernetes - Traefik
Nginx Ingress Controller的一个范例,虽然最后没跑起来
Kubernetes Ingress with Nginx Example - Kubernetes Book
Nginx Ingress Controller的排查手册
Troubleshooting - NGINX Ingress Controller