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