一、背景
Docker是一个开源的应用容器引擎,它以容器的形式将应用程序及其依赖向打包在一起,以确保应用程序在人和环境中无缝运行。
持续集成是在每次提交之后不断的基础所有提交到存储库的代码,并编译检查错误。
二、解决的问题
由于不同的机器有不同的操作系统,以及不同的库和组件,将一个应用部署到多台机器上需要进行大量的环境配置操作。Docker主要解决环境配置问题,它是一种虚拟化技术,对进程进行隔离,被隔离的进程独立于宿主系统和其他隔离的进程。使用Docker可以不修改应用程序代码,不需要开发人员学习特定环境下的技术,就能够将现有的应用程序部署在其他机器上。
三、Docker与虚拟机比较
虚拟机也是一种虚拟化技术,它与Docker最大的区别就是他是通过模拟硬件,并在硬件上安装操作系统来实现。
1、启动速度
启动虚拟机需要先启动虚拟机的操作系统,在启动应用,过程复杂且慢。
启动Docker相当于启动宿主操作系统上的一个进程。
2、占用资源
虚拟机是一个完整的操作系统,需要占用大量的磁盘资源,内存和CPU资源,一台机器只能开启几十个虚拟机。
Docker只是一个进程,只需要将应用及相关的组件打包,在运行时占很少的资源,一台机器可以开启成千上万个Docker。
四、Docker的优势
1、更容易迁移
提供了一致性的运行环境。已经打包好的应用可以在不同的机器上进行迁移,不用担心环境变化导致无法运行。
2、更容易维护
使用分层技术和镜像,使得应用可以更容易复用重复部分。复用成都越高,维护工作也越容易。
3、更容易扩展
可以使用基础镜像进一步扩展得到新的镜像,并且官方和开源社区提供了大量的镜像,通过扩展这些镜像可以非常容易得到想要的镜像。
五、使用场景
1、持续集成
持续集成指的是频繁地将代码集成到主干上,这样能够更快地发现错误。
Docker 具有轻量级以及隔离性的特点,在将代码集成到一个 Docker 中不会对其它 Docker 产生影响。
2、提供可伸缩的云服务
根据应用的负载情况,可以很容易地增加或者减少 Docker。
3、搭建微服务架构
Docker 轻量级的特点使得它很适合用于部署、维护、组合微服务。
六、Docker介绍
1、Docker镜像
Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。
# 列出本机的所有 image 文件。
$ docker image ls
# 删除 image 文件
$ docker image rm[imageName]
image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。
为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。此外,出售自己制作的 image 文件也是可以的。
2、Docker容器
Docker容器包括应用程序及其所有依赖项,作为操作系统的独立进程运行。
image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
# 列出本机正在运行的容器
$ docker container ls
# 列出本机所有容器,包括终止运行的容器
$ docker container ls--all
镜像是一种静态的结构,可以看成面向对象里面的类,而容器是镜像的一个实例。
镜像包含着容器运行时所需要的代码以及其它组件,它是一种分层结构,每一层都是只读的(read-only layers)。构建镜像时,会一层一层构建,前一层是后一层的基础。镜像的这种分层存储结构很适合镜像的复用以及定制。
构建容器时,通过在镜像的基础上添加一个可写层(writable layer),用来保存着容器运行过程中的修改。
3、Docker容器有几种状态
运行,已暂停,重新启动,已退出
4、Dockerfile 文件
如果你要推广自己的软件,势必要自己制作 image 文件。
这就需要用到 Dockerfile 文件。它是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件。
七、Docker示例
1、编写Dockerfile文件
首先在项目的根目录,新建文本文件.dockerignore,写入内容:
.git
node_modules
npm-debug.log
上面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。
然后,在项目的根目录下,新建一个文本文件 Dockerfile,写入下面的内容:
FROM node:8.4 //该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
COPY./app //将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
WORKDIR/app //指定接下来的工作路径为/app。
RUN npm install--registry=https://registry.npm.taobao.org //在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
EXPOSE 3000 //将容器 3000 端口暴露出来, 允许外部连接这个端口。
2、创建image文件
有了 Dockerfile 文件以后,就可以使用 docker image build 命令创建 image 文件了。
$ docker image build-t koa-demo.
# 或者
$ docker image build-t koa-demo:0.0.1.
上面代码中,-t参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。
3、生成容器
docker container run命令会从 image 文件生成容器。
$ docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
$ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
-p参数:容器的 3000 端口映射到本机的 8000 端口。
-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
如果一切正常,运行上面的命令以后,就会返回一个命令行提示符。
root@66d80f4aaf1e: /app#
表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符。执行下面的命令。
root@66d80f4aaf1e:/app# node demos/01.js
这个例子中,Node 进程运行在 Docker 容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)。
现在,在容器的命令行,按下 Ctrl + c 停止 Node 进程,然后按下 Ctrl + d (或者输入 exit)退出容器。此外,也可以用docker container kill终止容器运行。
# 在本机的另一个终端窗口,查出容器的 ID
$ docker container ls
# 停止指定的容器运行$ docker container kill[containerID]
容器停止运行之后,并不会消失,用下面的命令删除容器文件。
# 查出容器的 ID$ docker container ls--all# 删除指定的容器文件
$ docker container rm[containerID]
也可以使用docker container run命令的--rm参数,在容器终止运行后自动删除容器文件。
$ docker container run --rm -p8000:3000-it koa-demo/bin/bash
4、发布image文件
首先,去 hub.docker.com 或 cloud.docker.com 注册一个账户。然后,用下面的命令登录。
$ docker login
接着,为本地的 image 标注用户名和版本。
$ docker image tag[imageName][username]/[repository]:[tag]
# 实例
$ docker image tag koa-demos:0.0.1ruanyf/koa-demos:0.0.1
也可以不标注用户名,重新构建一下 image 文件。
$ docker image build-t[username]/[repository]:[tag].
最后,发布 image 文件。
$ docker image push[username]/[repository]:[tag]
发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。
八、其他有用命令
1、docker container start
前面的docker container run命令是新建容器,每运行一次,就会新建一个容器。同样的命令运行两次,就会生成两个一模一样的容器文件。如果希望重复使用容器,就要使用docker container start命令,它用来启动已经生成、已经停止运行的容器文件。
$ docker container start [containerID]
2、docker container stop
前面的docker container kill命令终止容器运行,相当于向容器里面的主进程发出 SIGKILL 信号。而docker container stop命令也是用来终止容器运行,相当于向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号。
$ bash container stop [containerID]
这两个信号的差别是,应用程序收到 SIGTERM 信号以后,可以自行进行收尾清理工作,但也可以不理会这个信号。如果收到 SIGKILL 信号,就会强行立即终止,那些正在进行中的操作会全部丢失。
3、docker container logs
docker container logs命令用来查看 docker 容器的输出,即容器里面 Shell 的标准输出。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令查看输出。
$ docker container logs [containerID]
4、docker container exec
docker container exec命令用于进入一个正在运行的 docker 容器。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令进入容器。一旦进入了容器,就可以在容器的 Shell 执行命令了。
$ docker container exec -it [containerID] /bin/bash
5、docker container cp
docker container cp命令用于从正在运行的 Docker 容器里面,将文件拷贝到本机。下面是拷贝到当前目录的写法。
$ docker container cp [containID] : [/path/to/file].