準備 Linux 以用於 Azure 映像
警告
本文會參考 CentOS,這是生命週期結束 (EOL) 狀態的 Linux 發行版本。 請據以考慮您的使用和規劃。 如需詳細資訊,請參閱 CentOS 生命週期結束指導。
適用於:✔️ Linux VM ✔️ 彈性擴展集
僅當您使用其中一個背書的發行版本時,Azure 平台服務等級協定 (SLA) 才會適用於執行 Linux 作業系統的虛擬機器 (VM)。 針對背書的發行版本,Azure Marketplace 提供預先設定的 Linux 映像。 如需詳細資訊,請參閱
在 Azure 上執行的所有其他發行版本,包含社群支援和非背書的發行版本,都有一些必要條件。
本文將著重於在 Azure 上執行 Linux 發行版本時的一般指導。 本文無法完整詳述,因為每個發行版本各不相同。 即使您符合本文描述的所有準則,還是可能需要對您的 Linux 系統進行大幅調整,以使其正常執行。
一般 Linux 安裝注意事項
Azure 不支援 Hyper-V 虛擬硬碟 (VHDX) 格式。 Azure 只支援固定 VHD。 您可以使用 Hyper-V 管理員或 Convert-VHD Cmdlet,將磁碟轉換為 VHD 格式。 如果您使用的是 VirtualBox,即會在建立磁碟時選取 [固定大小] 而不是預設值 (動態配置的)。
Azure 支援 Gen1 (BIOS 開機) 和 Gen2 (UEFI 開機) 虛擬機器。
必須在核心中啟用虛擬檔案配置表 (VFAT) 核心模組。
允許的 VHD 大小上限為 1023 GB。
安裝 Linux 系統時,建議您使用標準磁碟分割,而不是邏輯磁碟區管理員 (LVM)。 LVM 是許多安裝程序的預設值。
使用標準磁碟分割將可避免 LVM 名稱與複製的 VM 發生衝突,特別是為了疑難排解而一律要將 OS 磁碟連接至另一個相同的 VM 時。 您可以在資料磁碟上使用 LVM 或 RAID。
需要裝載了使用者定義函式 (UDF) 檔案系統的核心支援。 在 Azure 上第一次開機時,佈建設定會透過連結至客體的 UDF 格式媒體傳遞至 Linux VM。 Azure Linux 代理程式必須裝載 UDF 檔案系統,才能讀取其設定並佈建 VM。
2.6.37 以前的 Linux 核心版本不支援具較大 VM 大小的 Hyper-V 非統一記憶體存取 (NUMA)。 這個問題主要會影響使用了上游 Red Hat 2.6.32 核心的較舊發行版本。 該問題已在 Red Hat Enterprise Linux (RHEL) 6.6 (kernel-2.6.32-504) 進行修正。
若系統執行的自訂核心是 2.6.37 以前版本,或 執行 2.6.32-504 以前版本的 RHEL 型核心,則必須在 grub.conf 的核心命令列上設定開機參數
numa=off
。 如需詳細資訊,請參閱 Red Hat KB 436883 \(英文\)。請勿在 OS 磁碟上設定交換磁碟分割。 如本文後段所述,您可以設定 Linux 代理程式以在暫存資源磁碟上建立分頁檔。
Azure 上的所有 VHD 必須具有與 1 MB (1024 x 1024 位元組) 對應的虛擬大小。 如本文後段所述,當您從原始磁碟轉換為 VHD 時,請在轉換前確定原始磁碟大小是 1 MB 的倍數。
使用最新的散發套件版本、套件和軟體。
移除使用者和系統帳戶、公開金鑰、敏感性資料、不必要的軟體和應用程式。
注意
Cloud-init 21.2 版或更新版本會移除 UDF 需求。 不過,若未啟用 udf
模組,就無法在佈建期間裝載 CD-ROM,進而無法套用自訂資料。 因應措施是套用使用者資料。 然而,與自訂資料不同,使用者資料並未經過加密。 如需詳細資訊,請參閱 cloud-init 文件中的使用者資料格式。
安裝不含 Hyper-V 的核心模組
Azure 會在 Hyper-V Hypervisor 上執行,因此 Linux 要求在 Azure 中執行某些核心模組。 如果您是在 Hyper-V 外部建立 VM,除非 VM 偵測到其執行環境為 Hyper-V 環境,否則 Linux 安裝程式在初始的 RAM 磁碟 (initrd 或 initramfs) 中可能不會包含 Hyper-V 的驅動程式。
使用不同的虛擬化系統 (例如 VirtualBox 或 KVM) 來準備 Linux 映像時,您可能需要重建 initrd,以確保在初始 RAM 磁碟上至少有 hv_vmbus
和 hv_storvsc
核心模組可以使用。 這個已知問題適用於以上游 Red Hat 發行版本為基礎的系統,而且可能還有其他系統。
重建 initrd 或 initramfs 映像的機制可能會根據發行版本而有所不同。 請參閱散發套件的文件或洽支援人員,以了解適當程序。 以下是使用 mkinitrd
公用程式重建 initrd 的範例之一:
備份現有的 initrd 映像:
cd /boot sudo cp initrd-`uname -r`.img initrd-`uname -r`.img.bak
使用
hv_vmbus
和hv_storvsc
核心模組重建 initrd:sudo mkinitrd --preload=hv_storvsc --preload=hv_vmbus -v -f initrd-`uname -r`.img `uname -r`
調整 VHD 的大小
Azure 上的 VHD 映像必須具有與 1 MB 對齊的虛擬大小。 一般而言,透過 Hyper-V 建立的 VHD 均會正確地對應儲存。 如果 VHD 並未正確地對應儲存,則當您嘗試從 VHD 建立映像時,可能會收到類似以下範例的錯誤訊息:
The VHD http://<mystorageaccount>.blob.core.windows.net/vhds/MyLinuxVM.vhd has an unsupported virtual size of 21475270656 bytes. The size must be a whole number (in MBs).
在此案例中,您可以使用 Hyper-V 管理員主控台或 Resize-VHD PowerShell Cmdlet 來調整 VM 的大小。 如果您不是在 Windows 環境中執行,建議使用 qemu-img
來轉換 VHD (如果需要) 並調整其大小。
注意
QEMU 2.2.1 版和之後的部份版本有 qemu-img 已知錯誤 (bug),該錯誤會導致 VHD 的格式不正確。 此問題已在 QEMU 2.6 中修正。 建議您使用 2.2.0 版或更早版本,或使用 2.6 版或更新版本。
直接使用工具 (例如
qemu-img
或vbox-manage
) 調整 VHD 的大小,可能會導致 VHD 無法開機。 建議您先使用以下程式碼,將 VHD 轉換為原始磁碟映像。如果 VM 映像已建立為原始磁碟映像,您可以略過此步驟。 將 VM 映像建立為原始磁碟映像是某些 Hypervisor (例如 KVM) 中的預設值。
sudo qemu-img convert -f vpc -O raw MyLinuxVM.vhd MyLinuxVM.raw
計算所需的磁碟映像大小,如此一來,虛擬大小即會對應儲存為 1 MB。 下列 Bash 殼層指令碼會使用
qemu-img info
來判斷磁碟映像的虛擬大小,然後計算到下一個 1 MB 的大小:rawdisk="MyLinuxVM.raw" vhddisk="MyLinuxVM.vhd" MB=$((1024*1024)) size=$(qemu-img info -f raw --output json "$rawdisk" | \ gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}') rounded_size=$(((($size+$MB-1)/$MB)*$MB)) echo "Rounded Size = $rounded_size"
使用
$rounded_size
調整原始磁碟的大小:sudo qemu-img resize MyLinuxVM.raw $rounded_size
將原始磁碟轉換回固定大小的 VHD:
sudo qemu-img convert -f raw -o subformat=fixed,force_size -O vpc MyLinuxVM.raw MyLinuxVM.vhd
或者,使用 2.6 版之前的 QEMU 版本來移除
force_size
選項:sudo qemu-img convert -f raw -o subformat=fixed -O vpc MyLinuxVM.raw MyLinuxVM.vhd
Linux 核心需求
適用於 Hyper-V 和 Azure 的 Linux Integration Services (LIS) 驅動程式會直接提供給上游 Linux Kernel。 許多包括最新 Linux 核心版本 (例如 3.x) 的發行版本已經有這些驅動程式可供使用,或透過其核心來提供這些驅動程式的向後移植版本。
LIS 驅動程式會在上游核心中不斷更新,並具有新的修正程式和功能。 建議您執行包含這些修正程式和更新的背書發行版本 (若適用)。
如果您執行的是 RHEL 版本 6.0 到 6.3 的變體,則必須安裝 Hyper-V 的最新 LIS 驅動程式。 從 RHEL 6.4+ (及衍生項目) 開始,核心就已經隨附 LIS 驅動程式,因此您無需額外的安裝套件。
如果需要自訂核心,建議您使用最新的核心版本 (例如 3.8+)。 針對發行版本或自行維護核心的廠商,您需要定期將 LIS 驅動程式從上游核心反向移植到您的自訂核心。
即使您已經在執行相對較新的核心版本,還是強烈建議您持續追蹤 LIS 驅動程式中的任何上游修正程式,並視需要將其反向移植。 LIS 驅動程式原始程式檔的位置均指定於 Linux 核心來源樹狀目錄的 MAINTAINERS 檔案中:
F: arch/x86/include/asm/mshyperv.h
F: arch/x86/include/uapi/asm/hyperv.h
F: arch/x86/kernel/cpu/mshyperv.c
F: drivers/hid/hid-hyperv.c
F: drivers/hv/
F: drivers/input/serio/hyperv-keyboard.c
F: drivers/net/hyperv/
F: drivers/scsi/storvsc_drv.c
F: drivers/video/fbdev/hyperv_fb.c
F: include/linux/hyperv.h
F: tools/hv/
VM 的作用中核心必須包含下列修補檔。 對於所有發行版本而言,此清單並不完整。
- ata_piix:依預設將磁碟委託給 Hyper-V 驅動程式
- storvsc:負責 RESET 路徑中的在途封包
- storvsc:避免使用 WRITE_SAME
- storvsc:針對 RAID 和虛擬主機介面卡驅動程式停用 WRITE SAME
- storvsc:NULL 指標取值修正
- storvsc:信號緩衝區失敗可能導致 I/O 凍結
- scsi_sysfs︰防範 __scsi_remove_device 雙重執行
Azure Linux 代理程式
Azure Linux 代理程式 (waagent
) 會在 Azure 中佈建 Linux 虛擬機器。 您可以在 Linux 代理程式 GitHub 存放庫中取得最新版本、回報問題或提交提取要求。
以下是使用 Azure Linux 代理程式的一些考量:
- Linux 代理程式已在 Apache 2.0 授權下發行。 許多發行版本已為代理程式提供 .rpm 或 .deb 套件。 您可以輕鬆安裝及更新這些套件。
- Azure Linux 代理程式需要 Python v2.6+。
- 代理程式還需要
python-pyasn1
模組。 大多數的發行版本都會以可個別安裝的套件形式提供此模組。 - 在某些情況下,Azure Linux 代理程式可能與 NetworkManager 不相容。 發行版本所提供的許多套件 (.rpm 或 .deb) 都會將 NetworkManager 設定為與
waagent
套件的衝突。 在這些情況下,當您安裝 Linux 代理程式套件時,代理程式將會解除安裝 NetworkManager。 - Azure Linux 代理程式必須等於或高於最小支援版本。
注意
請確定已啟用 udf
和 vfat
模組。 停用 udf
模組會導致佈建失敗。 停用 vfat
模組會同時導致佈建和開機失敗。 在這兩個條件存在的情況下,Cloud-init 21.2 版或更新版本可以佈建 VM 而無需使用 UDF:
- 您使用 SSH 公開金鑰而非密碼來建立 VM。
- 您未提供任何自訂資料。
一般的 Linux 系統需求
修改 GRUB 或 GRUB2 中的核心開機行以包含下列參數,如此便會將所有主控台訊息傳送到第一個序列埠。 這些訊息均可協助 Azure 支援來偵錯任何問題。
GRUB_CMDLINE_LINUX="rootdelay=300 console=ttyS0 earlyprintk=ttyS0 net.ifnames=0"
我們也建議移除下列參數 (如果有的話):
rhgb quiet crashkernel=auto
在雲端環境中,您會想要將所有記錄傳送到序列埠,因此不適合使用圖形化和無訊息開機。 您可以視需要保留已設定的
crashkernel
選項,但此參數會減少 VM 中至少 128 MB 的可用記憶體數量。 減少可用的記憶體可能會對較小的 VM 大小造成問題。在您編輯 /etc/default/grub 之後,請執行下列命令以重建 GRUB 設定:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
使用
dracut
來新增適用於 initramfs 的 Hyper-V 模組:cd /boot sudo cp initramfs-<kernel-version>.img <kernel-version>.img.bak sudo dracut -f -v initramfs-<kernel-version>.img <kernel-version> --add-drivers "hv_vmbus hv_netvsc hv_storvsc" sudo grub-mkconfig -o /boot/grub/grub.cfg sudo grub2-mkconfig -o /boot/grub2/grub.cfg
使用
mkinitramfs
來新增適用於 initrd 的 Hyper-V 模組:cd /boot sudo cp initrd.img-<kernel-version> initrd.img-<kernel-version>.bak sudo mkinitramfs -o initrd.img-<kernel-version> <kernel-version> --with=hv_vmbus,hv_netvsc,hv_storvsc sudo update-grub
確定您已安裝 SSH 伺服器,並已設定為在開機時啟動。 此設定通常是預設值。
安裝 Azure Linux 代理程式。
如需在 Azure 上佈建 Linux 映像,您需要 Azure Linux 代理程式。 許多發行版本會以 .rpm 或 .deb 套件的形式提供代理程式。 套件通常稱為
WALinuxAgent
或walinuxagent
。 您也可以遵循 Azure Linux 代理程式指南中的步驟來手動安裝代理程式。注意
請確定已啟用
udf
和vfat
模組。 移除或停用該模組將導致佈建或開機失敗。 Cloud-init 21.2 版或更新版本會移除 UDF 需求。執行下列其中一個命令,以安裝 Azure Linux 代理程式、cloud-init 和其他必要的公用程式。
針對 Red Hat 或 CentOS 使用此命令:
sudo yum install -y WALinuxAgent cloud-init cloud-utils-growpart gdisk hyperv-daemons
針對 Ubuntu/Debian 使用此命令:
sudo apt install walinuxagent cloud-init cloud-utils-growpart gdisk hyperv-daemons
針對 SUSE 使用此命令:
sudo zypper install python-azure-agent cloud-init cloud-utils-growpart gdisk hyperv-daemons
然後在所有發行版本上啟用代理程式和 cloud-init:
sudo systemctl enable waagent.service sudo systemctl enable cloud-init.service
請不要在 OS 磁碟上建立交換空間。
您可以使用 Azure Linux 代理程式或 cloud-init,透過本機資源磁碟來設定交換空間。 在 Azure 上佈建後,此資源磁碟會連結至 VM。 本機資源磁碟是暫存磁碟,可能會在 VM 取消佈建時清空。 下列區塊示範如何設定此交換程序。
若您選擇 Azure Linux 代理程式,請在 /etc/waagent.conf 中修改下列參數:
ResourceDisk.Format=y ResourceDisk.Filesystem=ext4 ResourceDisk.MountPoint=/mnt/resource ResourceDisk.EnableSwap=y ResourceDisk.SwapSizeMB=2048 ## NOTE: Set this to your desired size.
若您選擇 cloud-init,請設定 cloud-init 來處理佈建程序:
sudo sed -i 's/Provisioning.Agent=auto/Provisioning.Agent=cloud-init/g' /etc/waagent.conf sudo sed -i 's/ResourceDisk.Format=y/ResourceDisk.Format=n/g' /etc/waagent.conf sudo sed -i 's/ResourceDisk.EnableSwap=y/ResourceDisk.EnableSwap=n/g' /etc/waagent.conf
若要將 cloud-init 設定為格式並建立交換空間,您可以使用兩個選項:
- 每次透過
customdata
建立 VM 時傳入 cloud-init 設定。 建議您採用此方法。 - 使用映像中的 cloud-init 指示詞,以在每次建立 VM 時設定交換空間。
使用 cloud-init 建立 .cfg 檔案以設定交換空間:
echo 'DefaultEnvironment="CLOUD_CFG=/etc/cloud/cloud.cfg.d/00-azure-swap.cfg"' | sudo tee -a /etc/systemd/system.conf cat << EOF | sudo tee /etc/cloud/cloud.cfg.d/00-azure-swap.cfg #cloud-config # Generated by Azure cloud image build disk_setup: ephemeral0: table_type: mbr layout: [66, [33, 82]] overwrite: True fs_setup: - device: ephemeral0.1 filesystem: ext4 - device: ephemeral0.2 filesystem: swap mounts: - ["ephemeral0.1", "/mnt/resource"] - ["ephemeral0.2", "none", "swap", "sw,nofail,x-systemd.requires=cloud-init.service,x-systemd.device-timeout=2", "0", "0"] EOF
- 每次透過
設定 cloud-init 來處理佈建:
設定 cloud-init 的
waagent
:sudo sed -i 's/Provisioning.Agent=auto/Provisioning.Agent=cloud-init/g' /etc/waagent.conf sudo sed -i 's/ResourceDisk.Format=y/ResourceDisk.Format=n/g' /etc/waagent.conf sudo sed -i 's/ResourceDisk.EnableSwap=y/ResourceDisk.EnableSwap=n/g' /etc/waagent.conf
如果您要遷移特定的虛擬機器,但不想建立一般化映像,請在 /etc/waagent.conf 設定中設定
Provisioning.Agent=disabled
。設定掛接:
echo "Adding mounts and disk_setup to init stage" sudo sed -i '/ - mounts/d' /etc/cloud/cloud.cfg sudo sed -i '/ - disk_setup/d' /etc/cloud/cloud.cfg sudo sed -i '/cloud_init_modules/a\\ - mounts' /etc/cloud/cloud.cfg sudo sed -i '/cloud_init_modules/a\\ - disk_setup' /etc/cloud/cloud.cfg
設定 Azure 資料來源:
echo "Allow only Azure datasource, disable fetching network setting via IMDS" cat << EOF | sudo tee /etc/cloud/cloud.cfg.d/91-azure_datasource.cfg datasource_list: [ Azure ] datasource: Azure: apply_network_config: False EOF
如果您已設定一個分頁檔,則請移除現有的分頁檔:
if [[ -f /mnt/resource/swapfile ]]; then echo "Removing swapfile" #RHEL uses a swap file by default swapoff /mnt/resource/swapfile rm /mnt/resource/swapfile -f fi
設定 cloud-init 記錄:
echo "Add console log file" cat << EOF | sudo tee -a /etc/cloud/cloud.cfg.d/05_logging.cfg # This tells cloud-init to redirect its stdout and stderr to # 'tee -a /var/log/cloud-init-output.log' so the user can see output # there without needing to look on the console. output: {all: '| tee -a /var/log/cloud-init-output.log'} EOF
執行下列命令以取消佈建虛擬機器。
警告
如果您要遷移特定的虛擬機器,但不想建立一般化映像,請略過取消佈建步驟。 執行
waagent -force -deprovision+user
命令會將來源機器轉譯為無法使用。 此步驟僅供您建立一般化映像。sudo rm -f /var/log/waagent.log sudo cloud-init clean sudo waagent -force -deprovision+user sudo rm -f ~/.bash_history sudo export HISTSIZE=0
執行
waagent -force -deprovision
後,您可能會在 VirtualBox 上看到錯誤訊息:[Errno 5] Input/output error
。 此錯誤訊息並不重要,您可以忽略此訊息。關閉虛擬機器,並將 VHD 上傳至 Azure。