Sağlama aracısı olmadan genelleştirilmiş görüntüler oluşturma
Şunlar için geçerlidir: ✔️ Linux VM'leri ✔️ Esnek ölçek kümeleri
Microsoft Azure, Linux VM'leri için walinuxagent veya cloud-init biçiminde sağlama aracıları sağlar (önerilir). Ancak sağlama aracınız için bu uygulamalardan herhangi birini kullanmak istemediğiniz bir senaryo olabilir, örneğin:
- Linux dağıtımınız/sürümünüz cloud-init/Linux Agent'ı desteklemiyor.
- Konak adı gibi belirli VM özelliklerinin ayarlanması gerekir.
Not
Herhangi bir özelliğin ayarlanmasını veya herhangi bir sağlama biçiminin gerçekleşmesini istemiyorsanız, özel bir görüntü oluşturmayı düşünmelisiniz.
Bu makalede, sağlama aracısı yüklemeden Azure platform gereksinimlerini karşılamak ve konak adını ayarlamak için VM görüntünüzü nasıl ayarlayabileceğiniz gösterilir.
Ağ ve raporlama hazır
Linux VM'nizin Azure bileşenleriyle iletişim kurmasını sağlamak için bir DHCP istemcisi gerekir. İstemci, sanal ağdan bir ana bilgisayar IP'sini, DNS çözümlemesini ve yol yönetimini almak için kullanılır. Dağıtımların çoğu bu yardımcı programlarla birlikte kullanıma açılır. Linux dağıtım satıcıları tarafından Azure'da test edilen araçlar arasında , network-manager
systemd-networkd
ve diğerleri bulunurdhclient
.
Not
Şu anda sağlama aracısı olmadan genelleştirilmiş görüntüler oluşturulurken yalnızca DHCP özellikli VM'ler desteklenir.
Ağ ayarlandıktan ve yapılandırıldıktan sonra "rapor hazır" seçeneğini belirleyin. Bu, Azure'a VM'nin başarıyla sağlandığını bildirir.
Önemli
Azure'a hazır raporun başarısız olması VM'nizin yeniden başlatılmasına neden olur!
Tanıtım/örnek
Linux Aracısı (walinuxagent) kaldırılmış ve özel python betiği eklenmiş mevcut bir Market görüntüsü (bu örnekte bir Debian Buster VM), Azure'a VM'nin "hazır" olduğunu söylemenin en kolay yoludur.
Kaynak grubunu ve temel VM'yi oluşturun:
$ az group create --location eastus --name demo1
Temel VM'yi oluşturma:
$ 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"
Görüntü sağlama Aracısını kaldırma
VM sağlandıktan sonra SSH aracılığıyla vm'ye bağlanabilir ve Linux Aracısı'nı kaldırabilirsiniz:
$ sudo apt purge -y waagent
$ sudo rm -rf /var/lib/waagent /etc/waagent.conf /var/log/waagent.log
Vm'ye gerekli kodu ekleme
Ayrıca VM'nin içinde, Azure Linux Aracısı'nı kaldırdığımız için hazır raporlamaya yönelik bir mekanizma sağlamamız gerekir.
Python betiği
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 betiği
#!/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
Genel adımlar (Python veya Bash kullanılmıyorsa)
VM'nizde Python yüklü veya kullanılabilir değilse, aşağıdaki adımlarla yukarıdaki betik mantığını program aracılığıyla yeniden oluşturabilirsiniz:
ContainerId
Yanıtı WireServer' dan ayrıştırarak ,InstanceId
veIncarnation
alın:curl -X GET -H 'x-ms-version: 2012-11-30' http://168.63.129.16/machine?comp=goalstate
.Ayrıştırılmış
ContainerId
,InstanceId
veIncarnation
öğesini yukarıdaki adımdan arak aşağıdaki XML verilerini oluşturma:<Health> <GoalStateIncarnation>INCARNATION</GoalStateIncarnation> <Container> <ContainerId>CONTAINER_ID</ContainerId> <RoleInstanceList> <Role> <InstanceId>INSTANCE_ID</InstanceId> <Health> <State>Ready</State> </Health> </Role> </RoleInstanceList> </Container> </Health>
Bu verileri WireServer'a gönderin:
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
İlk önyüklemede kodu çalıştırmayı otomatikleştirme
Bu tanıtımda, modern Linux dağıtımlarında en yaygın init sistemi olan systemd kullanılır. Bu nedenle, bu rapora hazır mekanizmanın doğru zamanda çalıştığından emin olmak için en kolay ve en yerel yol, sistemli bir hizmet birimi oluşturmaktır. Aşağıdaki birim dosyasını 'a /etc/systemd/system
ekleyebilirsiniz (bu örnek, birim dosyasını azure-provisioning.service
adlandırabilir):
[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
Bu sistemli hizmet, temel sağlama için üç şey yapar:
- Azure'a hazır raporlar (başarılı olduğunu belirtmek için).
- Bu verileri Azure Örnek Meta Veri Hizmeti'nden (IMDS) çekerek kullanıcı tarafından sağlanan VM adını temel alarak VM'yi yeniden adlandırır. Not IMDS, konak adından daha fazlasını ayarlayabilmeniz için SSH Ortak Anahtarları gibi başka örnek meta verileri de sağlar.
- Kendisini, sonraki yeniden başlatmalarda değil yalnızca ilk önyüklemede çalışacak şekilde devre dışı bırakır.
Dosya sistemindeki üniteyle, etkinleştirmek için aşağıdakileri çalıştırın:
$ sudo systemctl enable azure-provisioning.service
Artık VM genelleştirilmeye hazırdır ve sanal makineden bir görüntü oluşturulur.
Görüntünün hazırlanması tamamlanıyor
Geliştirme makinenize döndüğünüzde, temel VM'den görüntü oluşturmaya hazırlanmak için aşağıdakileri çalıştırın:
$ az vm deallocate --resource-group demo1 --name demo1
$ az vm generalize --resource-group demo1 --name demo1
Görüntüyü bu VM'den oluşturun:
$ az image create \
--resource-group demo1 \
--source demo1 \
--location eastus \
--name demo1img
Artık görüntüden yeni bir VM oluşturmaya hazırız. Bu, birden çok VM oluşturmak için de kullanılabilir:
$ 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
Not
Walinuxagent görüntüden oluşturulacak bu VM'de mevcut olmadığından olarak ayarlanması --enable-agent
false
önemlidir.
VM başarıyla sağlanmalıdır. Yeni sağlama VM'sinde oturum açtıktan sonra rapora hazır sistemli hizmetin çıkışını görebilmeniz gerekir:
$ 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.
Destek
Kendi sağlama kodunuzu/aracınızı uygularsanız, bu kodun desteği size aittir, Microsoft desteği yalnızca sağlama arabirimlerinin kullanılamamasıyla ilgili sorunları araştırır. Bu alanda sürekli iyileştirmeler ve değişiklikler yapıyoruz, bu nedenle API değişikliklerini sağlamak için cloud-init ve Azure Linux Aracısı'ndaki değişiklikleri izlemeniz gerekir.
Sonraki adımlar
Daha fazla bilgi için bkz . Linux sağlama.