10.4.3 使用 Kaniko 构建镜像

我们编译镜像大部分使用 docker build 的方式,而现在大部分的 CI/CD 系统运行在容器内,如果要在容器内编译镜像,你或许会想到将宿主机上的 /var/run/docker.sock 文件通过 hostPath 的方式挂载到 pod 容器内。

但这种方式存在明显的缺陷:得在宿主机额外安装 Docker 且有安全风险。那是否有一种能摆脱 Docker,能快速安全的构建容器镜像的方法呢?这就是下面要介绍的 Kaniko。

Kaniko 是什么

Kaniko 是谷歌开源的一款构建容器镜像的工具。

Kaniko 并不依赖于 Docker 守护进程,完全在用户空间根据 Dockerfile 的内容逐行执行命令来构建镜像,这就使得在一些无法获取 docker 守护 进程的环境下也能够构建镜像。

Kaniko 如何工作

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

集成 Kaniko 到 Tekton 流水线

有了 kaniko,在 Pod 内构建镜像就变得简单了。如下定义了一个镜像编译的 Task。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-and-push
spec:
  resources:
    inputs:
      - name: repo
        type: git
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor:v1.3.0
      env:
        - name: DOCKER_CONFIG
          value: /tekton/home/.docker
      command:
        - /kaniko/executor
        - --dockerfile=Dockerfile
        - --context=/workspace/repo/src
        - --destination=arthurk/tekton-test:latest

2. 镜像构建

熟悉常用的 Dockerfile 指令之后,我们可以开始尝试通过 Dockerfile 构建一个 Nginx 镜像。

#第1阶段
FROM skillfir/alpine:gcc AS builder01
RUN wget https://nginx.org/download/nginx-1.24.0.tar.gz -O nginx.tar.gz && \
tar -zxf nginx.tar.gz && \
rm -f nginx.tar.gz && \
cd /usr/src/nginx-1.24.0 && \
 ./configure --prefix=/app/nginx --sbin-path=/app/nginx/sbin/nginx && \
  make && make install
  
#第2阶段
FROM skillfir/alpine:glibc
RUN apk update && apk upgrade && apk add pcre openssl-dev pcre-dev zlib-dev 

COPY --from=builder01 /app/nginx /app/nginx
WORKDIR /app/nginx
EXPOSE 80
CMD ["./sbin/nginx","-g","daemon off;"]

制作镜像

docker build -t alpine:nginx .

查看镜像产物

$ docker images 
REPOSITORY                TAG             IMAGE ID       CREATED          SIZE
alpine                    nginx           ca338a969cf7   17 seconds ago   23.4MB

测试镜像

docker run --rm --name nginx -p 80:80 alpine:nginx

构建镜像最有挑战性之一的就是使用镜像尽可能小,小的镜像不论在大规模集群部署、故障转移、存储成本方面都有巨大的优势,以下是一些镜像构建的小技巧:

  • 选用精简的基础镜像
  • 使用多阶段构建
  • COPY ADD 和 RUN 命令都会增加镜像层数,所以构建镜像时可以通过合并 RUN 指令减少叠加层,同时 RUN 命令最后可以通过一些工具的清理命令如yum clean conda clean --all来清理缓存,以此来减小 RUN 层的大小
总字数:783
Last Updated:
Contributors: isno