Traefik-v2.x快速入門

一、概述

traefik 與 nginx 一樣,是一款優秀的反向代理工具,或者叫 Edge Router。至於使用它的原因則基於以下幾點

  • 無須重啓即可更新配置
  • 自動的服務發現與負載均衡
  • 與 docker 的完美集成,基於 container label 的配置
  • 漂亮的 dashboard 界面
  • metrics 的支持,對 prometheus 和 k8s 的集成

接下來講一下它的安裝,基本功能以及配置。traefik 在 v1 與 v2 版本間差異過大,本篇文章採用了 v2

traefik官方文檔:https://docs.traefik.io/

注意:Traefikv2.0之後的版本在修改了很多bug之後也增加了新的特性,比如增加了TCP的支持,並且更換了新的WEB UI界面

 

二、快速開始

環境介紹

操作系統:centos7.6

數量:1臺

docker版本:19.03.6

docker版本:1.24.1

ip地址:192.168.28.218

 

docker-compose啓動

新建yaml文件

vi traefik-v2.1.yaml

內容如下:

version: '3'
services:
  reverse-proxy:
    image: traefik:2.1.6
    # Enables the web UI and tells Traefik to listen to docker
    # 啓用webUI 並告訴Traefile去監聽docker的容器實例
    command: --api.insecure=true --providers.docker
    ports:
      # traefik暴露的http端口
      - "80:80"
      # webUI暴露的端口(必須制定--api.insecure=true纔可以訪問)
      - "8080:8080"
    volumes:
      # 指定docker的sock文件來讓traefik獲取docker的事件,從而實現動態負載均衡
      - /var/run/docker.sock:/var/run/docker.sock

 

使用docker-compose創建集羣

# docker-compose -f traefik-v2.1.yaml up -d reverse-proxy
Creating network "opt_default" with the default driver
Creating opt_reverse-proxy_1 ... done

 

查看使用docker-compose啓動的應用

# docker-compose -f traefik-v2.1.yaml ps
       Name                      Command               State                     Ports                   
---------------------------------------------------------------------------------------------------------
opt_reverse-proxy_1   /entrypoint.sh --api.insec ...   Up      0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp

 

直接訪問traefik對外暴露的http接口

curl -s  "http://localhost:8080/api/rawdata" | python -m json.tool

輸出如下:

{
    "middlewares": {
        "dashboard_redirect@internal": {
            "redirectRegex": {
                "permanent": true,
                "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$",
                "replacement": "${1}/dashboard/"
            },
            "status": "enabled",
            "usedBy": [
                "dashboard@internal"
            ]
        },
        "dashboard_stripprefix@internal": {
            "status": "enabled",
            "stripPrefix": {
                "prefixes": [
                    "/dashboard/",
                    "/dashboard"
                ]
            },
            "usedBy": [
                "dashboard@internal"
            ]
        }
    },
    "routers": {
        "api@internal": {
            "entryPoints": [
                "traefik"
            ],
            "priority": 2147483646,
            "rule": "PathPrefix(`/api`)",
            "service": "api@internal",
            "status": "enabled",
            "using": [
                "traefik"
            ]
        },
        "dashboard@internal": {
            "entryPoints": [
                "traefik"
            ],
            "middlewares": [
                "dashboard_redirect@internal",
                "dashboard_stripprefix@internal"
            ],
            "priority": 2147483645,
            "rule": "PathPrefix(`/`)",
            "service": "dashboard@internal",
            "status": "enabled",
            "using": [
                "traefik"
            ]
        },
        "reverse-proxy-opt@docker": {
            "rule": "Host(`reverse-proxy-opt`)",
            "service": "reverse-proxy-opt",
            "status": "enabled",
            "using": [
                "http",
                "traefik"
            ]
        }
    },
    "services": {
        "api@internal": {
            "status": "enabled",
            "usedBy": [
                "api@internal"
            ]
        },
        "dashboard@internal": {
            "status": "enabled",
            "usedBy": [
                "dashboard@internal"
            ]
        },
        "reverse-proxy-opt@docker": {
            "loadBalancer": {
                "passHostHeader": true,
                "servers": [
                    {
                        "url": "http://172.18.0.2:80"
                    }
                ]
            },
            "serverStatus": {
                "http://172.18.0.2:80": "UP"
            },
            "status": "enabled",
            "usedBy": [
                "reverse-proxy-opt@docker"
            ]
        }
    }
}
View Code

 

查看Traefik官方Dashboard

http://192.168.28.218:8080/

效果如下:

 

 

三、創建一個路由

Traefik來檢測新服務併爲你創建一個路由

創建一個新服務

vi test-service.yaml

內容如下:

version: '3'
services:
  whoami:
    image: containous/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"

 

創建服務

# docker-compose -f test-service.yaml up -d whoami
WARNING: Found orphan containers (opt_reverse-proxy_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Creating opt_whoami_1 ... done

 

查看新創建的服務

# docker-compose  -f test-service.yaml ps
    Name       Command   State   Ports 
---------------------------------------
opt_whoami_1   /whoami   Up      80/tcp

 

 

再次查看traefik中的路由信息(就會發現服務自動加載進去了)
其實有點兒類似kong 的路由,只是traefik會自動監聽docker的事件

curl -s  "http://localhost:8080/api/rawdata" | python -m json.tool

輸出如下:

{
    "middlewares": {
        "dashboard_redirect@internal": {
            "redirectRegex": {
                "permanent": true,
                "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$",
                "replacement": "${1}/dashboard/"
            },
            "status": "enabled",
            "usedBy": [
                "dashboard@internal"
            ]
        },
        "dashboard_stripprefix@internal": {
            "status": "enabled",
            "stripPrefix": {
                "prefixes": [
                    "/dashboard/",
                    "/dashboard"
                ]
            },
            "usedBy": [
                "dashboard@internal"
            ]
        }
    },
    "routers": {
        "api@internal": {
            "entryPoints": [
                "traefik"
            ],
            "priority": 2147483646,
            "rule": "PathPrefix(`/api`)",
            "service": "api@internal",
            "status": "enabled",
            "using": [
                "traefik"
            ]
        },
        "dashboard@internal": {
            "entryPoints": [
                "traefik"
            ],
            "middlewares": [
                "dashboard_redirect@internal",
                "dashboard_stripprefix@internal"
            ],
            "priority": 2147483645,
            "rule": "PathPrefix(`/`)",
            "service": "dashboard@internal",
            "status": "enabled",
            "using": [
                "traefik"
            ]
        },
        "reverse-proxy-opt@docker": {
            "rule": "Host(`reverse-proxy-opt`)",
            "service": "reverse-proxy-opt",
            "status": "enabled",
            "using": [
                "http",
                "traefik"
            ]
        },
        "whoami@docker": {
            "rule": "Host(`whoami.docker.localhost`)",
            "service": "whoami-opt",
            "status": "enabled",
            "using": [
                "http",
                "traefik"
            ]
        }
    },
    "services": {
        "api@internal": {
            "status": "enabled",
            "usedBy": [
                "api@internal"
            ]
        },
        "dashboard@internal": {
            "status": "enabled",
            "usedBy": [
                "dashboard@internal"
            ]
        },
        "reverse-proxy-opt@docker": {
            "loadBalancer": {
                "passHostHeader": true,
                "servers": [
                    {
                        "url": "http://172.19.0.2:80"
                    }
                ]
            },
            "serverStatus": {
                "http://172.19.0.2:80": "UP"
            },
            "status": "enabled",
            "usedBy": [
                "reverse-proxy-opt@docker"
            ]
        },
        "whoami-opt@docker": {
            "loadBalancer": {
                "passHostHeader": true,
                "servers": [
                    {
                        "url": "http://172.19.0.3:80"
                    }
                ]
            },
            "serverStatus": {
                "http://172.19.0.3:80": "UP"
            },
            "status": "enabled",
            "usedBy": [
                "whoami@docker"
            ]
        }
    }
}
View Code

 

查看http反向代理記錄

查看Traefik中的http反向代理記錄,點擊HTTP

 

測試traefik相關功能

 測試訪問

# curl -H Host:whoami.docker.localhost http://localhost
Hostname: c334de4bc3c8
IP: 127.0.0.1
IP: 172.19.0.3
RemoteAddr: 172.19.0.2:57632
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.29.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.19.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 1ee8d25b3aac
X-Real-Ip: 172.19.0.1

 

單機擴容

# docker-compose -f test-service.yaml up -d --scale whoami=2
WARNING: Found orphan containers (opt_reverse-proxy_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Starting opt_whoami_1 ... done
Creating opt_whoami_2 ... done

 

再次訪問(就會發現自動負載到兩個不同的實例上去了)

# curl -H Host:whoami.docker.localhost http://localhost
Hostname: c334de4bc3c8
IP: 127.0.0.1
IP: 172.19.0.3
RemoteAddr: 172.19.0.2:57632
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.29.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.19.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 1ee8d25b3aac
X-Real-Ip: 172.19.0.1

 

查看Traefike後端每個service的詳情信息:

 

 

 就會看到2個service

 

 

四、Traefik配置介紹

traefik配置結構圖

 

在traefik中的配置,會涉及到兩方面內容:

  • 動態的路由配置(即由k8s-api或docker相關api來自動發現服務的endpoint而進行路由的配置描述)
  • 靜態的啓動配置(即traefik標準的啓動配置參數)

注意:使用docker run traefik[:version] --help可查看traefik的配置參數

 

五、k8s部署Traefik

環境介紹

操作系統 ip 主機名 配置 備註
centos 7.6 192.168.31.150  k8s-master 2核4G Kubernetes1.16.3
centos 7.6 192.168.31.178  k8s-node01 2核8G Kubernetes1.16.3

 

 

 

 

yaml文件介紹

mkdir /opt/traefik

目錄結構如下:

./
├── traefik-config.yaml
├── traefik-ds-v2.1.6.yaml
├── traefik-rbac.yaml
└── ui.yaml

 

traefik-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: traefik-config
  namespace: kube-system
data:
  traefik.toml: |
    defaultEntryPoints = ["http","https"]
    debug = false
    logLevel = "INFO"
    # Do not verify backend certificates (use https backends)
    InsecureSkipVerify = true
    [entryPoints]
      [entryPoints.http]
      address = ":80"
      compress = true
      [entryPoints.https]
      address = ":443"
        [entryPoints.https.tls]
    #Config to redirect http to https
    #[entryPoints]
    #  [entryPoints.http]
    #  address = ":80"
    #  compress = true
    #    [entryPoints.http.redirect]
    #    entryPoint = "https"
    #  [entryPoints.https]
    #  address = ":443"
    #    [entryPoints.https.tls]
    [web]
      address = ":8080"
    [kubernetes]
    [metrics]
      [metrics.prometheus]
      buckets=[0.1,0.3,1.2,5.0]
      entryPoint = "traefik"
    [ping]
    entryPoint = "http"
View Code

 

traefik-ds-v2.1.6.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: apps/v1
#apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller-v2
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  selector:
    matchLabels:
      name: traefik-ingress-lb-v2
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb-v2
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      containers:
      - image: traefik:2.1.6
        name: traefik-ingress-lb-v2
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: admin
          containerPort: 8080
          hostPort: 8080
        securityContext:
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        args:
        - --api
        - --api.insecure=true
        - --providers.kubernetesingress=true
        - --log.level=INFO
        #- --configfile=/config/traefik.toml
        #volumeMounts:
        #- mountPath: /config
        #  name: config
      volumes:
      - configMap:
          name: traefik-config
        name: config
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service-v2
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb-v2
spec:
  selector:
    k8s-app: traefik-ingress-lb-v2
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin
View Code

 

traefik-rbac.yaml

---
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
  - apiGroups:
    - extensions
    resources:
    - ingresses/status
    verbs:
    - update
---
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
View Code

 

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: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  rules:
  - host: prod-traefik-ui.bgbiao.cn
    http:
      paths:
      - path: /
        backend:
          serviceName: traefik-web-ui
          servicePort: web
View Code

 

部署

cd /opt/traefik
kubectl apply -f .

 

查看pod

# kubectl get pods -n kube-system | grep traefik
traefik-ingress-controller-v2-hz82b        1/1     Running   0          8m4s

 

 查看svc

# kubectl get svc -n kube-system | grep traefik
traefik-ingress-service-v2   ClusterIP   10.1.188.71    <none>        80/TCP,8080/TCP          8m56s
traefik-web-ui               ClusterIP   10.1.239.107   <none>        80/TCP                   46m

 

查看ingresses

# kubectl get ingresses.extensions -n kube-system
NAME             HOSTS                       ADDRESS   PORTS   AGE
traefik-web-ui   prod-traefik-ui.bgbiao.cn             80      48m

 

查看traefik的dashboard

域名訪問

由於沒有dns服務器,這裏直接修改hosts來測試。windows 10添加一條hosts記錄

192.168.31.178 prod-traefik-ui.bgbiao.cn 

注意:這裏的192.168.31.178是node節點ip

 

效果如下:

 

 

ip方式

直接通過node ip+8080方式,比如:

http://192.168.31.178:8080

效果同上!

 

點擊http

 

 查看 http service

 

 效果如下:

 

 

注意:雖然traefikv2.x改動了很多,但是還是向下兼容一些內容的,比如我重新創建traefik-v2.0.1之後,之前創建的ingress規則會自動導入

 

 

本文參考鏈接:

https://www.jianshu.com/p/0fc6df85d00d

https://zhuanlan.zhihu.com/p/97420459

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章