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
参数来指定用来缓存的远程仓库。
遇到的问题
- 构建成功后有 push 失败的情况且原因不明
- Harbor 作为目标 registry 的时候,在 Web UI 看不到镜像(https://github.com/GoogleContainerTools/kaniko/issues/539)
Build on Kube
更多在 Kube 上构建镜像的讨论,请见:https://github.com/kubernetes/kubernetes/issues/1806