Linux VM 重启后不会重新创建交换文件

适用于:✔️ Linux VM

原始 KB 数: 4577868

注意

本文中引用的 CentOS 是 Linux 分发版,将达到生命周期结束(EOL)。 请相应地考虑使用和规划。 有关详细信息,请参阅 CentOS 生命周期指南

本文提供了在重启 Linux 虚拟机后无法重新创建交换文件的问题的解决方法。

现象

在由 cloud-init 预配且已安装 Microsoft Azure Linux 代理(waagent)的 Linux 虚拟机(VM)上,你可能会发现在重启后不会重新创建交换文件。

原因

出现此问题的原因是配置错误,导致 Azure Linux 代理和 cloud-init 都尝试配置交换文件。 当 cloud-init 负责预配时,交换文件必须由 cloud-init 配置,以便仅启用一个代理(cloud-init 或 waagent)进行预配。 由于 waagent 守护程序启动时的时间,此问题可能是间歇性的。

解决方法

若要解决该问题,请执行以下步骤:

  1. 禁用 waagent 配置 /etc/waagent.conf 中的资源磁盘格式设置和交换配置,因为此任务现在由 Cloud-Init 处理。 按如下所示设置参数:

    # Format if unformatted. If 'n', resource disk will not be mounted.
    ResourceDisk.Format=n
    
    # Create and use swapfile on resource disk.
    ResourceDisk.EnableSwap=n
    
    #Mount point for the resource disk
    ResourceDisk.MountPoint=/mnt
    
    #Size of the swapfile.
    ResourceDisk.SwapSizeMB=0
    
  2. 重启 Azure Linux 代理。 有关如何 更新 VM 上的 Azure Linux 代理,了解有关不同 Linux 分发版的重启命令的信息。

  3. 确保 VM 配置为使用 cloud-init 创建交换文件:

    1. 使用以下命令创建脚本 /var/lib/cloud/scripts/per-boot/create_swapfile.sh

      #!/bin/sh
      if [ ! -f '/mnt/swapfile' ]; then
      fallocate --length 2GiB /mnt/swapfile
      chmod 600 /mnt/swapfile
      mkswap /mnt/swapfile
      swapon /mnt/swapfile
      swapon -a 
      else
      swapon /mnt/swapfile; fi
      

      在某些情况下, fallocate 该命令不会正确创建交换文件。 如果未正确创建交换文件,则可以使用以下备用脚本:

      dd if=/dev/zero of=/mnt/swapfile bs=1M count=2048
      
    2. 使用 # chmod +x create_swapfile.sh 命令使文件可执行文件。

    3. 停止并启动 VM 或从门户重新部署 VM,并检查交换启用。 下面是如何启用交换功能的示例:

      root@ub1804-ephemeral:/var/lib/cloud/scripts/per-boot# free -m 
      total used free shared buff/cache available 
      Mem: 7953 296 7384 0 272 7412 
      Swap: 2047 0 2047
      

若要隔离问题,请将日志与/var/log/waagent.log/var/log/cloud-init.log重新启动时间范围进行比较。

若要完全避免这种情况,请在预配期间使用交换配置自定义数据部署 VM。

在 Linux VM 上使用 cloud-init 配置交换分区

本文介绍如何使用 cloud-init 在各种 Linux 分发版中配置交换分区。 在传统上,交换分区由 Linux 代理 (WALA) 根据分发版的需要进行配置。 本文档概述了使用 cloud-init 在预配期间按需生成交换分区的过程。 有关 cloud-init 如何在 Azure 以及受支持的 Linux 发行版中本机工作的详细信息,请参阅 cloud-init 概述

为基于 Ubuntu 的映像创建交换分区

在 Azure 上,Ubuntu 库映像默认不会创建交换分区。 若要在预配 VM 期间使用 cloud-init 启用交换分区配置,请参阅 Ubuntu wiki 中的 AzureSwapPartitions 文档

为基于 Red Hat 和 CentOS 的映像创建交换分区

在当前 shell 中,创建名为 cloud_init_swappart.txt 的文件并粘贴以下配置。 对于此示例,请在不处于本地计算机上的 Cloud Shell 中创建文件。 可使用任何想要使用的编辑器。 输入 sensible-editor cloud_init_swappart.txt 以创建文件并查看可用编辑器的列表。 选择 #1 以使用 nano 编辑器 。 请确保已正确复制整个 cloud-init 文件,尤其是第一行。

#cloud-config
disk_setup:
  ephemeral0:
    table_type: gpt
    layout: [66, [33,82]]
    overwrite: true
fs_setup:
  - device: ephemeral0.1
    filesystem: ext4
  - device: ephemeral0.2
    filesystem: swap
mounts:
  - ["ephemeral0.1", "/mnt"]
  - ["ephemeral0.2", "none", "swap", "sw,nofail,x-systemd.requires=cloud-init.service,x-systemd.device-timeout=2", "0", "0"]

使用选项创建 nofail 装载,以确保即使装载未成功完成,启动也会继续。

在部署此映像之前,需要使用 az group create 命令创建资源组。 Azure 资源组是在其中部署和管理 Azure 资源的逻辑容器。 以下示例在“eastus”位置创建名为“myResourceGroup”的资源组。

az group create --name myResourceGroup --location eastus

现在,使用 az vm create 创建 VM,并通过 --custom-data cloud_init_swappart.txt 指定 cloud-init 文件,如下所示:

az vm create \
  --resource-group myResourceGroup \
  --name centos74 \
  --image OpenLogic:CentOS:7-CI:latest \
  --custom-data cloud_init_swappart.txt \
  --generate-ssh-keys 

验证是否已创建交换分区

通过 SSH 连接到 VM 的公共 IP 地址显示在先前命令的输出中。 按如下所示输入自己的 publicIpAddress

ssh <publicIpAddress>

通过 SSH 连接到 VM 后,请验证是否已创建交换分区

swapon -s

此命令的输出应如下所示:

Filename                Type        Size    Used    Priority
/dev/sdb2  partition   2494440 0   -1

注意

如果在现有的 Azure 映像中配置了交换分区,而你想要更改新映像的交换分区配置,则应删除现有的交换分区。 有关详细信息,请参阅 自定义映像以通过 cloud-init 进行预配。

后续步骤

有关配置更改的其他 cloud-init 示例,请参阅以下文章:

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区