10.4.4 构建镜像以及创建 Pipeline
Tekton 的任务是在 Pod 只执行,如果在再使用 docker build 的方式编译镜像,就不合适了:
- 现在容器运行时大部分是 Containerd,不太可能再为构建镜像安装 Docker。
- 就算容器运行时是 Docker,Pod 内也得用特权模式访问 docker.sock ,因此产生安全问题。
那么,是否有一种能脱离 Docker,实现完全在容器内构建镜像的方式?当然有,这就是 Kaniko。
Kaniko 是什么
Kaniko 是谷歌开源的一款构建容器镜像的工具。Kaniko 并不依赖于 Docker 守护进程,完全在用户空间根据 Dockerfile 的内容逐行执行命令来构建镜像,这就使得在一些无法获取 docker 守护 进程的环境下也能够构建镜像。
图 10-7 Kaniko 如何工作
Kaniko 解析指定的 Dockerfile,先拉取基础镜像,然后按顺序执行 Dockerfile 中的每条指令(如 RUN、COPY、ADD),并将更改应用到镜像层中。构建完成后,Kaniko 将最终镜像推送到指定的远端镜像仓库。
定义了一个构建镜像的 Task,资源文件(build-and-push.yaml )内容如下所示
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:latest
env:
- name: DOCKER_CONFIG
value: /tekton/home/.docker
command:
- /kaniko/executor
- --dockerfile=Dockerfile
- --context=/workspace/repo/src
- --destination=isno/tekton-test:latest
Task 中的 steps 执行 /kaniko/executor,通过 --dockerfile 指定 Dockerfile 路径,--context 指定构建上下文,我们这里当然就是项目的根目录了,然后 --destination 参数指定最终我们的镜像名称。
到目前,我们已经完成两个 Task 的创建,现在再用 Pipeline 将这两个 Task 组织起来。
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: test-build-push
spec:
params:
- name: repo
type: string
tasks:
# 运行应用测试
- name: test
taskRef:
name: test
resources:
inputs:
- name: repo # Task 输入名称
resource: repo # Pipeline 资源名称
# 构建并推送 Docker 镜像
- name: build-and-push
taskRef:
name: build-and-push
runAfter:
- test # 测试任务执行之后
resources:
inputs:
- name: repo # Task 输入名称
resource: repo # Pipeline 资源名称
Pipeline 通过 spec.tasks 指定多个 task,然后根据 taskRef.name 关联到具体的 Task。
同样的,Pipeline 提交之后并不会被执行,再创建一个 PipelineRun 实例化和执行上面的 Pipeline。
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: test-build-push-run
spec:
pipelineRef:
name: test-build-push
params:
- name: repo
value: "https://github.com/isno/tekton-example"
使用 create 的方式将 PipelineRun 提交到 Kubernetes,之后就会触发我们的流水线任务了。
$ kubectl create -f test-build-push-run.yaml