【Traefik】3 - Sablier
背景
我的测试环境有两个Deployment,我想在开发的时候启动,30分钟没请求后自动关闭,不占用资源。
Sablier就解决了这个问题,它支持Kubernetes,并且支持Traefik。
环境
traefik: v2.9.10
kubernetes: v1.24.6+k3s1
Sablier: v1.7.0
安装
在K3S中,我们已经内置了Traefik,所以如果想安装插件,我们需要对内置的Traefik进行改造,添加插件。
由于K3S会周期性的执行 /var/lib/rancher/k3s/server/manifests
目录下的所有yaml,而如果我们修改了默认的traefik.yaml
,K3S会自动恢复默认文件,所以我们这里需要新建一个yaml文件,用HelmChartConfig
的方式修改traefik安装的配置即可。
创建配置文件 nano /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
1 | apiVersion: helm.cattle.io/v1 |
- additionalArguments用于添加插件的启动参数,在启动Traefik时,他会自动下载,需要注意的是,他是自主访问github下载的,如果网络不通畅,下载插件会失败,但Traefik会正常启动,导致所有使用了fail2ban的Middleware全部失效,所以启动后还要确保有没有fail2ban的成功日志信息
- experimental用于启动插件(新版本好像不配置也可以)
- allowCrossNamespace允许跨命名空间调用(比如我在A命名空间创建了有关fail2ban的Middleware,但我想在B命名空间同样使用这个Middleware,所以需要允许跨命名空间调用)
- allowEmptyServices启用后,服务不可用返回5xx,如果不启用,服务返回404(该插件必须必须启用)
- 因为自带的Traefik版本比较低,所以指定下新版本的镜像,亲测在2.10版本中无法使用,所以只能升级到2.9版本的,在自带的2.6版本同样无法使用,会报
plugin: unknown plugin type: fail2ban
的错误,重启也无效
部署
创建Sablier用户文件
sablier-sa.yaml
,然后执行kubectl apply -f sablier-sa.yaml
1
2
3
4
5apiVersion: v1
kind: ServiceAccount
metadata:
name: sablier
namespace: kube-system创建Sablier角色文件
sablier-cr.yaml
,然后执行kubectl apply -f sablier-cr.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: sablier
namespace: kube-system
rules:
- apiGroups:
- apps
- ""
resources:
- deployments
- deployments/scale
- statefulsets
- statefulsets/scale
verbs:
- patch # Scale up and down
- get # Retrieve info about specific deployment or statefulset
- update # Scale up and down
- list # Events
- watch # Events创建Sablier角色绑定文件
sablier-crb.yaml
,然后执行kubectl apply -f sablier-crb.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sablier
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: sablier
subjects:
- kind: ServiceAccount
name: sablier
namespace: kube-system创建Sablier Deployment文件
sablier-deployment.yaml
,然后执行kubectl apply -f sablier-deployment.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
27apiVersion: apps/v1
kind: Deployment
metadata:
name: sablier-deployment
namespace: kube-system
labels:
app: sablier
spec:
replicas: 1
selector:
matchLabels:
app: sablier
template:
metadata:
labels:
app: sablier
spec:
serviceAccountName: sablier
serviceAccount: sablier
containers:
- name: sablier
image: acouvreur/sablier:1.7.0
args:
- "start"
- "--provider.name=kubernetes"
ports:
- containerPort: 10000创建Sablier Service文件
sablier-service.yaml
,然后执行kubectl apply -f sablier-service.yaml
1
2
3
4
5
6
7
8
9
10
11
12apiVersion: v1
kind: Service
metadata:
name: sablier
namespace: kube-system
spec:
selector:
app: sablier
ports:
- protocol: TCP
port: 10000
targetPort: 10000使用
kubectl -n kube-system get deployments
查看Sablier是否创建成功:1
2
3
4
5
6NAME READY UP-TO-DATE AVAILABLE AGE
local-path-provisioner 1/1 1 1 8m25s
coredns 1/1 1 1 8m25s
metrics-server 1/1 1 1 8m24s
traefik 1/1 1 1 3m25s
sablier-deployment 1/1 1 1 90s或者使用
kubectl -n kube-system logs deployments/sablier-deployment
查看是否启动成功:1
2
3
4time="2022-11-14T01:40:49Z" level=info msg="(version=1.1.1, branch=HEAD, revision=a913bc2a3b0f4aca5b9ac7ddc9af5428ef411dba)"
time="2022-11-14T01:40:49Z" level=info msg="using provider \"kubernetes\""
time="2022-11-14T01:40:49Z" level=info msg="initialized storage to /etc/sablier/state.json"
time="2022-11-14T01:40:49Z" level=info msg="server listening :10000"现在,在cluster中,就可以用
http://sablier:10000
访问了。
Middleware
创建Traefik Middleware 文件code-server-sablier-middleware.yaml
然后执行 kubectl apply -f code-server-sablier-middleware.yaml
1 | apiVersion: traefik.containo.us/v1alpha1 |
其中spec.plugin.sablier.names
是我们侦测的服务,因为我的两个都是Deployment,所以deployment
开头,然后是命名空间test-app
,然后是服务名test-api
,最后因为我只有1个pod,所以根据pod名称再加上1
,最后这些用_
连接即可,多个服务用逗号分割
最终的规则如下:类型_命名空间_服务名_1
,对于其他的配置,详细查看官方文档
接下来添加到你的Ingress即可
1 | apiVersion: networking.k8s.io/v1 |
测试
直接访问服务即可,你会看到加载页,pod处于健康后,流量会从sablier转到对应服务中,session到期后,pod数量会自动缩减为0,然后自动删除。经测试,有时候是不太准确启动的,比如启动了第一个,第二个有很小的几率没启动,好像是因为version的原因导致启动失败了,总之,这尽量用于不太重要的服务或者前端页面,对于后端而言还是测试环境吧~