Docker Cheat Sheet

为什么要使用Docker:“有了Docker,开发人员能够借助任何工具、使用语言来构建任何应用”。Docker化的应用是完全绿色便携的,能运行在任何平台。

Docker的安装

Docker安装:https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker

Linux:

1
2
curl -sSL https://get.docker.com/ | sh

OR

1
2
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Macos:

1
$ brew cask install docker

![](https://gitee.com/fuhailin/Object-Storage-Service/raw/master/Screenshot from 2019-09-20 22-12-42.png)

*如果机器有支持深度学习的Gpu,可以继续执行如下命令以支持容器对gpu的调用[目前仅支持linux]:

1
2
3
4
5
6
7
8
# Add the package repositories
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-container-toolkit
sudo systemctl restart docker

运行容器

安装完 Docker 之后,咱们先来用下面的命令运行一个 httpd 服务。

1
$ docker run -d centos/httpd:latest

run 的意思就是要启动一个容器, -d 参数里 d 是 Daemon 的首字母,也就是让容器在后台运行。最后一个参数 centos/httpd:latest 指定了具体要启动哪一个镜像,比如这里咱们启动的是 centos/httpd 这个镜像的 latest 版本。

1
2
3
4
$ docker run -it --rm ubuntu:18.04 bash
root@e7009c6ce357:/# uname -a
Linux bff9f261bab2 4.15.0-106-generic #107-Ubuntu SMP Thu Jun 4 11:27:52 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
root@e7009c6ce357:/# exit

docker run 就是运行容器的命令,后面如果只跟镜像,那么就执行镜像的默认命令然后退出。

  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
  • --rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。
  • ubuntu:18.04:这是指用 ubuntu:18.04 镜像为基础来启动容器。
  • bash:放在镜像名后的是 命令,这里我们希望有个交互式 Shell,因此用的是 bash。

进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。通过exit 退出。

Docker 实验

我们建一个单独的目录来存放示例所需的文件。为了尽量简化例子,我们要部署的服务是用 Nginx 来 serve 一个简单的 HTML 文件 html/index.html。

1
2
3
4
$ mkdir docker-demo
$ cd docker-demo
$ mkdir html
$ echo '<h1>Hello Docker!</h1>' > html/index.html

接下来在当前目录创建一个叫 Dockerfile 的新文件,包含下面的内容:

1
2
FROM nginx
COPY html/* /usr/share/nginx/html

每个 Dockerfile 都以 FROM ... 开头。 FROM nginx 的意思是以 Nginx 官方提供的镜像为基础来构建我们的镜像。在构建时,Docker 会从 Docker Hub 查找和下载需要的镜像。Docker Hub 对于 Docker 镜像的作用就像 GitHub 对于代码的作用一样,它是一个托管和共享镜像的服务。使用过和构建的镜像都会被缓存在本地。第二行把我们的静态文件复制到镜像的 /usr/share/nginx/html 目录下。也就是 Nginx 寻找静态文件的目录。Dockerfile 包含构建镜像的指令,更详细的信息可以参考这里。

然后就可以构建镜像了:

1
$ docker build -t docker-demo:0.1 .

请确保你按照上面的步骤为这个实验新建了目录,并且在这个目录中运行 docker build。如果你在其它有很多文件的目录(比如你的用户目录或者 /tmp)运行,docker 会把当前目录的所有文件作为上下文发送给负责构建的后台进程。

这行命令中的名称 docker-demo 可以理解为这个镜像对应的应用名或服务名,0.1 是标签。Docker 通过名称和标签的组合来标识镜像。可以用下面的命令来看到刚刚创建的镜像:

1
2
3
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker-demo 0.1 efb8ca048d5a 5 minutes ago 109MB

下面我们把这个镜像运行起来。Nginx 默认监听在 80 端口,所以我们把宿主机的 8080 端口映射到容器的 80 端口:

1
$ docker run --name docker-demo -d -p 8080:80 docker-demo:0.1

用下面的命令可以看到正在运行中的容器:

1
2
3
$ docker container ps
CONTAINER ID IMAGE ... PORTS NAMES
c495a7ccf1c7 docker-demo:0.1 ... 0.0.0.0:8080->80/tcp docker-demo

这时如果你用浏览器访问 http://localhost:8080,就能看到我们刚才创建的「Hello Docker!」页面。

在现实的生产环境中 Docker 本身是一个相对底层的容器引擎,在有很多服务器的集群中,不太可能以上面的方式来管理任务和资源。所以我们需要 Kubernetes 这样的系统来进行任务的编排和调度。在进入下一步前,别忘了把实验用的容器清理掉:

1
2
$ docker container stop docker-demo
$ docker container rm docker-demo

Docker Hub

Docker语法 描述
docker search searchterm Search Docker Hub for images.
docker pull user/image Downloads an image from Docker Hub.
docker login Authenticate to Docker Hub (or other Docker registry).
docker push user/image Uploads an image to Docker Hub. You must be authenticated to run this command.

Image and Container Information

Docker语法 描述
docker images 查看本地镜像(list 镜像)
docker ps List all running containers.查看运行中的容器
docker ps -a List all container instances, with their ID and status.
docker history user/image Lists the history of an image.
docker logs [container name or ID] Displays the logs from a running container.
docker logs -f -n1 10 [container name or ID] diaplay the latest 10 logs from a running container.
docker port [container name or ID] Displays the exposed port of a running container.
docker diff [container name or ID] Lists the changes made to a container.

Work With Images and Containers

Docker语法 描述
docker run -it user/image Runs an image, creating a container and changing the terminal to the terminal within the container.
docker exec -it [CONTAINER ID] /bin/bash 进入运行中/后台运行的容器
docker run -p $HOSTPORT:$CONTAINERPORT -d user/image Run an image in detached mode with port forwarding.
ctrl+p then ctrl+q From within the container’s command prompt, detach and return to the host’s prompt.
docker attach [container name or ID] Changes the command prompt from the host to a running container.
docker stop [container name or ID] Stop a container.
docker rm -f [container name or ID] Delete a container.
docker rmi [image] Delete an image.
docker tag user/image:tag user/image:newtag Add a new tag to an image.
docker exec [container name or ID] shell command Executes a command within a running container.
docker cp /local/file [container ID]:/container/path 将本地文件copy到容器中
docker system df 查看docker所占的硬盘大小
docker system prune 该指令默认会清除所有如下资源: 已停止的容器(container) 未被任何容器所使用的卷(volume) 未被任何容器所关联的网络(network) 所有悬空镜像(image)。
docker overlay磁盘100% https://blog.csdn.net/jabony/article/details/104667678

–net=host : 使用host网络

–gpu=all:通过–gpu 指定使用哪个gpu, –gpu all 则是使用所有gpu

–link display:xserver client:latest:当你有时需要一个固定的服务时,不妨把服务端单独拎出来作为后台容器一直存在,专注开发客户端代码,每次运行时通过(–link)绑定服务端容器

Image Creation

Docker语法 描述
docker commit user/image Save a container as an image.
docker save user/image Save an image to a tar archive.
docker build -t sampleuser/ubuntu . Builds a Docker image from a Dockerfile in the current directory.
docker load Loads an image from file.

Volume create

1
2
3
4
5
docker volume create --driver local \
--opt type=none \
--opt device=/Users/vincent/Documents/projects/CPP \
--opt o=bind \
bazel-build

Docker net/http: TLS handshake timeout的解决办法

Docker Hub 源使用帮助

由于国内网络环境问题,Docker pull国外镜像出现无法使用的网络问题,因此更换国内镜像:
修改 sudo vim /etc/docker/daemon.json,添加如下地址:

1
2
3
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}

重启Docker服务:sudo systemctl restart docker

解决每次使用Docker命令都需要root权限的问题

将你使用的具有root权限的用户加入docker group: sudo usermod -aG docker $USER

https://www.linode.com/docs/applications/containers/docker-commands-quick-reference-cheat-sheet/


nvidia-docker(可使用GPU的docker容器)

https://blog.csdn.net/submarineas/article/details/108477031

1
sudo docker run --gpus all -it --name='gpu' --network=host tensorflow/tensorflow:latest-gpu /bin/bash
1
2
3
4
5
6
7
8
DIR=$(pwd)
sudo docker run --gpus all -it \
-p 8023:22 \
-v /root/fuhailin/projects/:/root/fuhailin/projects \
--ipc=host \
--name="tfio" \
--net=host \
tensorflow/tensorflow:latest-gpu /bin/bash

其中,
-p 8023:22:设置端口映射,将tcp22端口转发到8023(后续将通过8023端口对容器进行访问),与已占用端口不冲突的情况下可以自由设置;
--ipc=host:用于设置主机与容器共享内存;
-v /home/**/:/home/**/:–volume,挂在数据卷,将服务器目录与容器目录进行共享,为方便记忆,通常将两个目录名设置为一样;
torch1.5:拉取的镜像名称。

-d:–detach ,后台运行命令
-e, –env list 设置env
-i, –interactive 启用交互式
-t, –tty 启用终端
-u, –user string 指定用户 (格式: <name|uid>[:<group|gid>])
-w, –workdir string 指定工作目录
--name:容器名字
--network:指定网络
--rm:容器停止自动删除容器

1
2
3
4
5
6
docker run --gpus all -it \
-v /root/fuhailin/projects/:/root/fuhailin/projects \
--ipc=host \
--name="builder" \
--net=host \
nvidia/cuda:11.4.1-devel-ubuntu20.04 /bin/bash
1
2
3
4
5
6
docker run --gpus all -it \
-v /root/fuhailin/projects/:/root/fuhailin/projects \
--ipc=host \
--name="tf_dev" \
--net=host \
nvidia/cuda:11.4.2-devel-ubuntu20.04 /bin/bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Install Bazelisk
RUN wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-$([ $(uname -m) = "aarch64" ] && echo "arm64" || echo "amd64") \
&& chmod +x /usr/local/bin/bazel && \
rm -r /download/*

# Install Open MPI
RUN wget --progress=dot:mega -O /tmp/openmpi-3.0.0-bin.tar.gz https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.4.tar.gz && \
cd /usr/local && \
tar -zxf /tmp/openmpi-3.0.0-bin.tar.gz && \
ldconfig && \
mpirun --version

# Install cuDNN
COPY cudnn-11.4-linux-x64-v8.2.4.15.tgz /download/
RUN cd /download/ && \
tar -xzvf cudnn-11.4-linux-x64-v8.2.4.15.tgz && \
cp cuda/include/cudnn*.h /usr/local/cuda/include && \
cp -P cuda/lib64/libcudnn* /usr/local/cuda/lib64 && \
chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn* && \
# Show cuDNN version
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

# Install Python
# Python 3.7 is supported by Ubuntu Bionic out of the box
ARG PYTHON_VERSION=3.7
# Install development and runtime libraries (~4GB)
RUN apt-get update --fix-missing && \
apt install software-properties-common -y && \
add-apt-repository ppa:deadsnakes/ppa -y && \
apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends \
tzdata wget vim bzip2 ca-certificates curl git build-essential cmake \
python${PYTHON_VERSION} \
python${PYTHON_VERSION}-dev \
python${PYTHON_VERSION}-distutils \
&& apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN ln -s /usr/bin/python${PYTHON_VERSION} /usr/bin/python

# Install pip

RUN curl -O https://bootstrap.pypa.io/get-pip.py && \
python get-pip.py && \
rm get-pip.py &&\
pip --version

# Install Miniconda
RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh && \
/opt/conda/bin/conda clean -tipsy && \
ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
echo "conda activate base" >> ~/.bashrc && \
conda -V && \
pip install numpy

# Configure NCCL2
# RUN cd /usr/local && tar xvf /download/nccl_2.11.4-1+cuda11.4_x86_64.txz
# mkdir -p /usr/local/cuda/nccl/lib && \
# ln -s /usr/lib/x86_64-linux-gnu/libnccl.so.2 /usr/local/cuda/nccl/lib/ &&\
# ln -s /usr/lib/x86_64-linux-gnu/libcudnn.so.7 /usr/local/cuda/lib64/

# renovate: datasource=github-releases depName=Kitware/CMake
ARG CMAKE_VERSION=3.22.5
RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-Linux-x86_64.sh \
-q -O /tmp/cmake-install.sh \
&& chmod u+x /tmp/cmake-install.sh \
&& mkdir /usr/bin/cmake \
&& /tmp/cmake-install.sh --skip-license --prefix=/usr/bin/cmake \
&& rm /tmp/cmake-install.sh

Kubernets

Deploying the Dashboard UI:kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml
使用 kubeconfig 或 token 进行用户身份认证
生成 token

需要创建一个admin用户并授予admin角色绑定,使用下面的yaml文件创建admin用户并赋予他管理员权限,然后可以通过token访问kubernetes,该文件见admin-role.yaml。

1
2
3
4
5
6
7
8
9
10
11
# 创建 serviceaccount 和角色绑定:
$ kubectl create -f admin-role.yaml
# 获取admin-token的secret名字:
$ kubectl -n kube-system get secret|grep admin-token
# 获取token的值
$ kubectl -n kube-system describe secret admin-token-528zm
# 使用 kubectl 提供的 Proxy 服务来访问Dashboard
# 如果8001端口号占用,加 --port 8002 参数
kubectl proxy
# 打开如下地址:
# http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

![/ ](https://gitee.com/fuhailin/Object-Storage-Service/raw/master/Screen Shot 2019-12-20 at 11.16.39 AM.png)
Docker Volumes: Why, When, and Which Ones?

Python项目容器化实践(四) - Kubernetes基础篇
Deploying Python ML Models with Flask, Docker and Kubernetes

Docker cheat sheet

Docker开启远程安全访问

Docker-compose

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-centos-7