目录

kubernetes应用-清理docker镜像缓存

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

需求背景

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

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

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

实施步骤

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

1. 安装 Openkruise

通过 helm 安装

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

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 有打污点,没打容忍度,而且上面并没有业务容器,不需要执行。