Docker
Docker
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker的应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
Docker 的优点
Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。
参考:https://www.runoob.com/docker/docker-tutorial.html
Docker 架构
Docker 包括三个基本概念:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
容器与镜像的关系类似于面向对象编程中的对象与类。
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
参考:https://www.runoob.com/docker/docker-architecture.html
Docker 镜像加速
- 网易:https://hub-mirror.c.163.com/
- 阿里云:https://<你的ID>.mirror.aliyuncs.com(阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors)
- 七牛云加速器:https://reg-mirror.qiniu.com
Docker 使用
简单上手
Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。
输出Hello world
docker run ubuntu:15.10 /bin/echo "Hello world"
参数解析:
- docker: Docker 的二进制执行文件。
- run: 与前面的 docker 组合来运行一个容器。
- ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
- /bin/echo "Hello world": 在启动的容器里执行的命令
可以理解为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果。
运行交互式的容器
docker run -i -t ubuntu:15.10 /bin/bash
- -t: 在新容器内指定一个伪终端或终端。
- -i: 允许你对容器内的标准输入 (STDIN) 进行交互。
执行此命令进入ubuntu15.10 系统的容器,运行命令 cat /proc/version和ls分别查看当前系统的版本信息和当前目录下的文件列表
退出容器:执行命令 exit
或使用 CTRL+D
启动容器(后台模式)
命令创建一个以进程方式运行的容器
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
输出:b0167279f8ff41e66df71bae4f4731bed1108191b80d31c12e76c7e89b401abc
这个长字符串叫做容器 ID,对每个容器来说都是唯一的
通过 docker ps 来查看容器是否有在运行
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
- created(已创建)
- restarting(重启中)
- running(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。
在宿主主机内使用 docker logs 命令,查看容器内的标准输出:
docker logs b0167279f8ff
或者使用自动分配的容器名称
docker logs kind_volhard
停止容器
使用 docker stop 命令来停止容器
docker stop b0167279f8ff
或
docker logs kind_volhard
通过 docker ps 查看,容器已经停止工作
Docker 容器
客户端常用命令
查看到 Docker 客户端的所有命令选项
docker
更深入的了解指定的 Docker 命令使用方法
docker command --help
如果我们本地没有 ubuntu 镜像,使用 docker pull 命令来载入 ubuntu 镜像
docker pull ubuntu
使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器
docker run -it ubuntu /bin/bash
参数说明:
- -i: 交互式操作。
- -t: 终端。
- ubuntu: ubuntu 镜像。
- /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash
退出终端: exit
查看所有的容器命令
docker ps -a
使用 docker start 启动一个已停止的容器
docker start 433aadf0cb0f
后台运行
在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。
docker run -itd --name ubuntu-test ubuntu /bin/bash
停止容器
docker stop <容器 ID>
重启容器
docker restart <容器 ID>
进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
- docker attach
- docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
示例:
docker attach <容器ID>
exec
docker exec -it 243c32535da7 /bin/bash
注意: 如果使用exec从这个容器退出,不会导致容器的停止
导出和导入容器
导出容器
如果要导出本地某个容器,可以使用 docker export 命令。
docker export 243c32535da7 > ubuntu.tar
导出容器 1e560fca3906 快照到本地文件 ubuntu.tar
导入容器
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
docker import ./ubuntu.tar test/ubuntu:v1
也可以通过指定 URL 或者某个目录来导入
docker import http://example.com/exampleimage.tgz example/imagerepo
删除容器
删除容器使用 docker rm 命令:
docker rm -f 243c32535da7
清理掉所有处于终止状态的容器
docker container prune
运行WEB应用容器
尝试使用 docker 构建一个 web 应用程序。
我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。
docker pull training/webapp # 载入镜像 docker run -d -P training/webapp python app.py
- -d: 让容器在后台运行。
- -P: 将容器内部使用的网络端口映射到我们使用的主机上。
使用 docker ps 来查看正在运行的容器:
PORTS 0.0.0.0:32769->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上
也可以通过 -p 参数来设置不一样的端口:
docker run -d -p 5000:5000 training/webapp python app.py
容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
使用 docker port 也可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
docker port <容器ID或名字>
查看 WEB 应用程序日志
docker logs [ID或者名字]
可以查看容器内部的标准输出。
查看WEB应用程序容器的进程
docker top [ID或者名字]
检查 WEB 应用程序
docker inspect [ID或者名字]
查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
停止 WEB 应用容器
docker stop [ID或者名字]
重启WEB应用容器
已经停止的容器,我们可以使用命令 docker start 来启动。
docker start [ID或者名字]
正在运行的容器,我们可以使用 docker restart
命令来重启。
移除WEB应用容器
docker rm [ID或者名字]
注意:删除容器时,容器必须是停止状态,否则会报错
Docker 镜像
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
列出本地所有镜像
docker images
输出选项说明:
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
说明:同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本
如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:
docker run -t -i ubuntu:15.10 /bin/bash
如果不指定一个镜像的版本标签,例如只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。
手动获取一个新的镜像
docker pull ubuntu:15.10
查找镜像
- 可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
- 也可以通过命令
docker search
搜索
例如:查找httpd
docker search httpd
搜索结果参数说明:
- NAME: 镜像仓库源的名称
- DESCRIPTION: 镜像的描述
- OFFICIAL: 是否 docker 官方发布
- stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
- AUTOMATED: 自动构建。
删除镜像
docker rmi hello-world
删除 hello-world 镜像
创建镜像
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
- 1、从已经创建的容器中更新镜像,并且提交这个镜像
- 2、使用 Dockerfile 指令来创建一个新的镜像
更新镜像
更新镜像之前,我们需要使用镜像来创建一个容器
docker run -t -i ubuntu:15.10 /bin/bash
在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit 命令来退出这个容器。
此时的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本
docker commit -m="has update" -a="royal" f76893e0cced demo/ubuntu:v2
各个参数说明:
- -m: 提交的描述信息
- -a: 指定镜像作者
- f76893e0cced :容器 ID
- demo/ubuntu:v2: 指定要创建的目标镜像名
可以使用 docker images 命令来查看我们的新镜像
使用我们的新镜像来启动一个容器
docker run -t -i runoob/ubuntu:v2 /bin/bash
构建镜像
我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
FROM centos:6.7 MAINTAINER Fisher "" RUN /bin/echo ‘root:123456‘ |chpasswd EXPOSE 22 EXPOSE 80 CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
docker build -t demo/centos:6.7 .
- -t :指定要创建的目标镜像名
- . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
使用docker images 查看创建的镜像已经在列表中存在
设置镜像标签
docker tag c9e39a58ab62 demo/centos:dev
docker tag 镜像ID,用户名称、镜像源名(repository name)和新的标签名(tag)。
使用 docker images 命令可以看到,ID为c9e39a58ab62的镜像多一个标签
Docker 容器连接
前面实现了通过网络端口来访问运行在 docker 容器内的服务。
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
网络端口映射
创建一个 python 应用的容器
docker run -d -P training/webapp python app.py
- -P :是容器内部端口随机映射到主机的高端口
- -p : 是容器内部端口绑定到指定的主机端口
如:
docker run -d -p 5000:5000 training/webapp python app.py
指定容器绑定的网络地址,比如绑定 127.0.0.1
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
- 如果要绑定 UDP 端口,可以在端口后面加上 /udp
docker port 命令可以让我们快捷地查看端口的绑定情况
Docker 容器互联
端口映射并不是唯一把 docker 连接到另一个容器的方法
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息
当创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用 --name 标识来命名容器,例如:
docker run -d -P --name demoWeb training/webapp python app.py
使用 docker ps 命令来查看容器名称
新建网络
docker network create -d bridge test-net
参数说明:
-d:参数指定 Docker 网络类型,有 bridge、overlay。其中 overlay 网络类型用于 Swarm mode
连接容器
运行一个容器并连接到新建的 test-net 网络
docker run -itd --name test1 --network test-net ubuntu /bin/bash
打开新的终端,再运行一个容器并加入到 test-net 网络:
docker run -itd --name test2 --network test-net ubuntu /bin/bash
通过 ping 来证明 test1 容器和 test2 容器建立了互联关系
注:如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping(可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)
apt-get update apt install iputils-ping
这样,test1 容器和 test2 容器建立了互联关系,如果有多个容器之间需要互相连接,推荐使用 Docker Compose
配置 DNS
可以在宿主机的 daemon.json 文件中增加以下内容来设置全部容器的 DNS:
{ "dns" : [ "114.114.114.114", "8.8.8.8" ] }
设置后重启 docker,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:
docker run -it --rm ubuntu cat etc/resolv.conf
手动指定容器的配置
docker run -it --rm host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
参数说明:
-h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
--dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
--dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com
如果没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS
Docker 仓库管理
仓库(Repository)是集中存放镜像的地方。以下 Docker Hub,只是远程的服务商不一样,操作都是一样的
目前 Docker 官方维护了一个公共仓库 Docker Hub
大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现
注册
在 https://hub.docker.com 免费注册一个 Docker 账号
登录和退出
登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像
docker login
退出
docker logout
拉取镜像:你可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地
推送镜像
docker tag ubuntu:18.04 username/ubuntu:18.04 #添加标签 docker push username/ubuntu:18.04 #推送镜像
推送成功可以使用docker search查找
Docker Dockerfile
什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
使用 Dockerfile 定制镜像
下面以定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)
在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:
FROM nginx RUN echo ‘这是一个本地构建的nginx镜像‘ > /usr/share/nginx/html/index.html
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:
RUN <命令行命令> # <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"] # 例如: # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
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 层镜像。可简化为以下格式: 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 文件的存放目录下,执行构建动作
以下示例,通过目录下的 Dockerfile 构建一个 nginx:test(镜像名称:镜像标签)
docker build -t nginx:test .
上下文路径
上面指令最后一个 . 是上下文路径
docker build -t nginx:test .
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢
指令详解
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径,格式:
COPY [--chown=<user>:<group>] <源路径1>... <目标路径> COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
[--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组
<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
COPY hom* /mydir/ COPY hom?.txt /mydir/
<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建
ADD
ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
- ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
- ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行。
- RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令> #例如 CMD ["<可执行文件或命令>","<param1>","<param2>",...] CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参
例如:
假设已通过 Dockerfile 构建了 nginx:test 镜像
FROM nginx ENTRYPOINT ["nginx", "-c"] # 定参 CMD ["/etc/nginx/nginx.conf"] # 变参
1、不传参运行
docker run nginx:test
容器内会默认运行以下命令,启动主进程
nginx -c /etc/nginx/nginx.conf
2、传参运行
docker run nginx:test -c /etc/nginx/new.conf
运行任务:
nginx -c /etc/nginx/new.conf
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量
格式:
ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...
在后续的指令中可以通过 $key 的方式应用,例如:
ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
- 避免重要的数据,因容器重启而丢失,这是非常致命的。
- 避免容器不断变大。
格式:
VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径>
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
EXPOSE
仅仅只是声明端口。
作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
格式:
EXPOSE <端口1> [<端口2>...]
WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
WORKDIR <工作目录路径>
USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令 HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
ONBUILD <其它指令>
Docker Compose
Compose 简介
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务
Compose 使用的三个步骤:
- 使用 Dockerfile 定义应用程序的环境。
- 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
- 最后,执行 docker-compose up 命令来启动并运行整个应用程序。
docker-compose.yml 的配置案例如下:
# yaml 配置实例 version: ‘3‘ services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis volumes: logvolume01: {}
Compose 安装
Linux
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。
运行以下命令以下载 Docker Compose 的当前稳定版本:
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
sudo chmod +x /usr/local/bin/docker-compose
创建软链:
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
测试是否安装成功:
docker-compose --version cker-compose version 1.24.1, build 4667896b
windows
Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序
简单使用
1、准备
创建一个测试目录:
mkdir composetest cd composetest
在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host=‘redis‘, port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr(‘hits‘) except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route(‘/‘) def hello(): count = get_hit_count() return ‘Hello World! I have been seen {} times.\n‘.format(count)
redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379
在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:
flask redis
2、创建 Dockerfile 文件
在 composetest 目录中,创建一个名为的文件 Dockerfile,内容如下:
FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["flask", "run"]
Dockerfile 内容解释:
FROM python:3.7-alpine:从 Python 3.7 映像开始构建镜像
WORKDIR /code:将工作目录设置为 /code
ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0
设置 flask 命令使用的环境变量
RUN apk add --no-cache gcc musl-dev linux-headers:安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
COPY requirements.txt requirements.txt RUN pip install -r requirements.txt
复制 requirements.txt 并安装 Python 依赖项。
COPY . .:将 . 项目中的当前目录复制到 . 镜像中的工作目录。
CMD ["flask", "run"]:容器提供默认的执行命令为:flask run
3、创建 docker-compose.yml
在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:
# yaml 配置 version: ‘3‘ services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
该 Compose 文件定义了两个服务:web 和 redis
- web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000
- redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像
4、使用 Compose 命令构建和运行您的应用
在测试目录中,执行以下命令来启动应用程序:
docker-compose up
如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d