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
相关产品推荐
相关产品推荐

