云原生|Packer插件开发在项目中应用

2023-11-02 10:31

本文主要是介绍云原生|Packer插件开发在项目中应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:李冠军  神州数码云基地 高级后端开发工程师

云时代我们可以在各云厂商控制台点一点,实例就生成了,但是这个点还是需要自己去点,如果把这些动作写成代码,直接运行,一切就完成了。

这就是Packer的作用,可以构建一个可以马上部署的云服务器镜像,可以在代码中定义基础镜像,预装哪些软件,装完后再生成一个镜像,然后就可以直接使用这个镜像生成实例了,实例启动后,一切险准备就绪,也不用执行什么初始化脚本,代码就可以在多个云平台上使用。

想要通过Packer构建不同云平台的镜像,这就需要安装不同云平台的Packer插件,当然一些云平台还不支持此工具,而这个时候就需要我们针对云平台进行packer插件的开发了。

Packer插件开发的本质上是通过调用云平台API来进行云资源的操作,如何进行Packer插件开发这里就不再赘述了,这里是官方文档-Packer 插件开发文档。

这里说一下我们实际的项目应用。

我们根据客户需求开发了一版针对移动合营云云平台的Packer插件(packer-plugin-hecloud)

插件基于Pakcer官方插件模板包,结合云平台SDK包调用云资源服务接口,进行镜像创建相关操作。

项目案例分享


一、Packer插件实例

实现Packer插件必须由Go语言实现

实现插件所需要做的是:

  • packer-plugin所需接口的实现
  • 使用packer-plugin-sdk中提供的服务器提供服务

Packer核心和 SDK 会处理服务器内部的所有通信细节

必须使用官方提供的两个包来实现服务器和接口

"github.com/hashicorp/packer-plugin-sdk/plugin" //包含官方提供插件的代码。这处理所有进程间通信。
"github.com/hashicorp/packer-plugin-sdk/packer" //包含必须为任何插件实现的所有接口

下图使用了其中上述之一http://github.com/hashicorp/packer-plugin-sdk/plugin

上图代码中

plugin.NewSet(): 调用处理与 Packer 核心通信和通过 RPC 为组件提供服务的所有细节。只要注册的结构实现了组件接口之一,Packer 现在就可以启动此插件并使用它。

ecsbuilder.Builder实现了"http://github.com/hashicorp/packer-plugin-sdk/packer",并通过pps.Run()提供服务

下面我们看一下builder目录中的代码

核心文件在/builder/ecs/builder.go

上图所示:

  • builder.go中的 Run()方法是实际执行自定义打包镜像的过程
  • 同级目录下的以step开头的文件,都实现了官方包http://github.com/hashicorp/packer-plugin-sdk/multistep中的Step interface,都属于打包步骤
  • 每个步骤一个文件,传入不同的配置参数,去调用云平台SDK包去实现相对应的操作
  • 最后由Builder执行Run()来进行打包操作

//打包镜像全步骤

目录都为同级builder/ecs/

  • step_load_zones.go中的StepLoadAZ用户加载可用区,listZones()方法调用云平台接口os-availability-zone
  • step_load_flavor.g中的StepLoadFlavor用户加载Flavor ,比如:s6.large.2
  • step_key_pair.go中的StepKeyPair 创建临时密钥对
  • step_source_image_info.go 设置source_image
  • step_create_volume.go 创建volume并记录volume_id
  • step_run_source_server.go ,根据配置以及source_image、flavor创建服务,并生成Server ID ,须在云平台已经开通弹性云服务
  • step_get_password.go 在使用winrm的情况下并且未设密码的情况下,自动生成密码
  • step_allocate_ip.go创建并分配IP,根据参数是否设置来分配,如下图

将浮动ip和实例端口相关联

  • step_connect.go通过ssh communicator服务建立连接
  • step_provision,官方步骤-打包过程Provision配置器处理,配置器配置的相关命令操作,如下图

  • step_cleanup_temp_keys-官方步骤清理临时密钥
  • step_stop_server 将创建的服务停掉
  • step_create_image根据当前服务实例创建镜像
  • step_add_image_members为新建镜像添加用户,未设置直接返回
  • step_update_image_mindisk更新磁盘镜像

上述步骤为实际执行过程的全步骤

//执行和返回过程

执行在b.runner.Run(ctx, state)这一步进行

如图示,执行后续根据错误返回err信息,未生成镜像返回nil,成功生成镜像,返回镜像相关信息

打包成功示意图:

以上就是Packer插件开发的代码实际流程。

二、兼容性问题

这里说一下项目交付后遇到的一个问题,就是Packer v1.7.0以下的版本 云平台插件需要做兼容处理。

由于项目开发阶段,客户没有要求Packer版本等事宜,上述插件是在Packer v1.8.0的基础上开发的。

然而客户生产环境Packer版本是v1.6.6,可能因为版本导致了一些兼容性的问题。

在当前的测试环境,将Packer版本切换到v1.6.6,并执行打包命令

脚本配置如下:

报错如下:

将Packer版本切换到v1.8.0及更高版本,执行打包命令 packer build ,发现能够正常执行打包。

故推测该问题由于低版本Packer打包调用高版本hecloud-ecs插件导致。

packer-plugin的开发,这里需要packer官方包packer-plugin-sdk

而官方在v1.7.x之前的packer-plugin开发的文档是没有找到的

由于客户Pakcer版本是v1.6.6,这里看了一下Packer的源码v1.6.6版,发现packer-plugin-sdk在当前项目目录下,也就是 http://github.com/hashicorp/packer/packer-plugin-sdk,进入后发现,Packer v1.7.0之前的版本,插件也要使用v1.7.0之前版本的插件开发工具包来保证API兼容性。

把Packer源码切换到v1.7.0版,发现http://github.com/hashicorp/packer/packer-plugin-sdk 不存在了,变成了一个独立的Repo:http://github.com/hashicorp/packer-plugin-sdk。

由于我们的移动云插件是基于v1.8.0开发的,也就是基于独立Repo:http://github.com/hashicorp/packer-plugin-sdk,而v1.7.0之前的插件开发是需要基于http://github.com/hashicorp/packer/packer-plugin-sdk。问题初步判定是packer-plugin-sdk版本的问题。

接下来解决问题,将当前插件版本的独立Repo sdk依赖,切换到依赖pakcer v1.6.6项目内置的sdk。

删除项目下go.mod:rm -f go.mod

指定packer依赖版本:go get http://github.com/hashicorp/packer@v1.6.6

项目内替换依赖项:搜索 hashicorp/packer-plugin-sdk 全部替换为 hashicorp/packer/packer-plugin-sdk

下载其余依赖:go mod tidy

重新编译:CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o packer-plugin-hecloud

编译成功后将packer-plugin-hecloud 放入 /usr/local/bin下

再次测试打包 packer build

能够成功运行打包程序,问题解决。

总结一下,这个问题是由Pakcer版本引起的,Packer在v1.7.0把用于插件开发的packer-plugin-sdk,由当前项目下独立了出去,低版本Packer在执行调用对应云平台打包插件时,需要对应云平台插件做低版本兼容。

版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。

公众号搜索神州数码云基地,后台回复“技术合集”,领取干货内容。

这篇关于云原生|Packer插件开发在项目中应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/329994

相关文章

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

centos7基于keepalived+nginx部署k8s1.26.0高可用集群

《centos7基于keepalived+nginx部署k8s1.26.0高可用集群》Kubernetes是一个开源的容器编排平台,用于自动化地部署、扩展和管理容器化应用程序,在生产环境中,为了确保集... 目录一、初始化(所有节点都执行)二、安装containerd(所有节点都执行)三、安装docker-

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Docker集成CI/CD的项目实践

《Docker集成CI/CD的项目实践》本文主要介绍了Docker集成CI/CD的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、引言1.1 什么是 CI/CD?1.2 docker 在 CI/CD 中的作用二、Docke

SpringBoot项目引入token设置方式

《SpringBoot项目引入token设置方式》本文详细介绍了JWT(JSONWebToken)的基本概念、结构、应用场景以及工作原理,通过动手实践,展示了如何在SpringBoot项目中实现JWT... 目录一. 先了解熟悉JWT(jsON Web Token)1. JSON Web Token是什么鬼

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择