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
相关推荐
乘云数字DATABUFF4 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
Patrick_Wilson5 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
Suroy5 天前
DockerView-Go:用 Go 写一个终端 Docker 监控工具,顺便做了个 Web 仪表盘
docker
云恒要逆袭5 天前
运行你的第一个Docker容器
后端·docker·容器
荣--6 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森6 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
宋均浩6 天前
# Docker 镜像瘦身实战:从 1.2G 到 80MB 的五个优化步骤
ci/cd·docker
Avan_菜菜7 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
程序员老赵7 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程
WangMingHua1117 天前
LM Studio Docker 部署——本地大模型一键启动
docker