Általánosított képek létrehozása kiépítési ügynök nélkül
A következőkre vonatkozik: ✔️ Linux rendszerű virtuális gépek rugalmas méretezési ✔️ csoportjai
A Microsoft Azure kiépítési ügynököket biztosít Linux rendszerű virtuális gépekhez walinuxagent vagy cloud-init formában (ajánlott). Előfordulhat azonban, hogy a kiépítési ügynök egyik alkalmazását sem szeretné használni, például:
- A Linux-disztribúció/verzió nem támogatja a cloud-init/Linux-ügynököt.
- Meg kell adnia bizonyos virtuálisgép-tulajdonságokat, például a gazdagép nevét.
Feljegyzés
Ha nincs szükség tulajdonságok beállítására vagy bármilyen kiépítési módra, érdemes speciális rendszerképet létrehoznia.
Ez a cikk bemutatja, hogyan állíthatja be a virtuálisgép-rendszerképet az Azure-platform követelményeinek megfelelően, és hogyan állíthatja be a gazdagépnevet kiépítési ügynök telepítése nélkül.
Hálózatkezelés és jelentéskészítés kész
Ahhoz, hogy Linux rendszerű virtuális gépe kommunikálhasson az Azure-összetevőkkel, DHCP-ügyfélre van szükség. Az ügyfél a gazdagép IP-címének, DNS-felbontásának és útvonalkezelésének lekérésére szolgál a virtuális hálózatról. A legtöbb disztribúció ezeket a segédprogramokat házon kívül szállítja. Az Azure-ban linuxos disztribúciós gyártók által tesztelt eszközök közé tartoznak többek között dhclient
az , network-manager
systemd-networkd
és mások is.
Feljegyzés
Jelenleg általánosított rendszerképek létrehozása kiépítési ügynök nélkül csak a DHCP-kompatibilis virtuális gépeket támogatja.
A hálózatkezelés beállítása és konfigurálása után válassza a "jelentés kész" lehetőséget. Ez azt jelzi az Azure-nak, hogy a virtuális gép üzembe helyezése sikeresen megtörtént.
Fontos
Ha nem sikerül az Azure-nak való jelentéskészítés, a virtuális gép újraindul.
Bemutató/minta
Egy meglévő Marketplace-rendszerkép (ebben az esetben egy Debian Buster virtuális gép) és a Linux-ügynök (walinuxagent) eltávolítása, valamint egy egyéni Python-szkript hozzáadása a legegyszerűbb módja annak, hogy az Azure-nak elmondja, hogy a virtuális gép "kész".
Hozza létre az erőforráscsoportot és az alapszintű virtuális gépet:
$ az group create --location eastus --name demo1
Hozza létre az alapszintű virtuális gépet:
$ 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"
A képkiépítési ügynök eltávolítása
A virtuális gép üzembe helyezése után SSH-val csatlakozhat hozzá, és eltávolíthatja a Linux-ügynököt:
$ sudo apt purge -y waagent
$ sudo rm -rf /var/lib/waagent /etc/waagent.conf /var/log/waagent.log
Kötelező kód hozzáadása a virtuális géphez
A virtuális gépen belül is, mivel eltávolítottuk az Azure Linux-ügynököt, létre kell hoznunk egy olyan mechanizmust, amely készen áll a jelentéskészítésre.
Python-szkript
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-szkript
#!/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
Általános lépések (ha nem Pythont vagy Basht használ)
Ha a virtuális gép nem rendelkezik Pythonnal, vagy nem érhető el, a fenti szkriptlogikát programozott módon reprodukálhatja az alábbi lépésekkel:
Kérje le a
ContainerId
,InstanceId
majdIncarnation
a WireServer válaszának elemzésével:curl -X GET -H 'x-ms-version: 2012-11-30' http://168.63.129.16/machine?comp=goalstate
.Hozza létre a következő XML-adatokat az elemzésbe
ContainerId
injektálva,InstanceId
majdIncarnation
a fenti lépésből:<Health> <GoalStateIncarnation>INCARNATION</GoalStateIncarnation> <Container> <ContainerId>CONTAINER_ID</ContainerId> <RoleInstanceList> <Role> <InstanceId>INSTANCE_ID</InstanceId> <Health> <State>Ready</State> </Health> </Role> </RoleInstanceList> </Container> </Health>
Tegye közzé ezeket az adatokat a WireServerben:
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
A kód első indításakor történő futtatásának automatizálása
Ez a bemutató a systemd rendszert használja, amely a modern Linux disztribúciók leggyakoribb init rendszere. Így a legegyszerűbb és legnatívabb módja annak, hogy ez a jelentéskész mechanizmus a megfelelő időben fusson, ha létrehoz egy rendszerezett szolgáltatási egységet. A következő egységfájlt is hozzáadhatja ( /etc/systemd/system
ez a példa az egységfájlt azure-provisioning.service
nevezi):
[Unit]
Description=Azure Provisioning
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /usr/local/azure-provisioning.py
ExecStart=/bin/bash -c "hostnamectl set-hostname $(curl \
-H 'metadata: true' \
'http://169.254.169.254/metadata/instance/compute/name?api-version=2019-06-01&format=text')"
ExecStart=/usr/bin/systemctl disable azure-provisioning.service
[Install]
WantedBy=multi-user.target
Ez a rendszerszintű szolgáltatás három dolgot végez az alapszintű kiépítéshez:
- Jelentések készen állnak az Azure-ra (annak jelzésére, hogy sikeresen megjelent).
- Átnevezi a virtuális gépet a felhasználó által megadott virtuális gép neve alapján úgy, hogy lekérte ezeket az adatokat az Azure Instance Metadata Service-ből (IMDS). Megjegyzés: Az IMDS más példány metaadatait is biztosítja, például az SSH nyilvános kulcsait, így a gazdagépnévnél többet is megadhat.
- Letiltja magát, hogy csak az első rendszerindításkor fusson, és ne az azt követő újraindításokon.
Az egység a fájlrendszeren való engedélyezéséhez futtassa az alábbiakat:
$ sudo systemctl enable azure-provisioning.service
A virtuális gép most már készen áll az általánosított használatra, és létrehoz egy rendszerképet belőle.
A kép előkészítésének befejezése
A fejlesztői gépre visszatérve futtassa a következőket, hogy felkészüljön a rendszerképek alapszintű virtuális gépről való létrehozására:
$ az vm deallocate --resource-group demo1 --name demo1
$ az vm generalize --resource-group demo1 --name demo1
És hozza létre a rendszerképet ebből a virtuális gépből:
$ az image create \
--resource-group demo1 \
--source demo1 \
--location eastus \
--name demo1img
Most már készen állunk egy új virtuális gép létrehozására a rendszerképből. Ez több virtuális gép létrehozásához is használható:
$ 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-agent false
Feljegyzés
Fontos beállítani --enable-agent
, false
mert a walinuxagent nem létezik ezen a virtuális gépen, amelyet a rendszerképből fog létrehozni.
A virtuális gépet sikeresen ki kellépíteni. Miután bejelentkezett az újonnan kiépítendő virtuális gépre, látnia kell a jelentésre kész, rendszerezett szolgáltatás kimenetét:
$ 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.
Támogatás
Ha saját kiépítési kódot/ügynököt implementál, akkor Ön a kód támogatása, a Microsoft ügyfélszolgálata csak a kiépítési felületekkel kapcsolatos problémákat vizsgálja meg, amelyek nem érhetők el. Folyamatosan fejlesztünk és módosítunk ezen a területen, ezért figyelnie kell a cloud-init és az Azure Linux Agent változásait az API-módosítások kiépítéséhez.
Következő lépések
További információ: Linux-kiépítés.