在 Kubernetes 环境中构建 Docker 镜像一直是一个挑战,传统的 Docker-in-Docker 方案存在安全风险和复杂性问题。Kaniko 作为 Google 开源的容器镜像构建工具,提供了一个安全、高效的解决方案。
什么是 Kaniko#
Kaniko 是由 Google 开发的开源工具,专门用于在容器或 Kubernetes 集群内构建容器镜像。它的核心优势包括:
主要特性#
- 无需 Docker Daemon: 不依赖 Docker 守护进程,避免了特权容器的安全风险
- Kubernetes 原生: 专为 Kubernetes 环境设计,可以作为 Pod 运行
- 安全性: 在用户空间执行,不需要特权权限
- 标准兼容: 完全兼容 Dockerfile 语法和 Docker 镜像格式
- 多平台支持: 支持推送到各种容器镜像仓库
使用场景#
- CI/CD 流水线: 在 Kubernetes 集群中构建镜像
- 安全环境: 需要避免特权容器的生产环境
- 云原生应用: 完全容器化的开发和部署流程
快速开始#
方法一:使用 Docker 命令行构建#
这种方法适合快速测试和本地开发环境:
第一步:准备认证配置#
# 创建 Docker 仓库认证信息(请替换为您的实际凭据)
echo -n "your_username:your_password" | base64
# 输出示例:eWFuZ3p1bjoxMjM0NTY=
# 创建 Docker 配置文件
cat > config.json << EOF
{
"auths": {
"https://your-registry.com/v2/": {
"auth": "eWFuZ3p1bjoxMjM0NTY="
}
}
}
EOF
安全提示:
- 请将示例中的用户名和密码替换为您的实际凭据
- 在生产环境中,建议使用 Kubernetes Secret 来管理认证信息
第二步:执行镜像构建#
# 创建简单的 Dockerfile 并使用 Kaniko 构建
echo -e 'FROM alpine \nRUN echo "created from standard input"' > Dockerfile | \
tar -cf - Dockerfile | gzip -9 | \
docker run --rm \
--interactive \
-v $(pwd):/workspace \
-v $(pwd)/config.json:/kaniko/.docker/config.json:ro \
gcr.io/kaniko-project/executor:v1.6.0 \
--context tar://stdin \
--destination=your-registry.com/kaniko-build:v1.0.0 \
--skip-tls-verify
参数说明:
--context tar://stdin: 从标准输入读取构建上下文--destination: 指定构建完成后推送的镜像地址--skip-tls-verify: 跳过 TLS 证书验证(仅用于测试环境)-v $(pwd)/config.json:/kaniko/.docker/config.json:ro: 挂载认证配置文件

图:Kaniko 镜像构建过程的控制台输出

基于 kubernetes 中 pod 构建镜像#
创建 localPV#
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: Immediate # Immediate or WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: kaniko-pv
spec:
storageClassName: local
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
local:
path: /data/kaniko/data/
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node3
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: kaniko-pvc
spec:
storageClassName: local
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
EOF

将之前创建的 config.json & dockerfile 创建为 secret 资源对象#
kubectl create secret generic kaniko-secret --from-file=./config.json
kubectl create secret generic kaniko-build-dockerfile --from-file=./Dockerfile
kubectl create secret generic kaniko-secret \
--from-file=config.json=./config.json \
--from-file=Dockerfile=./Dockerfile
pod 资源清单#
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
image: idocker.io/kaniko-project/executor:v1.6.0
args:
- "--dockerfile=/kaniko/.docker/Dockerfile"
- "--context=dir://workspace"
- "--destination=idocker.io/kaniko-build:v1.0.1"
- "--skip-tls-verify"
volumeMounts:
- name: docker-secret
readOnly: true
mountPath: /kaniko/.docker
- name: dockerfile-storage
mountPath: /workspace
restartPolicy: Never
volumes:
- name: dockerfile-storage
persistentVolumeClaim:
claimName: kaniko-pvc
- name: docker-secret
secret:
secretName: kaniko-secret
EOF


基于 python 项目进行实战构建#
Dockerfile 所需文件的准备#
cd /data/kaniko/data
git init
git remote add origin https://github.com/cdryzun/python-dockerfile-build.git
git pull https://github.com/cdryzun/python-dockerfile-build.git master
git pull
git branch --set-upstream-to=origin/master master
# rm -rf .git # 删除无用隐藏文件
使用 pod 进行构建#
kubectl delete po kaniko # 删除之前测试 pod
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
containers:
- name: kaniko
image: idocker.io/kaniko-project/executor:v1.6.0
args:
- "--dockerfile=/workspace/Dockerfile"
- "--context=/workspace/"
- "--destination=idocker.io/python-demo:v1.0.1"
- "--skip-tls-verify"
volumeMounts:
- name: docker-secret
readOnly: true
mountPath: /kaniko/.docker
- name: dockerfile-storage
mountPath: /workspace
restartPolicy: Never
volumes:
- name: dockerfile-storage
persistentVolumeClaim:
claimName: kaniko-pvc
- name: docker-secret
secret:
secretName: kaniko-secret
EOF


测试构建的容器#
docker run -it --name test -d --rm -p 18080:8080 idocker.io/python-demo:v1.0.1
curl 127.0.0.1:18080
Hello World

请求监听端口,可以看到容器正常进行了输出,表示容器正常可以正常使用。
参考文档#
https://github.com/GoogleContainerTools/kaniko
https://www.baeldung.com/ops/kaniko
