使用 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/81331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webman用nginx代理静态json文件的异步跨域

场景 有.json文件置于webman的public目录下,使用了nginx做代理,直接访问文件是可以正常加载的,但跨域浏览器就无法加载文件。 nginx配置 文件是否存在于跟目录,存在则设置请求头,不存在则将请求交给webman处理即可。…

JDK 21新特性全面解析

Java Development Kit (JDK) 21作为Oracle长期支持(LTS)版本,于2023年9月正式发布,带来了多项令人振奋的新特性和改进。本文将全面介绍JDK 21中的主要更新,帮助开发者了解如何利用这些新功能提升开发效率和代码质量。 一、虚拟线程(Virtual …

如何选择高性价比的 1T 服务器租用服务​

选择高性价比的 1T 服务器租用服务​,可参考以下内容: 1、根据需求选配置​ 明确自身业务需求是关键。若为小型网站或轻量级应用,数据存储与处理需求不高,选择基础配置服务器即可。如个人博客网站,普通的 Intel Xeon …

JavaScript性能优化实战(11):前沿技术在性能优化中的应用

引言 随着Web应用复杂度和性能需求不断提高,传统的JavaScript优化技术已经无法满足某些高性能计算场景的需求。本文将深入探讨前沿Web技术如何突破JavaScript的性能瓶颈,为Web应用提供接近原生应用的性能体验。从底层计算到图形渲染,从并发处理到动画优化,我们将通过实际案…

package.json 和 package-lock.json 的区别

package.json​​ ​​作用​​ ​​声明项目元数据​​:如项目名称、版本、描述、入口文件等。​​定义依赖范围​​:在 dependencies 和 devDependencies 中声明项目​​直接依赖​​的包及其​​版本范围​​(如 ^1.2.3)。​​…

Rollup入门与进阶:为现代Web应用构建超小的打包文件

我们常常面临Webpack复杂配置或是Babel转译后的冗余代码,结果导致最终的包体积居高不下加载速度也变得异常缓慢,而在众多打包工具中Rollup作为一个轻量且高效的选择,正悄然改变着这一切,本文将带你深入了解这个令人惊艳的打包工具…

基于C#的MQTT通信实战:从EMQX搭建到发布订阅全解析

MQTT(Message Queueing Telemetry Transport) 消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点。 它被设计用于低带宽,不稳定或高延迟的…

Mysql数据库之集群进阶

一、日志管理 5.7版本自定义路径时的文件需要自己提前创建好文件,不会自动创建,否则启动mysql会报错 错误日志 rpm包(yum) /var/log/mysql.log 默认错误日志 ###查询日志路径 [rootdb01 ~]# mysqladmin -uroot -pEgon123 variables | grep -w log_e…

当硅基存在成为人性延伸的注脚:论情感科技重构社会联结的可能性

在东京大学机器人实验室的档案室里,保存着一份泛黄的二战时期设计图——1943年日本陆军省秘密研发的“慰安妇替代品”草图。这个诞生于战争阴霾的金属躯体,与2025年上海进博会上展出的MetaBox AI伴侣形成时空对话:当人类将情感需求投射于硅基…

5月17日

这几天不知道为啥没更新。可能是玩得太疯了。或者是考试有点集中?? 线性代数开课了,英语昨天完成了debate 昨天中午debate结束我们就出去玩了,去的那里时光民俗,别墅很好,770平米,但是缺点是可…

FIFO的应用案例(基于Zephyr OS )

目录 概述 1. 软硬件环境 1.1 软件开发环境 1.2 硬件环境 2 FIFO的函数接口 3 FIFO的应用函数实现 3.1 实现步骤 3.2 代码设计 3.3 测试代码实现 3.4 源代码文件 4 编译和测试 4.1 编译代码 4.2 测试 概述 本文介绍了在nRF52832开发板上使用Zephyr操作系统进行…

AWS Elastic Beanstalk部署极简Spring工程(EB CLI失败版)

弃用 这里我没有走通EB CLI方式部署。 问题 最近又加入了AWS项目组,又要再次在AWS云上面部署Spring服务,我这里使用的使用AWS中国云。需要使用AWS Elastic Beanstalk部署一个极简Spring工程。 EB CLI安装 安装EB CLI之前需要先在本地安装好Git&…

粒子群算法(PSO算法)

粒子群算法概述 1.粒子群优化算法(Particle Swarm Optimization,简称PSO)。粒子群优化算法是在1995年由Kennedy博士和Eberhart博士一起提出的,它源于对鸟群捕食行为的研究。 2.基本核心是利用群体中的个体对信息的共享从而使得整…

leetcode2934. 最大化数组末位元素的最少操作次数-medium

1 题目:最大化数组末位元素的最少操作次数 官方标定难度:中 给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,这两个数组的长度都是 n 。 你可以执行一系列 操作(可能不执行)。 在每次操作中,你可以选…

Elasticsearch 官网阅读之 Term-level Queries

Term-level Queries 参考:https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-exists-query 一、Term Query Term Query 是 term 精准查询。需要注意的是,在进行 Term Query 的时候,要避免 text 类型的字段&#x…

信贷域——互联网金融业务

摘要 本文深入探讨了信贷域全托与半托业务的定义、特点、适用场景及注意事项,并分析了互联网金融核心信息流的多个方面,包括资金流、信息流、风险流、合规流、物流、技术流和商流,还阐述了金融系统“断直连”业务的相关内容,以及…

科技晚报 AI 速递:今日科技热点一览 丨 2025 年 5 月 17 日

科技晚报AI速递:今日科技热点一览 丨2025年5月17日 我们为您汇总今日的科技领域最新动向,带您快速了解前沿技术、突破性研究及行业趋势。 黄仁勋劝特朗普:AI 芯片出口规则得改,中国紧追其后:英伟达 CEO 黄仁勋在华盛顿 “山与谷论…

使用streamlit实现vLLM多实例信息统一监控

本文代码和配置文件实现了一个基于 Streamlit 和 FastAPI 的前后端分离的应用程序,用于管理和展示 VLLM(Very Large Language Model)实例的信息。以下是代码和配置文件的总结摘要: 概要 功能概述 前后端启动方式: 使用…

搭建一个WordPress网站需要多少成本

WordPress 最初可能只是一个简单的博客平台。但近年来,它不仅成为了最好的博客平台,还成为了一个全面的内容管理系统。白宫、jQuery、NGINX、《纽约时报》等企业都把 WordPress 作为自己的网上家园。 不过,它们只是其中的佼佼者。根据 Built…

飞帆控件 post or get it when it has get

我在这里分享两个链接: post_get_it 设计 - 飞帆 有人看出来这个控件是干什么用吗? 控件的配置: