2

替代kubernetes crontab的神器kala

 2 years ago
source link: https://zhangrr.github.io/posts/20211125-kubernetes_crontab_kala/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

替代kubernetes Crontab的神器kala

2021-11-25 4 分钟阅读

本来 k8s 的 crontab 是启动一个容器来运行的,很简单,如下:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: curl-cron
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: curl-cron
            image: radial/busyboxplus:curl
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date;echo "run crontab";curl http://www.baidu.com
          restartPolicy: OnFailure
  successfulJobsHistoryLimit: 2
  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管理配置工具,项目地址:

https://github.com/ajvb/kala

image-20211125164706478

卡拉是基于 Airbnb 的 Chronos 翻写的 Go 程序。

它比 crontab 更好一些的是,可以指定未来某天的一次性执行任务,有个使用界面

Kala 可以执行本地的命令,也可以发起 http 的请求。

注意,kala 的源代码里有一个地方需要修改,否则参数bolt-path不生效,我们改掉它自己编译个2进制程序出来。

Modify cmd/server.go

switch viper.GetString("jobdb") {
case "boltdb":
db = boltdb.GetBoltDB(viper.GetString("boltpath"))

Change to
db = boltdb.GetBoltDB(viper.GetString("bolt-path"))

Run it :
./kala serve --jobdb=boltdb --bolt-path=/data/db
fallback

我们用 Dockerfile 造一个镜像出来:

FROM alpine:3.12
RUN apk add --update bash && rm -rf /var/cache/apk/*

COPY . /data/

RUN mkdir /lib64 && \
    ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 && \
    mv /data/kubectl /bin && \
    mv /data/.kube /root && \
    rm -rf /data/Dockerfile

WORKDIR /data
EXPOSE 8000

CMD ["/data/kala", "serve","--jobdb=boltdb","--bolt-path=/data/db"]
#CMD /bin/sh -c "while true; do echo hi; sleep 10; done"

注意上面我们把 kubectl 和 .kube 配置一起放进了镜像,当然一些 yaml 和脚本也可以都打进去,然后推到阿里云镜像仓库去(注意安全问题)。

备注 :kala默认的端口是8000,访问 url 是 /webui

然后我们生成一个 secret 放进 k8s

htpasswd -c auth kala-auth
New password:
Re-type new password:
Adding password for user kala

kubectl create secret generic kala-auth --from-file=kala-auth
secret "kala-auth" created

kubectl get secret kala-auth -o yaml

然后我们定义一系列的资源文件,Deployment、SVC、Ingress,其中 ingress 引用了 kala-auth 的 secret,并且指定了 app-root 是 /webui/。

另外 kala 使用了 k8s-kala-5g 的持久化卷,务必事先准备好 pv 和 pvc,不持久化的话 pod 一重启,之前保存的配置信息就全没了。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kala-deploy
  labels:
    app: kala
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kala
  template:
    metadata:
      labels:
        app: kala
    spec:
      containers:
      - name: kala
        image: registry.cn-shanghai.aliyun.com/xxx/kala:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8000
        volumeMounts:
        - mountPath: /data/db
          name: kala-data
      volumes:
        - name: kala-data
          persistentVolumeClaim:
            claimName: k8s-kala-5g
---
apiVersion: v1
kind: Service
metadata:
 name: kala-svc
 labels:
   app: kala
spec:
 ports:
 - name: http
   protocol: TCP
   port: 8000
   targetPort: 8000
 selector:
   app: kala
 type: ClusterIP
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: kala-com-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/block-cidrs: 111.201.134.93/32
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: kala-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - Kala'
    nginx.ingress.kubernetes.io/app-root: '/webui/'
spec:
  rules:
  - host: kala.rendoumi.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kala-svc
          servicePort: 80

这样 kala 就可以从公网访问了,http://kala.rendoumi.com:8000/ ,且需要提供密码才能进入。

下面说一下具体的用法,还是有一些技巧性的,登录进去后的页面:

image-20211125170959532

进入后左上角点击 Create 建立新任务

image-20211125171027673

要填写内容如下:

  • 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 就行了

然后我们可以再建一个恢复的任务

image-20211125171551356

我们去界面就可以看到多了两个任务,增大HPA和恢复HPA,这样就 OK 了

image-20211125171655096

注意:JOB一旦建立,以后就可以直接从界面上手动执行,Run Manually

image-20211125171831594

这东西真是个神器,产品部的同事可以随时修改hpa和恢复,而不用通过研发部了,善莫大焉。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK