VM映像构建实践

news2025/2/25 12:09:46

概述

VM映像做为创建VM的必要条件,各类云环境映像市场均有提供最基础的映像。创建VM后,通常还需要根据组织或用户的需求,安装一些软件、修改配置后才能满足使用需求。这类需求通常可以手动部署或者借助一些配置管理工具,如ansible、puppet、saltstack等来实现,也可以考虑构建自定义的映像,集成软件部署和配置。

映像构建的过程

通常自定义映像比较繁琐,需要经历如下几个步骤,以Azure云为例:

1)创建构建映像使用的VM

2)部署软件/修改配置

3)通用化

4)关机

5)捕获映像

6)删除构建映像使用的VM

使用packer可以自动完成上述这些步骤

Packer构建映像

Packer是HashiCorp推出的一款自动构建VM/Docker映像的工具,支持各大主流云平台,可以结合puppet、ansible等配置管理工具高效定制映像。

packer官方文档:https://developer.hashicorp.com/packer/docs

Packer构建AVD映像

本文分享使用packer构建AVD映像的案例,AVD(Azure Virtual Desktop)是Azure推出的虚拟桌面服务,通过集成一些常用的客户端工具,为用户提供方便快捷的资源访问入口。基于Azure VMSS(Virtual Machine Scale Sets)提供会话主机,VMSS使用的映像需要集成各类客户端工具。本场景中我们使用packer+ansible来实现AVD映像的自动构建。有关AVD的介绍,请参考:https://docs.azure.cn/zh-cn/virtual-desktop/overview

环境准备

准备一台用来执行映像构建的VM,本案例使用的VM信息如下

操作系统:CentOS 7

VMSIZE:Standard_D2s_v3

安装packer、ansible

[localhost]# yum install epel-release -y
[localhost]# yum install ansible -y
[localhost]# wget -c 'https://releases.hashicorp.com/packer/1.8.1/packer_1.8.1_linux_amd64.zip'
[localhost]# unzip packer_1.8.1_linux_amd64.zip -d /usr/bin/
[localhost]# pip install pywinrm

生成VM托管标识和授权

VM托管标识(Managed Identity)是用来在Azure上做身份认证和授权的,认证可选的方式还有Service Principal(SP)方式,需要在packer的模版文件中声明client_id、client_secret。此处更推荐使用托管标识的方式,无需在packer模版文件配置相关敏感信息,且托管标识方式跟Azure资源绑定后才能使用,更加安全。有关托管标识的说明,请参考:https://learn.microsoft.com/zh-cn/entra/identity/managed-identities-azure-resources/overview

安装azcli

导入azcli仓库key

[localhost]# rpm --import https://packages.microsoft.com/keys/microsoft.asc

添加azcli仓库

[localhost]# echo -e "[azure-cli]
name=Azure CLI
baseurl=https://packages.microsoft.com/yumrepos/azure-cli
enabled=1
gpgcheck=1
gpgkey=https://packages.microsoft.com/keys/microsoft.asc" | sudo tee /etc/yum.repos.d/azure-cli.repo

安装azcli并登录

[localhost]# yum install -y azure-cli
[localhost]# az cloud set -n AzureChinaCloud
[localhost]# az login 

创建VM托管标识

开启VM托管标识和授予订阅参与者权限

[localhost]$ az vm identity assign --identities [system] --role Contributor --scope /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx --ids /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/RG/providers/Microsoft.Compute/virtualMachines/VM

packer模版文件编辑

packer模版语法支持HCL和JSON格式,并且可以从HCL转换到JSON格式,此处为了方便添加注释,使用HCL来描述模版。

[localhost]# cat avd-images.pkr.hcl
source "azure-arm" "avd-images" { #avd-images为模版名称
# use Azure Managed Identity
 client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx" #VM托管标识的objectID
 cloud_environment_name = "AzureChinaCloud"
 managed_image_resource_group_name = "resourcegroup" #映像所在的资源组
 managed_image_name = "avd-images-test" #映像名称
 os_type = "Windows" #映像操作系统类型和版本
 image_publisher = "MicrosoftWindowsServer"
 image_offer = "WindowsServer"
 image_sku = "2019-Datacenter"
 build_resource_group_name = "resourcegroup" #构建映像时使用的资源组,默认会创建“pkr-Resource-Group-”命名格式的资源组
 virtual_network_name = "virtualnetwork" #构建映像时使用虚拟网络,默认会创建”pkrvn“命名格式的虚拟网络
 virtual_network_subnet_name = "subnetwork" #构建映像时使用的子网
 virtual_network_resource_group_name = "networkresourcegroup" #虚拟网络所在的资源组
 private_virtual_network_with_public_ip = false #构建映像时是否创建公网IP,默认为true
 vm_size = "Standard_DS2_v2" #构建映像时使用的vm型号
# config winrm
 communicator = "winrm" #winrm连接的相关配置,ansible通过winrm方式来管理windows机器
 winrm_use_ssl = true
 winrm_insecure = true
 winrm_timeout = "5m"
 winrm_username = "packer"
# define tags #配置一些tag信息
 azure_tags = {
   key1 = "value1"
   key2 = "value2"
 }
}
build {
 sources = ["sources.azure-arm.avd-images"]
# config winrm for ansible
 provisioner "powershell" { #下载和执行powershell脚本,配置winrm
   inline = [
      "$wirmsrc = 'https://xxxxxxxxxxx/ConfigureRemotingForAnsible.ps1'",
      "$wirmdes = 'C:\\ConfigureRemotingForAnsible.ps1'",
      "Invoke-WebRequest -uri $wirmsrc -OutFile $wirmdes",
      "Unblock-File $wirmdes",
      "powershell.exe -ExecutionPolicy Unrestricted -File 'C:\\ConfigureRemotingForAnsible.ps1'",
      "rm 'C:\\ConfigureRemotingForAnsible.ps1'"
   ]
 }
# exec ansile playbook
 provisioner "ansible" { #调用ansible playbook,执行软件安装配置
   playbook_file = "./playbook.yml"
   user = "packer"
   use_proxy = false
   extra_arguments = [
      "-e",
      "ansible_winrm_server_cert_validation=ignore",
      "-vvv"
   ]
 }
# generalized image
 provisioner "powershell" { #执行通用化
   inline = [
      "while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
      "while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
      "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit",
      "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10 } else { break } }"
   ]
 }
}

ansible playbook预览

[localhost]# cat playbook.yml 
---
- hosts: default
 gather_facts: false
 roles:
    - init
    - winrar
    - winscp
    - storageexplorer
    - vscode
    - chrome
    - putty
……

ansible-role预览

[localhost]# tree -L 1 roles/
roles/
├── chrome
├── config_env_variables
├── config_proxy
├── edge
├── fslogix
……

ansible task预览

[localhost]# cat roles/winrar/tasks/main.yml 
---
# tasks file for winrar
- name: Download winrar
 win_get_url:
   url: 'https://xxxx/winrar-x64-602.exe'
   dest: C:\TempAvd\
- name: Install winrar
 win_command: 'C:\TempAvd\winrar-x64-602.exe -S'
 args:
   creates: 'C:\Program Files\WinRAR\WinRAR.exe'
Note
使用ansible或脚本方式在windows上部署软件时,需要使用静默安装的方式,不同安装包支持的参数可能存在差异,可以在命令行使用"/?"来查看帮助,如xxx.exe /?,xxx.msi /?

构建映像

[localhost]# packer build avd-images.pkr.hcl

看到如下输出表示构建完成

OSType: Windows
ManagedImageResourceGroupName: resourcegroup
ManagedImageName: avd-images-test
ManagedImageId: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/resourcegroup/providers/Microsoft.Compute/images/avd-images-test
ManagedImageLocation: chinaeast2

packer构建映像会执行如下几个步骤:

1)检查或创建资源组、创建VM、创建keyvault

2)配置winrm、调用ansible playbook部署软件

3)执行通用化

4)捕获映像

5)删除构建映像时由packer创建的临时资源

使用构建后的映像部署到AVD的VMSS,可以看到playbook中定义的软件都已安装

随后AVD发布应用效果如下

小结

1)packer使用模版描述构建映像时所需的步骤,自动完成映像构建和临时资源清理工作

2)packer支持集成系统shell和调用配置管理工具实现软件部署、配置管理

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

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

相关文章

KVM+GFS分布式存储系统构建高可用群集

KVMGFS 分布式存储系统构建 KVM 高可用群集 一:理论概述 1.1:Glusterfs 简介 Glusterfs 文件系统是由 Gluster 公司的创始人兼首席技术官 Anand Babu Periasamy编写。 一个可扩展的分布式文件系统, 用于大型的、 分布式的、 对大量数据进行访…

Java版SaaS模式云HIS系统源码Java+Spring+SpringBoot+SpringMVC 基层卫生健康云HIS源码

Java版SaaS模式云HIS系统源码JavaSpring+SpringBoot+SpringMVC 基层卫生健康云HIS源码 云HIS全称为基于云计算的医疗卫生信息系统(Cloud-BasedHealthcareInformationSystem),是运用云计算、大数据、物联网等新兴信息技…

宝藏速成秘籍(6)归并排序法

一、前言 1.1、概念 归并排序(Merge Sort)是一种基于分治思想的排序算法。它将数组分成两个子数组,分别对这两个子数组进行排序,然后再将它们合并成一个有序的数组。归并排序是一种经典的分治算法,它的核心思想是将待…

Elasticsearch搜索引擎(高级篇)

3.1 查询语法 | 《ElasticSearch入门到实战》电子书 (chaosopen.cn) day09-Elasticsearch02 - 飞书云文档 (feishu.cn) 目录 第一章 DSL查询 1.1 基本语法 1.2 叶子查询 全文检索查询 精确查询 1.3 复合查询 算分函数查询 bool查询 1.4 排序 1.5 分页 基础分页 深度分…

Visual Studio Code连接VMware虚拟机

1.安装VS Code插件 在拓展中安装插件 Remote-SSH 2.在虚拟机中安装OpenSSH服务器 使用超级用权限(root)更新软件包列表,Debian系统和Ubuntu系统使用apt包管理工具: sudo apt update CentOS系统使用yum或dnf包管理工具: sudo yum update …

618全面开战,抖音电商头部品牌罗拉密码突然“不干”了?

前言: 随着618电商大战的硝烟渐浓,各大电商平台纷纷摩拳擦掌,准备在这场年度购物盛宴中大展拳脚。然而,在这热闹非凡的氛围中,一个熟悉的名字却显得格外低调——罗拉密码。作为抖音电商领域的头部品牌,罗拉…

el-table 多选回显,分页回显

实现el-table多选分页回显功能&#xff0c;左侧是分页的数据源&#xff0c;右侧是选择后的人员数据&#xff0c;切换下一页&#xff0c;选中的数据会在左侧表格回显。 实现&#xff1a; <template><el-dialog :title"title" :visible.sync"show"…

C#开发-集合使用和技巧(二)Lambda 表达式介绍和应用

C#开发-集合使用和技巧 Lambda 表达式介绍和应用 C#开发-集合使用和技巧介绍简单的示例&#xff1a;集合查询示例&#xff1a; 1. 基本语法从主体语句上区分&#xff1a;1. 主体为单一表达式2. 主体是代码块&#xff08;多个表达式语句&#xff09; 从参数上区分1. 带输入参数的…

【LeetCode:2786. 访问数组中的位置使分数最大 + 递归 + 记忆化缓存 + dp】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

MySQL之优化服务器设置(一)

优化服务器设置 配置MySQL的IO行为 有一些配置影响着MySQL怎样同步数据到磁盘以及如何做恢复操作。这些操作对性能的影响非常大&#xff0c;因为都涉及到昂贵的IO操作。它们也表现了性能和数据安全之间的权衡。通常&#xff0c;保证数据立刻并且一致地写到磁盘是很昂贵的。如…

Leetcode刷题笔记11

415. 字符串相加 415. 字符串相加 - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a;头插 头插是指将一个新元素插入到链表的头部&#xff08;即第一个位置&#xff09;。 比如对于456和77&#xff0c;先计算两个数字的末项67的结果&#xff0c;然后往前挪动一位 …

Android开发AndroidStudio安装教程

本文图示展示AndroidStudio安装教程。 目录 一、下载安装包 二、安装 一、下载安装包 https://developer.android.google.cn/studio?hlzh-cn 二、安装 双击exe Next Next Next 默认点击Install Next 点击finish进入设置文件界面。 如果本地有设置文件&#xff0c;选择C…

Vulnhub-DC-9

靶机IP:192.168.20.144 kaliIP:192.168.20.128 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) 信息收集 nmap扫描一下端口及版本号 dirsearch扫目录 最后去前端界面观察发现也没什么隐藏路径。 观察功能&#xff0c;search引起注意&#xff0c;SQL注入测试 当输…

tsp可视化python

随机生成点的坐标并依据点集生成距离矩阵&#xff0c;通过点的坐标实现可视化 c代码看我的这篇文章tsp动态规划递归解法c from typing import List, Tuple import matplotlib.pyplot as plt from random import randintN: int 4 MAX: int 0x7f7f7f7fdistances: List[List[in…

模板方法模式(大话设计模式)C/C++版本

模板方法模式 C #include <iostream> using namespace std;class TestPaper { public:void TestQ1(){cout << "杨过得到&#xff0c;后来给了郭靖&#xff0c;炼成倚天剑&#xff0c;屠龙刀的玄铁可能是[ ]\na.球磨铸铁 b.马口贴 c.高速合金钢 d.碳素纤维&q…

仿FC数学金刚游戏介绍

简介 Math Monkey是Simple2l工作室开发的第二款小游戏&#xff0c;灵感来源于FC游戏平台的数学金刚游戏。小学时玩FC游戏是业余时间最期待的事情&#xff0c;还记得有一次和玩伴玩游戏时已经晚上了&#xff0c;于是约定再玩一把就各回各家&#xff0c;没想到又连玩了N把每一把…

Pytorch 卷积神经网络-手写数字识别

卷积神经网络是深度学习中的一个里程碑式的技术&#xff0c;有了这个技术&#xff0c;才会让计算机有能力理解图片和视频信息&#xff0c;才会有计算机视觉的众多应用。 本文讨论卷积神经网络模型&#xff08;CNN&#xff09;的Hello World。前面讨论的是一个二分类问题&#x…

LeetCode | 387.字符串中的第一个唯一字符

这道题可以用字典解决&#xff0c;只需要2次遍历字符串&#xff0c;第一次遍历字符串&#xff0c;记录每个字符出现的次数&#xff0c;第二次返回第一个出现次数为1的字符的下标&#xff0c;若找不到则返回-1 class Solution(object):def firstUniqChar(self, s):""…

MFC基础学习应用

MFC基础学习应用 1.基于对话框的使用 左上角为菜单键&#xff08;其下的关于MFC主要功能由IDD_ABOUTBOX决定) 附图 右下角为按钮&#xff08;基本功能由IDD_DIALOG决定,添加按钮使用由左上角的工具箱完成) 附图 2.自行添加功能与按钮//功能代码 void CMFCApplication4Dlg:…

使用thymeleaf直接渲染字符串

目录 一、依赖 二、示例代码 一、依赖 <--JAVA 8--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId><version>2.7.18</version></dependency><-…