Docker容器创建好后修改容器配置

创建好容器后,如果想要修改配置,例如环境变量,可以通过直接修改/var/lib/docker/container中的json配置文件来实现,避免重新创建容器。因为重新创建容器会造成原来的数据丢失,而如果容器中的数据很多,例如几百GB,备份数据就会非常耗时,所以直接修改json就更方便,但这种方法有风险且不规范。这篇文章记录了问题的解决过程,但不推荐这种方法。

背景

在Ubuntu 22.04 server中执行sudo ubuntu-drivers install --gpgpu nvidia:580-server命令安装了显卡驱动,进入容器后运行某程序报错,排查问题过程中执行了ldconfig -p | grep -E 'libEGL_nvidia|libnvidia-eglcore|libnvidia-glcore'命令找不到libnvidia-glcore.so、libnvidia-eglcore.so和libEGL_nvidia.so,且宿主机中的库文件版本是565。

在执行sudo apt install libnvidia-gl-580-server安装库后,容器内依然找不到这些库。排查到container的runtime时,发现runtime不是nvidia而是runc,导致一些GPU相关的功能无法正常使用。

为了不备份并重新创建容器,采用了修改容器的json配置文件的方式来解决问题。具体是将runtime改为nvidia,并添加两个环境变量:NVIDIA_VISIBLE_DEVICES=all和NVIDIA_DRIVER_CAPABILITIES=all。

解决过程

  1. 记录容器ID和配置文件路径,your_container替换为容器的实际名称
bash 复制代码
CONTAINER=your_container

CID=$(docker inspect --format '{{.Id}}' "$CONTAINER")
ROOT=$(docker info --format '{{.DockerRootDir}}')

CFG="$ROOT/containers/$CID/config.v2.json"
HOSTCFG="$ROOT/containers/$CID/hostconfig.json"

echo "$CFG"
echo "$HOSTCFG"
  1. 停止容器和docker服务
bash 复制代码
docker stop "$CONTAINER"
sudo systemctl stop docker.socket
sudo systemctl stop docker.service
  1. 备份配置文件
bash 复制代码
sudo cp "$CFG" "$CFG.bak"
sudo cp "$HOSTCFG" "$HOSTCFG.bak"
  1. 生成新的hostconfig.json并验证,如果输出是"nvidia"则正确
bash 复制代码
sudo cat "$HOSTCFG" \
| jq '.Runtime = "nvidia"' \
| sudo tee "$HOSTCFG.new" > /dev/null
bash 复制代码
sudo cat "$HOSTCFG.new" | jq empty
sudo cat "$HOSTCFG.new" | jq '.Runtime'
  1. 生成新的config.v2.json并验证,如果输出NVIDIA_VISIBLE_DEVICES=all和NVIDIA_DRIVER_CAPABILITIES=all则正确
bash 复制代码
sudo cat "$CFG" \
| jq '
  .Config.Env =
    (
      (.Config.Env // [])
      | map(
          select(
            (
              startswith("NVIDIA_VISIBLE_DEVICES=") or
              startswith("NVIDIA_DRIVER_CAPABILITIES=")
            )
            | not
          )
        )
      + [
          "NVIDIA_VISIBLE_DEVICES=all",
          "NVIDIA_DRIVER_CAPABILITIES=all"
        ]
    )
' \
| sudo tee "$CFG.new" > /dev/null
bash 复制代码
sudo cat "$CFG.new" | jq empty

sudo cat "$CFG.new" \
| jq -r '.Config.Env[]? | select(startswith("NVIDIA_"))'
  1. 覆盖原配置文件
bash 复制代码
sudo mv "$HOSTCFG.new" "$HOSTCFG"
sudo mv "$CFG.new" "$CFG"
  1. 重启电脑,然后启动docker服务
bash 复制代码
sudo systemctl start docker.service
sudo systemctl start docker.socket
相关推荐
考研保研资料分享40 分钟前
自动化控制保研经验合辑:上交夏令营、北工大预推免与跨专业面试复盘(2025)
运维·面试·自动化
灯澜忆梦1 小时前
【docker】#2 | 基础命令
docker·容器·eureka
乐维_lwops1 小时前
2026选择运维监控系统时应该重点考察哪些功能?
大数据·运维·人工智能
峥无2 小时前
Linux NPTL线程:创建/终止/等待/分离/栈布局内核原理|线程下篇
linux·运维·线程
元岳数字人小元2 小时前
数字人私有化部署:企业级AI数字场景长效落地优选方案
运维·人工智能·开源·人机交互·交互
程序员老赵3 小时前
Docker 部署 WordPress:轻松搭建开源内容管理平台
docker·开源·wordpress
Thneonl3 小时前
全集群钟差 300 毫秒会发生什么:证书悄悄过期,日志倒流
运维·后端
是jin奥3 小时前
Ubuntu 访问 Windows 共享目录
linux·运维·ubuntu
Gauss松鼠会3 小时前
【GaussDB】破除gaussdb ugin索引支持中文模糊查询的迷思-字符序
java·运维·服务器·网络·数据库·gaussdb·经验总结