Traefik2.2從坑出發

↑ 點擊上方「喬邊故事」關注咱們


Traefik2.2安裝

Traefik 2.2新增的功能以下:
1. 支持了udp
2. traefik2.2 支持使用K/V存儲作爲動態配置的源,分別是 consuletcdRediszookeeper
3. 可以使用kubernetes CRD自定義資源定義UDP負載平衡 IngressRouteUDP
4. 可以使用 rancher, consul catalog, docker和 marathon中的標籤訂義UDP的負載平衡
5. 增長了對ingress註解的主持
6. 將TLS存儲功能 TLSStores添加到Kubernetes CRD中,使kubernetes用戶無需使用配置文件和安裝證書便可提供默認證書。
7. 在日誌中增長了http的請求方式,是http仍是https
8. 由於TLS的配置可能會影響CPU的使用率,所以增長了 TLS version和 TLS cipher使用的指標信息
9. 當前的WRR算法對於權重不平衡端點存在嚴重的誤差問題,將EDF調度算法用於WeightedRoundRobin, Envoy也是使用了 EOF調度算法
10. 支持請求主體用於流量鏡像
11. 增長了 ElasticAPM做爲traefik的tracing系統。
12. Traefik的Dashboard增長了UDP的頁面
13. Traefik也增長了黑暗主題
node


下面進行安裝過程。linux

注:咱們這裏是將traefik部署在ingress-traefik命名空間,若是你須要部署在其餘命名空間,須要更改資源清單,若是你是部署在和我一樣的命令空間中,你須要建立該命名空間。web

建立命名空間:算法

# kubectl create ns ingress-traefik


一、建立CRD資源

Traefik 2.0版本後開始使用CRD來對資源進行管理配置,因此咱們須要先建立CRD資源。
traefik-crd.yamldocker

## IngressRoute
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutes.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRoute
    plural: ingressroutes
    singular: ingressroute
---
## IngressRouteTCP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutetcps.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteTCP
    plural: ingressroutetcps
    singular: ingressroutetcp
---
## Middleware
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: middlewares.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: Middleware
    plural: middlewares
    singular: middleware
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsoptions.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSOption
    plural: tlsoptions
    singular: tlsoption
---
## TraefikService
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: traefikservices.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TraefikService
    plural: traefikservices
    singular: traefikservice

---
## TraefikTLSStore
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsstores.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSStore
    plural: tlsstores
    singular: tlsstore

---
## IngressRouteUDP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressrouteudps.traefik.containo.us 
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteUDP
    plural: ingressrouteudps
    singular: ingressrouteudp


建立資源清單:json

# kubectl apply -f traefik-crd.yaml
# kubectl get crd
NAME                                    CREATED AT
ingressroutes.traefik.containo.us       2019-12-13T05:40:30Z
ingressroutetcps.traefik.containo.us    2019-12-13T05:40:30Z
middlewares.traefik.containo.us         2019-12-13T05:40:30Z


二、建立RBAC權限

traefik-rbac.yamlapi

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: ingress-traefik 
  name: traefik-ingress-controller
---
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"]
  - apiGroups: ["traefik.containo.us"]
    resources: ["middlewares"]
    verbs: ["get","list","watch"]
  - apiGroups: ["traefik.containo.us"]
    resources: ["ingressroutes","traefikservices"]
    verbs: ["get","list","watch"]
  - apiGroups: ["traefik.containo.us"]
    resources: ["ingressroutetcps","ingressrouteudps"]
    verbs: ["get","list","watch"]
  - apiGroups: ["traefik.containo.us"]
    resources: ["tlsoptions","tlsstores"]
    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: ingress-traefik


建立RBAC資源清單:微信

# kubectl apply -f traefik-rbac.yaml


三、建立traefik配置文件

traefik-config.yaml網絡

kind: ConfigMap
apiVersion: v1
metadata:
  name: traefik-config
  namespace: ingress-traefik
data:
  traefik.yaml: |-
    serversTransport:
      insecureSkipVerify: true
    api:
      insecure: true
      dashboard: true
      debug: true
    metrics:
      prometheus: ""
    entryPoints:
      web:
        address: ":80"
      websecure:
        address: ":443"
    providers:
      kubernetesCRD: ""
    log:
      filePath: ""
      level: error
      format: json
    accessLog:
      filePath: ""
      format: json
      bufferingSize: 0
      filters:
        retryAttempts: true
        minDuration: 20
      fields:
        defaultMode: keep
        names:
          ClientUsername: drop
        headers:
          defaultMode: keep
          names:
            User-Agent: redact
            Authorization: drop
            Content-Type: keep


建立ConfigMap:app

# kubectl apply -f traefik-config.yaml


四、給節點打標籤

因爲是 Kubernetes DeamonSet 這種方式部署 Traefik,因此須要提早給節點設置 Label,這樣當程序部署時 Pod 會自動調度到設置 Label 的點上。
節點設置 Label 標籤

  • 格式:kubectl label nodes [節點名] [key=value]
kubectl label nodes 172.16.0.33 IngressProxy=true


查看節點標籤:

# kubectl get nodes --show-labels 
NAME          STATUS                     ROLES    AGE   VERSION   LABELS
172.16.0.33   Ready,SchedulingDisabled   master   20d   v1.15.0   IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.0.33,kubernetes.io/os=linux,kubernetes.io/role=master
172.16.0.52   Ready                      node     20d   v1.15.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=172.16.0.52,kubernetes.io/os=linux,kubernetes.io/role=node


五、部署traefik

不少時候咱們會採用DS方式部署,而且設置網絡爲hostNetwork=True,這樣方便流量進入。可是在這裏我採用的是service的nodeport進行暴露。

(1)、Service的配置清單
traefik-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: ingress-traefik
spec:
  type: NodePort
  ports:
    - name: web
      port: 80
    - name: websecure
      port: 443
    - name: admin
      port: 8080
  selector:
    app: traefik


(2)、DS的配置清單
traefik-ds.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: traefik-ingress-controller
  namespace: ingress-traefik
  labels:
    app: traefik
spec:
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      name: traefik
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 1
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/rookieops/traefik:v2.2.0
          name: traefik-ingress-lb
          ports:
            - name: web
              containerPort: 80
            - name: websecure
              containerPort: 443
            - name: admin
              containerPort: 8080
          resources:
            limits:
              cpu: 2000m
              memory: 1024Mi
            requests:
              cpu: 1000m
              memory: 1024Mi
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
          args:
            - --configfile=/config/traefik.yaml
          volumeMounts:
            - mountPath: "/config"
              name: "config"
      volumes:
        - name: config
          configMap:
            name: traefik-config 
      tolerations:              #設置容忍全部污點,防止節點被設置污點
        - operator: "Exists"
      nodeSelector:             #設置node篩選器,在特定label的節點上啓動
        IngressProxy: "true"

3) 配置traefik路由規則

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-route
  namespace: ingress-traefik
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`traefik.coolops.cn`)
      kind: Rule
      services:
        - name: traefik
          port: 8080

而後建立資源:

# kubectl apply -f traefik-svc.yaml
# kubectl apply -f traefik-ds.yaml
# kubectl get svc -n ingress-traefik 
NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                     AGE
traefik   NodePort   10.102.225.66   <none>        80:30161/TCP,443:30629/TCP,8080:32359/TCP   31m
# kubectl get pod -n ingress-traefik 
NAME                               READY   STATUS    RESTARTS   AGE
traefik-ingress-controller-whbjm   1/1     Running   0          22m


而後本地配置hosts

10.1.10.128 traefik.coolops.cn


因爲咱們ingress是經過svc的nodeport暴露的,因此輸入如下訪問


而且能夠看到我配置的HTTP


六、配置SSL

這裏使用Let's Encrypt 來進行自動化 HTTPS。
修改配置文件,新增以下內容:

    certificatesresolvers:
      default:
        acme:
          tlsChallenge: {}
          email: "coolops@163.com"
          storage: "acme.json"

更新配置文件。

新增一個https的ingressRoute,以下:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-webui-tls
  namespace: ingress-traefik 
spec:
  entryPoints:
  - websecure  # 注意這裏是websecure這個entryPoint,監控443端口
  routes:
  - match: Host(`traefik.coolops.cn`)
    kind: Rule
    services:
    - name: traefik
      port: 8080
  tls:
    certResolver: default 

查看pod的日誌信息,報錯以下:

{"level":"error","msg":"Unable to obtain ACME certificate for domains \"traefik.coolops.cn\": cannot get ACME client get directory at 'https://acme-v02.api.letsencrypt.org/directory': Get \"https://acme-v02.api.letsencrypt.org/directory\": dial tcp 172.65.32.248:443: connect: connection refused","providerName":"default.acme","routerName":"ingress-traefik-traefik-webui-tls-fcde00a088d29eefb3a6@kubernetescrd","rule":"Host(`traefik.coolops.cn`)","time":"2020-05-26T02:49:49Z"}

這是由於pod裏的網絡和https://acme-v02.api.letsencrypt.org/directory 不通形成的。

部署成功後可使用HTTPS訪問了。



上面是自動生成證書,若是有本身的域名證書,那麼一切都簡單了,你只須要配置一個secret,而後在ingressRoute中引用便可,好比下面來自官方的例子:

apiVersion: v1
kind: Secret
metadata:
  name: supersecret
data:
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=

---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutetls
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`foo.com`) && PathPrefix(`/bar`)
    kind: Rule
    services:
    - name: whoami
      port: 443
  tls:
    secretName: supersecret

用Let's Encrypt的話,雖然免費,用起來仍是有坑,這就須要本身去踩了~~!


-----------------------

公衆號:喬邊故事(ID:qiaobiangushi)

知乎: 喬邊故事

博客:酷維-COOLOPS

永遠不要高估本身,作一個謙遜又自信的人。

-----------------------

掃碼二維碼關注公衆號,不按期維護優質內容,技術乾貨!


舒適提示

若是你喜歡本文,請分享到朋友圈,想要得到更多信息,請關注我。




本文分享自微信公衆號 - 極客運維圈(qiaobiangushi)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索