You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EC2用户数据脚本中NVIDIA驱动生效但ECS Agent更新需手动执行的问题

ECS Agent启动时更新失败问题排查与解决

问题描述

我使用如下user-data脚本启动ECS优化的Amazon Linux 2实例:

#!/bin/bash -xe

# --- NVIDIA setup (works on boot) ---
yum install -y wget gcc kernel-devel-$(uname -r) dkms

wget https://us.download.nvidia.com/tesla/535.154.05/NVIDIA-Linux-x86_64-535.154.05.run
chmod +x NVIDIA-Linux-x86_64-535.154.05.run
./NVIDIA-Linux-x86_64-535.154.05.run --no-opengl-files -s

# add NVIDIA Docker repo & install toolkit
distribution=$(. /etc/os-release; echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo \
  | tee /etc/yum.repos.d/nvidia-docker.repo
yum clean expire-cache
yum install -y nvidia-container-runtime nvidia-container-toolkit

# configure ECS for GPU & restart
echo "ECS_ENABLE_GPU_SUPPORT=true" | tee -a /etc/ecs/ecs.config
systemctl restart ecs

# configure Docker default runtime
cat > /etc/docker/daemon.json <<EOF
{
  "default-runtime": "nvidia",
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  }
}
EOF
systemctl restart docker

docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi

# --- ECS agent update (failing at boot) ---
docker pull amazon/amazon-ecs-agent:latest

mkdir -p /var/cache/ecs
docker save amazon/amazon-ecs-agent:latest \
  -o /var/cache/ecs/ecs-agent.tar

systemctl stop ecs || true
docker rm -f ecs-agent 2>/dev/null || true
rm -rf /var/lib/ecs/data

systemctl daemon-reload
systemctl enable --now ecs

sleep 5
curl -s http://localhost:51678/v1/metadata \
  || echo "Metadata endpoint unavailable."

启动时NVIDIA驱动与运行时可正常安装,但ECS Agent更新始终无法生效,必须手动SSH登录执行相关命令才能成功。手动执行时,Agent可被正常拉取、保存并重启,元数据端点可响应;但通过EC2启动执行时,Agent未更新且元数据端点不可用。请问用户数据执行与手动执行存在哪些差异?如何让该系列命令在启动时可靠生效?


用户数据执行与手动执行的核心差异

  • 执行时机与环境变量:用户数据脚本在实例启动初期执行,此时ECS服务可能还在初始化,部分ECS相关系统环境变量未完全加载;手动执行时系统已稳定运行,所有环境变量和依赖服务状态正常。
  • 服务依赖冲突:用户数据中重启ECS服务的操作,可能与系统自带的ECS初始化进程冲突,导致你更新的Agent容器被系统默认进程重新拉起,覆盖更新操作。
  • 网络与资源就绪性:启动初期实例网络可能尚未完全稳定,docker pull虽无报错,但可能存在镜像拉取不完整或缓存异常的情况;手动执行时网络连接已完全就绪。
  • 会话上下文差异:用户数据属于系统启动会话,部分服务状态检测逻辑与交互式SSH会话不同,导致服务重启后的状态反馈不准确。

让ECS Agent更新在启动时可靠生效的解决方案

1. 调整ECS服务操作顺序,避免系统初始化冲突

在停止ECS服务前先禁用自动启动,防止被系统进程重新拉起:

# 先禁用ECS自动启动,再停止服务
systemctl disable --now ecs
systemctl stop ecs || true
docker rm -f ecs-agent 2>/dev/null || true
rm -rf /var/lib/ecs/data

# 完成更新后重新启用并启动服务
systemctl daemon-reload
systemctl enable --now ecs

2. 增加Docker服务就绪等待逻辑

修改daemon.json并重启Docker后,确保Docker完全就绪再执行后续操作:

systemctl restart docker
# 等待Docker服务就绪
until docker info >/dev/null 2>&1; do
    sleep 2
done

3. 替换固定睡眠为循环检测ECS Agent状态

用循环替代sleep 5,确保Agent完全启动后再验证:

# 最多等待60秒,检测ECS Agent元数据端点
MAX_WAIT=60
WAIT_COUNT=0
until curl -s http://localhost:51678/v1/metadata >/dev/null; do
    sleep 2
    WAIT_COUNT=$((WAIT_COUNT+2))
    if [ $WAIT_COUNT -ge $MAX_WAIT ]; then
        echo "ECS Agent failed to start within $MAX_WAIT seconds."
        exit 1
    fi
done
echo "ECS Agent is running successfully."

4. 增加镜像拉取校验步骤

确保镜像拉取成功后再进行后续操作:

if ! docker pull amazon/amazon-ecs-agent:latest; then
    echo "Failed to pull ECS Agent image."
    exit 1
fi
# 校验镜像是否存在
if ! docker inspect amazon/amazon-ecs-agent:latest >/dev/null 2>&1; then
    echo "ECS Agent image not found after pull."
    exit 1
fi

5. 通过ECS配置文件指定Agent版本(可选)

直接在ecs.config中配置Agent版本,无需手动替换:

echo "ECS_AGENT_IMAGE=amazon/amazon-ecs-agent:latest" | tee -a /etc/ecs/ecs.config

系统启动时会自动使用指定版本的Agent,避免手动操作带来的冲突。


内容的提问来源于stack exchange,提问作者Mrblue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:28:16