Docker

Posted royal6

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 镜像加速

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/versionls分别查看当前系统的版本信息和当前目录下的文件列表

退出容器:执行命令 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: 容器的端口信息和使用的连接类型(tcpudp)。

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 "fisher@sudops.com"

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.
‘.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

yml 配置指令参考

https://www.cnblogs.com/royal6/p/13053996.html

以上是关于Docker的主要内容,如果未能解决你的问题,请参考以下文章

markdown docker-compose片段

sh Docker片段

《Docker 源码分析》全球首发啦!

docker 部署 coredns(内部域名解析)

docker 部署 coredns(内部域名解析)

将 Docker 容器限制为单个 cpu 核心