Traefik高性能代理

高性能七層反向代理(達到NGINX的八九成效率),支持熱更新,並對接到包括容器編排框架在內的多種後端服務web

總體架構

由於是七層反向代理,因此是經過開放http,https端口接收域名請求並轉發,不支持直接經過ip和端口進行轉發 輸入圖片說明docker

配置

配置加載優先級:KV Store(包括Consule、etcd、ZK) > Arguments命令參數 > ConfigFile配置文件 > Defaultexpress

配置文件

#entrypoints配置
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"

#frontends配置
[frontends]
  [frontends.myfront]
  backend = "mybackend"
  passHostHeader = true
  passTLSCert = true
  priority = 10
  entrypoints = ["https"]
    [frontends.myfront.headers.customresponseheaders] #自定義頭部
    X-MY-Response-Header = "xxx"
    [frontends.myfront.headers.customrequestheaders]
    X-MY-Request-Herder = "xxx"
    [frontends.myfront.routes.test_1]
    rule = "Host:my.com"

#backends配置
[backends]
  [backends.mybackend]
    [backends.mybackend.circuitbreaker]
    expression = "NetworkErrorRatio() > 0.5"
    [backends.mybackend.LoadBalancer]
    method = "drr" #或者使用靜態值wrr
    [backends.mybackend.loadbalancer.stickiness] #基於cookie的會話黏性配置
	cookieName = "my_cookie" #自定義植入的黏性cookie名
    [backends.mybackend.healthcheck]
    path = "/health"
    interval = "10s"
    port = 8080
    [backends.mybackend.maxconn]
    amount = 1000 #併發上限
    extractorfunc = "request.host" #其餘候選值:client.ip、request.header.字段名
    [backends.mybackend.servers.server1]
    url = "http://172.17.0.2:80"
    weight = 1
    [backends.mybackend.servers.server2]
    url = "http://172.17.0.3:80"
    weight = 2

[acme]
email = "xxx@yyy.com"
storage = "acme.json"
onHostRule = true #自動爲acme.entryPoint下的新域名申請證書
onDemand = true #在新域名接受第一次https請求時申請證書
caServer = "https://acme-staging.api.letsencrypt.org/directory" #默認是申請生產證書,這裏改成申請staging證書進行測試
entryPoint = "https"
  [acme.httpChallenge]
  entryPoint = "http"
[[acme.domains]]
  main = "local1.com"
  sans = ["test1.local1.com", "test2.local1.com"]
[[acme.domains]]
  main = "local2.com"
  sans = ["test1.local2.com", "test2.local2.com"]

#ping健康檢查配置(健康時:traefik healthcheck命令退出碼爲0,/ping接口返回200狀態)
[ping]
entryPoint = "traefik" #指定是哪一個entrypoint

標籤

traefik支持自動解析service對象的標籤(具體參考https://docs.traefik.io/configuration/backends/rancher/#labels-overriding-default-behaviour)json

* traefik.enable=true
* traefik.frontend.rule=Host:test.traefik.io
* traefik.backend=someservice

docker-compose部署

version: '2'

services:
  reverse-proxy:
    image: traefik
    command: --api --docker #啓用WebUI,監聽docker
    ports:
      - "80:80" #http端口
      - "8080:8080" #WebUI(--api選項)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ~/traefik.toml:/etc/traefik/traefik.toml #自定義配置(可選)

K8S部署

RBAC受權

若是集羣配置了RBAC,則須要對traefik受權訪問後端

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-controller
    namespace: kube-system

DaemonSet部署

---
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: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
        securityContext:
          privileged: true
        args:
        - --api
        - --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: 8080
      name: admin
  type: NodePort

建立TraefikUI入口

apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik-ui.example.com
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80

Http Basic

針對TraefikUI的訪問認證保護api

htpasswd -c ./auth 用戶名 #根據提示輸入密碼

kubectl create secret generic mysecret --from-file auth --namespace=monitoring

#在traefik ui ingress對象上註冊以下annotations
ingress.kubernetes.io/auth-type: "basic"
ingress.kubernetes.io/auth-secret: "mysecret"
相關文章
相關標籤/搜索