Kubernetes 部署 Ingress 控制器 Traefik v2.2

Kubernetes 部署 Ingress 控制器 Traefik v2.2

文章目录

  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。


系统环境:

  • Traefik 版本:v2.2.8
  • Kubernetes 版本:1.18.5

参考地址:

示例部署文件:

  • 示例部署文件 Github 地址:https://github.com/my-dlq/blog-example/tree/master/kubernetes/traefik-v2.2-deploy

一、Traefik 简介

       Traefik 是一个流行的 HTTP 反向代理和负载均衡器,使用 Traefik 可以很方便的与现在流程的基础架构组件(如 Docker、Swarm、Kubernetes、Marathon、Consul、Etcd、Rancher、Amazon ECS ......)集成,并可以针对不同的组件实现动态配置。

二、Kubernetes 部署 Traefik

       Traefik 最新推出了 v2.2 版本,这里将 Traefik 升级到最新版本,简单的介绍了下如何在 Kubernetes 环境下安装 Traefik v2.2,下面将介绍如何在 Kubernetes 环境下部署并配置 Traefik v2.2。

       当部署完 Traefik 后还需要创建外部访问 Kubernetes 内部应用的路由规则,Traefik 支持两种方式创建路由规则,一种是创建 Traefik 自定义 Kubernetes CRD 资源方式,还有一种是创建 Kubernetes Ingress 资源方式。

注意:这里 Traefik 是部署在 Kube-system Namespace 下,如果不想部署到配置的 Namespace,需要修改下面部署文件中的 Namespace 参数。

1、创建 CRD 资源

Traefik v2.0 版本后,开始使用 CRD(Custom Resource Definition)来完成路由配置等,所以需要提前创建 CRD 资源。

# 创建 traefik-crd.yaml 文件

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

# 创建 Traefik CRD 资源

1$ kubectl apply -f traefik-crd.yaml

2、创建 RBAC 权限

Kubernetes 在 1.6 版本中引入了基于角色的访问控制(RBAC)策略,方便对 Kubernetes 资源和 API 进行细粒度控制。Traefik 需要一定的权限,所以,这里提前创建好 Traefik ServiceAccount 并分配一定的权限。

# 创建 traefik-rbac.yaml 文件:

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

# 创建 Traefik RBAC 资源

  • -n:指定部署的 Namespace
1$ kubectl apply -f traefik-rbac.yaml -n kube-system

3、创建 Traefik 配置文件

由于 Traefik 配置很多,通过 CLI 定义不是很方便,一般时候都会通过配置文件配置 Traefik 参数,然后存入 ConfigMap,将其挂入 Traefik 中。

# 创建 traefik-config.yaml 文件

下面配置中可以通过配置 kubernetesCRDkubernetesIngress 两项参数,让 Traefik 支持 CRD 与 Ingress 两种路由方式。

 1kind: ConfigMap
 2apiVersion: v1
 3metadata:
 4  name: traefik-config
 5data:
 6  traefik.yaml: |-
 7    ping: ""                    ## 启用 Ping
 8    serversTransport:
 9      insecureSkipVerify: true  ## Traefik 忽略验证代理服务的 TLS 证书
10    api:
11      insecure: true            ## 允许 HTTP 方式访问 API
12      dashboard: true           ## 启用 Dashboard
13      debug: false              ## 启用 Debug 调试模式
14    metrics:
15      prometheus: ""            ## 配置 Prometheus 监控指标数据,并使用默认配置
16    entryPoints:
17      web:
18        address: ":80"          ## 配置 80 端口,并设置入口名称为 web
19      websecure:
20        address: ":443"         ## 配置 443 端口,并设置入口名称为 websecure
21    providers:
22      kubernetesCRD: ""         ## 启用 Kubernetes CRD 方式来配置路由规则
23      kubernetesIngress: ""     ## 启动 Kubernetes Ingress 方式来配置路由规则
24    log:
25      filePath: ""              ## 设置调试日志文件存储路径,如果为空则输出到控制台
26      level: error              ## 设置调试日志级别
27      format: json              ## 设置调试日志格式
28    accessLog:
29      filePath: ""              ## 设置访问日志文件存储路径,如果为空则输出到控制台
30      format: json              ## 设置访问调试日志格式
31      bufferingSize: 0          ## 设置访问日志缓存行数
32      filters:
33        #statusCodes: ["200"]   ## 设置只保留指定状态码范围内的访问日志
34        retryAttempts: true     ## 设置代理访问重试失败时,保留访问日志
35        minDuration: 20         ## 设置保留请求时间超过指定持续时间的访问日志
36      fields:                   ## 设置访问日志中的字段是否保留(keep 保留、drop 不保留)
37        defaultMode: keep       ## 设置默认保留访问日志字段
38        names:                  ## 针对访问日志特别字段特别配置保留模式
39          ClientUsername: drop  
40        headers:                ## 设置 Header 中字段是否保留
41          defaultMode: keep     ## 设置默认保留 Header 中字段
42          names:                ## 针对 Header 中特别字段特别配置保留模式
43            User-Agent: redact
44            Authorization: drop
45            Content-Type: keep
46    #tracing:                     ## 链路追踪配置,支持 zipkin、datadog、jaeger、instana、haystack 等 
47    #  serviceName:               ## 设置服务名称(在链路追踪端收集后显示的服务名)
48    #  zipkin:                    ## zipkin配置
49    #    sameSpan: true           ## 是否启用 Zipkin SameSpan RPC 类型追踪方式
50    #    id128Bit: true           ## 是否启用 Zipkin 128bit 的跟踪 ID
51    #    sampleRate: 0.1          ## 设置链路日志采样率(可以配置0.0到1.0之间的值)
52    #    httpEndpoint: http://localhost:9411/api/v2/spans     ## 配置 Zipkin Server 端点    

# 创建 Traefik ConfigMap 资源

  • -n: 指定程序启的 Namespace
1$ kubectl apply -f traefik-config.yaml -n kube-system

4、节点设置 Label 标签

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

# 节点设置 Label 标签

  • 格式:kubectl label nodes [节点名] [key=value]
1$ kubectl label nodes k8s-node-2-12 IngressProxy=true

# 查看节点是否设置 Label 成功

1$ kubectl get nodes --show-labels
2
3NAME            STATUS ROLES  VERSION  LABELS
4k8s-master-2-11 Ready  master  v1.18.5  kubernetes.io/hostname=k8s-master-2-11,node-role.kubernetes.io/master=
5k8s-node-2-12   Ready  <none> v1.18.5  kubernetes.io/hostname=k8s-node-2-12,IngressProxy=true
6k8s-node-2-13   Ready  <none> v1.18.5  kubernetes.io/hostname=k8s-node-2-13
7k8s-node-2-14   Ready  <none> v1.18.5  kubernetes.io/hostname=k8s-node-2-14

如果想删除标签,可以使用 "kubectl label nodes k8s-node-2-12 IngressProxy-" 命令

5、Kubernetes 部署 Traefik

下面将用 DaemonSet 方式部署 Traefik,便于在多服务器间扩展,用 hostport 方式绑定服务器 80443 端口,方便流量通过物理机进入 Kubernetes 内部。

# 创建 traefik 部署 traefik-deploy.yaml 文件

 1apiVersion: v1
 2kind: Service
 3metadata:
 4  name: traefik
 5spec:
 6  ports:
 7    - name: web
 8      port: 80
 9    - name: websecure
10      port: 443
11    - name: admin
12      port: 8080
13  selector:
14    app: traefik
15---
16apiVersion: apps/v1
17kind: DaemonSet
18metadata:
19  name: traefik-ingress-controller
20  labels:
21    app: traefik
22spec:
23  selector:
24    matchLabels:
25      app: traefik
26  template:
27    metadata:
28      name: traefik
29      labels:
30        app: traefik
31    spec:
32      serviceAccountName: traefik-ingress-controller
33      terminationGracePeriodSeconds: 1
34      containers:
35        - image: traefik:v2.2.8
36          name: traefik-ingress-lb
37          ports:
38            - name: web
39              containerPort: 80
40              hostPort: 80         ## 将容器端口绑定所在服务器的 80 端口
41            - name: websecure
42              containerPort: 443
43              hostPort: 443        ## 将容器端口绑定所在服务器的 443 端口
44            - name: admin
45              containerPort: 8080  ## Traefik Dashboard 端口
46          resources:
47            limits:
48              cpu: 2000m
49              memory: 1024Mi
50            requests:
51              cpu: 1000m
52              memory: 1024Mi
53          securityContext:
54            capabilities:
55              drop:
56                - ALL
57              add:
58                - NET_BIND_SERVICE
59          args:
60            - --configfile=/config/traefik.yaml
61          volumeMounts:
62            - mountPath: "/config"
63              name: "config"
64          readinessProbe:
65            httpGet:
66              path: /ping
67              port: 8080
68            failureThreshold: 3
69            initialDelaySeconds: 10
70            periodSeconds: 10
71            successThreshold: 1
72            timeoutSeconds: 5
73          livenessProbe:
74            httpGet:
75              path: /ping
76              port: 8080
77            failureThreshold: 3
78            initialDelaySeconds: 10
79            periodSeconds: 10
80            successThreshold: 1
81            timeoutSeconds: 5    
82      volumes:
83        - name: config
84          configMap:
85            name: traefik-config 
86      tolerations:              ## 设置容忍所有污点,防止节点被设置污点
87        - operator: "Exists"
88      nodeSelector:             ## 设置node筛选器,在特定label的节点上启动
89        IngressProxy: "true"

# Kubernetes 部署 Traefik

1$ kubectl apply -f traefik-deploy.yaml -n kube-system

到此 Traefik v2.2 应用已经部署完成。

三、配置路由规则

       Traefik 应用已经部署完成,但是想让外部访问 Kubernetes 内部服务,还需要配置路由规则,上面部署 Traefik 时开启了 Traefik Dashboard,这是 Traefik 提供的视图看板,所以,首先配置基于 HTTPTraefik Dashboard 路由规则,使外部能够访问 Traefik Dashboard。然后,再配置基于 HTTPSKubernetes Dashboard 的路由规则,这里分别使用 CRDIngress 两种方式进行演示。

1、方式一:使用 CRD 方式配置 Traefik 路由规则

使用 CRD 方式创建路由规则可言参考 Traefik 文档 Kubernetes IngressRoute

(1)、配置 HTTP 路由规则 (Traefik Dashboard 为例)

# 创建 Traefik Dashboard 路由规则 traefik-dashboard-route.yaml 文件

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

# 创建 Traefik Dashboard 路由规则对象

1$ kubectl apply -f traefik-dashboard-route.yaml -n kube-system

(2)、配置 HTTPS 路由规则(Kubernetes Dashboard 为例)

这里我们创建 KubernetesDashboard 看板创建路由规则,它是 Https 协议方式,由于它是需要使用 Https 请求,所以我们配置基于 Https 的路由规则并指定证书。

# 创建私有证书 tls.key、tls.crt 文件

1# 创建自签名证书
2$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=cloud.mydlq.club"
3
4# 将证书存储到 Kubernetes Secret 中
5$ kubectl create secret generic cloud-mydlq-tls --from-file=tls.crt --from-file=tls.key -n kube-system

# 创建 Traefik Dashboard CRD 路由规则 kubernetes-dashboard-route.yaml 文件

 1apiVersion: traefik.containo.us/v1alpha1
 2kind: IngressRoute
 3metadata:
 4  name: kubernetes-dashboard-route
 5spec:
 6  entryPoints:
 7  - websecure
 8  tls:
 9    secretName: cloud-mydlq-tls
10  routes:
11  - match: Host(`cloud.mydlq.club`) 
12    kind: Rule
13    services:
14      - name: kubernetes-dashboard
15        port: 443

# 创建 Kubernetes Dashboard 路由规则对象

1$ kubectl apply -f kubernetes-dashboard-route.yaml -n kube-system

2、方式二:使用 Ingress 方式配置 Traefik 路由规则

使用 Ingress 方式创建路由规则可言参考 Traefik 文档 Kubernetes Ingress

(1)、配置 HTTP 路由规则 (Traefik Dashboard 为例)

# 创建 Traefik Ingress 路由规则 traefik-dashboard-ingress.yaml 文件

 1apiVersion: extensions/v1beta1
 2kind: Ingress
 3metadata:
 4  name: traefik-dashboard-ingress
 5  namespace: kube-system
 6  annotations:
 7    kubernetes.io/ingress.class: traefik            
 8    traefik.ingress.kubernetes.io/router.entrypoints: web
 9spec:
10  rules:
11  - host: traefik.mydlq.club                                 
12    http:
13      paths:
14      - path: /              
15        backend:
16          serviceName: traefik
17          servicePort: 8080

# 创建 Traefik Dashboard Ingress 路由规则对象

1$ kubectl apply -f traefik-dashboard-ingress.yaml -n kube-system

(2)、配置 HTTPS 路由规则(Kubernetes Dashboard 为例)

跟上面以 CRD 方式创建路由规则一样,也需要创建使用证书,然后再以 Ingress 方式创建路由规则。

# 创建私有证书 tls.key、tls.crt 文件

1# 创建自签名证书
2$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=cloud.mydlq.club"
3
4# 将证书存储到 Kubernetes Secret 中
5$ kubectl create secret generic cloud-mydlq-tls --from-file=tls.crt --from-file=tls.key -n kube-system

# 创建 Traefik Dashboard Ingress 路由规则 kubernetes-dashboard-ingress.yaml 文件

 1apiVersion: extensions/v1beta1
 2kind: Ingress
 3metadata:
 4  name: kubernetes-dashboard-ingress
 5  namespace: kube-system
 6  annotations:
 7    kubernetes.io/ingress.class: traefik                  
 8    traefik.ingress.kubernetes.io/router.tls: "true"
 9    traefik.ingress.kubernetes.io/router.entrypoints: websecure
10spec:
11  tls:
12  - secretName: cloud-mydlq-tls
13  rules:
14  - host: cloud.mydlq.club                               
15    http:
16      paths:
17      - path: /                                     
18        backend:
19          serviceName: kubernetes-dashboard
20          servicePort: 443

# 创建 Traefik Dashboard 路由规则对象

1$ kubectl apply -f kubernetes-dashboard-ingress.yaml -n kube-system

四、方式创建路由规则后的应用

1、配置 Host 文件

客户端想通过域名访问服务,必须要进行 DNS 解析,由于这里没有 DNS 服务器进行域名解析,所以修改 hosts 文件将 Traefik 所在节点服务器的 IP 和自定义 Host 绑定。打开电脑的 Hosts 配置文件,往其加入下面配置:

1192.168.2.12  traefik.mydlq.club
2192.168.2.12  cloud.mydlq.club

2、访问对应应用

# 访问 Traefik Dashboard

打开浏览器输入地址:http://traefik.mydlq.club 打开 Traefik Dashboard。

# 访问 Traefik Dashboard

打开浏览器输入地址:https://cloud.mydlq.club 打开 Dashboard Dashboard。

到此文章结束,可以访问我的 Github 下载 部署文件,别忘点颗 Start!!

---End---


  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。