本节内容:前端
traefik 是一个前端负载均衡器,对于微服务架构尤为是 kubernetes 等编排工具具备良好的支持;同 nginx 等相比,traefik 可以自动感知后端容器变化,从而实现自动服务发现。node
因为微服务架构以及 Docker 技术和 kubernetes 编排工具最近几年才开始逐渐流行,因此一开始的反向代理服务器好比 nginx、apache 并未提供其支持,毕竟他们也不是先知;因此才会出现 Ingress Controller 这种东西来作 kubernetes 和前端负载均衡器如 nginx 之间作衔接;即 Ingress Controller 的存在就是为了能跟 kubernetes 交互,又能写 nginx 配置,还能 reload 它,这是一种折中方案;而 traefik 天生就是提供了对 kubernetes 的支持,也就是说 traefik 自己就能跟 kubernetes API 交互,感知后端变化,所以能够得知: 在使用 traefik 时,Ingress Controller 已经没什么用了,总体架构以下:nginx
部署两个服务nginx1-7和nginx1-8,后面用Traefik去负载这两个服务:web
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx1-7
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx1-7-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx1-7
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: my-nginx
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx1-8
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx1-8-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx1-8
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
运行两个服务:apache
[root@node1 nginx_ingress]# kubectl create -f nginx1-7.yaml service "frontend" created deployment "nginx1-7-deployment" created [root@node1 nginx_ingress]# kubectl create -f nginx1-8.yaml service "my-nginx" created deployment "nginx1-8-deployment" created
我这里部署的是1.6.0集群,开启了RBAC,受权须要使用角色和绑定角色。vim
[root@node1 traefik]# pwd
/opt/traefik
[root@node1 traefik]# vim ingress-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: ingress
subjects:
- kind: ServiceAccount
name: ingress
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
[root@node1 traefik]# pwd
/opt/traefik
[root@node1 traefik]# vim traefik-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: traefik-ingress-lb
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
terminationGracePeriodSeconds: 60
hostNetwork: true
restartPolicy: Always
serviceAccountName: ingress
containers:
- image: traefik
name: traefik-ingress-lb
resources:
limits:
cpu: 200m
memory: 30Mi
requests:
cpu: 100m
memory: 20Mi
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8580
hostPort: 8580
args:
- --web
- --web.address=:8580
- --kubernetes
其中 traefik 监听 node 的 80 和 8580 端口,80 提供正常服务,8580 是其自带的 UI 界面,本来默认是 8080,由于环境里端口冲突了,因此这里临时改一下。后端
【注意】:这里用的是Deploy类型,没有限定该pod运行在哪一个主机上。api
[root@node1 traefik]# cat traefik.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-ingress
namespace: default
spec:
rules:
- host: traefik.nginx.io
http:
paths:
- path: /
backend:
serviceName: my-nginx
servicePort: 80
- host: traefik.frontend.io
http:
paths:
- path: /
backend:
serviceName: frontend
servicePort: 80
其中的backend中要配置default namespace中启动的service名字,若是你没有配置namespace名字,默认使用default namespace,若是你在其余namespace中建立服务想要暴露到kubernetes集群外部,能够建立新的ingress.yaml文件,同时在文件中指定该namespace,其余配置与上面的文件格式相同。path就是URL地址后的路径,如traefik.frontend.io/path,service将会接受path这个路径,host最好使用service-name.filed1.filed2.domain-name这种相似主机名称的命名方式,方便区分服务。浏览器
根据实际环境中部署的service的名字和端口自行修改,有新service增长时,修改该文件后可使用kubectl replace -f traefik.yaml来更新。bash
traefik 自己还提供了一套 UI 供咱们使用,其一样以 Ingress 方式暴露,只须要建立一下便可。
[root@node1 traefik]# cat traefik-ui-service.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- name: web
port: 80
targetPort: 8580
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
rules:
- host: traefik-ui.local
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
最后一块儿建立:
[root@node1 traefik]# kubectl create -f . serviceaccount "ingress" created clusterrolebinding "ingress" created deployment "traefik-ingress-lb" created service "traefik-web-ui" created ingress "traefik-web-ui" created ingress "traefik-ingress" created
查看traefik pod被分配到了哪台主机上:
[root@node1 traefik]# kubectl get pods -n kube-system -l k8s-app=traefik-ingress-lb -o wide NAME READY STATUS RESTARTS AGE IP NODE traefik-ingress-lb-4237248072-1dg9n 1/1 Running 0 2m 172.16.7.152 172.16.7.152
浏览器输入http://172.16.7.152:8580/,将能够看到dashboard。
左侧黄色部分部分列出的是全部的rule,右侧绿色部分是全部的backend。
在Kubernetes集群的任意一个节点上执行。假如如今我要访问nginx的"/"路径。
curl -H Host:traefik.nginx.io http://172.16.7.152/
若是须要在kubernetes集群之外访问就须要设置DNS,或者修改本机的hosts文件。
172.16.7.152 traefik.nginx.io 172.16.7.152 traefik.frontend.io
全部访问这些地址的流量都会发送给172.16.7.152这台主机,就是咱们启动traefik的主机。
Traefik会解析http请求header里的Host参数将流量转发给Ingress配置里的相应service。
修改hosts后就就能够在kubernetes集群外访问以上两个service。
关于健康检查,测试可使用 kubernetes 的 Liveness Probe 实现,若是 Liveness Probe检查失败,则 traefik 会自动移除该 pod。
【示例】:咱们定义一个 test-health 的 deployment,健康检查方式是 cat /tmp/health,容器启动 2 分钟后会删掉这个文件,模拟健康检查失败。
test-health的deployment:
[root@node1 traefik]# cat test-health-deploy.yaml
apiVersion: v1
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: test
namespace: default
labels:
test: alpine
spec:
replicas: 1
selector:
matchLabels:
test: alpine
template:
metadata:
labels:
test: alpine
name: test
spec:
containers:
- image: mritd/alpine:3.4
name: alpine
resources:
limits:
cpu: 200m
memory: 30Mi
requests:
cpu: 100m
memory: 20Mi
ports:
- name: http
containerPort: 80
args:
command:
- "bash"
- "-c"
- "echo ok > /tmp/health;sleep 120;rm -f /tmp/health"
livenessProbe:
exec:
command:
- cat
- /tmp/health
initialDelaySeconds: 20
test-health 的 service:
[root@node1 traefik]# vim test-health-service.yaml
apiVersion: v1
kind: Service
metadata:
name: test
labels:
name: test
spec:
ports:
- port: 8123
targetPort: 80
selector:
name: test
test-health的 Ingress:
[root@node1 traefik]# vim test-health-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: test.com
http:
paths:
- path: /
backend:
serviceName: test
servicePort: 8123
所有建立好之后,进入 traefik ui 界面,能够观察到每隔 2 分钟健康检查失败后,kubernetes 重建 pod,同时 traefik 会从后端列表中移除这个 pod。