首页 > 代码库 > Dockerfile.md

Dockerfile.md

Docker 使用

前提条件

  • Docker目前只能在64位CPU架构的计算机上运行(目前只能是x86_64 、amd64)。

  • Linux 3.8 或 更高版本的内核。3.8之前的版本也能运行,但效果不同,遇到问题时大家都建议你升级。

  • 在运行CentOS 6.5及以后版本时,需要内核版本>=2.6.32-431,因为这些内核包含了运行Docker的一些特定修改。

  • 内核必须支持一些是和的存储驱动(strage drive),例如:

    • Device Manage

    • AUFS

    • vfs

    • btrfs

    • 默认存储驱动通常是Device

  • 内核必须支持并开启cgroup和命名空间(banespace)功能

安装

这里安装测试是在CentOS 7中进行。
Docker RPM包已经包含在CentOS-Extra仓库中,所以我们可以直接使用Yum安装:

$ sudo yum install docker

也可以用 DaoCloud 的安装脚本

curl -sSL https://get.daocloud.io/docker | sh

命令使用

Docker 命令使用可以从下面的变迁图所示:

 

技术分享
 

 

选项

  • --config=~/.docker:客户端配置文件的位置

  • -D, --debug:启用debug 模块

  • -H, --host=[]:要连接的守护程序套接字

  • -l, --log-level=info:设置log级别

  • --tls:使用TLS; 隐含的--tlsverify

  • --tlscacert=~/.docker/ca.pem:仅由此CA签署的信任证书

  • --tlscert=~/.docker/cert.pem

  • --tlskey=~/.docker/key.pem

  • --tlsverify:使用TLS并验证远程

镜像仓库

login

登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
格式

docker login [OPTIONS] [SERVER]

子选项

  • -p, --password string Password

  • -u, --username string Username

logout

登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub。
格式

docker logout [SERVER]

从Docker Hub查找镜像。
格式

docker search [OPTIONS] TERM

子选项

  • -f, --filter value:基于提供的条件过滤输出

  • --limit int:搜索结果的最大数量(默认为25)

# docker search  --limit 2 --filter=stars=10 centos 
NAME      DESCRIPTION                     STARS     OFFICIAL   AUTOMATED
centos    The official build of CentOS.   3005      [OK]

pull

从镜像仓库中拉取镜像或repository。
格式

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

子选项

  • -a, --all-tags:下载镜像仓库中的所有标记的镜像

  • --disable-content-trust:跳过镜像验证(默认为true)

下面是在官方仓库下载最近版本的官方镜像,所以在pull镜像是最好是指定版本。

# docker pull nginx:1.10.0
1.10.0: Pulling from library/nginx
51f5c6a04d83: Pull complete 
a3ed95caeb02: Pull complete 
14ef99dba46e: Pull complete 
3e91b3ec524a: Pull complete 
Digest: sha256:7224f0a40f2110889889f47dcafa972a8658b7bdd3b50cfa12fd5f80364cbcfe
Status: Downloaded newer image for nginx:1.10.0

当然也可以从官方镜像中下载别人自己制作好的镜像,形如docker pull username/repository<:tag_name>
我们也可以在自己搭建的私有仓库中进行获取镜像,例如:docker pull registry.domain.com:5000/repos:<tag_name>

push

将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。
格式

docker push [OPTIONS] NAME[:TAG]

子选项

  • --disable-content-trust:跳过镜像验证(默认为true)

上传本地镜像到仓库中:

# docker push nginx:1.10.0

本地镜像管理

images

列出本地镜像。
格式

docker images [OPTIONS] [REPOSITORY[:TAG]]

子选项

  • -a, --all:显示所有镜像(默认隐藏中间镜像)

  • --digests:显示DIGEST信息

  • -f, --filter value:基于提供的条件过滤输出(默认[])

  • -q, --quiet:仅显示数字ID

# docker images
REPOSITORY                              TAG                    IMAGE ID            CREATED             SIZE
registry                                latest                 182810e6ba8c        2 weeks ago         37.6 MB
nginx                                   1.11.8                 01f818af747d        2 weeks ago         181.6 M
# docker images -q
182810e6ba8c
01f818af747d

rmi

删除本地一个或多少镜像。
格式

docker rmi [OPTIONS] IMAGE [IMAGE...]

子选项

  • -f :强制删除;

  • --no-prune :不移除该镜像的过程镜像,默认移除;

tag

标记本地镜像,将其归入某一仓库。
格式

docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]

使用
将镜像ubuntu:latest标记为 ubuntu:16.04 镜像。

# docker tag ubuntu:latest ubuntu:16.04

build

根据Dockerfile创建镜像。
格式

docker build [OPTIONS] PATH | URL | -

子选项

  • --build-arg=[] :设置镜像创建时的变量;

  • -c, --cpu-shares int :设置 cpu 使用权重;

  • --cpu-period :限制 CPU CFS周期;

  • --cpu-quota :限制 CPU CFS配额;

  • --cpuset-cpus :指定使用的CPU id;

  • --cpuset-mems :指定使用的内存 id;

  • --disable-content-trust :忽略校验,默认开启;

  • -f, --file string:指定要使用的Dockerfile路径;

  • --force-rm :设置镜像过程中删除中间容器;

  • --isolation :使用容器隔离技术;

  • --label=[] :设置镜像使用的元数据;

  • -m, --memory string:设置内存最大值;

  • --memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap;

  • --no-cache :创建镜像的过程不使用缓存;

  • --pull :尝试去更新镜像的新版本;

  • -q :安静模式,成功后只输出镜像ID;

  • --rm :设置镜像成功后删除中间容器;

  • --shm-size :设置/dev/shm的大小,默认值是64M;

  • -t, --tag value:名称和可选的“name:tag”格式的标签(默认[])

  • --ulimit :Ulimit配置。

举例

history

格式

docker history [OPTIONS] IMAGE

子选项

  • -H :以可读的格式打印镜像大小和日期,默认为true;

  • --no-trunc :显示完整的提交记录;

  • -q :仅列出提交记录ID。

举例
查看本地镜像nginx:1.10.0的创建历史:

# docker history nginx:1.10.0
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
16666ff3a57f        7 months ago        /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon o   0 B                 
<missing>           7 months ago        /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp         0 B                 
<missing>           7 months ago        /bin/sh -c ln -sf /dev/stdout /var/log/nginx/   0 B                 
<missing>           7 months ago        /bin/sh -c apt-key adv --keyserver hkp://pgp.   57.65 MB            
<missing>           7 months ago        /bin/sh -c #(nop) ENV NGINX_VERSION=1.10.0-1~   0 B                 
<missing>           7 months ago        /bin/sh -c #(nop) MAINTAINER NGINX Docker Mai   0 B                 
<missing>           7 months ago        /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B                 
<missing>           7 months ago        /bin/sh -c #(nop) ADD file:5d8521419ad6cfb695   125.1 MB

save

将指定镜像保存成 tar 归档文件。
格式

docker save [OPTIONS] IMAGE [IMAGE...]

选项

  • -o :写入到文件,而不是STDOUT

使用举例
将镜像nginx:1.10.0 生成nginx_1.10.0.tar文档

# docker save -o nginx_1.10.0.tar nginx:1.10.0

import

从归档文件中创建镜像。
格式

docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

子选项

  • -c :将Dockerfile指令应用于创建的映像(默认[])

  • -m :提交时的说明文字;

举例
从镜像归档文件nginx_1.10.0.tar创建镜像,命名为local/nginx:1.10.0

# docker import -m "local import" nginx_1.10.0.tar local/nginx:1.10.0
sha256:ff9738d2818bbb2690603b54256af69999a44c78b4f3aa4ccd598639227d83ff
# docker history local/nginx:1.10.0
IMAGE               CREATED             CREATED BY          SIZE                COMMENT
ff9738d2818b        33 seconds ago                          190.7 MB            local import

容器生命周期管理

run

格式

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

docker run命令首先会从特定的image创之上create一层可写的container,然后通过start命令来启动它。停止的container可以重新启动并保留原来的修改。
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载

  • 利用镜像创建并启动一个容器

  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层

  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去

  • 从地址池配置一个 ip 地址给容器

  • 执行用户指定的应用程序

  • 执行完毕后容器被终止

子选项

  • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;

  • -d: 后台运行容器,并返回容器ID;

  • -i: 以交互模式运行容器,通常与 -t 同时使用;

  • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

  • --name="nginx-lb": 为容器指定一个名称;

  • --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;

  • --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;

  • -h "mars": 指定容器的hostname;

  • -e username="ritchie": 设置环境变量;

  • --env-file=[]: 从指定文件读入环境变量;

  • --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;

  • -m :设置容器使用内存最大值;

  • --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;

  • --link=[]: 添加链接到另一个容器;

  • --expose=[]: 开放一个端口或一组端口;

  • -p, --publish value: 开启容器时将容器的端口与主机的端口进行绑定;

  • -P, --publish-all:将所有暴露的端口发布到随机端口;

  • -v, --volume value:绑定挂载的卷;

  • --volumes-from value:从指定的容器挂载卷;

  • -w, --workdir string:容器中的工作目录

使用举例
创建一个容器执行相关命令:

# docker run centos:6.8 echo ‘Hello World!‘
Hello World!

上面的例子中是运行一个docker 容器,然后打印Hello World!,之后就退出容器。在上面的例子中虽然容器退出了但是该容器并没有删除,在测试时候我们可以在启动容器使用--rm 参数来在使用容器后删除容器。

# docker run -it --rm --name test centos:6.8 /bin/bash
[root@cf33a287ad44 /]#

上面的例子是指定了容器的名字test,在日常使用中这么操作比较容易管理。

运行出一个container放到后台运行:

# docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 2; done"
ae60c4b642058fefcc61ada85a610914bed9f5df0e2aa147100eab85cea785dc

映射host到container的端口和目录:
映射主机到容器的端口是很有用的,比如在container中运行memcached,端口为11211,运行容器的host可以连接container的 internel_ip:11211 访问,如果有从其他主机访问memcached需求那就可以通过-p选项,形如-p <host_port:contain_port>,存在以下几种写法:

-p 11211:11211 这个即是默认情况下,绑定主机所有网卡(0.0.0.0)的11211端口到容器的11211端口上
-p 127.0.0.1:11211:11211 只绑定localhost这个接口的11211端口
-p 127.0.0.1::5000
-p 127.0.0.1:80:8080

目录映射其实是“绑定挂载”host的路径到container的目录,这对于内外传送文件比较方便,在搭建私服那一节,为了避免私服container停止以后保存的images不被删除,就要把提交的images保存到挂载的主机目录下。使用比较简单,-v <host_path:container_path>,绑定多个目录时再加-v。

-v /tmp/docker:/tmp/docker

start

格式

docker start [OPTIONS] CONTAINER [CONTAINER...]

子选项

  • -a, --attach:Attach STDOUT/STDERR and forward signals

  • --detach-keys string:覆盖用于分离容器的键序列

  • -i, --interactive:Attach container‘s STDIN

stop

格式

docker stop [OPTIONS] CONTAINER [CONTAINER...]

子选项

  • -t, --time int:容器停止之前等待多少时间kill掉。(默认10)

restart

格式

docker restart [OPTIONS] CONTAINER [CONTAINER...]

子选项

  • -t, --time int:容器停止之前等待多少时间kill掉。(默认10)

kill

格式

docker kill [OPTIONS] CONTAINER [CONTAINER...]

子选项

  • -s, --signal string:发送到容器的信号(默认为“KILL”)

rm

格式

docker rm [OPTIONS] CONTAINER [CONTAINER...]

子选项

  • -f, --force :通过SIGKILL信号强制删除一个运行中的容器

  • -l, --link:移除容器间的网络连接,而非容器本身

  • -v, --volumes:删除与容器关联的卷

pause

暂停一个或多个容器中所有的进程。
格式

docker pause CONTAINER [CONTAINER...]

unpause

取消暂停一个或多个容器中的所有进程。
格式

 docker unpause CONTAINER [CONTAINER...]

create

创建一个新的容器但不启动它。
格式

docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

子选项
子选项和run 命令的子选项通用。

exec

在运行的容器中执行命令。
格式

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

子选项

  • -d :分离模式: 在后台运行

  • -i :即使没有附加也保持STDIN 打开

  • -t :分配一个伪终端

  • -u, --user:Username or UID (format: <name|uid>[:<group|gid>])

容器操作

ps

列出容器。
格式

docker ps [OPTIONS]

子选项

  • -a :显示所有的容器,包括未运行的。

  • -f :根据条件过滤显示的内容。

  • --format :指定返回值的模板文件。

  • -l, --latest :显示最近创建的容器。

  • -n :列出最近创建的n个容器。

  • --no-trunc :不截断输出。

  • -q, --quiet :静默模式,只显示容器编号。

  • -s, --size :显示总的文件大小。

inspect

获取容器/镜像的元数据。
格式

docker inspect [OPTIONS] CONTAINER|IMAGE|TASK [CONTAINER|IMAGE|TASK...]

子选项

  • -f, --format :使用给定的go模板格式化输出。

  • -s, --size :如果类型为容器,则显示总文件大小。

  • --type :为指定类型返回JSON。

举例
获取正在运行的容器ubuntu_test的 IP。

# docker inspect -f ‘{{ .NetworkSettings.IPAddress }}‘ ubuntu_test
172.17.0.2

top

查看容器中运行的进程信息,支持 ps 命令参数。
格式

docker top CONTAINER [ps OPTIONS]

容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程。

events

从服务器获取实时事件。
格式

docker events [OPTIONS]

子选项

  • -f, --filter value :根据条件过滤事件;

  • --since string :从指定的时间戳后显示所有事件;

  • --until string :流水时间显示到指定的时间为止;

logs

获取容器的日志。
格式

docker logs [OPTIONS] CONTAINER

子选项

  • -f, --follow : 跟踪日志输出

  • --since string :显示某个开始时间的所有日志

  • -t, --timestamps : 显示时间戳

  • --tail string :仅列出最新N条容器日志

  • --details:显示提供给日志的额外详情

wait

阻塞运行直到容器停止,然后打印出它的退出代码。
格式

docker wait CONTAINER [CONTAINER...]

export

将容器的文件系统导出为tar存档。
格式

docker export [OPTIONS] CONTAINER
  • -o, --output string:将输入内容写到文件。

将名称为ubuntu_test 的容器保存为ubuntu_test.tar 文件:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
d749ca04f897        ubuntu:14.04        "sh"                About an hour ago   Up About an hour                        ubuntu_test
# docker export -o ubuntu_test.tar ubuntu_test

port

列出端口映射或容器的特定映射。
格式

docker port CONTAINER [PRIVATE_PORT[/PROTO]]

容器rootfs命令

commit

从容器创建一个新的镜像。
格式

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

子选项

  • -a, --author string :提交的镜像作者;

  • -c, --change value :使用Dockerfile指令来创建镜像;

  • -m :提交时的说明文字;

  • -p :在commit时,将容器暂停。

cp

用于容器与主机之间的数据拷贝。
格式

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

子选项
-L, --follow-link :保持源目标中的链接

举例
将当前目录中的Dockerfile拷贝到ubuntu_test容器的tmp目录下:

# docker cp Dockerfile ubuntu_test:/tmp/

diff

检查容器里文件结构的更改。
格式

docker diff CONTAINER

Dockerfile

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

FROM

格式为 FROM <image>FROM <image>:<tag>
第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令( 每个镜像一次) 。

MAINTAINER

格式为 MAINTAINER <name> ,指定维护者信息。

RUN

格式为 RUN <command>RUN ["executable", "param1", "param2"]
前者将在 shell 终端中运行命令,即 /bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。

CMD

CMD指令用于指定一个容器启动时要运行的命令。这有点类是于RUN指令,只是RUN指令是指定镜像被构建时要运行的命令,而CMD是指定容器被启动时要运行的命令。这和使用docker run 命令启动容器时指定要运行的命令非常类似。

支持三种格式

  • CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;

  • CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;

  • CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;

注意

  • 指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

  • 如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

EXPOSE

格式为 EXPOSE <port> [<port>...]
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。

ENV

格式为 ENV <key> <value> 。 指定一个环境变量,会被后续 RUN指令使用,并在容器运行时保持。
例如

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

ADD

格式为 ADD <src> <dest>
该命令将复制指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件( 自动解压为目录) 。

COPY

格式为 COPY <src> <dest>
复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径) 到容器中的 <dest>
当使用本地目录为源目录时,推荐使用 COPY 。

ENTRYPOINT

两种格式:

  • ENTRYPOINT ["executable", "param1", "param2"]

  • ENTRYPOINT command param1 param2 ( shell中执行) 。

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

VOLUME

格式为 VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据
等。

USER

格式为 USER daemon
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以使用 gosu ,而不推荐 sudo 。

WORKDIR

格式为 WORKDIR /path/to/workdir
为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为 /a/b/c 。

ONBUILD

格式为 ONBUILD [INSTRUCTION]
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile 使用如下的内容创建了镜像 image-A 。

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A 指定基础镜像时,会自动执行 ONBUILD 指令内容,等价于在后面添加了两条指令。

FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild 。

LABEL

LABEL指令用于为Docker镜像添加元数据。元数据以键值对的形式展现。

STOPSIGNAL

STOPSIGNAL 指令用来设置停止容器时发送什么系统调用信号给容器。这个信号必须是内核系统调用表中合法的数,如9,或者SIGNAME 格式的信号名称,如SIGKILL。

ARG

ARG 指令用来定义可以在docker build 命令运行时传递给构建运行时的变量,我们只需要在构建时使用--build-arg 标志即可。用户只能在构建时指定在Dockerfile 文件中定义过的参数。
例如:

ARG build
ARG webapp_user=user

上面例子中第二条 ARG 指令设置了一个默认值,如果构建时没有为该参数指定值,就会使用这个默认值。如果我们在 docker build 中使用这些参数:

docker build --build-arg build=1234 -t example/web .

这里构建example/web 镜像时,build变量将会设置为1234,而webapp_user变量则会继承设置的默认值user。

Dockerfile.md