Traefik 2.2新增的功能如下:
1. 支持了udp
2. traefik2.2 支持使用K/V存储做为动态配置的源,分别是 consul, etcd, Redis, zookeeper
3. 能够使用kubernetes CRD自定义资源定义UDP负载平衡 IngressRouteUDP
4. 能够使用 rancherconsul catalogdockermarathon中的标签定义UDP的负载平衡
5. 增加了对ingress注解的主持
6. 将TLS存储功能 TLSStores添加到Kubernetes CRD中,使kubernetes用户无需使用配置文件和安装证书即可提供默认证书。
7. 在日志中增加了http的请求方式,是http还是https
8. 因为TLS的配置可能会影响CPU的使用率,因此增加了 TLS versionTLS 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的话,虽然免费,用起来还是有坑,这就需要自己去踩了~~!