天天看点

ubuntu 卸载docker_Docker

Docker: 码头工人 (搬砖高手)

Life is short. We use Docker.

版本:Ubuntu 16.04 LTS,Docker 19.03.1, build 74b1e89e8a

安装 docker

# 本节参考 Docker 官方文档:
# https://docs.docker.com/install/linux/docker-ce/ubuntu/
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates gnupg-agent software-properties-common

# 添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 设置稳定存储库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 测试
sudo docker run hello-world
           

执行步骤

Docker 的 5 个基本部件:Docker Client,Docker Daemon,Docker Image,Docker Container,Docker Hub (Registry)。

  1. Docker Client 联系 Docker Daemon。
  2. Docker Daemon 从 Docker Hub 中提取名为 hello-world 的 Docker Image。
  3. Docker Daemon 从该 Docker Image 创建了一个 Docker Container,用于生成当前输出。
  4. Docker Daemon 将该输出流式传输到 Docker Client。
ubuntu 卸载docker_Docker

卸载 docker

sudo apt-get purge docker-ce
# 删除相关文件
sudo rm -rf /var/lib/docker
           

基本命令

docker --version
sudo docker info
           

USER 加入 docker 组

# 用户访问 Docker daemon,需要管理员权限 sudo,或加入 docker 组
# Docker 安装完成会建立 docker 组
cat /etc/group | grep docker
cat /etc/group | sed -n '/docker/p' | awk -F ":" '{print $1}'

# 加入 docker 组
sudo usermod -aG docker $USER
# 重启
echo -e "USER_PASSWDn" | sudo -S reboot
# 检查是否已加入 docker 组
groups | grep docker
           

常用命令

# 详细版本信息
docker version
# 列出 image
docker image ls --all
docker images
docker images -a
# 列出 container
docker container ls
docker container ls --all
docker container ls -aq
# 搜索
docker search python
docker search anaconda
# 显示运行的容器
docker ps
docker ps -a
           
ubuntu 卸载docker_Docker

上图介绍了基本的 docker 命令流,我们从一个小例子开始。

docker pull busybox
docker images
docker run busybox pwd
docker run busybox echo 'I love Python'
           

docker pull + docker run 能够让我们迅速、便捷地运行一个 docker image。

dock pull

格式:docker pull [OPTIONS] NAME[:TAG|@DIGEST]

常用参数

-a, --all-tags               # 下载 repository 中所有 tagged images
    --disable-content-trust  # 跳过镜像验证 (默认跳过)
-q, --quiet                  # 取消进度显示
           

docker run

格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

常用参数:

-it                          # -i 交互模式,-t 分配伪 tty
-P                           # 随机端口映射
-p                           # 指定端口映射,主机端口:容器端口
--name                       # 指定容器名称
-e, --env list               # 设置环境变量
-v, --volume list            # 本地文件夹与 container 文件夹绑定
-w                           # 容器内的工作目录
--dns                        # 设置 DNS 服务器 
-h, --hostname string        # 设置容器的 hostname;
--rm                         # 自动移除容器
--env-file list              # 从文件读入环境变量
-d                           # 后台运行容器
-m                           # 设置容器内存上限
--link list                  # 链接到其他容器
           

拉取并执行镜像

# 通过示例展示 docker run 的用法
# 例一:busybox
docker pull busybox
# -it 表示可以交互式地输入命令
docker run -it busybox sh

# 例二:tensorflow
docker pull tensorflow/tensorflow 
# --rm 在容器退出时自动清理容器并删除文件系统
# 默认 python=2.7,tensorflow=1.14.0
docker run -it --rm tensorflow/tensorflow
# 退出后运行 
docker container ls --all #不显示 tensorflow,说明 --rm 功能


# 定制 python=3.5,tensorflow=1.11.0
docker pull tensorflow/tensorflow:1.11.0-rc2-py3

# --name 指定 container 名称 [a-zA-Z0-9][a-zA-Z0-9_.-]
# 命令最后指定 python 解释器,后面可以接 .py 文件
docker run -it --rm --name tf_11-py_35 tensorflow/tensorflow:1.11.0-rc2-py3 python 

# -v 将本地目录映射 container 目录
# $PWD:/dl 将本地当前目录 $PWD,挂载到 container 的 /dl 目录下
# -v 命令可以实现数据的完全共享、读写同步
# 如果想要禁止 container 的写权利,可以 -v $PWD:/dl:ro
docker run -it --rm --name tf_11-py_35 -v $PWD:/dl tensorflow/tensorflow:1.11.0-rc2-py3 sh # bash 窗口操作

# -p 指定端口映射,可以在本地 http://127.0.0.1:8888 访问 container
# 本地的 $HOME 目录将被挂载到 /tf 目录下
docker run -it --rm -v $HOME:/tf -p 8888:8888 tensorflow/tensorflow:nightly-py3-jupyter

# 例三:jupyter
# 将 container 的 8888 端口映射到本机 127.0.0.1 的 666 端口,
# http://localhost:666/
docker run -p 127.0.0.1:666:8888 jupyter/scipy-notebook:17aba6048f44
           
ubuntu 卸载docker_Docker

删除 Container,Image

# 删除 container
# 用 CONTAINER ID 或名字
docker rm c1b9ce7f84d5
docker rm tf_11-py_35
docker rm -f $(docker ps -aq)
# 删除所有状态为 exited 的容器
docker rm $(docker ps -a -q -f status=exited)
# 删除镜像 [需要删除镜像的容器]
# 用 IMAGE ID 或 REPOSITORY:TAG
docker rmi [OPTIONS] IMAGE [IMAGE...]
           

容器操作

# 启动 container 
docker start d3c0ea01414d
# 停止 container
docker stop d3c0ea01414d
# kill container
docker kill -s kill d3c0ea01414d
# 重启 container
docker restart d3c0ea01414d
# commit
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
           

创建镜像

首先是 docker 的核心之一,Dockerfile —— 制作 Docker Image 的说明书。

ubuntu 卸载docker_Docker

Dockerfile

先看三个小例子

例一:ubuntu 16.04 LTS (xenial) 官方 Dockerfile

FROM ubuntu:xenial

RUN apt-get update && apt-get install -y --no-install-recommends 
		ca-certificates 
		curl 
		netbase 
		wget 
	&& rm -rf /var/lib/apt/lists/*

RUN set -ex; 
	if ! command -v gpg > /dev/null; then 
		apt-get update; 
		apt-get install -y --no-install-recommends 
			gnupg 
			dirmngr 
		; 
		rm -rf /var/lib/apt/lists/*; 
	fi
           

例二:jupyter minimal-notebook 官方 Dockerfile

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
ARG BASE_CONTAINER=jupyter/base-notebook
FROM $BASE_CONTAINER

LABEL maintainer="Jupyter Project <[email protected]>"

USER root

# Install all OS dependencies for fully functional notebook server
RUN apt-get update && apt-get install -yq --no-install-recommends 
    build-essential 
    emacs 
    git 
    inkscape 
    jed 
    libsm6 
    libxext-dev 
    libxrender1 
    lmodern 
    netcat 
    pandoc 
    python-dev 
    texlive-fonts-extra 
    texlive-fonts-recommended 
    texlive-generic-recommended 
    texlive-latex-base 
    texlive-latex-extra 
    texlive-xetex 
    tzdata 
    unzip 
    nano 
    && rm -rf /var/lib/apt/lists/*

# Switch back to jovyan to avoid accidental container runs as root
USER $NB_UID
           

例三:nvidia/cuda 的 cuda9.0+cudnn7.6 官方 Dockerfile

ARG IMAGE_NAME
FROM ${IMAGE_NAME}:9.0-devel-ubuntu16.04
LABEL maintainer "NVIDIA CORPORATION <[email protected]>"

ENV CUDNN_VERSION 7.6.3.30
LABEL com.nvidia.cudnn.version="${CUDNN_VERSION}"

RUN apt-get update && apt-get install -y --no-install-recommends 
    libcudnn7=$CUDNN_VERSION-1+cuda9.0 
libcudnn7-dev=$CUDNN_VERSION-1+cuda9.0 
&& 
    apt-mark hold libcudnn7 && 
    rm -rf /var/lib/apt/lists/*
           

Dockerfile 指令解析

# FROM 指定基础的 Docker Image,可以来自官方远程仓库,也可位于本地仓库
# 没有指定镜像标签,则默认使用 latest 标签
FROM ImageName

# 创建镜像的用户
MAINTAINER UserName
MAINTAINER "Jupyter Project <[email protected]>"
LABEL maintainer="Jupyter Project <[email protected]>"

# 每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像,
# 后续的 RUN 都以之前 RUN 提交的镜像为基础,
# 镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建。
RUN command1 && command2 && ...

# ENV 设置环境变量,后续 RUN 指令使用,并在容器运行时保留
ENV KEY value       # 只能设置一个变量
ENV KEY=value       # 允许一次设置多个变量

# ARG 定义了一个变量,能让用户可以在构建期间使用 docker build 命令和其参数 --build-arg 对这个变量赋值
# 例三中,可以用如下命令传入参数:
# docker build --build-arg IMAGE_NAME=nvidia/cuda Dockerfile
ARG <name>[=<default value>]


# COPY,ADD 将宿主目录下 [或者远程文件 URLS] 的文件拷贝进镜像
# ADD 可自动处理 URL 和解压 tar 包,COPY 不能指定远程文件 URLS
COPY src dest
ADD src dest

# WORKDIR 指定在创建 container 后,终端默认登录的 container 的工作目录,未指定则在根目录
WORKDIR

# CMD 指定一个容器启动时要运行的命令
# DockerFile 中可以有多个 CMD 指令,但是只有最后一个生效
# 如果用户启动容器时指定了运行的命令,则会覆盖掉 CMD 指定的命令。
# 如:docker run -it --rm --name tf_11-py_35 -v $PWD:/dl tensorflow/tensorflow:1.11.0-rc2-py3 sh
CMD
CMD echo $HOME
CMD [ "sh", "-c", "echo $HOME" ]

# ENTRYPOINT 配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
# 每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个生效。
ENTRYPOINT

# 指定对外的端口号
# 默认为 8888,对于 docker run 指令中的 -p 参数产生影响
EXPOSE

# 容器数据卷,用于数据保存和持久化工作
VOLUME
VOLUME /docker_data
           

docker build

格式:

docker build [OPTIONS] PATH | URL | -
docker image build [OPTIONS] PATH | URL | -
           

常用参数:

-f, --file string       # Name of the Dockerfile (Default is 'PATH/Dockerfile')
--build-arg list        # Set build-time variables
--compress              # Compress the build context using gzip
-t, --tag list          # Name and optionally a tag in the 'name:tag' format
--rm                    # Remove intermediate containers after a successful build (default true)
           

下面通过两个例子展示编写 Dockerfile 及创建镜像的过程。

例一:定制一个简单的 tensorflow 工作环境

python==3.6,numpy==1.14.2,tensorflow==1.12.0

Dockerfile

FROM python:3.6
WORKDIR /tensorflow
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./tf.py" ] # tf.py 是用户自己的 .py 文件 
           

requirements.txt

numpy==1.14.2
tensorflow==1.12.0
           

创建镜像

# build image
docker image build -t py36tf:0.0.1 .
           

创建过程如下,注意 docker 镜像是分层创建的,每次执行命令都会产生新的镜像

Step 1/6 : FROM python:3.6                                     #下载 python:3.6 的 image
 ---> 1c515a624542
Step 2/6 : WORKDIR /home/lizhongding/codeLinux/dp
 ---> Running in 4c77d0b86f09                                  # 设置工作目录,在容器 4c77d0b86f09 中运行
Removing intermediate container 4c77d0b86f09                   # 移除中间 container 4c77d0b86f09
 ---> 708c4ca1c9dd 
Step 3/6 : COPY requirements.txt ./                            # 拷贝 requirements.txt,到镜像的根目录下
 ---> ee1bde24d6b1
Step 4/6 : RUN pip install --no-cache-dir -r requirements.txt  # 安装 numpy==1.14.2,tensorflow==1.12.0 及相关依赖
 ---> Running in ed988a6febfe
Removing intermediate container ed988a6febfe
 ---> 22348b6a3d9f
Step 5/6 : COPY . .                                            # 将当前目录的文件拷贝进镜像的当前目录
 ---> 0117e5a5ae26
Step 6/6 : CMD python tf.py                                    # 执行命令 python tf.py
 ---> Running in 4edf63c674f8
Removing intermediate container 4edf63c674f8
 ---> 1fde2f3a630f
Successfully built 1fde2f3a630f                                # 建立镜像 1fde2f3a630f
Successfully tagged py36tf:0.0.1                               # REPOSITORY:TAG = py36tf:0.0.1 
           

上传镜像

# 在 hub.docker.com 上注册帐号
docker login

# 建立本地映像与存储库的关联
docker image tag ImageName UserName/repository[:tag] # 默认 tag 为 latest
docker image tag py36tf:0.0.1 lizhongding/py36tf:0.0.1
docker image push lizhongding/py36tf:0.0.1
# 成功后,可在 hub.docker.com 上查看 image
# 相似依赖的镜像,再上传时会尽量利用已有镜像
docker image tag py36tf:0.0.2 lizhongding/py36tf:0.0.2
docker image push lizhongding/py36tf:0.0.2
           

例二:基于 cuda_9.0,cudnn_7.0 定制可训练对抗生成网络(GAN)的环境

下载最新版的 ananconda3,利用 conda 安装以下 package:

  1. jupyter,Pillow,matplotlib,pyyaml,python-lmdb,scikit-learn,tqdm,
  2. tensorflow-gpu=1.11.0,cudatoolkit=9.0,python=3.6

Dockfile 构建如下。[参考项目:okwrtdsh/anaconda3]

FROM nvidia/cuda:9.0-cudnn7-devel

USER root
ENV DEBIAN_FRONTEND=noninteractive 
	LANG=C.UTF-8 
	LC_ALL=C.UTF-8 
	PATH=/opt/conda/bin:$PATH 
	NOTEBOOK_DIR=/src/notebooks 
	NOTEBOOK_IP=0.0.0.0 
	NOTEBOOK_PORT=8888

RUN apt-get update -qq 
 && apt-get upgrade -y 
 && apt-get install --no-install-recommends -y 
	curl grep sed dpkg wget bzip2 ca-certificates 
	libglib2.0-0 libxext6 libsm6 libxrender1 
	git mercurial subversion 
	libgtk2.0-0 
 # 最新版 annaconda3 安装
 && echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh 
 && ANACONDA_INSTALL_SCRIPT='Anaconda3-2019.03-Linux-x86_64.sh' 
 && wget --quiet https://repo.continuum.io/archive/$ANACONDA_INSTALL_SCRIPT -O ~/anaconda.sh 
 && /bin/bash ~/anaconda.sh -b -p /opt/conda 
 && rm ~/anaconda.sh 
 && apt-get clean 
 && rm -rf /var/lib/apt/lists/*

RUN conda config --add channels conda-forge 
 && conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ 
 && conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ 
 && conda install -y --quiet 
    jupyter 
    Pillow 
    matplotlib 
    pyyaml 
    python-lmdb 
    scikit-learn 
    tqdm 
    tensorflow-gpu=1.11.0 
    cudatoolkit=9.0 
    python=3.6 
 && conda install -c menpo opencv3 
 && conda clean -tipsy

# 安装 tini
ENV TINI_VERSION=v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
RUN chmod +x /usr/bin/tini
ENTRYPOINT [ "/usr/bin/tini", "--" ]

CMD jupyter notebook 
	--notebook-dir=${NOTEBOOK_DIR} 
	--ip=${NOTEBOOK_IP} 
	--port=${NOTEBOOK_PORT} 
	--NotebookApp.token='' 
	--no-browser 
	--allow-root
           

上传镜像

docker image build -t :0.0.1 .
docker login
docker image tag gan:0.0.1 lizhongding/gan:0.0.1
docker image push lizhongding/gan:0.0.1
           

docker save and docker load

docker 镜像可以不必在 docker hub 存取,也可本地存取。

格式:docker save [OPTIONS] IMAGE [IMAGE...]

参数:--output , -o

示例:

docker save busybox > busybox.tar
ls -sh busybox.tar
# 2.7M busybox.tar

docker save --output busybox.tar busybox
ls -sh busybox.tar
# 2.7M busybox.tar

# 用 gzip 压缩
docker save gan:0.0.1 | gzip > gan:0.0.1.tar.gz
           

格式:docker load [OPTIONS]

参数:--input , -i

docker load < busybox.tar.gz
docker load --input fedora.tar
docker images
           

nvidia-docker

当镜像中包含 gpu 的操作时,需要 nvidia-docker 来 run 镜像。

ubuntu 卸载docker_Docker
# 卸载 nvidia-docker 1.0
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge 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-container-toolkit
sudo systemctl restart docker

# 用 nvidia-smi 测试镜像
docker run --gpus all nvidia/cuda:9.0-base nvidia-smi

# 安装 nvidia-docker2
sudo apt-get install nvidia-docker2
sudo pkill -SIGHUP dockerd

# 用 tensorflow-gpu 进行测试
# 注意 tensorflow/tensorflow 镜像中支持的 cuda 版本要与本机 cuda 版本匹配
# 最新版要求 cuda>=10.0
nvidia-docker run -it --rm --name tf_gpu tensorflow/tensorflow:1.11.0-devel-gpu-py3 
python -c "import tensorflow as tf; tf.enable_eager_execution(); print(tf.reduce_sum(tf.random_normal([1000, 1000])))"
           

docker exec

在正在运行的容器中运行命令

格式:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

参数:

--detach, -d           # 分离模式:在后台运行命令
--detach-keys	       # 覆盖用于分离容器的键序列
--env, -e	       # 设置环境变量
--interactive, -i      # 即使没有连接,也要保持STDIN打开
--privileged           # 为命令提供扩展权限
--tty, -t              # 分配伪TTY
--user, -u             # 用户名或UID(格式:<name | uid> [:<group | gid>])
--workdir, -w          # 容器内的工作目录
           

示例:

docker restart tf_gpu
# 访问 container
docker exec -it tf_gpu bash
docker exec -it tf_gpu python
           

docker inspect

格式:docker inspect [OPTIONS] NAME|ID [NAME|ID...]

docker inspect tf_gpu
docker inspect 157efda75cac
# 打印 json 字符串,所有相关信息都可以查看
           

docker attach

将本地标准输入,输出和错误流附加到正在运行的容器。

简单说,就是可以在命令行进入并操作容器。

格式:docker attach [OPTIONS] CONTAINER

docker attach tf_gpu
docker attach f8268dbfd125
           

Namespace

namespace 是实现隔离的机制。

  1. 每个 namespace 中的进程只能影响同一个 namespace 或子 namespace 中的进程。
  2. /proc 包含正在运行的进程,在 container 中的 /proc 目录只能看到自己 namespace 中的进程。
  3. namespace 允许嵌套,父 namespace 可以影响子 namespace 的进程,子 namespace 可在父 namespace 中看到,但是具有不同的 pid。
  4. 网络隔离是通过网络 namespace 实现的, 每个网络 namespace 有独立的 network devices,IP addresses,IP routing tables,/proc/net 目录。这样每个 container 的网络就能隔离开来。 docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个 docker bridge 连接在一起。
  5. 每个 container 有不同的 user 和 group id, container 用户在 container 内部执行程序而非 Host 上的用户。

参考链接

https://blog.csdn.net/zmx729618/article/details/72930474​blog.csdn.net | Docker Documentation​docs.docker.com

ubuntu 卸载docker_Docker

Docker Hub​hub.docker.com A Docker Tutorial for Beginners​docker-curriculum.com

ubuntu 卸载docker_Docker

okwrtdsh/anaconda3​github.com

ubuntu 卸载docker_Docker

DockerFile解析​www.jianshu.com

ubuntu 卸载docker_Docker

Docker容器技术之Docker file​mp.weixin.qq.com

ubuntu 卸载docker_Docker

https://www.centos.bz/2016/12/dockerfile-arg-instruction/​www.centos.bz CMD 容器启动命令 · Docker -- 从入门到实践​yeasy.gitbooks.io docker load​docs.docker.com

ubuntu 卸载docker_Docker

NVIDIA/nvidia-docker​github.com

ubuntu 卸载docker_Docker