使用 Kaniko 在Kubernetes平台上构建容器镜像

我们之前使用Jenkins构建容器镜像,做法是 Jenkins容器挂载宿主机的socket文件到容器内部,容器内部运行 docker build 就行。

但是这样有一个问题。如果宿主机的 docker daemon 重启的话,必须把Jenkins容器也重启一遍(因为原有socket文件已失效了,但是容器内部是不知道的,还用着原有的socket文件),否则就会报错。

另外由于 /var/run/docker.sock 文件是root权限,将其挂在在容器里就存在风险了,所以挂载socket文件不是一种优雅的 docker build 方式。

kaniko

Kaniko是谷歌开源的一款用来构建容器镜像的工具。Kaniko 不依赖于Docker daemon进程,它在用户空间根据 Dockerfile 的内容逐行执行命令来构建镜像,这就和宿主机上的docker解绑了,更加安全可靠。

Kaniko 以容器镜像的方式来运行的,同时需要三个参数: Dockerfile,上下文,以及远端镜像仓库的地址

  1. Kaniko会先提取基础镜像(Dockerfile FROM 之后的镜像)的文件系统
  2. 根据Dockerfile中所描述的,一条条执行命令,每一条命令执行完以后会在用户空间下面创建一个snapshot,并与存储与内存中的上一个状态进行比对,如果有变化,就将新的修改生成一个镜像层添加在基础镜像上,并且将相关的修改信息写入镜像元数据中。
  3. 等所有命令执行完,kaniko会将最终镜像推送到指定的远端镜像仓库。

demo

$ cat Dockerfile
FROM alpine:latest
    
MAINTAINER <devops008@sina.com xiaomage>
    
RUN apk add busybox-extras curl
    
CMD ["echo","Hello DevOps"]

在kubernetes cluster上面创建一个pod,yaml文件如下:

apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
 containers:
 - name: kaniko
   image: gcr.io/kaniko-project/executor:latest
   args: ["--dockerfile=/workspace/Dockerfile",
          "--context=/workspace/",
          "--destination=dllhb/kaniko-test:v0.4"]
    volumeMounts:
      - name: kaniko-secret
        mountPath: /kaniko/.docker
      - name: dockerfile
        mountPath: /workspace/Dockerfile
        subPath: Dockerfile
restartPolicy: Never
volumes:
      - name: dockerfile
        configMap:
          name: dockerfile
      - name: kaniko-secret
         projected:
         sources:
         - secret:
              name: regcred
              items:
                - key: .dockerconfigjson
                  path: config.json
  • args 部分

    这部分就是上面所讲的,kaniko运行时需要三个参数: Dockerfile(–dockerfile),上下文(–context),远端镜像仓库(–destination)

  • secret 部分

    推送至指定远端镜像仓库需要credential的支持,所以需要将credential以secret的方式挂载到/kaniko/.docker/这个目录下,文件名称为config.json,内容如下:

{   
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "AbcdEdfgEdggds="
       }
    }
    
}

其中auth的值为: echo"docker_registry_username:docker_registry_password"|base64

参考资料


俄罗斯会被踢出SWIFT吗?- 微信公众号 新程序员003:云原生和全面数字化实践