
使用 Tekton Sidecar 实现 Docker IN Docker 构建
作者 |阳明
来源 | k8s技术圈(ID:kube100)
在 Tekton 中有一项 Sidecar 功能,和 Pod 中的 Sidecar 类似,它也是一个容器,用于和 Task 任务的 Steps 中指定的容器一起运行,为这些 Steps 的执行提供一些辅助支持,比如 Sidecar 可以运行一个 logging daemon、更新共享 volume 上的文件或者提供网络代理等功能。
Tekton 会将 Sidecar 注入属于 TaskRun 的 Pod,一旦 Task 中的所有 Steps 完成执行,Pod 内运行的每一个 Sidecar 就会终止掉,如果 Sidecar 成功退出,kubectl get pods 命令会将 Pod 的状态返回为 Completed,如果 Sidecar 退出时出现了错误,则返回 Error,而忽略实际执行 Pod 内部 Steps 的容器镜像的退出码值。
上面我们在构建容器镜像的时候是通过挂载宿主机的 docker.sock 文件到容器中来执行的,严格意义上来说这种方式叫 Dood - Docker Outside of Docker,DooD 通过绑定安装 Docker 套接字来使用其底层宿主机的 Docker Daemon,而真正的 DinD 是在其中包含一个完整的 Docker 服务。显然 DooD 这种方式更快,因为可以利用它的缓存机制,而 DinD 显然更加安全、更加干净,对宿主机产生的影响更小,而且支持并行运行,因为每个容器里面都是一个独立的 Docker Daemon,互相不受影响,当然 DooD 更加简单易用。这里我们就来使用 Sidecar 的方式为 Tekton 中的容器构建提供一个 DinD 模式的构建服务。
新建一个如下所示的 Task 任务,专门用来构建 Docker 镜像:
上面的 Task 最重要的就是其中的 sidecars 部分,使用了一个 docker:dind 镜像来提供 docker 服务端,由于是 sidecar 模式,所以它和上面构建的 steps 中的容器是共享 network namespace 的,所以在构建的时候我们可以通过 tcp://localhost:2376 和 docker 服务端进行通信,由于还使用的是 TLS 证书模式,所以需要将证书目录进行声明挂载。
接着重新修改我们的 Pipeline 流水线:
这里的流水线最重要的就是将镜像构建的任务替换成上面的 docker-build-push 这个 Task,然后传入几个需要的参数,接着修改 PipelineRun:
这里就比较简单了,只需要引用上面的 Pipeline 流水线,然后提供需要的几个参数即可,直接创建上面的几个资源对象即可执行我们的流水线了:
我们也可以看到很快就构建成功了:最终在 Harbor 中也可以看到我们刚刚推送的镜像版本:
这种方式还可以避免在宿主机上产生大量无用的构建过程产生的镜像,因为每次构建完成就销毁掉了,这才是真正的 Docker IN Docker,也是 Tekton 中的 Sidecar 的一个使用场景。
