关键的概念
简单概括图中的内容,就是容器运行着由镜像定义的系统。镜像是由一个或多个层加上一些Docker元数据组成。
容器是从镜像中创建的,继承了它们的文件系统,并使用它们的元数据来确定其启动配置。容器是相互隔离的,但可以通过配置进行彼此通信。容器在启动时会运行一个进程,在这个进程完成时,容器将停止。这个启动进程可以派生其他进程。文件的变更通过写时复制(copy-on-write)机制存储在容器中,基础镜像不会受容器影响。
一个Docker镜像是由文件和元数据组成的。镜像文件占用了大部分空间。因为每个容器提供的隔离性,它们必须拥有自己所需工具的副本,包括语言环境和库。元数据包含了环境变量、端口映射、卷等。同一个镜像可以运行多个容器。
层是文件变更的集合。每当一个运行中的容器需要写入一个文件时,它会通过将该项目复制到磁盘的一个新区域来记录这一修改。在执行Docker提交时,这块磁盘新区域将被冻结并记录为具有自身标识符的一个层。每个层都可以被多个运行中的容器共享,就像一个共享库可以在内存中被多个运行中的进程共享一样。
常用的Docker子命令
docker build:构建一个Docker镜像
docker run:以容器形式运行一个Docker镜像
docker commit:将一个Docker容器作为一个镜像提交
docker tag:给一个Docker镜像打标签
构建一个Docker应用
以构建一个todo应用镜像为例。
一、编写一个Dockerfile:
Dockerfile是一个包含一系列命令的文本文件,Docker根据它来创建镜像。示例如下:
[root@test1 todo]# cat Dockerfile 1 FROM node 2 MAINTAINER [email protected] 3 RUN git clone -q https://github.com/docker-in-practice/todo.git 4 WORKDIR todo 5 RUN npm install > /dev/null 6 EXPOSE 8000 7 CMD ["npm","start"]
1.使用FROM命令定义基础镜像。
2.MAINTAINER命令声明维护人员。这一行不是必需的,但最好有。
3.使用RUN命令在容器内运行git命令克隆todoapp代码。Git是在基础node镜像中已经安装好的。
4. 使用WORKDIR移动到git命令克隆的新目录中。这不仅会改变构建环境中的目录,最后一条WORKDIR命令还决定了从所构建的镜像启动容器时用户所处的默认目录。
5.运行node包管理器的安装命令(npm)。这将为应用程序设置依赖。将安装过程中输出的内容重定向到/dev/null中。
6.使用EXPOSE指定从所构建的镜像启动容器时应该监听8000端口。
7.CMD命令告诉Docker在容器启动时将运行哪条命令。
二、 构建一个Docker镜像:
[root@test1 todo]# docker build . ---- “.”是Dockerfile所在的路径,也可以替换为绝对路径。 Sending build context to Docker daemon 2.048 kB ---- Docker会上传docker build指定目录下的文件和目录。 Step 1/7 : FROM node ---> 8672b25e842c ---- Dockerfile中的每个命令会创建一个新镜像,此处为新镜像的ID。 Step 2/7 : MAINTAINER [email protected] ---> Running in be971bd42141 ---> 42c18ab41ef0 Removing intermediate container be971bd42141 Step 3/7 : RUN git clone -q https://github.com/docker-in-practice/todo.git ---> Running in 201520d3d57a …… Step 7/7 : CMD npm start ---> Running in 7d985aec88cf ---> fca66c0f0497 Removing intermediate container 7d985aec88cf Successfully built fca66c0f0497 ---- fca66c0f0497就是此次构建的最终镜像ID。
像“fca66c0f0497”这样的ID引用起来会很麻烦,可以为其打标签以方便引用:
[root@test1 todo]# docker tag fca66c0f0497 todoapp:v1
或者,也可以在构建时使用-t选项为镜像指定一个标签:
[root@test1 todo]# docker build -t="todoapp:v2" . --- 标签是唯一的
三、 运行一个Docker容器:
通过以下命令运行一个Docker镜像:
[root@test1 todo]# docker run -p 8000:8000 --name example1 todoapp:v1 > [email protected] prestart /todo > make all npm install npm WARN [email protected] No repository field. npm WARN [email protected] license should be a valid SPDX license expression audited 840 packages in 3.33s found 17 vulnerabilities (7 low, 9 high, 1 critical) run `npm audit fix` to fix them, or `npm audit` for details if [ ! -e dist/ ]; then mkdir dist; fi cp node_modules/react/dist/react.min.js dist/react.min.js LocalTodoApp.js:9: // TODO: default english version LocalTodoApp.js:84: fwdList = this.host.get('/TodoList#'+listId); // TODO fn+id sig TodoApp.js:117: // TODO scroll into view TodoApp.js:176: if (i>=list.length()) { i=list.length()-1; } // TODO .length local.html:30: <!-- TODO 2-split, 3-split --> model/TodoList.js:29: // TODO one op - repeated spec? long spec? view/Footer.jsx:61: // TODO: show the entry's metadata view/Footer.jsx:80: todoList.addObject(new TodoItem()); // TODO create default view/Header.jsx:25: // TODO list some meaningful header (apart from the id) > [email protected] start /todo > node TodoAppServer.js Swarm server started port 8000
-p标志将容器的8000端口映射到宿主机的8000端口上,前一个8000端口是宿主机上的端口。
--name标志为容器指定唯一的名称。
todoapp就是镜像名称。
此时,可以使用浏览器访问http://localhost:8000来查看这个应用程序了。
现在使用ctrl+c终止进程和容器。
# docker ps -a ---- 运行这个命令查看已经启动和停止的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd686168ae67 todoapp "npm start" 7 minutes ago Exited (0) 2 seconds ago example1
# docker start example1 ---- 重新启动容器,这时是在后台运行的
# docker ps ---- 仅显示正在运行的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd686168ae67 todoapp "npm start" 8 minutes ago Up 1 second 0.0.0.0:8000->8000/tcp example1
# docker diff example1 ---- docker diff命令显示了自镜像被实例化成一个容器以来哪些文件收到了影响 C /root ---- C指修改,D指删除,A指增加 C /root/.config/configstore C /root/.config/configstore/update-notifier-npm.json C /root/.npm C /root/.npm/_locks D /root/.npm/_logs A /root/.npm/_logs/2018-10-08T11_13_30_377Z-debug.log A /root/.npm/_logs/2018-10-08T11_13_50_405Z-debug.log C /root/.npm/anonymous-cli-metrics.json C /root/.npm/index-v5/34/8e/30c54cce758990bcd1b33114c4aa8a9e5a25c152ac39d9feab22b7e13e00 C /todo D /todo/.swarm A /todo/.swarm/_log D /todo/dist A /todo/dist/LocalTodoApp.app.js A /todo/dist/TodoApp.app.js A /todo/dist/react.min.js