命令图解

docker 命令图解

docker 基础

查看信息/帮助

1
2
3
$ docker version		# 显示 docker 的版本信息
$ docker info # 显示 docker 的系统信息,包括镜像、容器等
$ docker xxx --help # 帮助命令

镜像命令

  • 列出本地镜像

    1
    2
    3
    4
    5
    $ docker images

    # options
    -a, --all # 列出所有镜像
    -q, --quiet # 只显示镜像 id
  • 在 docker hub 上搜索镜像

    1
    2
    3
    4
    $ docker search xxxxx

    # options
    --filter=STARS=3000 # 只展示 STARS 数在 3000 以上的
  • 从 docker hub 拉取镜像到本地

    1
    $ docker pull xxx[:TAG]		# TAG 可选,如果不写,默认是 latest
  • 删除本地镜像

    1
    2
    3
    $ docker rmi 镜像名/id				# 删除镜像
    $ docker rmi 镜像名/id 镜像名/id # 删除多个镜像
    $ docker rmi $(docker images -aq) # 删除所有镜像

容器命令

  • 创建并启动容器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $ docker run [options] 镜像名/id [cmd]

    # options
    --name="xxx" # 为容器设置名字,用来区分容器
    --rm # 容器停止后自动删除
    -e KEY=value # 设置环境变量
    -d # 守护态运行
    -it # 使用交互方式运行,这样可以进入容器
    -p # 映射端口
    -p 主机端口:容器端口(最常用)
    -p ip:主机端口:容器端口
    -P # 将主机的所有端口映射到容器上
    -v xxx:xxx[:args] # 挂载数据卷或目录到容器
    -v 主机目录:容器内目录 # 将主机目录挂载到容器内目录
    -v 容器内目录 # 匿名挂载。创建一个数据卷并挂载到容器内目录,数据卷名随机
    -v 数据卷名:容器内目录 # 具名挂载。创建一个数据卷并挂载到容器内目录
    # args
    ro # 只读。容器内无法修改,只能读取(容器外可以修改)
    rw # 可读可写。如果不写权限,默认就是 rw
    --volumes-from=容器id # 继承已有容器的数据卷,可以方便的实现容器间数据卷共享
  • 退出容器(在容器中时)

    1
    2
    EOF				# 退出并停止容器
    ctrl + p + q # 退出但不停止容器
  • 进入容器

    1
    2
    $ docker exec -it 容器id /bin/bash	# 进入容器并在新的会话中执行 /bin/bash(常用)
    $ docker attach 容器id # 进入容器,使用容器中原有的会话,不创建新会话
  • 查看容器

    1
    2
    3
    4
    5
    6
    $ docker ps		# 列出正在运行的容器

    # options
    -a # 列出所有容器
    -n=num # 列出最近创建的 num 个容器
    -q # 只显示容器 id
  • 删除容器

    1
    2
    3
    4
    5
    $ docker rm 容器id	# 删除容器
    $ docker rm -f $(docker ps -aq) # 删除所有容器

    # options
    -f # 强行删除容器(如果不加这个参数,无法删除正在运行的容器)
  • 启动/停止容器(从容器外部)

    1
    2
    3
    4
    $ docker start 容器id		# 启动容器
    $ docker restart 容器id # 重启容器
    $ docker stop 容器id # 停止容器
    $ docker kill 容器id # 强制停止容器

数据卷命令

  • 列出数据卷

    1
    $ docker volume ls
  • 查看数据卷的元数据

    1
    $ docker volume inspect 数据卷名

其他常用命令

  • 查看容器日志

    1
    2
    3
    4
    5
    6
    $ docker logs -tf --tail 日志条数 容器id

    # options
    -t # 显示时间戳
    -f # follow log output
    --tail num # 显示末尾 num 条日志
  • 查看容器内部的进程信息

    1
    $ docker top 容器id
  • 查看镜像/容器的元数据

    1
    $ docker inspect 镜像id/容器id
  • 主机和容器互相拷贝文件

    1
    2
    $ docker cp 容器id:容器内路径  主机路径		# 从容器拷贝文件到主机
    $ docker cp 主机路径 容器id:容器内路径 # 从主机拷贝文件到容器
  • commit 镜像

    当运行一个容器时,我们做的任何文件修改都会被记录于容器存储层里(如果不使用卷的话)。docker commit 命令可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。

    1
    $ docker commit -m="提交的描述信息" -a="作者" 容器id 新镜像名[:TAG]

    一般不推荐使用 docker commit,而是提倡使用 Dockerfile 定制镜像以修改容器。docker commit 一般仅在紧急情况下保护现场使用。

  • 查看镜像的生成过程

    1
    $ docker history 镜像名/id

用 Dockerfile 构建镜像

编写 Dockerfile

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
# 指定基础镜像(如 scratch, centos, ubuntu)
FROM image[:tag]

# 声明镜像的作者
MAINTAINER name<email>

# 设置工作目录
WORKDIR /path/to/dir

# 设置环境变量
ENV KEY1=value1 KEY2=value2

# 指定容器需要映射到宿主机的端口
EXPOSE port1 port2 port3

# 挂载匿名卷
# docker run 时会自动创建匿名卷挂载到 VOLUME 指令指定的目录下
VOLUME ["/path/to/dir1", "/path/to/dir2"]

# 运行命令
# 如果有多个命令需要执行,尽量不要写多个 RUN,而是用 && 或 ; 将多个命令一起执行,只写一个 RUN,因为每条 RUN 都会成为一层镜像
RUN command # command 会用 `/bin/sh -c` 的方式执行
RUN ["command", "param1", "param2"]

# CMD 会被拼接到 ENTRYPOINT 后面作为容器启动时执行的命令
# 如果写了多条 ENTRYPOINT,只有最后一条有效
ENTRYPOINT command
ENTRYPOINT ["command", "param1", "param2"]

# 如果写了多条 CMD 指令,只会执行最后一条
# docker run 时如果写了 cmd,只会执行该 cmd,而不执行 dockerfile 中指定的 cmd
CMD command
CMD ["command/param", "param1", "param2"]

# 复制文件
# 第一个参数是相对路径(相对于 "上下文路径")
# 第二个参数是容器内的绝对路径
# 支持通配符
COPY filename/dirname /path/to/dir

# 更高级的复制文件
# 基本功能与 COPY 相同,不过在 COPY 的基础上添加了一些功能
# 1. 源路径可以是个 URL,docker 引擎会自动下载文件
# 2. 源路径如果是 .tar .tar.gz .tar.bz2 .tar.xz 文件,会自动解压。如果不想解压,就必须使用 COPY 了
ADD filename/dirname/URL /path/to/dir

注意:一般要在 Dockerfile 中写命令以清除构建过程中下载安装的包、apt 缓存等,防止镜像臃肿。

构建镜像

  • 从指定路径构建

    1
    2
    3
    4
    $ docker build -t 镜像名[:TAG] -f Dockerfile路径 上下文路径

    # “上下文路径” 中的所有文件都会用来构建镜像,如果不想发送某些文件,可以用 .gitignore 一样的语法写一个 .dockerignore
    # 如果没指定 Dockerfile 的路径,会默认在上下文路径中寻找 Dockerfile
  • 从压缩包构建

    1
    2
    $ docker build -t 镜像名[:TAG] xxx.tar.gz			# 用本地压缩包构建
    $ docker build -t 镜像名[:TAG] https://xxx.com/xxx.tar.gz # 从远程压缩包构建
  • 从远程 git 仓库构建

    1
    $ docker build -t 镜像名[:TAG] https://github.com/username/repo.git

发布镜像

发布镜像到 Docker hub:

1
2
$ docker login
$ docker push 作者/镜像名:TAG

发布镜像到 阿里云镜像服务:

  1. 浏览器登陆阿里云的容器镜像服务
  2. 创建命名空间和镜像仓库,镜像仓库可以选择公有或私有
  3. 点击镜像仓库,会有详细的操作步骤

docker 网络

docker 网络图解

如图,同一个网络的容器会使用 veth-pair 技术与 docker0 相连。docker0 相当于路由器。

创建容器时默认会使用 docker0,容器之间不能通过 容器名/id 互相访问,只能通过 ip 互相访问。

自己创建的网络中的容器支持通过 容器名/id 互相访问。一般一个集群使用一个网络。

创建网络:

1
$ docker network create [options] 网络

列出所有网络:

1
$ docker network ls

查看网络元信息:

1
$ docker network inspect 网络

将一个网络中的某个容器与另一个网络建立连接(原理是为这个容器分配两个 ip)

1
$ docker network connect 网络 容器名/id