欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 使用 Kaniko来构建镜像

使用 Kaniko来构建镜像

2025/5/18 20:00:17 来源:https://blog.csdn.net/u010339879/article/details/148035775  浏览:    关键词:使用 Kaniko来构建镜像

使用 Kaniko来构建镜像

Kaniko 是一种专注于容器镜像构建的开源工具,其核心设计理念与 Docker 存在显著差异。以下从功能定位、技术实现和适用场景三方面进行对比分析:


一、Kaniko 的核心特性

  1. 无需 Docker 守护进程
    Kaniko 直接在容器或 Kubernetes 集群中运行,完全脱离 Docker 守护进程(Docker Daemon)。这种设计通过消除对特权模式的依赖,提升了安全性和资源利用率。
  2. 基于用户空间的构建流程
    它会逐行解析 Dockerfile,提取基础镜像文件系统,并在用户空间内执行每条指令,通过快照比对生成镜像层,最后推送至镜像仓库。此过程避免了传统 Docker 构建中的权限依赖。
  3. 云原生场景优化
    专为 Kubernetes 和 CI/CD 流水线设计,支持通过 Secret 挂载凭证,可直接集成到 Jenkins 等工具中,实现自动化构建。

二、与 Docker 的主要区别

对比维度KanikoDocker
架构依赖无需 Docker Daemon,独立运行于容器环境依赖 Docker Daemon 执行构建任务
安全性容器隔离构建,避免挂载宿主机敏感文件需挂载 /var/run/docker.sock ,存在特权风险
适用环境Kubernetes、无 Docker 环境的云原生场景本地开发环境、传统 Docker 宿主机
构建效率并行构建技术缩短时间,但受网络/缓存影响本地构建速度快,但集群场景需额外配置
镜像推送强制要求构建后推送至远程仓库支持本地存储或手动推送

三、典型使用场景建议

  1. Kubernetes 集群内构建
    当宿主机未安装 Docker 或需避免特权模式时(如 Kubernetes v1.24+ 默认使用 containerd),Kaniko 是更安全的选择。
  2. 高安全要求的 CI/CD 流水线
    在 Jenkins 等工具中,通过 Pod 模板调用 Kaniko,可避免暴露宿主机 Docker 套接字,符合安全合规要求。
  3. 多平台镜像构建
    支持 --platform 参数指定目标架构(如 linux/amd64),适合跨平台交付场景。

四、性能注意事项

尽管 Kaniko 具备并行构建优势,但实际速度可能受基础镜像拉取延迟缓存配置(如 --cache-repo 参数优化)和上下文传输方式(如 GCS/S3 存储桶)影响,需结合网络环境调优。


五、Kaniko的优势

Kaniko作为一个创新的容器镜像构建工具,在云原生时代提供了显著的优势,特别是在高效且灵活的容器镜像构建方面。以下是Kaniko的主要优势:

无守护进程构建

Kaniko无需Docker守护进程即可独立运行,这不仅节省了资源,还提高了构建效率。这种设计使得Kaniko在资源有限的环境中也能高效工作,特别是在Kubernetes集群或容器环境中。

安全隔离

Kaniko在单独的容器中执行构建,与宿主机系统隔离,从而增强了安全性。这种隔离机制可以有效防止潜在的安全威胁影响到宿主系统。

构建速度快

Kaniko使用并行构建技术,显著缩短了构建时间。这意味着用户可以在短时间内完成复杂的构建任务,节省宝贵的时间。

高度可定制

Kaniko允许用户定制构建过程,包括添加自定义脚本和修改构建环境,以满足特定的需求。这种灵活性使得Kaniko能够满足不同项目和环境的多样化需求。

易于集成

Kaniko可以轻松集成到CI/CD流水线中,实现自动构建和部署。这使得Kaniko成为持续集成和持续部署流程中的重要组成部分,提高了开发和部署的自动化水平。

在Kubernetes环境中的应用

Kaniko非常适合在Kubernetes环境中构建镜像,可以无缝集成,简化镜像构建和部署。这种集成方式不仅提高了效率,还增加了系统的可靠性。

对云原生应用的支持

Kaniko是云原生应用镜像构建的理想选择,可快速构建和部署,满足敏捷开发的要求。这种快速构建和部署的能力使得Kaniko在云原生应用的开发和运维中发挥着重要作用。

微服务架构的支持

Kaniko也适用于微服务架构的镜像构建,可独立构建每个微服务,实现高效的开发和部署。这种支持使得Kaniko在微服务架构的推广和应用中具有重要意义。

未来前景

随着云原生应用和微服务架构的发展,Kaniko的作用将越来越重要,成为构建容器镜像的标准工具,为开发者提供更快速、更安全、更定制化的构建体验。

综上所述,Kaniko以其无守护进程构建、安全隔离、快速构建、高度可定制、易于集成等优势,在容器镜像构建领域占据了重要地位,特别是在云原生和微服务架构的应用中,Kaniko展现出了巨大的潜力和价值。

kaniko 使用命令常用参数

说一下 kaniko 的使用 ,参数 其实和docker build 类似,需要知道 上下文 context ,dockerfile 的位置信息, destination 构建镜像完成后 要推送的地址 ,skip-tls-verify 跳过检查 https 以及配置缓存相关的。

// 构建镜像  
def buildImage(Map config) {def kanikoCommand = '/usr/local/bin/executor ' +"--context dir://${config.WORKSPACE} " +"--dockerfile ${config.WORKSPACE}/Dockerfile " +"--destination ${config.IMAGE_TAG} " +'--skip-tls-verify ' +'--verbosity=info ' +'--cache=true ' +"--cache-repo ${config.DOCKER_REGISTRY}/cache-repo/${config.IMAGE_NAME} " +'--cache-ttl=168h ' +'--cache-dir=/kaniko/.cache 'echo "Building Docker image for ${config.envType} environment with Kaniko"try {echo "Current working directory: ${pwd()}"container('kaniko') {sh '''/usr/local/bin/executor version'''sh "${kanikoCommand}"}} catch (err) {error "Failed to build Docker image: ${err}"}
}
创建秘钥

配置 kaniko 使用 Docker 注册表凭证

kubectl create secret docker-registry regcred \--namespace=dev \--docker-server=172.19.89.106:12300 \--docker-username=admin \--docker-password=xxxxxxxxxx

这个命令是用来在 Kubernetes 集群中创建一个名为 regcred 的 Docker registry 类型的 Secret。这个 Secret 用于存储访问私有 Docker registry 所需的认证信息,以便 Kubernetes 能够拉取私有仓库中的镜像。具体来说,该命令的作用如下:

  • kubectl create secret docker-registry regcred: 使用 kubectl 命令行工具创建一个类型为 docker-registry 的 Secret。regcred 是这个 Secret 的名称,您可以在需要引用此 Secret 时使用这个名字。

  • --namespace=dev: 指定这个 Secret 应该被创建在哪个命名空间(namespace)中。这里指定的是 dev 命名空间。Kubernetes 中的资源是按命名空间来组织的,这有助于对不同环境或团队的资源进行隔离。

  • --docker-server=172.19.89.106:12300: 指定 Docker registry 的服务器地址。在这个例子中,它是一个位于 172.19.89.106 的私有 Docker registry,并且监听着 12300 端口。

  • --docker-username=admin: 指定用于登录 Docker registry 的用户名。这里是 admin

  • --docker-password=xxxxxxxxxx: 指定与上述用户名关联的密码。这里是 xxxxxxxxxx

创建了这个 Secret 后,您可以在 Pod 或其他 Kubernetes 资源定义中引用它,以确保 Kubernetes 在尝试从指定的 Docker registry 拉取镜像时能够提供正确的认证信息。例如,在 Pod 的定义中,您可以添加 imagePullSecrets 字段,并将 regcred 作为值之一,这样 Kubernetes 就知道使用这个 Secret 来获取必要的认证凭据。

kubectl get secret regcred   -n dev  -o yamlapiVersion: v1
data:.dockerconfigjson: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6ImFkbWluNzMxIiwiYXV0aCI6IllXUnRhVzQ2WVdSdGFXNDNNekU9In19fQ==
kind: Secret
metadata:creationTimestamp: "2025-04-10T06:29:02Z"name: regcrednamespace: devresourceVersion: "58990830"uid: f50b2868-1a0f-46e1-88c1-a8bc70c119b1
type: kubernetes.io/dockerconfigjson
在Pipeline 中的一个Stage 中
stage('Build CODE') {steps {script {String branchName = params.BRANCHString envType = params.ENVecho """\Build CODE:WORKSPACE: ${WORKSPACE}envType: ${envType}branchName: ${branchName}""".stripIndent()sh 'ls -al'/* groovylint-disable-next-line VariableTypeRequired */def String gitSha = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()def String currentDate = sh(returnStdout: true, script: 'date +%Y%m%d').trim()// 设置 IMAGE_TAG 环境变量 动态传值/* groovylint-disable-next-line LineLength */env.IMAGE_TAG = "${DOCKER_REGISTRY}/${IMAGE_NAME}/${SHORT_NAME}:${branchName}-${currentDate}-${gitSha}"// 打印 image  tagecho "current tag:  ${env.IMAGE_TAG}"// 构建镜像 和推送镜像buildImage([envType: envType,branchName: branchName,WORKSPACE: WORKSPACE,IMAGE_TAG: env.IMAGE_TAG,DOCKER_REGISTRY: DOCKER_REGISTRY,IMAGE_NAME: IMAGE_NAME,SHORT_NAME: SHORT_NAME])}}
}
#!/bin/bash # 重新打tag 
docker tag gcr.io/kaniko-project/executor:v1.23.0  172.19.89.106:12300/library/kaniko-project/executor:v1.23.0docker login -uadmin -padmin-xxxxx-xxxx 172.19.89.106:12300docker push 172.19.89.106:12300/library/kaniko-project/executor:v1.23.0

把官方镜像 推送的私有仓库。 这个镜像 一旦开始启动 就停止了,不像其他镜像 可以一直常驻在前台,可以理解为 一次性容器我想在容器起来之后 ,根据需要 创建我的容器镜像 tag ,需要根据 时间或者分支名 组合生成,而不是传入一个destination 定义固定的值。

比如上面的例子中:TAG 生成逻辑,当前分支,当前日志,以及git提交的hash值

/* groovylint-disable-next-line VariableTypeRequired */
def String gitSha = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
def String currentDate = sh(returnStdout: true, script: 'date +%Y%m%d').trim()// 设置 IMAGE_TAG 环境变量 动态传值
/* groovylint-disable-next-line LineLength */
env.IMAGE_TAG = "${DOCKER_REGISTRY}/${IMAGE_NAME}/${SHORT_NAME}:${branchName}-${currentDate}-${gitSha}"
// 打印 image  tag
echo "current tag:  ${env.IMAGE_TAG}"
官方镜像改造

我对官方的镜像 进行了一点点改造

# 第一阶段:使用 kaniko 构建应用
FROM 172.19.89.106:12300/library/kaniko-project/executor:v1.23.0 AS builder
# FROM gcr.io/kaniko-project/executor:v1.23.0 AS builder# 第二阶段:使用一个适合运行时环境的基础镜像
FROM alpine:latest# 安装 busybox
RUN apk add --no-cache busybox# 创建一个符号链接,使得 /bin/sh 指向 busybox 的 sh
RUN ln -sf /bin/busybox /bin/sh# 从第一阶段复制 /kaniko/executor 到第二阶段
COPY --from=builder /kaniko/executor /usr/local/bin/executor
COPY --from=builder /kaniko/executor /kaniko/executor
# 将 /usr/local/bin 添加到 PATH(如果它还没有在 PATH 中)
ENV PATH=/kaniko:/usr/local/bin:$PATH# 设置默认的 ENTRYPOINT 和 CMD
ENTRYPOINT ["/usr/local/bin/executor"]CMD ["--help"]
# 重新构建镜像
docker  build . -t  172.19.89.106:12300/library/kaniko-project/executor:v1.23.0-v1# 保存镜像 到文件 
docker save -o executor-v1.tar  172.19.89.106:12300/library/kaniko-project/executor:v1.23.0-v1# 加载镜像
docker load -i executor.tar# 推送到 私有仓库中
docker  push  172.19.89.106:12300/library/kaniko-project/executor:v1.23.0-v1

这样的好处 这样镜像中有了 sh 环境, 在启动容器的 时候, 我就可以通过

  - name: kanikoimage: 172.19.89.106:12300/library/kaniko-project/executor:v1.23.0-v1imagePullPolicy: IfNotPresentcommand: ["/bin/sh"]args: ["-c", "tail -f /dev/null"]  # 保持容器运行env:- name: DOCKER_CONFIG   # 这个配置指向该卷来传递凭证value: /home/jenkins/agent/.dockervolumeMounts:- name: docker-configmountPath: /home/jenkins/agent/.docker- name: workspace-volumemountPath: /home/jenkins/agent- name: kaniko-cache    # kaniko 缓存相关mountPath: /kaniko/.cachesecurityContext:runAsUser: 0resources:requests:memory: "1Gi"  # 根据实际需求调整cpu: "500m"     # 根据实际需求调整limits:memory: "2Gi"cpu: "1000m"volumes:- name: workspace-volumeemptyDir: {}- name: docker-configsecret:secretName: regcreditems:- key: .dockerconfigjsonpath: config.json- name: kaniko-cachepersistentVolumeClaim:claimName: kaniko-cache-pvc

把docker-config 挂载到 /home/jenkins/agent/.docker 这个目录下面,kanio 就可以有权限来推送镜像了。

通过tail -f 让容器 一直运行状态,之后 我需要执行构建镜像的时候 传入 镜像的名称即可。

六、Q&A : Kaniko 构建完成后 会自动推送镜像吗?

A: Kaniko 在构建完成后会自动推送镜像到指定的 Docker 注册表。这是 Kaniko 的一个关键特性之一,它不仅负责构建 Docker 镜像,还会将构建好的镜像推送到你指定的目标仓库。

是的,Kaniko 在构建完成后会自动推送镜像到指定的 Docker 注册表。这是 Kaniko 的一个关键特性之一,它不仅负责构建 Docker 镜像,还会将构建好的镜像推送到你指定的目标仓库。

具体工作原理

  1. 构建镜像Kaniko 会读取 Dockerfile 并按照其中的指令逐层构建镜像。
  2. 推送镜像:在构建完成后,Kaniko 会直接将构建好的镜像推送到你通过 --destination 参数指定的 Docker 注册表。这个过程不需要与 Docker 守护进程交互,也不需要挂载 Docker Socket。

如何确保 Kaniko 推送镜像

为了确保 Kaniko 能够成功推送镜像,你需要满足以下条件:

  1. 提供有效的 Docker 注册表凭证

    • Kaniko 需要访问 Docker 注册表的权限,因此你必须提供有效的用户名和密码(或令牌)。这通常通过 Kubernetes Secret 来实现。
    • 在 Jenkins Pipeline 中,我们通过挂载 docker-config 卷并将 DOCKER_CONFIG 环境变量指向该卷来传递凭证。
  2. 正确设置 --destination 参数

    • --destination 参数指定了目标镜像的完整路径,包括注册表地址、仓库名称和标签。例如:

      --destination 172.19.89.106:12300/zhiexa-web-official/web-official:master-20241210-fd880b6
      
    • 确保这个路径是正确的,并且你有权限推送镜像到该位置。

  3. 网络连接

    • Kaniko 需要能够访问 Docker 注册表的网络地址。确保你的 Kubernetes 集群中的 Pod 可以访问外部网络或私有注册表的地址。

示例命令

在 Jenkins Pipeline 中,Kaniko 的调用命令如下:

sh """/kaniko/executor \--context dir://${WORKSPACE} \--dockerfile ${WORKSPACE}/Dockerfile \--destination ${env.IMAGE_TAG} \--build-arg BUILD_ENV=${envType}
"""

在这个命令中:

  • --context 指定了构建上下文的路径,通常是代码库的根目录。
  • --dockerfile 指定了 Dockerfile 的路径。
  • --destination 指定了目标镜像的完整路径,Kaniko 会在构建完成后将镜像推送到这个位置。
  • --build-arg 用于传递构建时的参数(如 BUILD_ENV)。

验证推送是否成功

你可以通过以下方式验证 Kaniko 是否成功推送了镜像:

  1. 日志输出Kaniko 会在控制台输出详细的构建和推送日志。如果你看到类似以下的日志,说明推送成功:

    Pushing layer sha256:xxxxxxxxxxxxx
    Pushing manifest for 172.19.89.106:12300/zhiexa-web-official/web-official:master-20241210-fd880b6
    Successfully pushed 172.19.89.106:12300/zhiexa-web-official/web-official:master-20241210-fd880b6
    
  2. 检查注册表:你也可以手动登录到 Docker 注册表,查看是否已经有新镜像被推送。

注意事项

  • 私有注册表:如果你使用的是私有 Docker 注册表,确保你已经正确配置了凭证,并且 Kaniko 有权限推送镜像。
  • 防火墙和网络策略:确保 Kubernetes 集群中的网络策略允许 Pod 访问 Docker 注册表的地址。
  • 镜像标签:确保你为镜像设置了唯一的标签(如基于 Git 提交哈希或构建时间),以避免覆盖旧版本的镜像。

总结

Kaniko 在构建完成后会自动推送镜像到指定的 Docker 注册表,而无需额外的推送步骤。只要确保提供了正确的凭证和网络访问权限,Kaniko 就可以顺利完成构建和推送任务。Kaniko 是不需要 Docker Daemon 比较适合K8S 环境来构建镜像。

参考文档

kanio github

分享快乐,留住感动. '2025-03-17 23:21:10' --frank

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词