說明
關於kubernetes的服務暴露方式以及traefik的原理篇這里不作詳細說明。traefik的原理可以參考官方文檔:https://docs.traefik.io/ ,而關於kubernetes的服務暴露方式以及將traefik作為kubernetes的ingress使用的基本原理也可以參考這篇文檔:https://mritd.me/2016/12/06/try-traefik-on-kubernetes/ 。這篇文檔主要闡述將traefik作為kubernetes的ingress的實際操作,包括在traefik中啟用https,將traefik的日志輸出為json並通過filebeat收集,以及通過prometheus監控traefik。
部署
創建一個獨立的命名空間
kubectl create ns ingress
配置rbac授權
我這里kubernetes使用1.8且啟用了rbac授權。官方的traefik-rbac.yaml文件可以參考:https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml ,但在我實際測試中,還是有問題。我這里直接采用了一個偷懶的做法,直接給了最大權限。 下面的配置文件中,先創建了一個serviceaccount名稱為traefik-ingress-controller,然后直接為這個serviceaccount授予了cluster-admin的權限
traefik.rbac.yaml示例如下:
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: traefik-ingress-controller
name: traefik-ingress-controller
namespace: ingress
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: traefik-ingress-controller
labels:
k8s-app: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: ingress
配置secret
我們將traefik作為ingress時,需要其同時處理https請求,所以需要為traefik配置證書文件。在這里將證書文件和key文件放入到secret中。我這里兩個文件的名稱分別是breezey.top.crt和breezey.top.key。創建secret方法如下:
kubectl create secret tls breezey-ingress-secret --key breezey.top.key --cert breezey.top.crt -n ingress
創建一個configmap用於存放traefik的配置文件
traefik.configmap.yaml配置如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: traefik-conf
namespace: ingress
data:
traefik.toml: |
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "/keys/breezey.top.crt"
keyFile = "/keys/breezey.top.key"
#traefikLogsFile = "log/traefik.log"
[accessLog]
filePath = "/logs/traefik.access.log"
format = "json"
需要說明的是,我這里同時支持http和https,並沒有做http強制跳轉到https。如果需要http強制跳轉到https,可以參考如下配置:
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "/keys/breezey.top.crt"
keyFile = "/keys/breezey.top.key"
#traefikLogsFile = "log/traefik.log"
[accessLog]
filePath = "/logs/traefik.access.log"
format = "json"
另外,在上面的配置中,我啟動了traefik的訪問日志,並將格式指定為json,這是為了方便后面直接通過filebeat作收集。這里也需要說明下,traefik的兩種日志,一種是traefik服務自身的日志,另一種是訪問日志。我這里只啟用了訪問日志。默認traefik的服務日志會通過容器的標准輸出打印。
配置traefik的deployment文件
在這里我采用nodeSelecter的方式將traefik固定在指定的兩個節點上,如果采用deployment的方式部署,需要在選定的節點上先打好標簽。
traefik.dm.yaml配置如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: traefik-ingress-lb
namespace: ingress
labels:
k8s-app: traefik-ingress-lb
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
replicas: 2
selector:
matchLabels:
k8s-app: traefik-ingress-lb
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8580"
spec:
terminationGracePeriodSeconds: 60
hostNetwork: true
restartPolicy: Always
volumes:
- name: traefik-config
configMap:
name: traefik-conf
- name: traefik-key
secret:
secretName: breezey-ingress-secret
- name: traefik-log
hostPath:
path: /mnt/srvlogs
- name: localtime
hostPath:
path: /etc/localtime
containers:
- image: dyhub.douyucdn.cn/library/traefik:v1.4.3
name: traefik-ingress-lb
# resources:
# limits:
# cpu: 200m
# memory: 30Mi
# requests:
# cpu: 100m
# memory: 20Mi
securityContext:
privileged: true
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: admin
containerPort: 8580
volumeMounts:
- mountPath: "/config"
name: "traefik-config"
- mountPath: "/logs"
name: "traefik-log"
- mountPath: "/keys"
name: "traefik-key"
- mountPath: "/etc/localtime"
name: "localtime"
args:
- --configfile=/config/traefik.toml
- --web
- --web.address=:8580
- --kubernetes
- --web.metrics.prometheus
serviceAccountName: traefik-ingress-controller
nodeSelector:
proxy: "true"
ingress: "traefik"
需要說明的是,通過volumeMounts的方式將訪問日志以及https證書及密鑰進行了相關掛載。然后在啟動參數中,指定--web.metrics.prometheus參數以暴露metrics供prometheus收集,另外指定了管理端口為8580。
最后創建上面配置的所有資源:
kubectl create -f ./
到此,traefik在kubernetes上部署完成。
配置服務
這里是一個將traefik-ui作為traefik的代理后端的示例。
先創建一個service文件traefik-ui.svc.yaml示例如下:
apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
namespace: ingress
spec:
clusterIP: None
selector:
k8s-app: traefik-ingress-lb
ports:
- name: web
port: 8580
targetPort: 8580
再創建一個traefik-ui.ingress.yaml文件如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
name: traefik-web-ui
namespace: ingress
spec:
tls:
# - hosts:
# - traefik-ui.breezey.top
- secretName: breezey-ingress-secret
rules:
- host: traefik-ui.breezey.top
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
創建相關資源:
kubectl create -f ./traefik-ui.svc.yaml
kubectl create -f ./traefik-ui.ingress.yaml
配置好dns解析,即可通過traefik-ui.breezey.top來訪問traefik-ui服務,http和https同時支持,且不會強制跳轉。
通過prometheus監控traefik
在啟動traefik時,使用了--web.metrics.prometheus選項,這時只需要將traefik服務的ip及admin端口添加至prometheus的配置文件中即可。如下:
- job_name: 'traefik'
static_configs:
- targets: ['192.168.0.101:8580','192.168.0.102:8580']
重啟prometheus:
systemctl restart prometheus
在本次示例中,prometheus未運行於kubernetes中,而是獨立部署
在prometheus的status的target中查看:

在grafana中添加dashboard,這里采用的官方的id為2870的dashboard,添加后效果如下:

