Back to prev

Docker In Use

Mar 19, 2021
Linkang Chan
@Jesse Chan

记录 docker 的一些常用命令, 主要是在日常查询和定位问题的时候比较有帮助。以期望能在必要时提供一些帮助。这些内容大多是实践之后的记录,不是一篇 docker 使用手册的笔记。

设置无 sudo 使用

$ sudo usermod -aG docker $USER

查看 docker 系统占用情况

其中 prune 也可以用docker image prune或者docker container prune。 如果很确认深度清理的话,可以增加-a选项。

$ docker system df
$ docker system events
$ docker system info
$ docker system prune

此外还可以通过docker network prunedocker volumes prune来清理相关的网络和卷的信息。

设置重启策略

在创建 docker 容器时,可以指定--restart always来设置容器的重启策略。

$ sudo docker run -d --restart always --name my-container busybox

可选的参数有:

  • no 默认值
  • on-failure[:max-retries]
  • always
  • unless-stopped

此外我们可以通过docker update来更新容器的重启策略。

$ sudo docker update --restart always my-container

设置容器使用 host 的时间和时区

docker run -d \
  --name my_container \
  -v /etc/localtime:/etc/localtime:ro \
  -v /etc/timezone:/etc/timezone:ro \
  -e TZ=$(cat /etc/timezone) \
  my_image

查看 container 的详情

$ sudo docker inspect  <container_name/container_id>

查看 container 的内存使用情况

$ sudo docker stats
CONTAINER ID    NAME    CPU %   MEM USAGE / LIMIT     MEM %    NET I/O           BLOCK I/O       PIDS
306d9e2f8631   cuda     0.00%   988KiB / 125.5GiB     0.00%    0B / 0B           6.61MB / 174MB   2
4e7decd2bcfc   goodbye  0.00%   1.93MiB / 125.5GiB    0.00%    6.97MB / 1.97kB   1.17MB / 172kB   4

查看 docker 自身的信息

$ sudo docker info
Containers: 26
 Running: 26
 Paused: 0
 Stopped: 0
Images: 19
Server Version: 18.06.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: nvidia runc
Default Runtime: runc
……

ubuntu 上查看 docker 日志

$ sudo journalctl -fu docker.service

删除 image

$ sudo docker rmi <image-id>

删除 container

$ sudo docker rm <container-id/container-name>

查看指定容器的日志

每隔两秒查看一下指定容器的最后 10 行日志

$ sudo docker logs -f --tail=10 --until=2s <container_name/container_id> 

[docker logs]: docker 官方文档

重新指定容器的 entry_point

在创建容器时,我们可以覆盖镜像原有的 entry_point 设置,一般我们是通过--entrypoint来指定。

$ sudo docker run -d --entrypoint /bin/sh --name my-container busybox

注意--entrypoint后面只能加一个参数,一般我们可以传一个脚本,这样可以做到处理多个命令。

提交一个容器的修改到一个新的镜像

$ sudo docker commit <container_name/container_id> <image_name>

[docker commit 文档]: 简单的一些示例

清空 log

当我们的 log 文件变得很大时,我们想将其清空时,可以通过如下命令进行操作:

$ : > $(docker inspect --format=`{{.LogPath}}` <container_name_or_id>)

注意这边的format的反引号要改成单引号

安装 nvidia toolkit

  • 添加相关的 gpg key
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt-get update
  • 安装 runtime
$ apt-get install nvidia-container-runtime
  • 重启 docker
$ sudo systemctl restart docker

[docker gpu support 文档]: Nvidia GPU 的支持

清理和删除容器

一般在启动一个容器时,我们可以通过指定--rm选项用来在容器退出时自动删除掉容器。这样可以在保证一些不重要的容器及时被清理掉。 除此之外,我们还可以使用 docker 命令来批量清理容器。

$ docker system prune

use conda in dockerfile

当我们在复制别人的 conda 环境到镜像中时,一般可以通过 environment.yml 文件完成。此时如果需要我们在镜像中启动 conda 环境时,可以通过如下的方式进行:

FROM continuumio/miniconda3

WORKDIR /app

# Create the environment:
COPY environment.yml .
RUN conda env create -f environment.yml

# Make RUN commands use the new environment:
SHELL ["conda", "run", "-n", "myenv", "/bin/bash", "-c"]

# Demonstrate the environment is activated:
RUN echo "Make sure flask is installed:"
RUN python -c "import flask"

# The code to run when container is started:
COPY run.py .
ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "myenv", "python", "run.py"]

两种情况,如果后续的 RUN 命令时,可以通过 SHELL 先进行一个激活操作。另外则是在设置 ENTRYPOINT 时可以直接在命令行上完成环境的激活。

[activate-conda-dockerfile]: 如何在 dockerfile 中激活 conda

CMD vs. ENTRYPOINT

CMD: 此命令会在容器启动且 docker run 没有指定其他命令时运行 ENTRYPOINT: ENTRYPOINT 的 Exec 格式用于设置容器启动时要执行的命令及其参数,同时可通过CMD命令或者命令行参数提供额外的参数。ENTRYPOINT 中的参数始终会被使用,这是与 CMD 命令不同的一点.

RUN. Mainly used to build images and install applications and packages. Builds a new layer over an existing image by committing the results. CMD. Sets default parameters that can be overridden from the Docker Command Line Interface (CLI) when a container is running. ENTRYPOINT. Default parameters that cannot be overridden when Docker Containers run with CLI parameters.

docker stopped container reuse

https://www.thorsten-hans.com/how-to-run-commands-in-stopped-docker-containers/

导出 Dockerfile

$ docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage <image-id>

这里面除了 COPY 相关的命令通过文件的形式替代,可以正确的还原出原本的 dockerfile 格式。

[generate a dockerfile]: 从镜像中生成 Dockerfile

CPU 限制相关

参考资料:

cpu set

修改默认网段

打开/etc/docker/daemon.json在内部添加;

{
  "default-address-pools":
  [
    {"base":"10.10.0.0/16","size":24}
  ]
}

指定好对应的 IP, 然后重启 docker 服务。

$ sudo systemctl restart docker.service

修复 nvidia-smi not work

NVIDIA-SMI has failed because it couldn‘t communicate with the NVIDIA driver.

首先查看驱动和 cuda 是否都在

$ nvcc -h

如果正常存在,则查看一下当前的驱动版本

$ ls /usr/src | grep nvidia
nvidia-470.74

根据输出的驱动版本,执行如下的命令,修复一下:

$ sudo apt-get install dkms
$ sudo dkms install -m nvidia -v 470.74  # version 根据上面的输出填写

reference

golang package version mistmatch

Error response from daemon: client version 1.40 is too new. Maximum supported API version is 1.39

此时的一个简单解决方案是:

export DOCKER_API_VERSION=1.39  # 该版本为期望的版本

删除 containerd 的镜像

$ ctr -n k8s.io i rm $(ctr -n k8s.io i ls -q | grep your_filter)

Rootless-mode Docker daemon not running after logging back in ssh

需要做两步,第一步是:

systemctl --user enable docker

第二步我们需要修改用户 linger 类型

sudo loginctl enable-linger xxx