使用traefik作為kubernetes的ingress


說明

關於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中查看:
prometheus-target

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM