重要
需要 Ansible 2.8(或更高版本)才能运行本文中示例的 playbooks。
Azure 虚拟机规模集 是一项 Azure 功能,可用于配置一组相同的负载均衡 VM。 规模集无需额外付费,它们是从虚拟机生成的。 只需为基础计算资源(例如 VM 实例、负载均衡器或托管磁盘存储)付费。 使用规模集时,提供管理和自动化层,以支持应用程序的运行和扩展。 可以改为手动创建和管理单个 VM。 但是,使用规模集有两个关键优势。 它们内置于 Azure 中,可自动缩放虚拟机以满足应用程序需求。
部署 VM 后,可以使用应用所需的软件配置 VM。 可以创建自定义映像,而不是为每个 VM 执行此配置任务。 自定义映像是包含任何已安装软件的现有 VM 的快照。 配置规模集时,请指定要用于该规模集 VM 的映像。 通过使用自定义映像,每个 VM 实例都为您的应用实现相同的配置。 有时,您可能需要更新虚拟机规模集的自定义映像。 此任务是本教程的重点。
在这篇文章中,你将学会如何:
- 使用 HTTPD 配置两个 VM
- 从现有 VM 创建自定义映像
- 从映像创建规模集
- 更新自定义映像
先决条件
- Azure 订阅:如果没有 Azure 订阅,请在开始之前创建 一个免费帐户 。
安装 Ansible:执行以下选项之一:
- 在 Linux 虚拟机上安装和 配置 Ansible
- 配置 Azure Cloud Shell ,如果无权访问 Linux 虚拟机, 请使用 Ansible 创建虚拟机。
配置两个 VM
本部分中的 playbook 代码创建两个虚拟机,其中两个虚拟机都安装了 HTTPD。
index.html每个虚拟机的页面上会显示一个测试字符串。
- 第一个 VM 显示值
Image A - 第二个 VM 显示的是值
Image B
此字符串旨在模拟使用不同软件配置每个 VM。
可通过两种方法获取示例剧本:
下载 playbook 并将其保存到
create_vms.yml。创建名为
create_vms.yml的新文件。 将以下代码插入到新文件中。
- name: Create two VMs (A and B) with HTTPS
hosts: localhost
connection: local
vars:
vm_name: vmforimage
admin_username: testuser
admin_password: Pass123$$$abx!
location: eastus
tasks:
- name: Create a resource group
azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
- name: Create virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
address_prefixes: "10.0.0.0/16"
- name: Create subnets for VM A and B
azure_rm_subnet:
resource_group: "{{ resource_group }}"
virtual_network: "{{ vm_name }}"
name: "{{ vm_name }}"
address_prefix: "10.0.1.0/24"
- name: Create Network Security Group that allows HTTP
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
rules:
- name: HTTP
protocol: Tcp
destination_port_range: 80
access: Allow
priority: 1002
direction: Inbound
- name: Create public IP addresses for VM A and B
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vm_name }}_{{ item }}"
loop:
- A
- B
register: pip_output
- name: Create virtual network interface cards for VM A and B
azure_rm_networkinterface:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}_{{ item }}"
virtual_network: "{{ vm_name }}"
subnet: "{{ vm_name }}"
public_ip_name: "{{ vm_name }}_{{ item }}"
security_group: "{{ vm_name }}"
loop:
- A
- B
- name: Create VM A and B
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}{{ item }}"
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
vm_size: Standard_B1ms
network_interfaces: "{{ vm_name }}_{{ item }}"
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
version: latest
loop:
- A
- B
- name: Create VM Extension
azure_rm_virtualmachineextension:
resource_group: "{{ resource_group }}"
name: testVMExtension
virtual_machine_name: "{{ vm_name }}{{ item }}"
publisher: Microsoft.Azure.Extensions
virtual_machine_extension_type: CustomScript
type_handler_version: 2.0
auto_upgrade_minor_version: true
settings: {"commandToExecute": "sudo apt-get -y install apache2"}
loop:
- A
- B
- name: Create VM Extension
azure_rm_virtualmachineextension:
resource_group: "{{ resource_group }}"
name: testVMExtension
virtual_machine_name: "{{ vm_name }}{{ item }}"
publisher: Microsoft.Azure.Extensions
virtual_machine_extension_type: CustomScript
type_handler_version: 2.0
auto_upgrade_minor_version: true
settings: {"commandToExecute": "printf '<html><body><h1>Image {{ item }}</h1></body></html>' >> index.html; sudo cp index.html /var/www/html/"}
loop:
- A
- B
- debug:
msg: "Public IP Address A: {{ pip_output.results[0].state.ip_address }}"
- debug:
msg: "Public IP Address B: {{ pip_output.results[1].state.ip_address }}"
使用 ansible-playbook 命令运行 playbook,将 myrg 替换为你的资源组名称:
ansible-playbook create-vms.yml --extra-vars "resource_group=myrg"
由于 playbook 的 debug 部分,该 ansible-playbook 命令将输出每个 VM 的 IP 地址。 复制这些 IP 地址供以后使用。
连接到两个虚拟机
在本部分中,你将连接到每个 VM。 如前一部分所述,字符串 Image A 和 Image B 模拟具有两个不同配置的 VM。
使用上一部分中的 IP 地址,打开浏览器并连接到每个 VM。
从每个 VM 创建映像
此时,有两个 VM 配置略有不同(其 index.html 文件)。
本部分中的 playbook 代码为每个 VM 创建自定义映像:
-
image_vmforimageA- 为在主页上显示Image A的 VM 创建的自定义映像。 -
image_vmforimageB- 为其主页上显示的Image BVM 创建的自定义映像。
可通过两种方法获取示例剧本:
下载 playbook 并将其保存到
capture-images.yml。创建名为
capture-images.yml的新文件。 将以下代码插入新文件中:
- name: Capture VM Images
hosts: localhost
connection: local
vars:
vm_name: vmforimage
tasks:
- name: Stop and generalize VMs
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}{{ item }}"
generalized: yes
loop:
- A
- B
- name: Create an images from a VMs
azure_rm_image:
resource_group: "{{ resource_group }}"
name: "image_{{ vm_name }}{{ item }}"
source: "{{ vm_name }}{{ item }}"
loop:
- A
- B
使用 ansible-playbook 命令运行 playbook,将其 myrg 替换为资源组名称:
ansible-playbook capture-images.yml --extra-vars "resource_group=myrg"
使用映像 A 创建规模集
在本节中,运行手册用于配置以下 Azure 资源:
- 公共 IP 地址
- 负载均衡器
- 引用
image_vmforimageA的规模集
可通过两种方法获取示例剧本:
下载 playbook 并将其保存到
create-vmss.yml。创建名为
create-vmss.yml的新文件。 将以下代码插入新文件中:
---
- hosts: localhost
vars:
vmss_name: vmsstest
location: eastus
admin_username: vmssadmin
admin_password: User123!!!abc
vm_name: vmforimage
image_name: "image_vmforimageA"
tasks:
- name: Create public IP address
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vmss_name }}"
register: pip_output
- name: Create a load balancer
azure_rm_loadbalancer:
name: "{{ vmss_name }}lb"
location: "{{ location }}"
resource_group: "{{ resource_group }}"
public_ip: "{{ vmss_name }}"
probe_protocol: Tcp
probe_port: 80
probe_interval: 10
probe_fail_count: 3
protocol: Tcp
load_distribution: Default
frontend_port: 80
backend_port: 80
idle_timeout: 4
natpool_frontend_port_start: 50000
natpool_frontend_port_end: 50040
natpool_backend_port: 22
natpool_protocol: Tcp
- name: Create a scale set
azure_rm_virtualmachinescaleset:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
vm_size: Standard_DS1_v2
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
ssh_password_enabled: true
capacity: 2
virtual_network_name: "{{ vm_name }}"
subnet_name: "{{ vm_name }}"
upgrade_policy: Manual
tier: Standard
managed_disk_type: Standard_LRS
os_disk_caching: ReadWrite
image:
name: "{{ image_name }}"
resource_group: "{{ resource_group }}"
load_balancer: "{{ vmss_name }}lb"
- debug:
msg: "Scale set public IP address: {{ pip_output.state.ip_address }}"
使用 ansible-playbook 命令来运行 playbook,将 myrg 替换为你的资源组名称:
ansible-playbook create-vmss.yml --extra-vars "resource_group=myrg"
由于 playbook 的特定部分,该 ansible-playbook 命令将打印出规模集的 IP 地址。 复制此 IP 地址供以后使用。
连接到规模集
使用上一部分的 IP 地址连接到规模集。
如前一部分所述,字符串 Image A 和 Image B 模拟具有两个不同配置的 VM。
规模集引用命名 image_vmforimageA的自定义映像。 自定义映像 image_vmforimageA 是从主页显示 Image A 的虚拟机创建的。
因此,你将看到一个主页,显示Image A。
继续下一部分时,将浏览器窗口保持打开状态。
更改规模集和升级实例中的自定义映像
在本部分中,playbook 代码将规模集的镜像从 image_vmforimageA 更改为 image_vmforimageB。 此外,由规模集部署的所有现有虚拟机都会被更新。
可通过两种方法获取示例剧本:
下载 playbook 并将其保存到
update-vmss-image.yml。创建名为
update-vmss-image.yml的新文件。 将以下代码插入新文件中:
- name: Update scale set image reference
hosts: localhost
connection: local
vars:
vmss_name: vmsstest
image_name: image_vmforimageB
admin_username: vmssadmin
admin_password: User123!!!abc
tasks:
- name: Update scale set - second image
azure_rm_virtualmachinescaleset:
resource_group: "{{ resource_group }}"
name: "{{ vmss_name }}"
vm_size: Standard_DS1_v2
admin_username: "{{ admin_username }}"
admin_password: "{{ admin_password }}"
ssh_password_enabled: true
capacity: 3
virtual_network_name: "{{ vmss_name }}"
subnet_name: "{{ vmss_name }}"
upgrade_policy: Manual
tier: Standard
managed_disk_type: Standard_LRS
os_disk_caching: ReadWrite
image:
name: "{{ image_name }}"
resource_group: "{{ resource_group }}"
load_balancer: "{{ vmss_name }}lb"
- name: List all of the instances
azure_rm_virtualmachinescalesetinstance_facts:
resource_group: "{{ resource_group }}"
vmss_name: "{{ vmss_name }}"
register: instances
- debug:
var: instances
- name: manually upgrade all the instances
azure_rm_virtualmachinescalesetinstance:
resource_group: "{{ resource_group }}"
vmss_name: "{{ vmss_name }}"
instance_id: "{{ item.instance_id }}"
latest_model: yes
with_items: "{{ instances.instances }}"
使用 ansible-playbook 命令运行 playbook,将 myrg 替换为资源组名称:
ansible-playbook update-vmss-image.yml --extra-vars "resource_group=myrg"
返回到浏览器并刷新页面,查看虚拟机的基础自定义映像是否已更新。
清理资源
将以下代码保存为
delete_rg.yml.--- - hosts: localhost tasks: - name: Deleting resource group - "{{ name }}" azure_rm_resourcegroup: name: "{{ name }}" state: absent register: rg - debug: var: rg使用 ansible-playbook 命令来运行 playbook。 将占位符替换为要删除的资源组的名称。 资源组中的所有资源都将被删除。
ansible-playbook delete_rg.yml --extra-vars "name=<resource_group>"要点:
- 因为 playbook 中的
register变量和debug部分,命令完成后会显示结果。
- 因为 playbook 中的