Traefik 2.2新增的功能如下:
1. 支持了udp
2. traefik2.2 支持使用K/V存储做为动态配置的源,分别是 consul, etcd, Redis, zookeeper
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也增加了黑暗主题


下面进行安装过程。

注:我们这里是将traefik部署在ingress-traefik命名空间,如果你需要部署在其他命名空间,需要更改资源清单,如果你是部署在和我同样的命令空间中,你需要创建该命名空间。

创建命名空间:

  1. # kubectl create ns ingress-traefik

1、创建CRD资源

Traefik 2.0版本后开始使用CRD来对资源进行管理配置,所以我们需要先创建CRD资源。
traefik-crd.yaml

  1. ## IngressRoute
  2. apiVersion: apiextensions.k8s.io/v1beta1
  3. kind: CustomResourceDefinition
  4. metadata:
  5. name: ingressroutes.traefik.containo.us
  6. spec:
  7. scope: Namespaced
  8. group: traefik.containo.us
  9. version: v1alpha1
  10. names:
  11. kind: IngressRoute
  12. plural: ingressroutes
  13. singular: ingressroute
  14. ---
  15. ## IngressRouteTCP
  16. apiVersion: apiextensions.k8s.io/v1beta1
  17. kind: CustomResourceDefinition
  18. metadata:
  19. name: ingressroutetcps.traefik.containo.us
  20. spec:
  21. scope: Namespaced
  22. group: traefik.containo.us
  23. version: v1alpha1
  24. names:
  25. kind: IngressRouteTCP
  26. plural: ingressroutetcps
  27. singular: ingressroutetcp
  28. ---
  29. ## Middleware
  30. apiVersion: apiextensions.k8s.io/v1beta1
  31. kind: CustomResourceDefinition
  32. metadata:
  33. name: middlewares.traefik.containo.us
  34. spec:
  35. scope: Namespaced
  36. group: traefik.containo.us
  37. version: v1alpha1
  38. names:
  39. kind: Middleware
  40. plural: middlewares
  41. singular: middleware
  42. ---
  43. apiVersion: apiextensions.k8s.io/v1beta1
  44. kind: CustomResourceDefinition
  45. metadata:
  46. name: tlsoptions.traefik.containo.us
  47. spec:
  48. scope: Namespaced
  49. group: traefik.containo.us
  50. version: v1alpha1
  51. names:
  52. kind: TLSOption
  53. plural: tlsoptions
  54. singular: tlsoption
  55. ---
  56. ## TraefikService
  57. apiVersion: apiextensions.k8s.io/v1beta1
  58. kind: CustomResourceDefinition
  59. metadata:
  60. name: traefikservices.traefik.containo.us
  61. spec:
  62. scope: Namespaced
  63. group: traefik.containo.us
  64. version: v1alpha1
  65. names:
  66. kind: TraefikService
  67. plural: traefikservices
  68. singular: traefikservice
  69. ---
  70. ## TraefikTLSStore
  71. apiVersion: apiextensions.k8s.io/v1beta1
  72. kind: CustomResourceDefinition
  73. metadata:
  74. name: tlsstores.traefik.containo.us
  75. spec:
  76. scope: Namespaced
  77. group: traefik.containo.us
  78. version: v1alpha1
  79. names:
  80. kind: TLSStore
  81. plural: tlsstores
  82. singular: tlsstore
  83. ---
  84. ## IngressRouteUDP
  85. apiVersion: apiextensions.k8s.io/v1beta1
  86. kind: CustomResourceDefinition
  87. metadata:
  88. name: ingressrouteudps.traefik.containo.us
  89. spec:
  90. scope: Namespaced
  91. group: traefik.containo.us
  92. version: v1alpha1
  93. names:
  94. kind: IngressRouteUDP
  95. plural: ingressrouteudps
  96. singular: ingressrouteudp

创建资源清单:

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

2、创建RBAC权限

traefik-rbac.yaml

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. namespace: ingress-traefik
  5. name: traefik-ingress-controller
  6. ---
  7. kind: ClusterRole
  8. apiVersion: rbac.authorization.k8s.io/v1beta1
  9. metadata:
  10. name: traefik-ingress-controller
  11. rules:
  12. - apiGroups: [""]
  13. resources: ["services","endpoints","secrets"]
  14. verbs: ["get","list","watch"]
  15. - apiGroups: ["extensions"]
  16. resources: ["ingresses"]
  17. verbs: ["get","list","watch"]
  18. - apiGroups: ["extensions"]
  19. resources: ["ingresses/status"]
  20. verbs: ["update"]
  21. - apiGroups: ["traefik.containo.us"]
  22. resources: ["middlewares"]
  23. verbs: ["get","list","watch"]
  24. - apiGroups: ["traefik.containo.us"]
  25. resources: ["ingressroutes","traefikservices"]
  26. verbs: ["get","list","watch"]
  27. - apiGroups: ["traefik.containo.us"]
  28. resources: ["ingressroutetcps","ingressrouteudps"]
  29. verbs: ["get","list","watch"]
  30. - apiGroups: ["traefik.containo.us"]
  31. resources: ["tlsoptions","tlsstores"]
  32. verbs: ["get","list","watch"]
  33. ---
  34. kind: ClusterRoleBinding
  35. apiVersion: rbac.authorization.k8s.io/v1beta1
  36. metadata:
  37. name: traefik-ingress-controller
  38. roleRef:
  39. apiGroup: rbac.authorization.k8s.io
  40. kind: ClusterRole
  41. name: traefik-ingress-controller
  42. subjects:
  43. - kind: ServiceAccount
  44. name: traefik-ingress-controller
  45. namespace: ingress-traefik

创建RBAC资源清单:

  1. # kubectl apply -f traefik-rbac.yaml

3、创建traefik配置文件

traefik-config.yaml

  1. kind: ConfigMap
  2. apiVersion: v1
  3. metadata:
  4. name: traefik-config
  5. namespace: ingress-traefik
  6. data:
  7. traefik.yaml: |-
  8. serversTransport:
  9. insecureSkipVerify: true
  10. api:
  11. insecure: true
  12. dashboard: true
  13. debug: true
  14. metrics:
  15. prometheus: ""
  16. entryPoints:
  17. web:
  18. address: ":80"
  19. websecure:
  20. address: ":443"
  21. providers:
  22. kubernetesCRD: ""
  23. log:
  24. filePath: ""
  25. level: error
  26. format: json
  27. accessLog:
  28. filePath: ""
  29. format: json
  30. bufferingSize: 0
  31. filters:
  32. retryAttempts: true
  33. minDuration: 20
  34. fields:
  35. defaultMode: keep
  36. names:
  37. ClientUsername: drop
  38. headers:
  39. defaultMode: keep
  40. names:
  41. User-Agent: redact
  42. Authorization: drop
  43. Content-Type: keep

创建ConfigMap:

  1. # kubectl apply -f traefik-config.yaml

4、给节点打标签

由于是 Kubernetes DeamonSet 这种方式部署 Traefik,所以需要提前给节点设置 Label,这样当程序部署时 Pod 会自动调度到设置 Label 的点上。
节点设置 Label 标签

  • 格式:kubectl label nodes [节点名] [key=value]
    1. kubectl label nodes 172.16.0.33 IngressProxy=true

查看节点标签:

  1. # kubectl get nodes --show-labels
  2. NAME STATUS ROLES AGE VERSION LABELS
  3. 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
  4. 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

5、部署traefik

很多时候我们会采用DS方式部署,并且设置网络为hostNetwork=True,这样方便流量进入。但是在这里我采用的是service的nodeport进行暴露。

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

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: traefik
  5. namespace: ingress-traefik
  6. spec:
  7. type: NodePort
  8. ports:
  9. - name: web
  10. port: 80
  11. - name: websecure
  12. port: 443
  13. - name: admin
  14. port: 8080
  15. selector:
  16. app: traefik

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

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: traefik-ingress-controller
  5. namespace: ingress-traefik
  6. labels:
  7. app: traefik
  8. spec:
  9. selector:
  10. matchLabels:
  11. app: traefik
  12. template:
  13. metadata:
  14. name: traefik
  15. labels:
  16. app: traefik
  17. spec:
  18. serviceAccountName: traefik-ingress-controller
  19. terminationGracePeriodSeconds: 1
  20. containers:
  21. - image: registry.cn-hangzhou.aliyuncs.com/rookieops/traefik:v2.2.0
  22. name: traefik-ingress-lb
  23. ports:
  24. - name: web
  25. containerPort: 80
  26. - name: websecure
  27. containerPort: 443
  28. - name: admin
  29. containerPort: 8080
  30. resources:
  31. limits:
  32. cpu: 2000m
  33. memory: 1024Mi
  34. requests:
  35. cpu: 1000m
  36. memory: 1024Mi
  37. securityContext:
  38. capabilities:
  39. drop:
  40. - ALL
  41. add:
  42. - NET_BIND_SERVICE
  43. args:
  44. - --configfile=/config/traefik.yaml
  45. volumeMounts:
  46. - mountPath: "/config"
  47. name: "config"
  48. volumes:
  49. - name: config
  50. configMap:
  51. name: traefik-config
  52. tolerations: #设置容忍所有污点,防止节点被设置污点
  53. - operator: "Exists"
  54. nodeSelector: #设置node筛选器,在特定label的节点上启动
  55. IngressProxy: "true"

3) 配置traefik路由规则

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: traefik-dashboard-route
  5. namespace: ingress-traefik
  6. spec:
  7. entryPoints:
  8. - web
  9. routes:
  10. - match: Host(`traefik.coolops.cn`)
  11. kind: Rule
  12. services:
  13. - name: traefik
  14. port: 8080

然后创建资源:

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



然后本地配置hosts

  1. 10.1.10.128 traefik.coolops.cn

由于我们ingress是通过svc的nodeport暴露的,所以输入以下访问
image.png

并且可以看到我配置的HTTP
image.png

6、配置SSL

这里使用Let’s Encrypt 来进行自动化 HTTPS。
修改配置文件,新增如下内容:

  1. certificatesresolvers:
  2. default:
  3. acme:
  4. tlsChallenge: {}
  5. email: "coolops@163.com"
  6. storage: "acme.json"

更新配置文件。

新增一个https的ingressRoute,如下:

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: traefik-webui-tls
  5. namespace: ingress-traefik
  6. spec:
  7. entryPoints:
  8. - websecure # 注意这里是websecure这个entryPoint,监控443端口
  9. routes:
  10. - match: Host(`traefik.coolops.cn`)
  11. kind: Rule
  12. services:
  13. - name: traefik
  14. port: 8080
  15. tls:
  16. certResolver: default

查看pod的日志信息,报错如下:

  1. {"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访问了。
image.png
image.png

上面是自动生成证书,如果有自己的域名证书,那么一切都简单了,你只需要配置一个secret,然后在ingressRoute中引用即可,比如下面来自官方的例子:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: supersecret
  5. data:
  6. tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  7. tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
  8. ---
  9. apiVersion: traefik.containo.us/v1alpha1
  10. kind: IngressRoute
  11. metadata:
  12. name: ingressroutetls
  13. spec:
  14. entryPoints:
  15. - web
  16. routes:
  17. - match: Host(`foo.com`) && PathPrefix(`/bar`)
  18. kind: Rule
  19. services:
  20. - name: whoami
  21. port: 443
  22. tls:
  23. secretName: supersecret

用Let’s Encrypt的话,虽然免费,用起来还是有坑,这就需要自己去踩了~~!