容器-11-Kubernetes实战-Ingress与Traefik

在上一篇中,通过NodePort模式,其实我们已经可以将一系列Pod暴露给集群外。但Service最多只能做好OSI 4层的负载均衡。而OSI 7层的负载均衡需要交给Ingress。
简单解释一下,2层的负载均衡就是虚拟MAC地址接收请求;3层的负载均衡就是虚拟IP地址;4层就是基于IP + 端口;7层就涉及URI等应用层。
以下文会提到的Traefik官方的一张图来说明,Ingress的作用就是根据不同的域名,正确找到对应的后台的Service:
Traefik作用
在Service接到请求后,再负责转交给Pod:
Kubernetes Service与Deployment

要使用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
2
3
4
5
6
7
8
9
10
11
12
13
piVersion: extensions/v1beta1
kind: Ingress
metadata:
name: <ingress-name>
spec:
rules:
- host: <host-name>
http:
paths:
- path: /
backend:
serviceName: <service-name>
servicePort: http

如果配置过Nginx的话就很容易理解这个配置文件了。
需要注意的是:Nginx的server_name可以是ip,但Ingress的spec.rules.host必须是一个域名格式(FQDN),不能是ip。
我们的POC项目按照这个模板配置一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: poc-ingress
spec:
rules:
- host: poc.demosite.net
http:
paths:
- path: /
backend:
serviceName: poc-web-service
servicePort: http

然后配置一个DNS指向任何一个Worker节点的ip,或修改本地的hosts,就可以访问我们的静态网站了。
如果是本机测试没有域名,可以将YAML简化为:

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

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
2
kubectl label node docker-5 node=edge
kubectl label node docker-6 node=edge

然后修改traefik-ds.yaml,将通过nodeSelector,限定Ingress Controller部署在边缘节点上:

1
2
3
4
5
6
7
8
9
10
11
spec:
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
# 中间省略
nodeSelector:
node: edge

在重新apply后,可以看到traefik-ingress-controller的Pod数量降低到了2个。
然后参考这篇部署keepalived即可:边缘节点配置

Kubernetes Edge Node Architecture

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

本文永久链接 [ https://galaxyyao.github.io/2019/06/27/容器-11-Kubernetes实战-Ingress与Traefik/ ]