docker常用命令

docker容器使用时的常用命令。

Docker容器使用
获取镜像

如果我们本地没有 ubuntu 镜像,我们可以使用 docker pull 命令来载入 ubuntu 镜像:

1
docker pull ubuntu
启动容器

以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:

1
docker run -it ubuntu /bin/bash

参数说明:

  • -i: 交互式操作。
  • -t: 终端。
  • ubuntu: ubuntu 镜像。
  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

要退出终端,直接输入 exit:

启动已停止运行的容器

查看所有的容器命令

1
docker ps -a

启动一个已停止的容器

1
docker start 容器ID
后台运行
1
docker run -itd --name ubuntu-test ubuntu /bin/bash

使用-d参数,容器启动后会进入后台,默认不会进入容器,想要进入容器需要使用指令docker exec

停止一个容器
1
docker stop 容器ID

停止的容器重启

1
docker restart 容器ID
进入容器
  • docker attach:从此容器中退出,会导致容器的停止。
  • docker exec:使用此命令,退出容器终端,不会导致容器的停止。
1
2
docker attach 容器ID
docker exec -it 容器ID /bin/bash
导入和导出容器
1
2
docker export 容器ID > ubuntu.tar
cat docker/ubuntu.tar | docker import - test/ubuntu:v1

ubuntu.tar为导出文件,test/ubuntu:v1为镜像。

删除容器
1
2
3
docker rm -f 容器ID
# 清除掉所有处于终止状态的容器
docker container prune
运行一个web应用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 载入镜像
docker pull training/webapp
docker run -d -P training/webapp python app.py

#查看进程
docker top 容器名称

#检查应用
docker inspect 容器名称

#停止web应用容器
docker stop 容器名称

#移除web应用容器,删除时容器必须停止,否则会报错
docker rm

-P将容器内部使用的网络端口映射到我们使用的主机上。

1
-p 主机IP:8080:8080
查看web应用程序日志

docker logs 参数 容器名/容器id

  • –details 显示提供给日志的其他详细信息
  • –follow , -f 实时跟踪日志输出
  • –since 显示自某个timestamp之后的日志大于等于某个时间,或相对时间,如1h 就是1h)
  • –tail , -n all 从日志末尾显示的行数,默认值为all 全部
  • –timestamps , -t 日志每行显示日志时间戳
  • –until 显示自某个timestamp之前的日志小于等于某个时间,或相对时间,如30m(即30分钟)
1
docker logs -t -n 5 容器名/容器id

显示时间戳

1
docker logs --tail=10 --since 1h 容器名/容器id

查询最近1小时的日志最新10行日志

1
docker logs -f 容器名/容器id

-f:让docker logs像使用tail -f一样来输出容器内部的标准输出。

1
docker logs -f --tail=1000 容器名/容器id

实时显示最新1000行日志

Docker镜像使用
镜像列表
1
docker images

列出本地主机上的镜像。

各个选项说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

查找镜像
1
docker search 镜像仓库源名称
  • NAME: 镜像仓库源的名称
  • DESCRIPTION: 镜像的描述
  • OFFICIAL: 是否 docker 官方发布
  • stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
  • AUTOMATED: 自动构建。
1
2
3
4
# 下载镜像
docker pull 镜像仓库名称
# 使用镜像
docker run 镜像仓库源名称
删除镜像
1
docker rmi 镜像名称
构建镜像

我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。

1
2
3
4
5
6
7
8
9
10
11
runoob@runoob:~$ cat Dockerfile 
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"

RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Docker image for springboot file run
# VERSION 0.0.1
# 基础镜像使用java
FROM java:8

EXPOSE 8080
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为app.jar
ADD after-0.0.2.jar app.jar
RUN bash -c 'touch /app.jar'
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ENTRYPOINT ["java", "-jar", "/app.jar", "--spring.profiles.active=dev"]

每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。

FROM指定使用哪个镜像源;

RUN 指令告诉docker 在镜像内执行命令,安装了什么。

1
2
3
4
5
6
7
8
9
10
11
12
runoob@runoob:~$ docker build -t runoob/centos:6.7 .
Sending build context to Docker daemon 17.92 kB
Step 1 : FROM centos:6.7
---> d95b5ca17cc3
Step 2 : MAINTAINER Fisher "fisher@sudops.com"
---> Using cache
---> 0c92299c6f03
Step 3 : RUN /bin/echo 'root:123456' |chpasswd
---> Using cache
---> 0397ce2fbd0a
Step 4 : RUN useradd runoob
······

参数说明:

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

使用新的镜像来创建容器

1
docker run -t -i runoob/centos:6.7  /bin/bash
设置镜像标签

使用 docker tag 命令,为镜像添加一个新的标签。

1
docker tag 860c279d2fec runoob/centos:dev
容器连接
网络端口映射
1
2
3
4
5
6
7
docker run -d -P training/webapp python app.py
docker run -d -p 5000:5000 training/webapp python app.py
# 查看镜像进程
docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
33e4523d30aa training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper

两种方式的区别是:

  • -P :是容器内部端口随机映射到主机的高端口。
  • -p :是容器内部端口绑定到指定的主机端口。

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1,可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。

1
2
3
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
95c6ceef88ca training/webapp "python app.py" ... 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker
容器命名

当我们创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用 --name 标识来命名容器。

1
docker run -d -P --name runoob training/webapp python app.py
Docker容器互联

端口映射并不是唯一把 docker 连接到另一个容器的方法。

docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。

docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。

新建网络
1
docker network create -d bridge test-net

参数说明:

-d:参数指定 Docker 网络类型,有 bridge、overlay。

连接容器

运行一个容器并连接到新建的 test-net 网络:

1
docker run -itd --name test1 --network test-net ubuntu /bin/bash

打开新的终端,再运行一个容器并加入到 test-net 网络:

1
docker run -itd --name test2 --network test-net ubuntu /bin/bash

可以通过ping命令来证明test1容器和test2容器建立了互联关系。

配置DNS

可以在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:

1
2
3
4
5
6
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}

设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。

配置完,需要重启 docker 才能生效。

查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:

1
docker run -it --rm ubuntu  cat etc/resolv.conf
Docker Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

FROM 和 RUN 指令的作用

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

RUN:用于执行后面跟着的命令行命令。有以下俩种格式:

shell 格式:

1
2
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。

exec 格式:

1
2
3
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

1
2
3
4
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

1
2
3
4
FROM centos
RUN yum install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

开始构建镜像

以下示例,通过目录下的 Dockerfile 构建一个 nginx:test(镜像名称:镜像标签)。

:最后的 . 代表本次执行的上下文路径.

1
docker build -t nginx:test .

使用docker images查看镜像是否建立成功。

指令详解
  1. COPY: 复制指令COPY 原路径 目标路径

  2. ADD: 同COPY,如果源文件是tar压缩文件,则会自动复制解压到目标路径。

  3. CMD: 类似于RUN,但CMD是在docker run时运行,RUN是在docker build。CMD shell命令

  4. ENTRYPOINT: 类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。ENTRYPOINT 可执行命令 参数1...

  5. ENV: 设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

  6. ARG: 构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。ARG <参数名>[=<默认值>]

  7. VOLUME: 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。VOLUME <路径>

    作用:

    • 避免重要的数据,因容器重启而丢失,这是非常致命的。
    • 避免容器不断变大。
  8. EXPOSE: 声明端口。EXPOSE 端口1...

  9. WORKDIR: 指定工作目录。WORKDIR <工作目录路径>

  10. USER: 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。USER <用户名>[:<用户组>]

  11. HEALTHCHECK: 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

    1
    2
    3
    4
    HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
    HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

    HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
  12. ONBUILD: 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。ONBUILD <其它指令>