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 Aracısı'nın 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, özelleştirilmiş bir görüntü oluşturmayı göz önünde bulundurmalısınız.
Bu makalede, azure platformu gereksinimlerini karşılamak için VM görüntünüzü nasıl ayarlayabileceğiniz ve bir sağlama aracısı yüklemeden konak adını nasıl ayarlayabileceğiniz gösterilmektedir.
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. Çoğu dağıtım, bu yardımcı programlarla birlikte kullanıma açılır. Azure'da Linux dağıtım satıcıları tarafından test edilen araçlar arasında dhclient
, network-manager
systemd-networkd
ve diğerleri bulunur.
Not
Şu anda sağlama aracısı olmadan genelleştirilmiş görüntüler oluşturmak yalnızca DHCP özellikli VM'leri destekler.
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 bildirimin başarısız olması VM'nizin yeniden başlatılmasına neden olur!
Tanıtım/örnek
Linux Aracısı'nın (walinuxagent) kaldırıldığı ve özel bir python betiğinin eklendiği 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şturun:
$ 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
WireServer' dan yanıtı 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
.Yukarıdaki adımdan ayrıştırılmış
ContainerId
,InstanceId
veIncarnation
eklenerek 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 örnekte birim dosyası azure-provisioning.service
olarak adlandırılabilir):
[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ıyla karşılandığını belirtmek için).
- Bu verileri Azure Instance Metadata Service'ten (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 devre dışı bırakır, böylece yalnızca ilk önyüklemede çalışır ve sonraki yeniden başlatmalarda çalışmaz.
Dosya sistemindeki üniteyi etkinleştirmek için aşağıdakileri çalıştırın:
$ sudo systemctl enable azure-provisioning.service
Artık VM genelleştirilmeye ve sanal makineden bir görüntü oluşturulmaya hazırdır.
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.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin