Migrera till Innovate Summit:
Lär dig hur migrering och modernisering till Azure kan öka företagets prestanda, motståndskraft och säkerhet, så att du kan använda AI fullt ut.Registrera dig nu
Den här webbläsaren stöds inte längre.
Uppgradera till Microsoft Edge och dra nytta av de senaste funktionerna och säkerhetsuppdateringarna, samt teknisk support.
Skapa generaliserade avbildningar utan en etableringsagent
Artikel
Gäller för: ✔️ Flexibla skalningsuppsättningar för virtuella Linux-datorer ✔️
Microsoft Azure tillhandahåller etableringsagenter för virtuella Linux-datorer i form av walinuxagent eller cloud-init (rekommenderas). Men det kan finnas ett scenario när du inte vill använda något av dessa program för din etableringsagent, till exempel:
Din Linux-distribution/-version stöder inte cloud-init/Linux-agenten.
Du måste ange specifika VM-egenskaper, till exempel värdnamn.
Anteckning
Om du inte kräver att några egenskaper anges eller om någon form av etablering sker bör du överväga att skapa en specialiserad avbildning.
Den här artikeln visar hur du kan konfigurera den virtuella datoravbildningen så att den uppfyller kraven för Azure-plattformen och ange värdnamnet, utan att installera en etableringsagent.
Nätverks- och rapporteringsklar
För att din virtuella Linux-dator ska kunna kommunicera med Azure-komponenter krävs en DHCP-klient. Klienten används för att hämta en värd-IP, DNS-matchning och routningshantering från det virtuella nätverket. De flesta distributioner levereras med dessa verktyg out-of-the-box. Verktyg som testas på Azure av Linux-distributionsleverantörer är dhclient, network-managersystemd-networkd och andra.
Anteckning
För närvarande har generaliserade avbildningar utan en etableringsagent endast stöd för DHCP-aktiverade virtuella datorer.
När nätverk har konfigurerats väljer du "rapportklar". Detta talar om för Azure att den virtuella datorn har etablerats.
Viktigt
Om du inte rapporterar redo till Azure kommer den virtuella datorn att startas om!
Demo/exempel
En befintlig Marketplace-avbildning (i det här fallet en virtuell Debian Buster-dator) med Linux-agenten (walinuxagent) borttagen och ett anpassat Python-skript som lagts till är det enklaste sättet att berätta för Azure att den virtuella datorn är "klar".
Skapa resursgruppen och den virtuella basdatorn:
Azure CLI
$ az group create --location eastus --name demo1
Skapa den virtuella basdatorn:
Azure CLI
$ az vm create \
--resource-group demo1 \
--name demo1 \
--location eastus \
--ssh-key-value<ssh_pub_key_path> \
--public-ip-address-dns-name demo1 \
--image"debian:debian-10:10:latest"
Ta bort avbildningsetableringsagenten
När den virtuella datorn har etablerats kan du ansluta till den via SSH och ta bort Linux-agenten:
Lägga till nödvändig kod till den virtuella datorn
Även i den virtuella datorn, eftersom vi har tagit bort Azure Linux-agenten måste vi tillhandahålla en mekanism för att rapportera redo.
Python-skript
Python
import http.client
import sys
from xml.etree import ElementTree
wireserver_ip = '168.63.129.16'
wireserver_conn = http.client.HTTPConnection(wireserver_ip)
print('Retrieving goal state from the Wireserver')
wireserver_conn.request(
'GET',
'/machine?comp=goalstate',
headers={'x-ms-version': '2012-11-30'}
)
resp = wireserver_conn.getresponse()
if resp.status != 200:
print('Unable to connect with wireserver')
sys.exit(1)
wireserver_goalstate = resp.read().decode('utf-8')
xml_el = ElementTree.fromstring(wireserver_goalstate)
container_id = xml_el.findtext('Container/ContainerId')
instance_id = xml_el.findtext('Container/RoleInstanceList/RoleInstance/InstanceId')
incarnation = xml_el.findtext('Incarnation')
print(f'ContainerId: {container_id}')
print(f'InstanceId: {instance_id}')
print(f'Incarnation: {incarnation}')
# Construct the XML response we need to send to Wireserver to report ready.
health = ElementTree.Element('Health')
goalstate_incarnation = ElementTree.SubElement(health, 'GoalStateIncarnation')
goalstate_incarnation.text = incarnation
container = ElementTree.SubElement(health, 'Container')
container_id_el = ElementTree.SubElement(container, 'ContainerId')
container_id_el.text = container_id
role_instance_list = ElementTree.SubElement(container, 'RoleInstanceList')
role = ElementTree.SubElement(role_instance_list, 'Role')
instance_id_el = ElementTree.SubElement(role, 'InstanceId')
instance_id_el.text = instance_id
health_second = ElementTree.SubElement(role, 'Health')
state = ElementTree.SubElement(health_second, 'State')
state.text = 'Ready'
out_xml = ElementTree.tostring(
health,
encoding='unicode',
method='xml'
)
print('Sending the following data to Wireserver:')
print(out_xml)
wireserver_conn.request(
'POST',
'/machine?comp=health',
headers={
'x-ms-version': '2012-11-30',
'Content-Type': 'text/xml;charset=utf-8',
'x-ms-agent-name': 'custom-provisioning'
},
body=out_xml
)
resp = wireserver_conn.getresponse()
print(f'Response: {resp.status}{resp.reason}')
wireserver_conn.close()
Bash-skript
#!/bin/bash
attempts=1
until [ "$attempts" -gt 5 ]
do
echo "obtaining goal state - attempt $attempts"
goalstate=$(curl --fail -v -X 'GET' -H "x-ms-agent-name: azure-vm-register" \
-H "Content-Type: text/xml;charset=utf-8" \
-H "x-ms-version: 2012-11-30" \
"http://168.63.129.16/machine/?comp=goalstate")
if [ $? -eq 0 ]
then
echo "successfully retrieved goal state"
retrieved_goal_state=true
break
fi
sleep 5
attempts=$((attempts+1))
done
if [ "$retrieved_goal_state" != "true" ]
then
echo "failed to obtain goal state - cannot register this VM"
exit 1
fi
container_id=$(grep ContainerId <<< "$goalstate" | sed 's/\s*<\/*ContainerId>//g' | sed 's/\r$//')
instance_id=$(grep InstanceId <<< "$goalstate" | sed 's/\s*<\/*InstanceId>//g' | sed 's/\r$//')
ready_doc=$(cat << EOF
<?xml version="1.0" encoding="utf-8"?>
<Health xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GoalStateIncarnation>1</GoalStateIncarnation>
<Container>
<ContainerId>$container_id</ContainerId>
<RoleInstanceList>
<Role>
<InstanceId>$instance_id</InstanceId>
<Health>
<State>Ready</State>
</Health>
</Role>
</RoleInstanceList>
</Container>
</Health>
EOF
)
attempts=1
until [ "$attempts" -gt 5 ]
do
echo "registering with Azure - attempt $attempts"
curl --fail -v -X 'POST' -H "x-ms-agent-name: azure-vm-register" \
-H "Content-Type: text/xml;charset=utf-8" \
-H "x-ms-version: 2012-11-30" \
-d "$ready_doc" \
"http://168.63.129.16/machine?comp=health"
if [ $? -eq 0 ]
then
echo "successfully register with Azure"
break
fi
sleep 5 # sleep to prevent throttling from wire server
done
Allmänna steg (om de inte använder Python eller Bash)
Om den virtuella datorn inte har Python installerat eller tillgängligt kan du programmatiskt återskapa det här ovanstående skriptlogik med följande steg:
ContainerIdHämta , InstanceIdoch Incarnation genom att parsa svaret från WireServer: curl -X GET -H 'x-ms-version: 2012-11-30' http://168.63.129.16/machine?comp=goalstate.
Konstruera följande XML-data och mata in parsade ContainerId, InstanceIdoch Incarnation från ovanstående steg:
Publicera dessa data till WireServer: curl -X POST -H 'x-ms-version: 2012-11-30' -H "x-ms-agent-name: WALinuxAgent" -H "Content-Type: text/xml;charset=utf-8" -d "$REPORT_READY_XML" http://168.63.129.16/machine?comp=health
Automatisera körning av koden vid första starten
Den här demonstrationen använder systemd, vilket är det vanligaste init-systemet i moderna Linux-distributioner. Så det enklaste och mest inbyggda sättet att se till att den här rapportklara mekanismen körs vid rätt tidpunkt är att skapa en systembaserad tjänstenhet. Du kan lägga till följande enhetsfil /etc/systemd/system i (i det här exemplet namnges enhetsfilen azure-provisioning.service):
Den här systemd-tjänsten gör tre saker för grundläggande etablering:
Rapporter som är redo för Azure (för att indikera att det har kommit upp).
Byter namn på den virtuella datorn baserat på namnet på den virtuella datorn som angetts av användaren genom att hämta dessa data från Azure Instance Metadata Service (IMDS). Obs! IMDS innehåller även andra instansmetadata, till exempel offentliga SSH-nycklar, så att du kan ange mer än värdnamnet.
Inaktiverar sig själv så att den bara körs vid första starten och inte vid efterföljande omstarter.
Med enheten i filsystemet kör du följande för att aktivera det:
Nu är vi redo att skapa en ny virtuell dator från avbildningen. Detta kan också användas för att skapa flera virtuella datorer:
Azure CLI
$ IMAGE_ID=$(az image show -g demo1 -n demo1img --query id -o tsv)
$ az vm create \
--resource-group demo12 \
--name demo12 \
--location eastus \
--ssh-key-value<ssh_pub_key_path> \
--public-ip-address-dns-name demo12 \
--image"$IMAGE_ID"--enable-agentfalse
Anteckning
Det är viktigt att ange --enable-agent till false eftersom walinuxagent inte finns på den virtuella datorn som kommer att skapas från avbildningen.
Den virtuella datorn bör etableras korrekt. När du har loggat in på den nyligen etablerade virtuella datorn bör du kunna se utdata från den rapportklara systemtjänsten:
Bash
$ sudo journalctl -u azure-provisioning.service
-- Logs begin at Thu 2020-06-11 20:28:45 UTC, end at Thu 2020-06-11 20:31:24 UTC. --
Jun 11 20:28:49 thstringnopa systemd[1]: Starting Azure Provisioning...
Jun 11 20:28:54 thstringnopa python3[320]: Retrieving goal state from the Wireserver
Jun 11 20:28:54 thstringnopa python3[320]: ContainerId: 7b324f53-983a-43bc-b919-1775d6077608
Jun 11 20:28:54 thstringnopa python3[320]: InstanceId: fbb84507-46cd-4f4e-bd78-a2edaa9d059b._thstringnopa2
Jun 11 20:28:54 thstringnopa python3[320]: Sending the following data to Wireserver:
Jun 11 20:28:54 thstringnopa python3[320]: <Health><GoalStateIncarnation>1</GoalStateIncarnation><Container><ContainerId>7b324f53-983a-43bc-b919-1775d6077608</ContainerId><RoleInstanceList><Role><InstanceId>fbb84507-46cd-4f4e-bd78-a2edaa9d059b._thstringnopa2</InstanceId><Health><State>Ready</State></Health></Role></RoleInstanceList></Container></Health>
Jun 11 20:28:54 thstringnopa python3[320]: Response: 200 OK
Jun 11 20:28:56 thstringnopa bash[472]: % Total % Received % Xferd Average Speed Time Time Time Current
Jun 11 20:28:56 thstringnopa bash[472]: Dload Upload Total Spent Left Speed
Jun 11 20:28:56 thstringnopa bash[472]: [158B blob data]
Jun 11 20:28:56 thstringnopa2 systemctl[475]: Removed /etc/systemd/system/multi-user.target.wants/azure-provisioning.service.
Jun 11 20:28:56 thstringnopa2 systemd[1]: azure-provisioning.service: Succeeded.
Jun 11 20:28:56 thstringnopa2 systemd[1]: Started Azure Provisioning.
Support
Om du implementerar din egen etableringskod/agent äger du supporten för den här koden. Microsoft-supporten undersöker endast problem som rör att etableringsgränssnitten inte är tillgängliga. Vi gör kontinuerligt förbättringar och ändringar på det här området, så du måste övervaka ändringar i cloud-init och Azure Linux Agent för etablering av API-ändringar.
Lär dig hur du skapar nya virtuella datorer från generaliserade avbildningar och använder Azure Image Builder-mallar för att skapa och hantera avbildningar i Azure.