跳过正文
  1. 博客文章/

使用 Kaniko 在 Kubernetes 中构建 Docker 镜像

·468 字·3 分钟·
Kubernetes DevOps Kaniko Docker Kubernetes CI/CD
Zayn
作者
Zayn
专注 Kubernetes、CI/CD、可观测性等云原生技术栈,记录生产环境中的实战经验与踩坑复盘。
目录

在 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 构建过程示例

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

image-20210615113608623

基于 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

image-20210615104008433

将之前创建的 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

image-20210615113730435

image-20210615113747518

基于 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

image-20210615144347957

image-20210615144430652

测试构建的容器
#

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

image-20210615144554104

请求监听端口,可以看到容器正常进行了输出,表示容器正常可以正常使用。

参考文档
#

https://github.com/GoogleContainerTools/kaniko

https://www.baeldung.com/ops/kaniko

ToDo
#

相关文章

在 Kubernetes 中使用 localPv 部署 Gitlab
·616 字·3 分钟
Kubernetes DevOps Ingress Gitlab CI/CD Localpv Postgres Redis
使用 Helm 部署 Spinnaker 持续部署(CD)平台
·1378 字·7 分钟
DevOps Kubernetes Helm Spinnaker CI/CD
企业级 GitLab 平台部署与运维完整指南
·3964 字·19 分钟
Docker Docker Compose DevOps Gitlab Docker Devops Git CI/CD