- Traefik 官方文档地址: Traefik Document
- 部署参考文档: kubernetes部署traefik
- Helm 部署方式参考: traefik-helm-chart
部署环境
- kubernetes 版本: 1.20.11
- CPU 架构: loongarch64
- 系统版本: Kylin Linux Advanced Server V10 (Tercel)
- Traefik 版本: v2.9.4
- 部署方式: DaemonSet
Traefik 简介
Træfɪk 是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。 它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 来自动化、动态的应用它的配置文件设置。
构建 Traefik 镜像
下载源码
从 GitHub 下载 traefik 源码
1
git clone -b v2.9.4 https://github.com/traefik/traefik.git
编译前端文件
由于 loong64 架构编译前端时可能会缺少很多的依赖,这里可以现在 x86 架构上预先编译好前端 webui 相关的文件
修改 webui/Dockerfile 文件,在 yarn install 之前设置 yarn 的 registry 源为
https://registry.npm.taobao.org
,如下所示1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17FROM node:14.16
# Current Active LTS release according to (https://nodejs.org/en/about/releases/)
ENV WEBUI_DIR /src/webui
RUN mkdir -p $WEBUI_DIR
COPY package.json $WEBUI_DIR/
COPY yarn.lock $WEBUI_DIR/
WORKDIR $WEBUI_DIR
RUN yarn config set registry https://registry.npm.taobao.org && \
yarn install
COPY . $WEBUI_DIR/
EXPOSE 8080
RUN yarn lint执行以下命令,编译 webui 前端文件
1
make generate-webui
生成的前端文件在
webui/static
目录,将该目录拷贝到 loong64 架构上的traefik/webui/
目录下,替换原来的 static 目录1
2
3
4
5
6
7
8
9
10
11tree ./webui/static/ -L 1
./webui/static/
├── css
├── DONT-EDIT-FILES-IN-THIS-DIRECTORY.md
├── fonts
├── img
├── index.html
├── js
└── statics
cd webui && tar zcvf static.tar.gz static/
编译 Traefik 二进制文件
在编译之前需要修改 go.mod 文件,替换
golang.org/x/sys
模块版本为v0.1.0
,否则编译会报错1
2
3
4
5
6
7
8
9# 修改 go.mod 文件,添加 golang.org/x/sys => golang.org/x/sys v0.1.0 到 replace 语句
// Containous forks
replace (
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20220627093034-b2dd784e613f
github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
golang.org/x/sys => golang.org/x/sys v0.1.0
)更新 mod,下载依赖
1
2
3
4
5
6go mod tidy
# 执行以下命令,编译二进制文件
export GOPROXY="https://goproxy.cn,direct"
go mod download替换 webui/static 目录为之前编译好的前端文件
1
2rm -rf webui/static && tar xf static.tar.gz -C webui/
编译 traefik
1
2
3
4
5
6# 设置 VERSION 环境变量,否则编译后的 traefik 文件版本号会是 git 当前的 HEAD 值
export VERSION=v2.9.4
# 编译
./script/make.sh generate binary编译好的 traefik 二进制文件会在 dist 目录下,测试 traefik 文件
1
2
3
4
5
6$ ./dist/traefik version
Version: v2.9.4
Codename: cheddar
Go version: go1.19
Built: 2022-11-04_03:22:18上午
OS/Arch: linux/loong64
构建镜像,推送到仓库
构建镜像
1
docker build -t registry-changsha.vonebaas.com/kubernetes/ingress-traefik/traefik:v2.9.4 .
推送镜像到 Hub 仓库
1
docker push registry-changsha.vonebaas.com/kubernetes/ingress-traefik/traefik:v2.9.4
部署 Traefik
traefik 有多种部署方式,可以以 deploymen/daemonset 方式手动部署,也可以使用helm来快速部署。也可以使用 Helm 方式部署
前置条件
创建 traefik 服务部署命名空间
1
kubectl create ns ingress-traefik
由于是使用 DaemonSet 方式部署,为避免在每个节点都部署 traefik 服务,所以需要先在节点打上标签
1
kubectl label nodes k8s-node01 ingress=true
创建 CRD 资源
在 traefik v2.1 版本后,开始使用 CRD(Custom Resource Definition)来完成路由配置等,所以需要提前创建 CRD 资源。
crd 配置可以在 kubernetes-crd 找到,展开 Configuration Examples 有相关配置文件
执行以下命令,创建 traefik CRD 配置
1
kubectl apply -f 00-traefik-crd.yaml
创建 RBAC 权限管理
创建 01-traefik-rbac.yaml 文件,文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-account
namespace: ingress-traefik
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- middlewaretcps
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
- serverstransports
verbs:
- get
- list
- watch
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-role
subjects:
- kind: ServiceAccount
name: traefik-account
namespace: ingress-traefik创建 RBAC 资源
1
kubectl create -f 01-traefik-rbac.yaml
创建 ConfigMap
由于 Traefik 配置很多,通过 CLI 定义不是很方便,一般选择将其配置选项放到配置文件中,然后存入 ConfigMap,将其挂入 traefik 中。
创建 02-traefik-cm.yaml 文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
namespace: ingress-traefik
data:
traefik.yaml: |-
ping: "" ## 启用 Ping
serversTransport:
insecureSkipVerify: true ## Traefik 忽略验证代理服务的 TLS 证书
api:
insecure: true ## 允许 HTTP 方式访问 API
dashboard: true ## 启用 Dashboard
debug: false ## 启用 Debug 调试模式
metrics:
prometheus: "" ## 配置 Prometheus 监控指标数据,并使用默认配置
entryPoints:
web:
address: ":80" ## 配置 80 端口,并设置入口名称为 web
websecure:
address: ":443" ## 配置 443 端口,并设置入口名称为 websecure
providers:
kubernetesCRD: "" ## 启用 Kubernetes CRD 方式来配置路由规则
kubernetesIngress: "" ## 启动 Kubernetes Ingress 方式来配置路由规则
log:
filePath: "" ## 设置调试日志文件存储路径,如果为空则输出到控制台
level: error ## 设置调试日志级别
format: json ## 设置调试日志格式
accessLog:
filePath: "" ## 设置访问日志文件存储路径,如果为空则输出到控制台
format: json ## 设置访问调试日志格式
bufferingSize: 0 ## 设置访问日志缓存行数
filters:
#statusCodes: ["200"] ## 设置只保留指定状态码范围内的访问日志
retryAttempts: true ## 设置代理访问重试失败时,保留访问日志
minDuration: 20 ## 设置保留请求时间超过指定持续时间的访问日志
fields: ## 设置访问日志中的字段是否保留(keep 保留、drop 不保留)
defaultMode: keep ## 设置默认保留访问日志字段
names: ## 针对访问日志特别字段特别配置保留模式
ClientUsername: drop
headers: ## 设置 Header 中字段是否保留
defaultMode: keep ## 设置默认保留 Header 中字段
names: ## 针对 Header 中特别字段特别配置保留模式
User-Agent: redact
Authorization: drop
Content-Type: keep更多参数说明请参考: Static Configuration: File
创建 configmap 资源
1
kubectl create -f 02-traefik-cm.yaml
部署 Traefik 服务
使用 DaemonSet 方式部署,便于在多服务器间扩展,用 hostport 方式占用服务器 80、443 端口,方便流量进入。
创建 traefik 部署文件 03-traefik-ds.yaml,文件内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76kind: DaemonSet
apiVersion: apps/v1
metadata:
name: traefik
namespace: ingress-traefik
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-account
nodeSelector:
ingress: "true"
hostNetwork: true
containers:
- name: traefik
image: registry-changsha.vonebaas.com/kubernetes/ingress-traefik/traefik:v2.9.4
args:
- --configfile=/etc/traefik/traefik.yaml
ports:
- name: web
containerPort: 80
hostPort: 80 ## 将容器端口绑定所在服务器的 80 端口
- name: websecure
containerPort: 443
hostPort: 443 ## 将容器端口绑定所在服务器的 443 端口
- name: dashboard
containerPort: 8080 ## Traefik Dashboard 端口
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
volumeMounts:
- name: config
mountPath: /etc/traefik
volumes:
- name: config
configMap:
name: traefik-config
tolerations:
- operator: "Exists"
apiVersion: v1
kind: Service
metadata:
name: traefik-svc
namespace: ingress-traefik
spec:
type: ClusterIP
ports:
- targetPort: 80
port: 80
name: web
- targetPort: 443
port: 443
name: websecure
- targetPort: 8080
port: 8080
name: dashboard
selector:
app: traefik部署 traefik 服务
1
kubectl create -f 03-traefik-ds.yaml
到此 Traefik v2.9.4 应用已经部署完成。
Traefik 路由规则配置
配置 HTTP 路由规则 (Traefik Dashboard 为例)
Traefik 应用已经部署完成,但是想让外部访问 Kubernetes 内部服务,还需要配置路由规则,这里开启了 Traefik Dashboard 配置,所以首先配置 Traefik Dashboard 看板的路由规则,使外部能够访问 Traefik Dashboard。
创建 Traefik Dashboard 的路由规则文件 04-traefik-dashboard-route.yaml,文件内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
namespace: ingress-traefik
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.vonebaas.com`)
kind: Rule
services:
- name: traefik-svc
port: 8080创建 Traefik Dashboard 路由规则对象
1
kubectl create -f 04-traefik-dashboard-route.yaml
配置 Host 解析
1
111.207.111.194 traefik.vonebaas.com
配置 HTTPS 路由规则(Kubernetes Dashboard 为例)
这里我们创建 Kubernetes 的 Dashboard 看板,它是 Https 协议方式,由于它是需要使用 Https 请求,所以我们配置基于 Https 的路由规则并指定证书。
创建证书文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 创建自签名证书
openssl req \
-x509 \
-nodes \
-days 3650 \
-newkey rsa:2048 \
-keyout tls.key \
-out tls.crt \
-subj "/CN=kubernetes.vonebaas.com"
# 将证书存储到 Kubernetes Secret 中
kubectl create secret generic kubernetes-dashboard-tls \
--from-file=tls.crt \
--from-file=tls.key \
-n kubernetes-dashboard创建 Traefik Dashboard 路由规则文件 05-kubernetes-dashboard-route.yaml,文件内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: kubernetes-dashboard-route
namespace: kubernetes-dashboard
spec:
entryPoints:
- websecure
tls:
secretName: kubernetes-dashboard-tls
routes:
- match: Host(`kubernetes.vonebaas.com`)
kind: Rule
services:
- name: kubernetes-dashboard
port: 443创建 Kubernetes Dashboard 路由规则对象
1
kubectl create -f 05-kubernetes-dashboard-route.yaml
配置 Host 解析
1
111.207.111.194 kubernetes.vonebaas.com
高可用配置
方案一
默认只在一个节点上启用了 traefik ,该节点故障将导致应用访问失败,一般在生产环境可以选择2个 node 节点设为专属的 taefik 边缘节点,以达到高可用的目的。
下面再启用一个节点开启traefik转发功能:
1
kubectl label nodes k8s-node02 ingress=true
为 k8s-node02 节点打上标签后 daemonset 会自动运行一个新的 pod,下次创建新的 ingressroute 规则时服务将在所有的 traefik 节点启用端口
1
2
3
4# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
traefik-l8dfh 1/1 Running 0 73m 192.168.201.170 k8s-node02 <none> <none>
traefik-s8pt8 1/1 Running 0 50m 192.168.201.245 k8s-node01 <none> <none>此时修改本地 hosts 解析,任一 traefik 节点停机都不影响对 traefik.vonebaas.com 的访问
1
2192.168.201.170 traefik.vonebaas.com
192.168.201.245 traefik.vonebaas.com实际生产环境需要在互联网边缘使用专用的负载均衡设备将请求转发到内网 kubernetes 集群的多个 ingress 节点上。
方案二
除了使用以上方式实现高可用方案以外,还可以通过配置 keepalived 的 vip 模拟统一的访问入口,具体配置参考