掌桥专利:专业的专利平台
掌桥专利
首页

基于Kubernetes的镜像构建方法及其构建系统

文献发布时间:2023-06-19 11:05:16


基于Kubernetes的镜像构建方法及其构建系统

技术领域

本发明涉及云原生技术领域,尤其涉及一种基于Kubernetes的镜像构建方法及其构建系统。

背景技术

从标准Dockerfile构建容器镜像通常依赖于对节点Docker守护进程的交互式访问,这需要授予容器访问计算机的根访问权限才能运行。这就导致了在不能轻松或安全地公开其Docker守护进程的环境中构建容器镜像非常困难,例如Kubernetes集群。一提到在Kubernetes中构建容器镜像,最先让人想到的就是运行DinD,即Docker-in-Docker。DinD通过内部的Docker来实现容器镜像的构建,但是这种方式存在以下问题:

1. DinD需要特权模式才能运行。当通过Kubernetes部署应用的时候,则需要使用privileged模式。该模式允许容器内的root拥有外部宿主机的root权限,可以访问宿主机上的所有设备,并可以执行mount进行挂载。当把宿主机磁盘设备通过mount挂载到容器内部后则容器可以获取对宿主机文件的读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令,存在很大的安全隐患。

2. DinD依赖于节点的Docker。当通过Kubernetes部署一次应用程序的时候,被调度到的节点则会增加一个dockerd进程。随着应用程序的增加,当部署的应用都被调度到相同节点的时候,会给该节点带来很大的压力,造成节点资源紧张。

3. DinD生成镜像时无缓存可用。对于全局性的二次构建,无法重用上次生产的镜像layer以及所需的依赖,需要重新生成新的layer,这就增加了构建时间,带来很不友好的构建体验。

在容器中构建镜像一直都是一个安全挑战,因为需要访问节点的文件系统才能与Docker守护进程通信。目前现有的技术方案节点的资源压力大,而且镜像构建时间长,构建体验不友好。

发明内容

针对以上技术问题,本发明公开了一种基于Kubernetes的镜像构建方法及其构建系统,在Kubernetes集群中更安全的构建镜像,减轻了节点的资源压力,并缩短了镜像构建时间。

对此,本发明采用的技术方案为:

一种基于Kubernetes的镜像构建方法,其包括如下步骤:

准备Dockerfile,挂载私有代码库的公私钥,克隆源代码到指定的目录,执行源代码编译得到制品,拷贝已经生成的制品制作最终镜像;

镜像制作,解析准备好的Dockerfile,执行镜像构建,缓存镜像层,删除基础镜像,推送到镜像仓库。

作为本发明对进一步改进,所述准备Dockerfile包括代码编译阶段和镜像构建阶段,在准备Dockerfile的过程中,给Dockerfile中的内容进行分阶段进行命名;

在代码编译阶段,对代码编译阶段的内容进行命名;在镜像构建阶段,通过获取代码编译阶段的内容的命名获取到制品,完成镜像的构建,重新命名;在获取到制品后,删除编译阶段的编译环境和制品。

关于容器镜像的构建,如何控制镜像体积是核心问题之一。一般情况下镜像构建的Dockerfile中不仅包含软件的编译环境还包含容器的运行环境,在这种情况下编译出来的镜像不仅体积非常庞大还可能会泄漏源代码。而最终镜像的运行并不需要编译环境,需要的仅仅是运行环境而已。还有一种普遍的做法是通过执行一个编译源代码的脚本得到制品,再额外编写一个只包含程序运行环境的Dockerfile,这样确实减少了最终镜像体积,但是这也无疑就增加了学习成本和维护工作,不仅需要学习脚本语法和Dockerfile语法,还需要对编译脚本和Dockerfile进行维护。采用本发明的技术方案,通过合理调整Dockerfile的内容得以解决。现有技术中一般采用Dockerfile将代码编译环境一起构建打包到了最终的镜像中,而本技术方案中通过给Dockerfile中的内容进行分阶段取名设计,具体来说第一阶段作为代码编译阶段,将源代码编译成制品;在第二阶段通过第一阶段的名称获取到制品完成镜像的构建。在第一阶段中代码编译环境和制品都是临时存在,等待第二阶段获取到制品后,编译环境和制品会被自动清理。当编译环境和制品被清理后,镜像体积自然而然就被压缩了。

作为本发明对进一步改进,在Dockerfile中临时挂载公私钥的方式得到拉取代码的凭证,所述私有代码库在Dockerfile中进行源代码拉取。

对于http/https协议可以使用basic auth方式实现认证授权,但是对于SSH协议,这就需要访问凭证。普遍做法是把SSH协议的公私钥挂载到容器中,但是这种方式很不安全,公私钥会在最终生成的镜像层中存在。

作为本发明做进一步改进,代码编译阶段,使用SSH类型的挂载将私有代码库公私钥进行临时挂载,私有代码库通过SSH协议拉取代码,等待代码拉取下来编译成功后,该SSH公私钥自动被清理。

对于源代码何时拉取,也是容器镜像的构建中需要考虑的问题。现有的做法都是提前使用git 客户端或者开源的实现了git API的工具通过SSH/http/https协议把源代码拉取到某个位置如/workspace下,再切换到源代码目录通过得到Dockerfile文件执行镜像构建。但是这种方式导致整个流程分散,构建体验不佳。在本发明中做进一步改进,通过在Dockerfile中临时挂载公私钥的方式得到拉取代码的凭证,从而在Dockerfile中实现源代码拉取。

作为本发明对进一步改进,所述镜像构建阶段,采用开源镜像构建工具Kaniko构建镜像。Kaniko,它的运行并不依赖于节点的Docker守护进程,这就使得在那些没有根访问权限的环境中构建容器镜像变得更加容易和安全,比如Kubernetes集群。

作为本发明对进一步改进,所述构建镜像包括如下步骤:给Kaniko的可执行程序executor指定 Dockerfile 文件路径、镜像推送地址和源代码位置,可执行程序executor自行提取Dockerfile中的内容作为容器的文件系统,然后自动完成镜像的构建,并且把镜像推送到指定的仓库地址并缓存起来供后续构建使用。使用Kaniko,在整个镜像构建过程当中都无需人工干预,实现自动构建。

本发明还公开了一种基于Kubernetes的镜像构建系统,其包括:

Dockerfile准备模块,用于准备Dockerfile,挂载私有代码库的公私钥,克隆源代码到指定的目录,执行源代码编译得到制品,拷贝已经生成的制品制作最终镜像;

镜像制作模块,用于解析准备好的Dockerfile,执行镜像构建,缓存镜像层,删除基础镜像,推送到镜像仓库。

作为本发明对进一步改进,所述Dockerfile准备模块包括命名模块,用于在代码编译阶段对代码编译阶段的内容进行命名,在镜像构建阶段,通过获取代码编译阶段的内容的命名获取到制品,完成镜像的构建,然后重新命名;

清理模块,在获取到制品后,删除编译阶段的编译环境和制品;

代码拉取模块,在代码编译阶段,使用SSH类型的挂载将私有代码库公私钥进行临时挂载,并得到拉取代码的凭证,私有代码库通过SSH协议在Dockerfile中拉取代码,等待代码拉取下来编译成功后,自动清理该SSH公私钥;

所述镜像制作模块包括开源镜像构建工具Kaniko,用于构建镜像。

作为本发明对进一步改进,所述Dockerfile准备模块包括镜像构建模块,用于给Kaniko的可执行程序executor指定 Dockerfile 文件路径、镜像推送地址和源代码位置,可执行程序executor自行提取Dockerfile中的内容作为容器的文件系统,然后自动完成镜像的构建,并且把镜像推送到指定的仓库地址并缓存起来供后续构建使用。

本发明还公开了一种计算机可读存储介质,其特征在于,所述计算机可读存储介质包括计算机程序,当计算机程序在计算机上运行时,执行如上任一项所述的基于Kubernetes的镜像构建方法。

本发明还公开了一种装置,其包括相连的处理器和存储器,其特征在于,所述处理器用于执行所述存储器中存储的计算机程序,以执行如上任一项所述的基于Kubernetes的镜像构建方法。

与现有技术相比,本发明的有益效果为:

采用本发明的技术方案,不仅能有效的控制镜像体积,保证私有代码库的安全性,节省镜像构建时间,还能实现源代码拉取和编译以及镜像构建、推送和缓存一体化。在整个构建过程中本方案的CPU使用率下降90%、内存使用率下降81%、构建时间(针对全局性的二次构建)缩短57%。相对于DinD方案,本发明的Kaniko方案节省了计算资源,缩短了构建时间,提高了宿主机安全性,提升了用户体验。

附图说明

图1是本发明一种基于Kubernetes的镜像构建方法的流程示意图。

图2是本发明一种基于Kubernetes的镜像构建方法与采用DinD方案的CPU使用率对比图。

图3是本发明一种基于Kubernetes的镜像构建方法与采用DinD方案的内存使用量的对比图。

图4是本发明一种基于Kubernetes的镜像构建方法与采用DinD方案的构建时间对比。

具体实施方式

下面对本发明的较优的实施例作进一步的详细说明。

如图1所示,一种基于Kubernetes的镜像构建方法,其包括:

1. 准备Dockerfile:挂载私有代码库的公私钥、克隆源代码到指定的目录以及执行源代码编译得到制品;拷贝已经生成的制品制作最终镜像。

2. 镜像制作:解析准备好的Dockerfile,执行镜像构建、缓存、推送到镜像仓库。

关于容器镜像的构建,存在以下三个比较核心的问题:

(1)如何控制镜像体积。一般情况下镜像构建的Dockerfile中不仅包含软件的编译环境还包含容器的运行环境,在这种情况下编译出来的镜像不仅体积非常庞大还可能会泄漏源代码。而最终镜像的运行并不需要编译环境,需要的仅仅是运行环境而已。还有一种普遍的做法是通过执行一个编译源代码的脚本得到制品,再额外编写一个只包含程序运行环境的Dockerfile,这样确实减少了最终镜像体积,但是这也无疑就增加了学习成本和维护工作,不仅需要学习脚本语法和Dockerfile语法,还需要对编译脚本和Dockerfile进行维护。

(2)通过SSH协议拉取代码的凭证问题。对于http/https协议可以使用basic auth方式实现认证授权,但是对于SSH协议,这就需要访问凭证。普遍做法是把SSH协议的公私钥挂载到容器中,但是这种方式很不安全,公私钥会在最终生成的镜像层中存在。

(3)源代码何时拉取。普遍做法都是提前使用git 客户端或者开源的实现了gitAPI的工具通过SSH/http/https协议把源代码拉取到某个位置如/workspace下。再切换到源代码目录通过得到Dockerfile文件执行镜像构建,但是这种方式并没做到自动化CI/CD。

针对控制镜像体积镜像体积的问题,在本方案中会通过合理调整Dockerfile内容解决。现有技术中,Dockerfile将代码编译环境一起构建打包到了最终的镜像中,造成体积大的问题。本方案中通过给Dockerfile中的内容进行分阶段取名设计。第一阶段作为代码编译阶段,将源代码编译成制品;在第二阶段通过第一阶段的名称获取到制品完成镜像的构建。在第一阶段中代码编译环境和制品都是临时存在,等待第二阶段获取到制品后,编译环境和制品会被自动清理。当编译环境和制品被清理后,镜像体积自然而然就被压缩了。

针对私有代码库中通过SSH协议拉取代码的问题,本实施例在Dockerfile的第一阶段中使用SSH类型的挂载将私有代码库公私钥临时挂载,等待代码拉取下来编译成功后,该SSH公私钥自动被清理。

针对源代码何时拉取的问题,本实施例中,在Dockerfile中临时挂载公私钥的方式得到拉取代码的凭证,从而在Dockerfile中实现源代码拉取。

综合上述内容即可确定出一个既能在Dockerfile中实现源代码自动拉取又能缩小镜像体积的合理的Dockerfile。

但是有了Dockerfile文件还不能实现镜像的自动构建,还需要借助Google推出的开源镜像构建工具Kaniko,它的运行并不依赖于节点的Docker守护进程,这就使得在那些没有根访问权限的环境中构建容器镜像变得更加容易和安全,比如Kubernetes集群。

使用Kaniko,在整个镜像构建过程当中都无需人工干预,通过给Kaniko的可执行程序executor指定 Dockerfile 文件路径、镜像推送地址和源代码位置,executor会自行通过提取Dockerfile中的内容作为容器的文件系统,然后自动实现镜像的构建并且把镜像正确的推送到指定的仓库地址并缓存起来供后续构建使用。

具体而言,Kaniko可以通过设置cache参数为true,即可使用缓存,将镜像layer缓存到文件。默认情况下是缓存到/cache中。可以通过cache-dir参数自行修改到目标文件。最后将镜像layer缓存到仓库,默认情况是缓存到最终镜像推送的仓库地址,即destination参数指定的值。可以通过cache-repo参数自行修改到目标仓库地址。

Kaniko工作原理为:读取指定的Dockerfile文件;将Dockerfile中指定的基础镜像(在FROM中指定的镜像)提取到容器的文件系统中;分别运行Dockerfile中的每个指令;每次运行后获取文件系统快照。该快照是在用户空间创建的,遍历文件系统并将其与存储在内存中的先前状态进行比较;对文件系统的任何修改作为一个新层附加到基础镜像中,并对镜像元数据进行相关的更改;执行完每个Dockerfile指令后,将新构建的镜像层推送到指定的镜像仓库中。

采用本实施例的技术方案,不仅能有效控制镜像体积、保证私有代码库的安全性以及节省镜像构建时间,还能实现源代码拉取和编译以及镜像构建、推送和缓存一体化。相对于DinD方案而言,在整个构建过程中本方案的CPU使用率下降90%、内存使用率下降81%、构建时间(针对全局性的二次构建)缩短57%,详见图2~图4。相对于DinD方案,Kaniko方案可以从节省计算资源、缩短构建时间以及提高宿主机安全性等方面提升用户体验。

本实施例还公开了一种基于Kubernetes的镜像构建系统,其特征在于:其包括:

Dockerfile准备模块,用于准备Dockerfile,挂载私有代码库的公私钥,克隆源代码到指定的目录,执行源代码编译得到制品,拷贝已经生成的制品制作最终镜像;

镜像制作模块,用于解析准备好的Dockerfile,执行镜像构建,缓存镜像层,删除基础镜像,推送到镜像仓库。

进一步的,所述Dockerfile准备模块包括命名模块,用于在代码编译阶段对代码编译阶段的内容进行命名,在镜像构建阶段,通过获取代码编译阶段的内容的命名获取到制品,完成镜像的构建,然后重新命名;

清理模块,在获取到制品后,删除编译阶段的编译环境和制品;

代码拉取模块,在代码编译阶段,使用SSH类型的挂载将私有代码库公私钥进行临时挂载,并得到拉取代码的凭证,私有代码库通过SSH协议在Dockerfile中拉取代码,等待代码拉取下来编译成功后,自动清理该SSH公私钥;

所述镜像制作模块包括开源镜像构建工具Kaniko,用于构建镜像。

所述镜像制作模块包括镜像构建模块,用于给Kaniko的可执行程序executor指定Dockerfile 文件路径、镜像推送地址和源代码位置,可执行程序executor自行提取Dockerfile中的内容作为容器的文件系统,然后自动完成镜像的构建,并且把镜像推送到指定的仓库地址并缓存起来供后续构建使用。

本实施例还公开了一种计算机可读存储介质,所述计算机可读存储介质包括计算机程序,当计算机程序在计算机上运行时,执行如上所述的基于Kubernetes的镜像构建方法。

本实施例还公开了一种装置,其包括相连的处理器和存储器,所述处理器用于执行所述存储器中存储的计算机程序,以执行如上所述的基于Kubernetes的镜像构建方法。

以上内容是结合具体的优选实施方式对本发明所作的进一步详细说明,不能认定本发明的具体实施只局限于这些说明。对于本发明所属技术领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干简单推演或替换,都应当视为属于本发明的保护范围。

相关技术
  • 基于Kubernetes的镜像构建方法及其构建系统
  • kubernetes集群节点镜像的构建方法及装置
技术分类

06120112793389