Docker实践(2) -- 初识Docker

  • 关键的概念

image.png

    简单概括图中的内容,就是容器运行着由镜像定义的系统。镜像是由一个或多个层加上一些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


猜你喜欢

转载自blog.51cto.com/13568014/2298871
今日推荐