Tr?fik是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。 它支持多种后台 (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, ...) 来自动化、动态的应用它的配置文件设置。
Tr?f?k 可以监听你的服务发现、管理API,并且每当你的微服务被添加、移除、杀死或更新都会被感知,并且可以自动生成它们的配置文件,指向到你服务的路由将会被直接创建出来。
如上图所示,kubernetes部署了一堆service,这里我们就可以通过在kubernetes上部署Tr?fik监听API,使用vhosts或者前缀路径配置反代:
域名api.domain.com将指向您的私有网络中微服务api
路径domain.com/web将指向您的私有网络的微服务Web
域名backoffice.domain.com将指向您的私有网络中的微服务backoffice,并在您的多个实例之间负载
让我们放大Tr?fik并查看其内部架构:
顾名思义,传入的请求在入口点结束,它们是Tr?fik的网络入口点(监听端口,SSL,流量重定向...)。
之后流量会被转发到匹配的前端。 前端定义从入口点到后端的路由。 路由是使用请求字段(Host, Path, Headers...)创建的,可以匹配或不匹配请求。
前端会将请求发送到后端。 后端可以由一台或经由负载均衡策略配置的多台服务器组成。
最后,服务器会将请求转发到私有网络中相应的微服务。
详细内容请查看官方文档:
https://docs.traefik.io/
二、Kubernetes安装Tr?fik
1.下载Tr?fik的yaml文件
# wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml # wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml # wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
2.更改DaemonSet文件中的端口
# cat traefik-ds.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: traefik-ingress-controller namespace: kube-system --- kind: DaemonSet apiVersion: extensions/v1beta1 metadata: name: traefik-ingress-controller namespace: kube-system labels: k8s-app: traefik-ingress-lb spec: template: metadata: labels: k8s-app: traefik-ingress-lb name: traefik-ingress-lb spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 60 hostNetwork: true containers: - image: 192.168.100.100/traefik/traefik:1.6.2 name: traefik-ingress-lb ports: - name: http containerPort: 80 hostPort: 80 - name: admin containerPort: 8081 securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE args: #- --api - --web.address=:8081 - --kubernetes - --logLevel=INFO --- kind: Service apiVersion: v1 metadata: name: traefik-ingress-service namespace: kube-system spec: selector: k8s-app: traefik-ingress-lb ports: - protocol: TCP port: 80 name: web - protocol: TCP port: 8081 name: admin type: NodePort
注:由于我的master节点同时也是node,而8080端口是kube-apiserver的端口,这产生了冲突,这里我将该端口改为8081端口。
同时去掉- --api选项并添加- --web.address=:8081选项。
3.更改镜像为私有镜像仓库(根据情况配置)并配置Tr?fik Web UI域名
# sed -i "s/image: traefik/image: 192.168.100.100\/traefik\/traefik:1.6.2/g" traefik-ds.yaml # sed -i "s/traefik-ui.minikube/traefik-ui.io/g" ui.yaml
4.运行yaml文件并查看
# kubectl create -f . serviceaccount "traefik-ingress-controller" created daemonset "traefik-ingress-controller" created service "traefik-ingress-service" created clusterrole "traefik-ingress-controller" created clusterrolebinding "traefik-ingress-controller" created service "traefik-web-ui" created ingress "traefik-web-ui" created # kubectl get pod -n kube-system | grep traefik traefik-ingress-controller-sjmp2 1/1 Running 0 3d traefik-ingress-controller-t5rgg 1/1 Running 0 3d traefik-ingress-controller-tltvm 1/1 Running 0 3d # kubectl exec -it traefik-ingress-controller-sjmp2 -n kube-system /traefik version Version: v1.6.2 Codename: tetedemoine Go version: go1.10.2 Built: 2018-05-22_03:19:06PM OS/Arch: linux/amd64
4.登陆Tr?fik Web UI
# kubectl get service -n kube-system | grep traefik traefik-ingress-service NodePort 10.244.46.110 <none> 80:29484/TCP,8081:13879/TCP 3d traefik-web-ui ClusterIP 10.244.87.207 <none> 80/TCP 3d # kubectl get ing -n kube-system NAME HOSTS ADDRESS PORTS AGE traefik-web-ui traefik-ui.io 80 3d
注:
80 对应服务端口,8080 对应 UI 端口
浏览器登陆http://<node_ip>:<node_port>访问Tr?fik
这里我们在客户端添加相应host来访问Tr?fik Web UI,如:
192.168.100.103 traefik-ui.io
现在我们可以使用traefik-ui.io来登陆查看
5.配置访问Prometheus
# cat prom.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: grafana namespace: monitoring ##根据情况配置namespace spec: rules: - host: prom.zhi.io ##替换为您集群默认的服务访问域名 http: paths: - path: backend: serviceName: grafana servicePort: 3000 # kubectl get ing -n monitoring NAME HOSTS ADDRESS PORTS AGE grafana prom.zhi.io 80 3d
查看Traefik Web UI
配置hosts后使用相应域名登陆Prometheus
三、配置Basic身份验证
1.使用htpasswd创建一个包含用户名和MD5密码文件
# yum -y install httpd # htpasswd -c auth admin ###创建秘钥文件auth并添加用户admin New password: Re-type new password: Adding password for user admin # cat auth admin:$apr1$h0.DZ9TF$6JN.FSka4Wdy5eUL4t1ut0
2.创建secret
# kubectl create secret generic mysecret --from-file auth --namespace=monitoring secret "mysecret" created
3.将下面的注释附加到 Ingress对象:
kubernetes.io/ingress.class: traefik ----->声明ingress后端采用traefik实现
ingress.kubernetes.io/auth-type: "basic" ----->声明认证模式为basic模式
ingress.kubernetes.io/auth-secret: "mysecret" ----->声明namespace里对应的secret
4.配置运行并确认
# cat prom.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: grafana namespace: monitoring annotations: kubernetes.io/ingress.class: traefik ingress.kubernetes.io/auth-type: "basic" ingress.kubernetes.io/auth-secret: "mysecret" spec: rules: - host: prom.zhi.io http: paths: - path: backend: serviceName: grafana servicePort: 3000 # kubectl apply -f prom.yaml ingress "grafana" configured
浏览器输入prom.zhi.io,弹出身份验证窗口,这里输入htpasswd命令创建的用户名和密码登录
输入用户名和密码并点击登录后即可进入该域名
四、Tr?fik添加TLS认证
1.使用openssl生成证书和密钥
# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=traefik-ui.io" Generating a 2048 bit RSA private key .................+++ ................................................................+++ writing new private key to 'tls.key' ----- # ls tls* tls.crt tls.key
2.创建Secret
# kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=tls.key --cert=tls.crt secret "traefik-ui-tls-cert" created # kubectl get secret -n kube-system traefik-ui-tls-cert NAME TYPE DATA AGE traefik-ui-tls-cert kubernetes.io/tls 2 1h
3.配置Entrypoints
Entrypoints是Tr?f?k的网络入口。它们可以通过以下方式来定义:
a.一个端口 (80, 443...)
b.SSL (证书, 密钥, 由受信任的CA签名的客户端证书的身份验证...)
c.重定向到其他的入口点 (重定向 HTTP 到 HTTPS)
# cat traefik.toml defaultEntryPoints = ["http","https"] insecureskipverify = true [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [[entryPoints.https.tls.certificates]] CertFile = "/ssl/tls.crt" KeyFile = "/ssl/tls.key"
注:
a.如上定义了两个入口点,http 和 https
b.http 监听 80 端口, https 监听 443 端口
c.通过提供一个证书和一个密钥在 https 中开启SSL
d.转发所有的 http 入口点请求到 https 入口点
e.insecureSkipVerify :
如果设置为true,则后端将接受无效的SSL证书。
这将禁用中间人×××的检测,因此只能用于安全的后端网络。
由于这里我希望traefik能代理Kubernetes dashboard(启用了https),所以启用了该选项
4.创建ConfigMap
# kubectl -n kube-system create configmap traefik --from-file=traefik.toml configmap "traefik" created # kubectl get configmap -n kube-system traefik NAME DATA AGE traefik 1 1h # kubectl get configmap -n kube-system traefik -o yaml apiVersion: v1 data: traefik.toml: |+ defaultEntryPoints = ["http","https"] insecureskipverify = true [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [[entryPoints.https.tls.certificates]] certFile = "/ssl/tls.crt" keyFile = "/ssl/tls.key" kind: ConfigMap metadata: creationTimestamp: 2018-06-04T05:55:44Z name: traefik namespace: kube-system resourceVersion: "10549957" selfLink: /api/v1/namespaces/kube-system/configmaps/traefik uid: eb9b845a-67bb-11e8-b7ff-000c297aff5d
5.配置DaemonSet
# cat traefik-ds.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: traefik-ingress-controller namespace: kube-system --- kind: DaemonSet apiVersion: extensions/v1beta1 metadata: name: traefik-ingress-controller namespace: kube-system labels: k8s-app: traefik-ingress-lb spec: template: metadata: labels: k8s-app: traefik-ingress-lb name: traefik-ingress-lb spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 60 hostNetwork: true volumes: - name: ssl secret: secretName: traefik-ui-tls-cert - name: config configMap: name: traefik containers: - image: 192.168.100.100/traefik/traefik:1.6.2 name: traefik-ingress-lb volumeMounts: - mountPath: "/ssl" name: "ssl" - mountPath: "/config" name: "config" ports: - name: http containerPort: 80 hostPort: 80 - name: https containerPort: 443 hostPort: 443 - name: admin containerPort: 8081 securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE args: #- --api - --configfile=/config/traefik.toml - --web.address=:8081 - --kubernetes - --logLevel=INFO --- kind: Service apiVersion: v1 metadata: name: traefik-ingress-service namespace: kube-system spec: selector: k8s-app: traefik-ingress-lb ports: - protocol: TCP port: 80 name: web - protocol: TCP port: 8081 name: admin type: NodePort # kubectl create -f traefik-ds.yaml serviceaccount "traefik-ingress-controller" created daemonset "traefik-ingress-controller" created service "traefik-ingress-service" created
6.配置UI
# cat ui.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: 8081 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: traefik-web-ui namespace: kube-system annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: traefik-ui.io http: paths: - path: / backend: serviceName: traefik-web-ui servicePort: web tls: - secretName: traefik-ui-tls-cert # kubectl create -f ui.yaml service "traefik-web-ui" created ingress "traefik-web-ui" created # kubectl get ing -n kube-system traefik-web-ui NAME HOSTS ADDRESS PORTS AGE traefik-web-ui traefik-ui.io 80, 443 1h
7.进行测试
浏览器输入traefik-ui.io会自动跳转至https://traefik-ui.io
浏览器输入prom.zhi.io自动跳转至https://prom.zhi.io,输入用户名、密码即可进入
8.配置traefik代理kubernetes dashboard
a.配置并运行ingress
# cat k8s.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: kubernetes-dashboard namespace: kube-system annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: "k8s.zhi.io" http: paths: - backend: serviceName: kubernetes-dashboard servicePort: 443 # kubectl create -f k8s.yaml ingress "kubernetes-dashboard" created # kubectl -n kube-system get ing kubernetes-dashboard NAME HOSTS ADDRESS PORTS AGE kubernetes-dashboard k8s.zhi.io 80 6m
b.进行测试
注:
a.在配置TLS中我参考了该篇博文:https://www.cnblogs.com/ericnie/p/8856339.html
b.在配置中可参考官方文档:https://docs.traefik.io
原文地址:http://blog.51cto.com/wangzhijian/2125520