kaniko构建镜像的方式
docker构建镜像
用docker来构建容器镜像也是常用的方法,在具备构建容器镜像所需的两个要素(Dockerfile & 上下文)的前提下,用下述命令就能构建一个容器镜像出来
```Plain Text docker build -t yourregistry/yourrepository:tag .
然后用 `docker push` 将镜像推送到镜像仓库
Plain Text docker push yourregistry/yourrepository:tag
现在DevOps 的CI/CD环境大多数都会运行在容器内,镜像的构成也是在容器内完成的。这时候,通常用以下两种方式来完成容器内构建镜像的工作: ## 挂载宿主机的socket文件到容器内部
Plain Text docker run -it -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/kaniko:/tmp/kaniko docker
然后在容器内部用 `docker build` 构建镜像 由于docker依赖于 `docker daemon` 进程, `docker daemon` 进程是一个 `Unixsocket` 连接,且 `/var/run/docker.sock` 文件是root权限
Plain Text $ ls -ltr /var/run/docker.sock lrwxr-xr-x 1 root daemon 69 Nov 26 15:13 /var/run/docker.sock
说明只有root权限才能访问 `docker daemon` 进程,在 `docker daemon` 无法暴露或者用户没有权限获取 `docker daemon` 进程的前提下,用 `docker build` 来构建镜像就变的非常困难了。 可能我们会想,docker build镜像无非就是需要docker命令能运行成功,只要在容器里面安装一个docker不就成功了吗?这也就是下面讲的第二种方法。 ## dind(docker-in-docker) 这种方式不需要挂载宿主机的socket文件,但是需要以 **--privileged** 权限来以dind镜像创建一个容器
Plain Text $ docker run --rm -it --privileged docker:18.06-dind
然后在容器里面构建容器镜像并推送至远端仓库。 dind能够满足构建容器镜像的需求,但是从上面的命令看,有一个参数:**--privileged** 。意味这这个容器具有一些特权,他可能会看到宿主机上的一些设备,而且能够执行mount命令。 上述两种方法,都能满足在容器内构建容器镜像且推送镜像至远端仓库的需求,但是从security角度来讲,**需要root 权限(第一种方式),提供特权(第二种方式)** 都使得风险增大,在Kubernetes 多租户的场景下,这种风险是不能接受的。那是否有一种不需要特殊权限,还能快速构建容器镜像的方法呢?答案就是下面将的Kaniko。 # Kaniko [https://github.com/GoogleContainerTools/kaniko](https://github.com/GoogleContainerTools/kaniko) kaniko是谷歌开源的一款用来构建容器镜像的工具。与docker不同,Kaniko 并不依赖于Docker daemon进程,完全是在用户空间根据Dockerfile的内容逐行执行命令来构建镜像,这就使得在一些无法获取 `docker daemon` 进程的环境下也能够构建镜像,比如在**标准的Kubernetes Cluster**上。 Kaniko 以容器镜像的方式来运行的,同时需要三个参数: Dockerfile,上下文,以及远端镜像仓库的地址。 Kaniko会先提取基础镜像(Dockerfile FROM 之后的镜像)的文件系统,然后根据Dockerfile中所描述的,一条条执行命令,每一条命令执行完以后会在用户空间下面创建一个snapshot,并与存储与内存中的上一个状态进行比对,如果有变化,就将新的修改生成一个镜像层添加在基础镜像上,并且将相关的修改信息写入镜像元数据中。等所有命令执行完,kaniko会将最终镜像推送到指定的远端镜像仓库。 ## kaniko使用 Dockerfile
Dockerfile $ cat Dockerfile FROM alpine:latest
MAINTAINER
RUN apk add busybox-extras curl
CMD ["echo","Hello DevOps"]
pod yaml
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:
secret: name: regcred items: - key: .dockerconfigjson path: config.json
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:
需要说明几点: - args 部分 这部分就是上面所讲的,kaniko运行时需要三个参数: **Dockerfile(--dockerfile),上下文(--context),远端镜像仓库(--destination)** - secret 部分 推送至指定远端镜像仓库需要credential的支持,所以需要将credential以secret的方式挂载到/kaniko/.docker/这个目录下,文件名称为config.json,内容如下:
JSON
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "AbcdEdfgEdggds="
}
}
}
> 其中auth的值为: `echo"docker_registry_username:docker_registry_password"|base64` ## 参数 #### Flag `--build-arg` 此标志允许您在构建时传入 ARG 值,类似于 Docker。 您可以为多个参数多次设置它。 请注意,传递包含空格的值本身不受支持 - 您需要 以确保在执行程序命令之前将 IFS 设置为 null。您可以设置 这是通过在执行人调用之前添加的。请参阅以下内容 例`export IFS=''`
Plain Text export IFS='' /kaniko/executor --build-arg "MY_VAR='value with spaces'" … ```
Flag --dockerfile
dockerfile的路径. (默认值为 "Dockerfile")
Flag --force
在容器外强制构建
Flag --insecure-registry
使用http协议访问镜像仓库,不推荐生产环境使用。
Flag --no-push
只生成镜像,不推送到镜像仓库
Flag --skip-tls-verify
推送镜像时跳过tls证书验证,不推荐生产环境使用。
Flag --skip-tls-verify-pull
拉取镜像时跳过tls证书验证,不推荐生产环境使用。
Flag --skip-tls-verify-registry
访问指定镜像仓库时跳过tls验证,可多次使用来跳过多个镜像仓库,不推荐生产环境使用。