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.solibnvidia-eglcore.solibEGL_nvidia.so,且宿主机中的库文件版本是565。

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

为了不备份并重新创建容器,采用了修改容器的json配置文件的方式来解决问题。具体是将runtime改为nvidia,并添加两个环境变量:NVIDIA_VISIBLE_DEVICES=allNVIDIA_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=allNVIDIA_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
相关推荐
敖行客 Allthinker5 小时前
Parallels Ubuntu虚拟机项目如何让手机访问?完整解决方案
linux·运维·ubuntu
BullSmall6 小时前
Anolis OS 8.10 完整安装 Docker CE(生产可用,解决 podman 冲突)
docker·容器·podman
元Y亨H6 小时前
生产环境监控与故障应急处理(5-5-5 标准)指南
运维
观山岳五楼7 小时前
Ubuntu 24 怎么使用Ubuntu 20 的镜像源
linux·运维·ubuntu
寒晓星8 小时前
[linux]线程及多线程
linux·运维
慧一居士8 小时前
Linux如何设置固定的静态ip
运维
梦梦代码精9 小时前
开源AI应用平台BuildingAI解析:插件化架构、应用市场与热门案例
人工智能·机器学习·docker·开源
国服第二切图仔10 小时前
13其他工具 - Skill/LSP/Sleep等
linux·运维·里氏替换原则
暴力求解10 小时前
Linux ---线程控制(二)
linux·运维·服务器·操作系统
梦痕长情11 小时前
等保三级三权账户
linux·运维·服务器