Docker 快速学习手册及相关笔记 附带一些问题解决方案
参考与前言
- Docker 官方教程 【英文】:https://docs.docker.com/get-started/
- Windows Docker 安装 | 菜鸟教程 (runoob.com)
- Docker 教程 | 菜鸟教程
Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境。
Docker 实质上是在已经运行的 Linux 下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的 Linux 主机。
因此,Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。
如需要在ubuntu下使用 像绝哥说的 用多了就是几条指令 非常快速的... 这个为走捷径教程,建议通过目录进行所需的观看
常用命令
-
查看已有镜像 image
docker images
-
删除对应镜像id的镜像
docker rmi image_id
-
查看已有容器 containers
docker ps -a
-
删除对应容器id的容器
docker rm container_id
-
删除所有无名
sudo docker rmi $(sudo docker images -q --filter "dangling=true")
如果想一次過將所有 container 停止及刪除, 執行以下指令:
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
0. 安装
docker
可以全球网络畅通的情况下:
Install Docker Engine on Ubuntu
-
docker engine
sudo apt-get update sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io
国内镜像一键安装:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
nvidia-docker
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi
1. 基础介绍
Docker 包括三个基本概念:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
容器与镜像的关系类似于面向对象编程中的对象与类。
镜像 → 类;容器 → 对象
运行与参数
docker run -it ubuntu /bin/bash
docker run -it -e DISPLAY=$DISPLAY --net=host --gpus all \
--name kin_carla2 carlasim/carla:0.9.10.1 /bin/bash
docker run -it --gpus '"device=1,2"' \
-v /data_shared/Docker/jcheng/workspace:/workspace \
-p 8010:6006 \
--name cj_01 cj/torch:1.10.0-cuda11.3-cudnn8-runtime /bin/zsh
参数说明:
-
i: 交互式操作。
-
t: 终端。
-
ubuntu: ubuntu 镜像名称
-
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash,比如最后一条使用的是bin/zsh 也就是zsh Shell
-
--gpus all
,也可以指定此容器可使用的gpu数量和设备,如果是数量的话 直接后接数字即可,如果是设备的话 如上 指标设备id,相关官方链接 -
--name kin_carla2
指明这个容器的名字,没有的话就是随机命名,有名字的话后面 docker start 可以直接接名字 省事 -
-p
的意思是把contrainer的端口映射到host上,例如-p 8010:6006
的意思是把容器中6006端口映射到host的8010端口上 -
--shm-size
是设置容器共享内存的大小,默认是64M,如果要跑DDP 多GPU训练是不够的,根据模型大小按需要设置,建议直接拉满 🥲 (>30% RAM for ray) -
-v host:container
是把host的folder映射到容器了,就不用再把 dataset 或结果来回拷了, 数据尽量不要直接存在容器里,不然重开容易很麻烦
停止结束
docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止
要退出终端,直接输入 exit:
启动一个已经停止的容器:
# 查看id
docker ps -a
# 根据id启动
docker start b750bbbcfd88 -i
端口映射
默认都是绑定 TCP 端口
-P
:是容器内部端口随机映射到主机的高端口。-p
: 是容器内部端口绑定到指定的主机端口。
# 随机
docker run -d -P training/webapp python app.py
# 内部端口到指定主机端口
docker run -d -p 5000:5000 training/webapp python app.py
# 默认tcp
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
# udp
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
# 查看
docker port adoring_stonebraker 5000
这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口
如果要绑定 UDP 端口,后面加一个udp
docker port 命令可以让我们快捷地查看端口的绑定情况。
更多请查看官网文档:
2. 制作上传
Dockerfile
from 杰哥 modify by 聪明,样例:
FROM carlasim/carla:0.9.10.1
LABEL maintainer="Kin Zhang <kin_eng@163.com>"
ENV DEBIAN_FRONTEND noninteractive
RUN apt update
RUN apt install -y --no-install-recommends openssh-server
RUN apt install -y libgl1-mesa-glx libglib2.0-0 libsm6 libxext6 libxrender-dev
RUN apt install -y wget git zsh tmux vim g++
RUN apt install -y python3-matplotlib \
python3.7 \
python3.7-dev \
python3-setuptools \
python3-pip
RUN pip3 install pandas
RUN pip3 install opencv-python
# installing conda
RUN curl -o ~/miniconda.sh -LO https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
chmod +x ~/miniconda.sh && \
~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh && \
/opt/conda/bin/conda clean -ya && \
/opt/conda/bin/conda create -n python37 python=3.7 numpy networkx scipy six requests
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.1.2/zsh-in-docker.sh)" -- \
-t robbyrussell \
-p git \
-p ssh-agent \
-p https://github.com/agkozak/zsh-z \
-p https://github.com/zsh-users/zsh-autosuggestions \
-p https://github.com/zsh-users/zsh-completions \
-p https://github.com/zsh-users/zsh-syntax-highlighting
build 制作
docker build -t nginx:v3 .
docker build -f Dockerfile /home/daisy/lifelong_learning/Cylinder3D/
docker build -t cylinder:v1 -f Dockerfile /home/daisy/lifelong_learning/Cylinder3D/
-t 命名:版本tag号
-f file从dockerfile里build,这里的Dockerfile正好是那里面的文件名字,也有其他从网页上拉取进行Build的
上传Hub
Docker 仓库管理
仓库(Repository)是集中存放镜像的地方。以下介绍一下 Docker Hub。当然不止 docker hub,只是远程的服务商不一样,操作都是一样的。
sudo chmod 666 /var/run/docker.sock
docker login
docker logout
上传自己的image
用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。
以下命令中的 username 请替换为你的 Docker 账号用户名
#
docker tag ubuntu:18.04 username/ubuntu:18.04
docker image ls
docker push username/ubuntu:18.04
docker search username/ubuntu
3. 更多操作 copy tmux
复制
ssh rsync 用法教程
- 比scp快10+倍的命令, 尤其是有上万个文件要transfer,scp会很慢
rsync -rvz -e 'ssh -p 23333' --progress ./* $QWRAMWK05:/data_shared/Docker/jcheng/data/
container < - > host
# 从 host 到 容器
docker cp <src-path> <container>:<dest-path>
# for example
docker cp "C:\ProcDump\procdump64.exe" sitecore-xm1_cm_1:"C:\"
docker cp "transfuser/log/" kin_carla_v5:/home/kin/transfuser
# 从 容器 到 host
docker cp <container>:<src-path> <local-dest-path>
# for example
docker cp sitecore-xm1_cm_1:"C:\inetpub\wwwroot\App_Data\logs" "C:\"
docker cp elegant_lamarr:"/home/carla/PythonAPI/carla/dist/carla-0.9.10-py3.7-linux-x86_64.egg" "/home/kin/Desktop"
多开终端
How to open multiple terminals in docker?
问题来源于,如果你是exit ctrl+D的话, docker start docker attach就会进入到同一个终端,那么C掉就同步C掉了
所以在自己终端中输入,即可在相同容器中打开另一个终端
docker exec -it <container> /bin/bash
例如一下,下图左图可知,attach都是attach到同一个终端,所以右图第一步CTRL+C的时候 是都C掉了,右图第二和三步给出了解法就是:②是attach上去的,③则是exec -it 容器 /bin/bash多开了一个可用终端,同时③的杀死不会影响②
4. Tmux 调试
这里主要介绍默认的状态
开启关闭
- 开启tmux,和terminator不一样的是tmux是一个需要运行的app,称作一个session
$ tmux new -t "name_as_you_like"
# or 直接
$ tmux
- 挂起tmux, 可以回到正常的terminal
$ tmux detach
- 回到挂起的 tmux
# 可以先查看所以运行的session
$ tmux ls
# 打开原来挂起的session
$ tmux attach -t "name_as_you_like"
- 统一关闭命令,对下面的窗口操作也适用:
ctrl + d
窗口操作
- 创建多个window, 可以理解为普通terminal中
ctrl-shift-t
的操作, 使用快捷键
ctrl + b c
-
窗口切换, 使用快捷键
ctrl + b 0/1/2/3
后面是窗口号,到几号窗写几号 -
分屏, 纵向分屏
ctrl + b %,
横向分屏ctrl + b “
-
分屏后的切换,
ctrl + b up_arrow
,后面是方向键 -
分屏后每个块是没有scroll bar的,想要往上划需要
ctrl + b [
或者是ctrl + b page_up
完整的cheat sheet: Tmux Cheat Sheet & Quick Reference
VSCODE
如何在vscode打开已开启的container中的文件夹:
电脑-主机-服务器 config
如果 从 自己电脑 - hk主机 - 服务器
首先需要把hk主机上的ssh key复制过来,比如下面的config是在自己的电脑 ~/.ssh/id_rsa_ust
:
需要复制的是: id_rsa.pub 和 id_rsa → 记得改名字 不然会和之前的重复,比如我加了一个后缀_ust
经耿博提醒 需要进行 chmod 600 id_rsa 开权限
Host Server8
HostName xxxx.ust.hk
IdentityFile ~/.ssh/id_rsa_ust
Port xxx
ProxyJump Kin_hkust
User kinzhang
IdentitiesOnly yes
Host Server12
HostName xxxx.ust.hk
IdentityFile ~/.ssh/id_rsa_ust
Port xxx
ProxyJump Kin_hkust
User kinzhang
IdentitiesOnly yes
Host Server13
HostName xxxx.ust.hk
IdentityFile ~/.ssh/id_rsa_ust
Port xxx
ProxyJump Kin_hkust
User kinzhang
IdentitiesOnly yes
git 配置:
git config --global user.email "kin_eng@163.com"
git config --global user.name "kin_docker"
A. 其他
inside container 时间同步:https://www.jianshu.com/p/ce5408b33972
ssh key
因为有时候 在服务器训练时 可能会修改代码,多次push或者是在build时,repo是私人的就会需要ssh或账号
经杰哥提醒 可以将本机上的代码进行链接的形式更安全些 code都可以不用在docker内
```bash
docker run -it -v /home/kin/workspace/ufomap_ws/src:/root/catkin_ws/src --name ufomap_rviz zhangkin/ufomap /bin/zsh
```
但注意 container内因为是root权限,所以需要提前在cantianer内 终端 `chmod 777 /root/catkin_ws/src` 解开权限
如何在container中打开rviz
亲测可用
- This permits the root user on the local machine to connect to X windows display.
xhost +local:docker # 一定要运行 !!
docker run -it --privileged --net=host -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --name test zhangkin/ufomap /bin/zsh
@thuaj 遇到的问题 无法打开,报错信息为 libGL error: failed to load driver: swrast
解决办法: 来源: ubuntu20.04安装NVIDIA驱动后docker中rviz,pcl_viewer等涉及到访问宿主机界面的程序不可用
问题原因为:宿主机在升级nvidia驱动后,opengl升级版本,而在docker中仍旧使用旧的opengl版本,同样在docker中升级一遍nvidia驱动后问题解决,安装指令如下:
#!/bin/bash
sudo apt-get install mesa-utils
version="$(glxinfo | grep "OpenGL version string" | rev | cut -d" " -f1 | rev)"
wget <http://us.download.nvidia.com/XFree86/Linux-x86_64/"$version"/NVIDIA-Linux-x86_64-"$version".run>
mv NVIDIA-Linux-x86_64-"$version".run NVIDIA-DRIVER.run
然后运行 copy NVIDIA-DRIVER.run **into docker****
apt-get install module-init-tools kmod
sh ./NVIDIA-DRIVER.run -a -N --ui=none --no-kernel-module
常用添加入 Dockerfile
此处主要添加一下大家常用的Dockerfile里build的小插件,直接复制进入自己的dockerfile就行~
一个是 取消交互,因为在build过程,是无法交互的,在顶端添加这句方便后续自己按默认配置走
# Just in case we need it
ENV DEBIAN_FRONTEND noninteractive
zsh终端:
RUN apt update && apt install -y --no-install-recommends \
git \
curl \
vim rsync ssh\
python-pip \
pip install --upgrade
RUN apt install -y wget git zsh tmux vim g++
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.1.2/zsh-in-docker.sh)" -- \
-t robbyrussell \
-p git \
-p ssh-agent \
-p https://github.com/agkozak/zsh-z \
-p https://github.com/zsh-users/zsh-autosuggestions \
-p https://github.com/zsh-users/zsh-completions \
-p https://github.com/zsh-users/zsh-syntax-highlighting
miniconda 注意此处 虽然有下载了 但是因为没配置bashrc zshrc 所以需要 /opt/conda/bin/conda
来启动conda
RUN curl -o ~/miniconda.sh -LO https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
chmod +x ~/miniconda.sh && \
~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh && \
/opt/conda/bin/conda clean -ya && \
/opt/conda/bin/conda create -n python37 python=3.7
git 相关的设置
# needs to be done before we can apply the patches
RUN git config --global user.email "xxx@163.com"
RUN git config --global user.name "kin-docker"
升级cmake
WORKDIR /opt
RUN wget https://github.com/Kitware/CMake/releases/download/v3.24.0-rc2/cmake-3.24.0-rc2-linux-x86_64.sh
RUN chmod +x /opt/cmake-3.24.0-rc2-linux-x86_64.sh
RUN bash /opt/cmake-3.24.0-rc2-linux-x86_64.sh
RUN rm -rf cmake-3.24.0-rc2-linux-x86_64.sh
RUN ln -s /opt/cmake-3.24.0-rc2-linux-x86_64/bin/* /usr/local/bin
问题合集
-
W: GPG error: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY A4B469963BF863CC
https://github.com/NVIDIA/nvidia-docker/issues/1632
RUN rm /etc/apt/sources.list.d/cuda.list RUN rm /etc/apt/sources.list.d/nvidia-ml.list
-
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied
给一下权限就好了
sudo chmod 666 /var/run/docker.sock
一次性解决:
sudo groupadd docker sudo usermod -aG docker $USER sudo chmod 777 /var/run/docker.sock sudo systemctl stop docker sudo systemctl stop docker.socket sudo systemctl start docker sudo systemctl enable docker
http://andy51002000.blogspot.com/2019/02/docker-permission-denied.html
赠人点赞 手有余香 😆;正向回馈 才能更好开放记录 hhh