1. 概述

在本教程中,我们将介绍如何使用 Kaniko 构建容器镜像。

2. 什么是 Kaniko

Kaniko 是一个可以根据 Dockerfile 构建容器镜像的工具。与 Docker 不同,Kaniko 不需要依赖 Docker 守护进程

✅ 这意味着在没有 root 权限的环境中(例如 Kubernetes 集群)也可以运行 Kaniko。

Kaniko 使用一个执行器镜像 gcr.io/kaniko-project/executor,在容器中运行。它在用户空间中逐条执行 Dockerfile 中的指令,并在每条指令执行后对文件系统进行快照。

如果文件系统发生了变化,Kaniko 会将变化部分作为“diff”层保存下来,并更新镜像的元数据。

Kaniko 支持在以下环境中运行:

  • Kubernetes 集群 ✅ 常用于 CI/CD 流水线中
  • gVisor
  • Google Cloud Build

在本教程中,我们将在 Kubernetes 集群中运行 Kaniko。

3. 安装 Minikube

我们将使用 Minikube 在本地搭建一个单节点的 Kubernetes 集群。

下载并安装 Minikube:

$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 &&
  chmod +x minikube

将 Minikube 添加到系统路径:

$ sudo mkdir -p /usr/local/bin/
$ sudo install minikube /usr/local/bin/

确认 Docker 守护进程正在运行:

$ docker version

启动 Minikube 集群:

$ minikube start --driver=docker

启动成功后,会看到类似如下提示:

Done! kubectl is now configured to use "minikube"
For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/

验证集群状态:

$ minikube status

输出应类似:

m01
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

接下来安装 kubectl 命令行工具:

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s \
  https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl &&
  chmod +x ./kubectl

将其添加到系统路径:

$ sudo mv ./kubectl /usr/local/bin/kubectl

验证安装:

$ kubectl version

4. 使用 Kaniko 构建镜像

现在我们已经准备好了一个 Kubernetes 集群,可以开始使用 Kaniko 构建镜像了。

4.1 创建构建上下文目录

我们需要创建一个本地目录,作为 Kaniko 的构建上下文。

SSH 进入 Minikube:

$ minikube ssh
$ mkdir kaniko && cd kaniko

创建一个简单的 Dockerfile,用于测试:

$ echo 'FROM ubuntu' >> dockerfile
$ echo 'ENTRYPOINT ["/bin/bash", "-c", "echo hello"]' >> dockerfile

查看内容:

$ cat dockerfile

输出应为:

FROM ubuntu
ENTRYPOINT ["/bin/bash", "-c", "echo hello"]

记录当前目录路径(用于后续配置):

$ pwd

输出类似:

/home/docker/kaniko

退出 SSH:

$ exit

4.2 Kaniko 执行器参数说明

Kaniko 执行器镜像支持以下关键参数:

参数 说明
--dockerfile 指定 Dockerfile 文件路径
--context 构建上下文路径,支持 GCS、S3、Git 仓库、本地目录等
--destination 构建完成后推送的目标镜像仓库地址(可选)
--no-push 禁止推送镜像,仅本地构建(我们本教程使用此参数)

更多参数详见 Kaniko GitHub 文档

4.3 配置 Kubernetes 资源文件

我们接下来创建所需的 Kubernetes 配置文件。

1. 创建 PersistentVolume

文件名:volume.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: dockerfile
  labels:
    type: local
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /home/docker/kaniko # 替换为你之前 pwd 的输出

2. 创建 PersistentVolumeClaim

文件名:volume-claim.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: dockerfile-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: local-storage

3. 创建 Pod 配置

文件名:pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args: ["--dockerfile=/workspace/dockerfile",
            "--context=dir://workspace",
            "--no-push"]
    volumeMounts:
      - name: dockerfile-storage
        mountPath: /workspace
  restartPolicy: Never
  volumes:
    - name: dockerfile-storage
      persistentVolumeClaim:
        claimName: dockerfile-claim

4.4 应用配置并运行

依次应用配置:

$ kubectl create -f volume.yaml
$ kubectl create -f volume-claim.yaml
$ kubectl create -f pod.yaml

检查 Pod 状态:

$ kubectl get po

输出应类似:

NAME     READY   STATUS      RESTARTS   AGE
kaniko    0/1   Completed       0        3m

查看构建日志:

$ kubectl logs kaniko

输出应包含如下内容:

INFO[0000] Resolved base name ubuntu to ubuntu          
INFO[0000] Resolved base name ubuntu to ubuntu          
INFO[0000] Retrieving image manifest ubuntu             
INFO[0003] Retrieving image manifest ubuntu             
INFO[0006] Built cross stage deps: map[]                
INFO[0006] Retrieving image manifest ubuntu             
INFO[0008] Retrieving image manifest ubuntu             
INFO[0010] Skipping unpacking as no commands require it. 
INFO[0010] Taking snapshot of full filesystem...        
INFO[0013] Resolving paths                              
INFO[0013] ENTRYPOINT ["/bin/bash", "-c", "echo hello"] 
INFO[0013] Skipping push to container registry due to --no-push flag

✅ 我们可以看到 Kaniko 一步步执行了 Dockerfile 中的指令,并最终构建出镜像,但因为设置了 --no-push,所以没有推送到仓库。

5. 小结

本教程中我们介绍了 Kaniko 的基本用法,包括:

  • Kaniko 的特点:无需 Docker 守护进程,适合在 Kubernetes 等环境中运行
  • 使用 Minikube 搭建本地 Kubernetes 环境
  • 编写 Dockerfile、配置 PV/PVC 和 Pod 描述文件
  • 使用 Kaniko 构建镜像并查看日志

如需查看完整代码,欢迎访问 GitHub 示例仓库

⚠️ 注意: 本教程没有涉及镜像推送,实际生产环境中你可能需要配置私有镜像仓库和认证信息。


原始标题:An Introduction to Kaniko