你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

为 Azure 操作员 Nexus 虚拟机创建映像

本文介绍如何创建可用于在 Operator Nexus 中创建虚拟机的容器映像。 具体而言,了解如何将虚拟磁盘添加到容器映像。 生成容器映像并将其推送到 Azure 容器注册表后,它可用于在操作员 Nexus 中创建虚拟机。

先决条件

在开始创建虚拟机(VM)映像之前,请确保满足以下先决条件:

  • 安装必需的 Azure CLI 扩展的最新版本。

  • 本文需要 2.49.0 或更高版本的 Azure CLI。 如果使用 Azure Cloud Shell,则最新版本已安装。

  • Azure 容器注册表(ACR):设置一个工作Azure 容器注册表来存储和管理容器映像。 ACR 提供一个安全和专用注册表,用于存储 VM 映像创建过程中使用的 Docker 映像。 可以按照Azure 容器注册表文档中的官方文档创建 ACR。

  • Docker:在本地计算机上安装 Docker。 Docker 是一个平台,可用于生成、打包和分发应用程序作为轻型容器。 使用 Docker 生成和打包 VM 映像。 可以从 Docker 的 官方网站下载 Docker。

注意

可以使用 az login 该命令向 Azure 进行身份验证,脚本将使用提供的 ACR 名称和订阅 ID 自动执行 ACR 登录。 如果计算机上未安装 Azure CLI,可以改为提供 ACR 登录的用户名和密码。

在继续创建 VM 映像之前,请确保计算机上安装了操作Azure 容器注册表(ACR)和 Docker。 熟悉 ACR 和 Docker 的使用和功能,因为它们对于管理容器映像和生成 VM 映像至关重要。

虚拟机映像要求

  • 确保虚拟网络函数(VNF)映像采用 qcow2 格式,可以使用 cloud-init 启动。

  • 需要在映像中配置引导加载程序、内核和 init 系统,以启用基于文本的串行控制台。 启用虚拟机(VM)的控制台支持需要此配置。 确保系统和终端上的串行端口设置匹配以建立适当的通信。

  • 需要确保 VM 映像支持 cloud-init 版本 2,并在 VM 初始化过程中启用高级配置选项。

  • 需要确保 VM 映像包含包含数据源的 nocloud cloud-init。 nocloud 数据源允许在 VM 预配期间进行初始配置和自定义。

  • 磁盘必须放置在 /disk 容器内的目录中。

  • 支持原始格式和 qcow2 格式。 建议使用 Qcow2 来减小容器映像的大小。

  • 容器磁盘应基于 scratch 映像,该映像是不包含映像本身以外的文件或目录的空基础映像。 用作 scratch 基础映像可确保容器映像尽可能小,并且仅包含 VNF 所需的文件。

为操作员 Nexus 虚拟机创建映像的步骤

可以使用提供的脚本为 VNF 创建映像。 它生成一个 Dockerfile,用于将 VNF 磁盘映像文件复制到容器的 /disk 目录中。

注意

以下示例提供了以下脚本。 如果需要,可以手动创建和推送容器映像,而不是遵循脚本。

以下环境变量用于配置用于为 VNF 创建虚拟机(VM)映像的脚本。 在执行脚本之前,请使用自己的值修改和导出这些变量:


# Azure subscription ID (provide if not using username-password)
export SUBSCRIPTION="your_subscription_id"

# (Mandatory) Azure Container Registry name
export ACR_NAME="your_acr_name"

# (Mandatory) Name of the container image
export CONTAINER_IMAGE_NAME="your_container_image_name"

# (Mandatory) Tag for the container image
export CONTAINER_IMAGE_TAG="your_container_image_tag"

# (Mandatory) VNF image (URL, local file, or full local path)
export VNF_IMAGE="your_vnf_image"

# (Optional) ACR URL (leave empty to derive from ACR_NAME)
export ACR_URL=""

# (Optional) ACR login username (provide if not using subscription)
export USERNAME=""

# (Optional) ACR login password (provide if not using subscription)
export PASSWORD=""

若要为 虚拟网络 函数(VNF)创建 VM 映像,请将提供的脚本create-container-disk.sh另存为,设置所需的环境变量,并执行脚本。

#!/bin/bash

# Define the required environment variables
required_vars=(
    "ACR_NAME"                  # Azure Container Registry name
    "CONTAINER_IMAGE_NAME"      # Name of the container image
    "CONTAINER_IMAGE_TAG"       # Tag for the container image
    "VNF_IMAGE"                 # VNF image (URL or file path)
)

# Verify if required environment variables are set
for var in "${required_vars[@]}"; do
    if [ -z "${!var}" ]; then
        echo "Error: $var environment variable is not set."
        exit 1
    fi
done

# Check if either SUBSCRIPTION or USERNAME with PASSWORD is provided
if [ -z "$SUBSCRIPTION" ] && [ -z "$USERNAME" ] && [ -z "$PASSWORD" ]; then
    echo "Error: Either provide SUBSCRIPTION or USERNAME with PASSWORD."
    exit 1
fi

# Set default value for DOCKERFILE_NAME if not set
if [ -z "$DOCKERFILE_NAME" ]; then
    DOCKERFILE_NAME="nexus-vm-img-dockerfile"
fi

# Check if ACR_URL is already set by the user
if [ -z "$ACR_URL" ]; then
    # Derive the ACR URL from the ACR_NAME
    ACR_URL="$ACR_NAME.azurecr.io"
fi

# Initialize variables for downloaded/copied files
downloaded_files=()

# Function to clean up downloaded files
cleanup() {
    for file in "${downloaded_files[@]}"; do
        if [ -f "$file" ]; then
            rm "$file"
        fi
    done
}

# Register the cleanup function to be called on exit
trap cleanup EXIT

# Check if the VNF image is a URL or a local file
if [[ "$VNF_IMAGE" == http* ]]; then
    # Use curl to download the file
    filename=$(basename "$VNF_IMAGE")
    # Download the VNF image file and save the output to a file
    curl -f -Lo "$filename" "$VNF_IMAGE"
    if [ $? -ne 0 ]; then
        echo "Error: Failed to download file."
        exit 1
    fi
    # Add the downloaded file to the list for cleanup
    downloaded_files+=("$filename")
elif [[ "$VNF_IMAGE" == /* ]]; then
    # Use the provided full local path
    filename=$(basename "$VNF_IMAGE")
    # Copy the VNF image file to the current directory for cleanup
    cp "$VNF_IMAGE" "./$filename"
    # Add the copied file to the list for cleanup
    downloaded_files+=("$filename")
else
    # Assume it's a local file in the current directory
    filename="$VNF_IMAGE"
fi

# Check if the file exists
if [ ! -f "$filename" ]; then
    echo "Error: File $filename does not exist."
    exit 1
fi

# Create a Dockerfile that copies the VNF image file into the container's /disk directory
# The containerDisk needs to be readable for the user with the UID 107 (qemu).
cat <<EOF > "$DOCKERFILE_NAME"
FROM scratch
ADD --chown=107:107 "$filename" /disk/
EOF

# Build the Docker image and tag it to the Azure Container Registry
docker build -f "$DOCKERFILE_NAME" -t "$CONTAINER_IMAGE_NAME:$CONTAINER_IMAGE_TAG" .

# Log in to Azure Container Registry
if [ -n "$USERNAME" ] && [ -n "$PASSWORD" ]; then
    docker login "$ACR_NAME.azurecr.io" -u "$USERNAME" -p "$PASSWORD"
else
    az acr login --name "$ACR_NAME" --subscription "$SUBSCRIPTION"
fi

docker tag "$CONTAINER_IMAGE_NAME:$CONTAINER_IMAGE_TAG" "$ACR_URL/$CONTAINER_IMAGE_NAME:$CONTAINER_IMAGE_TAG"
docker push "$ACR_URL/$CONTAINER_IMAGE_NAME:$CONTAINER_IMAGE_TAG"

# Remove the downloaded/copied files
cleanup

rm "$DOCKERFILE_NAME"

echo "VNF image $ACR_URL/$CONTAINER_IMAGE_NAME:$CONTAINER_IMAGE_TAG created successfully!"

执行脚本后,将为 虚拟网络 函数(VNF)定制 VM 映像。 可以使用此映像部署 VNF。

用法示例

  1. 设置所需的环境变量。

    export SUBSCRIPTION=""00000000-0000-0000-0000-000000000000""
    export ACR_NAME="myvnfacr"
    export CONTAINER_IMAGE_NAME="ubuntu"
    export CONTAINER_IMAGE_TAG="20.04"
    export VNF_IMAGE="https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img"
    
  2. 将提供的脚本 create-container-disk.sh 另存为并使其可执行。

    chmod +x create-container-disk.sh
    
  3. 执行该脚本。

    $ ./create-container-disk.sh
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  622M  100  622M    0     0  24.7M      0  0:00:25  0:00:25 --:--:-- 26.5M
    [+] Building 36.6s (5/5) FINISHED
     => [internal] load .dockerignore                                                              0.1s
     => => transferring context: 2B                                                                0.0s
     => [internal] load build definition from nexus-vm-img-dockerfile                              0.1s
     => => transferring dockerfile: 137B                                                           0.0s
     => [internal] load build context                                                              36.4s
     => => transferring context: 652.33MB                                                          36.3s
     => CACHED [1/1] ADD --chown=107:107 ubuntu-20.04-server-cloudimg-amd64.img /disk/             0.0s
     => exporting to image                                                                         0.0s
     => => exporting layers                                                                        0.0s
     => => writing image sha256:5b5f531c132cdbba202136b5ec41c9bfe9d91beeb5acee617c1ef902df4ca772   0.0s
     => => naming to docker.io/library/ubuntu:20.04                                                0.0s
    Login Succeeded
    The push refers to repository [myvnfacr.azurecr.io/ubuntu]
    b86efae7de58: Layer already exists
    20.04: digest: sha256:d514547ee28d9ed252167d0943d4e711547fda95161a3728c44a275f5d9669a8 size: 529
    VNF image myvnfacr.azurecr.io/ubuntu:20.04 created successfully!
    

后续步骤

请参阅快速入门指南,了解如何使用创建的映像部署 VNF。