容器是一种历史悠久的虚拟化技术。Linux 的 LXC、Solaris 上的 Zones等,都是容器的不同实现方式。
一个容器实质上就是运行在宿主机上的一个进程。只不过在启动进程之前,进行了一些特殊处理,让这个进程进入了一个全新的虚拟环境,与宿主机环境分开。所以这个进程以及它的子进程认为自己运行在一个独立的世界里面。
简介
Docker 是一个能够把开发的应用程序自动部署到容器的轻量级的容器管理引擎。
- 提供一个简单、轻量的建模方式。大多数 Docker 应用程序只需要不到 1 秒钟即可启动。
- 职责的逻辑分离。使用 Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。
- 快速、高效的开发生命周期。Docker 的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。
- 鼓励使用面向服务的架构和微服务架构
核心组件
- Docker 的客户端和服务端,也称为 Docker 引擎
- Docker 镜像
- Registry
- Docker 容器
镜像和仓库
什么是 Docker 镜像?
Docker 镜像是由文件系统叠加而成。最低端是一个引导文件系统,即 bootfs,这很像典型的 Linux/Unix 的引导文件系统。Docker 用户几乎永远不会和引导文件系统有什么交互。实际上,当一个容器启动后,它将会被移到内存中,而引导文件系统则会被写在(unmount),以留出更多的内存供 initrd 磁盘镜像使用。
到目前为止,Docker 看起来还很像一个典型的 Linux 虚拟化栈。实际上,Docker 镜像的第二层是 root 文件系统 rootfs,它位于引导文件系统之上。rootfs 可以是一种或多种操作系统。
为了区分一个仓库中的不同镜像,Docker 提供了一种称为标签(tag)的功能。
构建镜像
有两种方式:
- 使用
docker commit
命令 - 使用
docker build
命令和Dockerfile
文件
后者更灵活、更强大。
一般来说,我们不是真正的创建新镜像,而是基于一个已有的基础镜像,如 Ubuntu 或 fedora 等,构建新镜像而已。
常用命令
1 | # Docker 相关的信息 |
Dockerfile
简介
Dockerfile 使用基本的基于 DSL(Domain Specific Language)语法的指令来构建一个 Docker 镜像。
Dockerfile 由一系列指令和参数组成。每条指令都必须为大写字母,且后面要跟随一个参数。Dockerfile 中的指令会按顺序从上到下执行,所以应该根据需要合理的安排指令的顺序。
每个 Dockerfile 的第一条指令必须是 FROM。FROM 指令指定一个已经存在的镜像,后续指令都将基于该镜像进行,FROM 指令指定的镜像被称为基础镜像(base image)。
Dockerfile 中指令执行流程
每条指令都会创建一个新的镜像并对新的镜像进行提交。大体流程如下:
- Docker 从基础镜像运行一个容器
- 执行一条指令,对容器做出修改
- 执行类似 docker commit 的操作,提交一个新的镜像
- Docker 再基于刚提交的镜像运行一个容器
- 执行 Dockerfile 中的下一条指令,直到所有指令都执行完毕
Dockerfile 指令
FROM
指定一个已经存在的镜像
MAINTAINER
告诉 Docker 该镜像的作者是谁,以及作者的电子邮件地址。
ENV
在镜像中设置环境变量。
RUN
在当前镜像中运行指定的命令。
EXPOSE
告诉 Docker 该容器内的应用将会使用容器的指定端口。
这并不意味着可以自动访问任意容器运行中服务的端口。处于安全的考虑,Docker 并不会自动打开该端口,而是用户在使用 docker run 运行容器是来指定需要打开哪些端口。
可以指定多个 EXPOSE 指令来向外部公开多个端口。
构建上下文
我们会创建一个目录来保存 Dockerfile,这个目录是我们的构建环境(build environment),Docker 则称此环节为上下文(content)或者构建上下文(build content)。
.dockerignore
用来设置那些文件不会被当做构建上下文的一部分。
docker run -d -p 80 –name static_web lizy/static_web:v1 nginx -g “daemon off;”
实践
在宿主机上启用 Nginx
1 | docker pull nginx |