前言

Ingress

Service可能会有很多,如果每个资源都绑定一个 node port的话,主机则需要开放外围的端口进行服务调用,管理上会比较混乱。

比较优雅的方式是通过一个外部的负载均衡器,比如 nginx ,绑定固定的端口比如80,然后根据域名/服务名向后面的Service Ip转发,但是这里对问题在于:当有新服务加入的时候如何修改 Nginx 配置?

手动改或者 Rolling Update Nginx Pod 都是不现实的。

对于这个问题, k8s 给出的七层解决方案是:Ingress

Traefik

Træfik 是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。 它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 来自动化、动态的应用它的配置文件设置。
Traefix是k3s里面的Ingress Controller。支持负载均衡和反向代理,类似于ngnix。

Traefik 的仪表板非常便捷,能够提供集群当前状态的详细概述,包括集群入口和服务网格路由配置的详细信息

k3s开启traefik dashboard(可视化面板不提供路由配置)

Traefik v1 启用 Dashborad

默认情况下,K3s 1.20 及更早版本默认安装 Traefik v1,并且默认没有启用 Traefik Dashboard。如果要在 K3s 中启用 Traefik v1 的 Dashborad,我们可以借助 HelmChartConfig 来自定义由 Helm 部署的 Traefik v1 并启用 Dashboard:

注意:

  • 不建议手动编辑 /var/lib/rancher/K3s/server/manifests/traefik.yaml 来修改 Traefik 配置文件,因为 K3s 重启后会覆盖修改的内容。
  • 建议通过在 /var/lib/rancher/K3s/server/manifests 中创建一个额外的 HelmChartConfig 清单来自定义 Traefik 配置,请参考:http://docs.rancher.cn/docs/K3s/helm/_index/
1
2
3
4
5
6
7
8
9
10
11
12
cat >> /var/lib/rancher/K3s/server/manifests/traefik-config.yaml << EOF
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
dashboard:
enabled: true
domain: "traefik.localhost"
EOF

此时,Traefik 将会重新部署,大约 10 秒钟左右,就可以通过 spec.valuesContent.domain 配置的域名来访问Traefik Dashboard 了:

Traefik v2 启用 Dashborad

默认情况下,K3s 1.21 及更高版本默认安装 Traefik v2。出于安全考虑,默认是不公开 Traefik Dashboard 的。我们常见的公开 Dashborad 的方式主要为以下两种:

方法 1:通过端口转发来实现

1
kubectl -n kube-system port-forward $(kubectl -n kube-system get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:900

端口转发开启后,可以通过http://127.0.0.1:9000/dashboard/ 来访问 Dashboard:

方法 2:自定义 IngressRoute CRD

另一种方法是通过定义和应用 IngressRoute CRD (kubectl apply -f dashboard.yaml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# dashboard.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: dashboard
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.example`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
kind: Rule
services:
- name: api@internal
kind: TraefikService

部署成功后,可通过 http://traefik.example/dashboard/ 访问 Dashboard:

测试样例

配置好一个ingress.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
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-test
# 声明命名空间
namespace: docker-demo
# 自定义注解(声明ingress controller),traefik
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
# 这里配置fronted,访问的host
- host: docker-demo.com
http:
paths:
# 配置backend,使用定义好的service,定义路径"/"必须配置,不配报错
- path: /
backend:
service:
# 映射到哪个service上
name: docker-demo
port:
# 这个service的内部端口号
number: 8080
pathType: Prefix
# 这里配置fronted,访问的host
- host: docker-demo2.com
http:
paths:
# 配置backend,使用定义好的service
- path: /
backend:
service:
# 映射到哪个service上
name: docker-demo2
port:
# 这个service的内部端口号
number: 8080
pathType: Prefix
# 这里配置fronted,访问的host
- host: docker-fronted.com
http:
paths:
# 配置backend,使用定义好的service
- path: /
backend:
service:
# 映射到哪个service上
name: docker-demo-frontend
port:
# 这个service的内部端口号
number: 80
pathType: Prefix

进行测试, 而且在traefik dashboard上也可以看到配置好的fronted和backend(见上面的图)

更多配置参考

Ingress 的pathType类型

  • ImplementationSpecific (默认): 对于这种类型,匹配取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 PrefixExact 类型作相同处理。
  • Exact:精确匹配 URL 路径,且对大小写敏感。
  • Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配对大小写敏感,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配

k3s 卸载 traefik

删除traefik

  • 删除 traefik 资源:

kubectl -n kube-system delete helmcharts.helm.cattle.io traefik

kubectl -n kube-system delete helmcharts.helm.cattle.io traefik-crd

修改 k3s.service 配置文件/禁用traefik

  • 停止k3s服务: systemctl stop k3s
  • 编辑服务文件vim /etc/systemd/system/k3s.service并将此行添加到ExecStart
1
--disable traefik \
  • 重新加载服务文件: systemctl daemon-reload
  • 从自动部署文件夹中删除清单文件: rm /var/lib/rancher/k3s/server/manifests/traefik.yaml
  • 启动k3s服务: systemctl restart k3s