目录

kubernetes应用-清理docker镜像缓存

利用 Openkruise AdvancedCronJob 清理 kubernetes 宿主机镜像缓存.

需求背景

IDC 机房因为发布比较频繁,docker 镜像拉取频繁,kubernetes 宿主机节点磁盘利用率经常到达 90% 的阈值触发 pod 驱逐事件,导致某些服务会有短时间内的报错,如果不及时清理,会有 pod 不断被驱逐,处于被驱逐状态的 pod kubernetes 也是不会自动清理的。

使用 Openkruise 的 AdvancedCronJob 资源,每天定时执行清理操作,清理14天前无效镜像,使节点磁盘使用率保持在 90% 以下不触发驱逐。

注意
关于 Openkruise ,可以登录他们的官网了解,这里不做过多赘述:访问官方文档

实施步骤

接下来我们来看看具体怎么操作。

1. 安装 Openkruise

通过 helm 安装

建议采用 helm v3.5+ 来安装 Kruise,helm 是一个简单的命令行工具可以从 这里 获取。

1
2
3
4
5
6
7
8
# Firstly add openkruise charts repository if you haven't do this.
$ helm repo add openkruise https://openkruise.github.io/charts/

# [Optional]
$ helm repo update

# Install the latest version.
$ helm install kruise openkruise/kruise --version 1.1.0
技巧
具体 helm chart 参数可以参考 这里 给出的参数.

2. 创建 AdvancedCronJob

AdvancedCronJob 跟原生的 cronjob 有点像,只不过他可以做到类似于守护进程一样,每个节点都拉起一个 job 。

 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
apiVersion: apps.kruise.io/v1alpha1
kind: AdvancedCronJob
metadata:
  name: clean-docker-images-cache
  namespace: kruise-system
spec:
  schedule: "52 04 * * *"
  startingDeadlineSeconds: 60
  template:
    broadcastJobTemplate:
      spec:
        template:
          spec:
            containers:
              - name: clean-docker-images-cache
                image: docker:latest
                securityContext:
                  privileged: true
                  runAsUser: 0
                command: ["/bin/sh", "-c"]
                args: ["/usr/local/bin/docker image prune -a -f --filter 'until=336h'"]
                volumeMounts:
                  - mountPath: /etc/localtime
                    name: volume-localtime
                  - mountPath: /var/run/docker.sock
                    name: docker-sock
                    readOnly: false
                  - mountPath: "/data/docker"
                    name: docker-directory
                    readOnly: false
                resources:
                  limits:
                    cpu: '1'
                    memory: 2Gi
                  requests:
                    cpu: 200m
                    memory: 500Mi
            volumes:
              - hostPath:
                  path: /etc/localtime
                  type: ''
                name: volume-localtime
              - hostPath:
                  path: /var/run/docker.sock
                  type: 'Socket'
                name: docker-sock
              - name: docker-directory
                hostPath:
                  path: /var/lib/docker
            restartPolicy: Never
        completionPolicy:
          type: Always
          ttlSecondsAfterFinished: 300
        failurePolicy:          
          type: Continue          
          restartLimit: 3
信息

资源要点:

  1. 使用 docker in docker 的镜像,过滤要删除的镜像参数 --filter 'until=336h'。

  2. 把宿主机的 docker.socke ,数据目录挂载进 pod ,我把时区挂载进去实际没有用到,定时任务读的还是 api 的时间。

  3. 要保证 startingDeadlineSeconds 时间,小于 ttlSecondsAfterFinished 的时间,不然会有重复创建 BroadcastJob bug 。

  4. 资源不要创建到有开启 istio 自动注入的命名空间上,不然注入了 sidecar 容器后,任务会一直 running 状态无法退出, sidecar 容器健康检查会一直失败一直重启。

这样将 yaml 文件应用到 kubernetes 集群后,每个节点都会定时去执行,master 节点除外,因为 master 有打污点,没打容忍度,而且上面并没有业务容器,不需要执行。