1、簡介html
Træfik是一個爲了讓部署微服務更加便捷而誕生的現代HTTP反向代理、負載均衡工具。 它支持多種後臺 (Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, ...) 來自動化、動態的應用它的配置文件設置。前端
Træfɪk 能夠監聽你的服務發現、管理API,而且每當你的微服務被添加、移除、殺死或更新都會被感知,而且能夠自動生成它們的配置文件,指向到你服務的路由將會被直接建立出來。node
如上圖所示,kubernetes部署了一堆service,這裏咱們就能夠經過在kubernetes上部署Træfik監聽API,使用vhosts或者前綴路徑配置反代:linux
域名api.domain.com將指向您的私有網絡中微服務apigit
路徑domain.com/web將指向您的私有網絡的微服務Webgithub
域名backoffice.domain.com將指向您的私有網絡中的微服務backoffice,並在您的多個實例之間負載web
讓咱們放大Træfik並查看其內部架構:後端
顧名思義,傳入的請求在入口點結束,它們是Træfik的網絡入口點(監聽端口,SSL,流量重定向...)。api
以後流量會被轉發到匹配的前端。 前端定義從入口點到後端的路由。 路由是使用請求字段(Host, Path, Headers...)建立的,能夠匹配或不匹配請求。瀏覽器
前端會將請求發送到後端。 後端能夠由一臺或經由負載均衡策略配置的多臺服務器組成。
最後,服務器會將請求轉發到私有網絡中相應的微服務。
詳細內容請查看官方文檔:
https://docs.traefik.io/
2、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
3、配置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命令建立的用戶名和密碼登陸
輸入用戶名和密碼並點擊登陸後便可進入該域名
4、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