Kaniko:无需特权在 Kubernetes 中构建镜像

2019/01/29 15:52 pm posted in  Kubernetes

Kaniko 是 Google 造的轮子之一,用于在 Kubernetes 上无需特权的构建 docker image,在 github(https://github.com/GoogleContainerTools/kaniko) 中,是这样介绍的:

kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster.

工作原理

传统的 Docker build 是 Docker daemon 根据 Dockerfile,使用特权用户(root)在宿主机依次执行,并生成镜像的每一层:

而 Kaniko 工作原理和此类似,也是按顺序执行每条命令,每条命令执行完毕后为文件系统做快照(snapshot)。并与上一个快照进行对比,如果发现任何不一致,变回创建一个新的层级,并将任何修改都写入镜像的元数据中。

当 Dockerfile 中每条命令都执行完毕后,Kaniko将新生成的镜像 push 到指定的 registry。

使用

Kaniko 解决了在 Kubernetes 构建的问题,但是构建的项目、目标 registry 的认证、Dockerfile 的分发,还是需要我们自己考虑。为了简单,我直接把项目代码、Dockerfile 放在某个 node 的 /root 下。

# pwd
/root/flask-demo
# ls
Dockerfile  README.md  app.py  requirements.txt  test.py

Dockerfile:

FROM python:3.6
RUN mkdir /catking
WORKDIR /catking
COPY ./requirements.txt /catking

RUN pip install -r requirements.txt -i https://pypi.douban.com/simple/
COPY . /catking

CMD ["python", "app.py"]

EXPOSE 5000

首先是解决目标 registry 的认证问题,官方文档中的样例是通过添加一个kaniko-secret.json 并把内容赋值给 GOOGLE_APPLICATION_CREDENTIALS 这个环境变量,如果是自建 registry 可以直接使用 docker config。

# echo "{\"auths\":{\"172.16.105.1\":{\"username\":\"username\",\"password\":\"password\"}}}" > config.json
# kubectl create configmap docker-config --from-file=config.json
configmap/docker-config created

使用 Pod 构建镜像:

apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    image: daocloud.io/gcr-mirror/kaniko-project-executor:latest
    args: ["--dockerfile=/demo/Dockerfile",
            "--context=/demo",
            "--insecure=true",
            "--skip-tls-verify=true",
            "--destination=172.16.105.1/demo/flask-web:v1"]
    volumeMounts:
      - name: docker-config
        mountPath: /kaniko/.docker/
      - name: project-volume
        mountPath: /demo
  restartPolicy: Never
  volumes:
    - name: docker-config
      configMap:
        name: docker-config
    - name: project-volume
      hostPath:
        path: /root/flask-demo
  nodeSelector:
    k8s.ihypo.net/build: kaniko

构建日志

镜像

补充

GCR 镜像获取不到

可以将

gcr.io/kaniko-project/executor
gcr.io/kaniko-project/warmer

替换为

daocloud.io/gcr-mirror/kaniko-project-executor
daocloud.io/gcr-mirror/kaniko-project-warmer

Debug

可以使用 debug 镜像进入 debug 模式:

daocloud.io/gcr-mirror/kaniko-project-executor:debug

构建缓存

可以使用 --cache=true 开启构建缓存,如果是本地缓存,将会使用 --cache-dir 定义的缓存目录。
也可以使用 --cache-repo 参数来指定用来缓存的远程仓库。

遇到的问题

  1. 构建成功后有 push 失败的情况且原因不明
  2. Harbor 作为目标 registry 的时候,在 Web UI 看不到镜像(https://github.com/GoogleContainerTools/kaniko/issues/539

Build on Kube

更多在 Kube 上构建镜像的讨论,请见:https://github.com/kubernetes/kubernetes/issues/1806