本来 k8s 的 crontab 是启动一个容器来运行的,很简单,如下:
1apiVersion: batch/v1beta1
2kind: CronJob
3metadata:
4 name: curl-cron
5spec:
6 schedule: "*/1 * * * *"
7 jobTemplate:
8 spec:
9 template:
10 spec:
11 containers:
12 - name: curl-cron
13 image: radial/busyboxplus:curl
14 imagePullPolicy: IfNotPresent
15 command:
16 - /bin/sh
17 - -c
18 - date;echo "run crontab";curl http://www.baidu.com
19 restartPolicy: OnFailure
20 successfulJobsHistoryLimit: 2
21 failedJobsHistoryLimit: 2
上面就跑了一个 busybox 的 pod,每分钟去访问百度,然后在 stdout 输出结果
这个没什么,注意上面文件的最后两行。限制成功以及失败 job 的 History 数量,如果不加限制,kubectl get pods 会看到无穷无尽的completed 状态的 curl-cron pod。
分割线,部署 crontab 的 yaml 很简单。但是,现在产品部有个需求,他们要在某一天进行促销活动,大概2天,期间会流量大增,于是想应用 hpa 来伸缩 pod,活动结束后关闭 hpa。之后他们还会有不断的促销,研发不知道什么时候开始,什么时候结束;但是研发又不想产品部看到 yaml,并且随时配合部署 hpa。
还有个问题,如果用crontab,那么活动开始运行一次,活动结束一次,最后研发还得清理删除掉这两个 crontab 来恢复正常。
这下麻烦了,有什么页面管理 crontab 的神器,能让产品部自己运行,然后权限分离,而且能指定再未来的某天运行一次或多次,且不用手工清理就好了。
还真的有一个,kala 就是了!!!
Kala 是一个cron管理配置工具,项目地址:
卡拉是基于 Airbnb 的 Chronos 翻写的 Go 程序。
它比 crontab 更好一些的是,可以指定未来某天的一次性执行任务,有个使用界面
Kala 可以执行本地的命令,也可以发起 http 的请求。
注意,kala 的源代码里有一个地方需要修改,否则参数bolt-path不生效,我们改掉它自己编译个2进制程序出来。
1Modify cmd/server.go
2
3switch viper.GetString("jobdb") {
4case "boltdb":
5db = boltdb.GetBoltDB(viper.GetString("boltpath"))
6
7Change to
8db = boltdb.GetBoltDB(viper.GetString("bolt-path"))
9
10Run it :
11./kala serve --jobdb=boltdb --bolt-path=/data/db
我们用 Dockerfile 造一个镜像出来:
1FROM alpine:3.12
2RUN apk add --update bash && rm -rf /var/cache/apk/*
3
4COPY . /data/
5
6RUN mkdir /lib64 && \
7 ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 && \
8 mv /data/kubectl /bin && \
9 mv /data/.kube /root && \
10 rm -rf /data/Dockerfile
11
12WORKDIR /data
13EXPOSE 8000
14
15CMD ["/data/kala", "serve","--jobdb=boltdb","--bolt-path=/data/db"]
16#CMD /bin/sh -c "while true; do echo hi; sleep 10; done"
注意上面我们把 kubectl 和 .kube 配置一起放进了镜像,当然一些 yaml 和脚本也可以都打进去,然后推到阿里云镜像仓库去(注意安全问题)。
备注 :kala默认的端口是8000,访问 url 是 /webui
然后我们生成一个 secret 放进 k8s
1htpasswd -c auth kala-auth
2New password:
3Re-type new password:
4Adding password for user kala
5
6kubectl create secret generic kala-auth --from-file=kala-auth
7secret "kala-auth" created
8
9kubectl get secret kala-auth -o yaml
然后我们定义一系列的资源文件,Deployment、SVC、Ingress,其中 ingress 引用了 kala-auth 的 secret,并且指定了 app-root 是 /webui/。
另外 kala 使用了 k8s-kala-5g 的持久化卷,务必事先准备好 pv 和 pvc,不持久化的话 pod 一重启,之前保存的配置信息就全没了。
1---
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: kala-deploy
6 labels:
7 app: kala
8spec:
9 replicas: 1
10 selector:
11 matchLabels:
12 app: kala
13 template:
14 metadata:
15 labels:
16 app: kala
17 spec:
18 containers:
19 - name: kala
20 image: registry.cn-shanghai.aliyun.com/xxx/kala:latest
21 imagePullPolicy: Always
22 ports:
23 - containerPort: 8000
24 volumeMounts:
25 - mountPath: /data/db
26 name: kala-data
27 volumes:
28 - name: kala-data
29 persistentVolumeClaim:
30 claimName: k8s-kala-5g
31---
32apiVersion: v1
33kind: Service
34metadata:
35 name: kala-svc
36 labels:
37 app: kala
38spec:
39 ports:
40 - name: http
41 protocol: TCP
42 port: 8000
43 targetPort: 8000
44 selector:
45 app: kala
46 type: ClusterIP
47---
48apiVersion: networking.k8s.io/v1beta1
49kind: Ingress
50metadata:
51 name: kala-com-ingress
52 annotations:
53 kubernetes.io/ingress.class: nginx
54 nginx.ingress.kubernetes.io/block-cidrs: 111.201.134.93/32
55 nginx.ingress.kubernetes.io/auth-type: basic
56 nginx.ingress.kubernetes.io/auth-secret: kala-auth
57 nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - Kala'
58 nginx.ingress.kubernetes.io/app-root: '/webui/'
59spec:
60 rules:
61 - host: kala.rendoumi.com
62 http:
63 paths:
64 - path: /
65 backend:
66 serviceName: kala-svc
67 servicePort: 80
这样 kala 就可以从公网访问了,http://kala.rendoumi.com:8000/ ,且需要提供密码才能进入。
下面说一下具体的用法,还是有一些技巧性的,登录进去后的页面:
进入后左上角点击 Create 建立新任务
要填写内容如下:
-
Job name:起个名字,叫:增大HPA
-
Command:要运行的脚本:/data/resize.sh 35 (固定扩大ECI的脚本)
-
Schedule:R0/2021-07-07T06:00:00+08:00/PT0S
这个最重要
这行的格式是这样的:Number of times to repeat/Start Datetime/Interval Between Runs
R0 重复0次,即只执行一次,不重复
2021-07-06T06:00:00+8:00 时间戳,注意时区中国+8:00
PT0S 无延迟0S启动
合起来就是
R0/2021-07-07T06:00:00+08:00/PT0S 就是在2021年7月7日中国时间6点无任何延迟执行一次脚本 resize.sh
- Reset Form 这个一定要选掉,保持空,否则下次进来上次的数据都没了,还得手动输入,麻烦
其他都不填写,然后 Create 就行了
然后我们可以再建一个恢复的任务
我们去界面就可以看到多了两个任务,增大HPA和恢复HPA,这样就 OK 了
注意:JOB一旦建立,以后就可以直接从界面上手动执行,Run Manually
这东西真是个神器,产品部的同事可以随时修改hpa和恢复,而不用通过研发部了,善莫大焉。