查看“Docker:基础”的源代码
←
Docker:基础
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Docker]] == 环境配置的难题 == 软件开发最大的麻烦事之一,就是环境配置: : 用户必须保证两件事:操作系统的设置,各种库和组件的安装。只有它们都正确,软件才能运行。 通常在新旧模块整合,测试代码、运行代码的发布时,都需要花费大量的时间精力用于环境配置。经常遇到的问题就是相同的代码,更换到不同的环境中却不能运行。而如果新旧模块的环境不兼容,那就意味着更大的麻烦。 总而言之,为了避免在开发过程中过多地关注于系统环境配置,就需要一种能够将开发、测试、运行的环境进行发布共享的方式。 === 虚拟机 === 虚拟机(virtual machine)就是一种模拟软件(系统)环境的解决方案: : 它可以在一种操作系统里面运行另一种操作系统,而应用程序对此毫无感知。 而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。 常用的虚拟机:VMWare、VirtualBox等; 但虚拟机的缺点让它不可能成为开发环境的解决方案: * 资源占用多: *: 虚拟机会独占一部分内存和硬盘空间;且用于虚拟机运行的资源往往远大于应用所实际使用的资源。 * 冗余步骤多: *: 虚拟机是完整的操作系统,相当内容是应用不需要;且一些系统级别的操作步骤,往往无法跳过,比如用户登录。 * 启动慢: *: 由于是真实的操作系统,启动过程等同于操作系统,这对于应用环境是相当累赘的。 === Linux 容器 === 由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:'''Linux 容器'''(Linux Containers,缩写为 '''LXC'''): : Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。 对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。 Linux 容器相对于虚拟机的优势: * 资源占用少: *: 容器只占用需要的资源,且多个容器可以共享资源。 * 体积小: *: 只要包含用到的组件。 * 启动快: *: 容器中的应用是底层系统的一个进程,而不是虚拟机内部的进程,所以,启动容器相当于启动本机的一个进程。 总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。 == Docker == Docker 属于 '''Linux 容器的一种封装''',提供简单易用的容器使用接口: : Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。 总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。 * 容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。 Docker 是目前最流行的 Linux 容器解决方案。 用途: # 提供一次性的环境: #: 比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。 # 提供弹性的云服务: #: 因为 Docker 容器可以随开随关,很适合动态扩容和缩容。 # 组建微服务架构: #: 通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。 == 基础概念 == === image 文件 === Docker 把'''应用程序'''及其'''依赖''',打包在 image 文件里面,只有通过这个文件,才能生成 Docker 容器。 * image 本质是'''二进制文件''',可以看作是容器的模板。 * Docker 根据 image 文件生成容器的实例,同一个 image 文件,可以生成多个同时运行的容器实例。 实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。 : 举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。 为了方便共享,image 文件制作完成后,可以上传到网上的仓库。 : Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。 相关命令: <syntaxhighlight lang="bash" highlight=""> # 列出本机的所有 image 文件。 $ docker image ls # 删除 image 文件 $ docker image rm [imageName] </syntaxhighlight> === 容器文件 === image 文件生成的'''容器实例''',本身也是一个文件,称为'''容器文件'''。 * 一旦容器生成,就会同时存在两个文件: *# image 文件, *# 容器文件。 * 关闭容器并不会删除容器文件。 相关命令: <syntaxhighlight lang="bash" highlight=""> # 列出本机正在运行的容器 $ docker container ls # 列出本机所有容器,包括终止运行的容器 $ docker container ls --all # 删除已停止的容器文件 $ docker container rm [containerID] </syntaxhighlight> === Dockerfile === Dockerfile 是一个'''文本文件''',用来配置 image。 : 即:'''Docker 根据 Dockerfile 文件生成二进制的 image 文件'''。 == 制作 Docker 容器 == 以 koa-demos 项目为例,介绍怎么写 Dockerfile 文件,实现让用户在 Docker 容器里面运行 Koa 框架: * 准备:下载源码 *: <syntaxhighlight lang="bash" highlight=""> $ git clone https://github.com/ruanyf/koa-demos.git $ cd koa-demos </syntaxhighlight> === 编写 Dockerfile 文件 === # '''dockerignore''': #: 在项目的根目录下,新建一个文本文件 '''.dockerignore''',写入以下内容: #: <syntaxhighlight lang="bash" highlight=""> .git node_modules npm-debug.log </syntaxhighlight> #: 说明: #* 排除以上三个路径,不要打包进入 image 文件。 #** 如果没有路径要排除,可以不建此文件。 # '''Dockerfile''': #: 在项目的根目录下,新建一个文本文件 Dockerfile,写入以下内容: #: <syntaxhighlight lang="bash" highlight=""> FROM node:8.4 COPY . /app WORKDIR /app RUN npm install --registry=https://registry.npm.taobao.org EXPOSE 3000 </syntaxhighlight> #: 说明: #* “FROM node:8.4”:该 image 文件继承官方的 node image,冒号表示标签,这里标签是 8.4(即 8.4 版本的 node)。 #* “COPY . /app”:将当前目录下的所有文件(除了“.dockerignore”排除的路径),都拷贝进入 image 文件的 /app 目录。 #* “WORKDIR /app”:指定接下来的工作路径为 /app。 #* “RUN npm install”:在 /app 目录下,运行 npm install 命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。 #* “EXPOSE 3000”:将容器 3000 端口暴露出来, 允许外部连接这个端口。 === 创建 image 文件 === # '''docker image build''': #: 有了 Dockerfile 文件以后,就可以使用该命令创建 image 文件了: #: <syntaxhighlight lang="bash" highlight=""> $ docker image build -t koa-demo . # 或者 $ docker image build -t koa-demo:0.0.1 . </syntaxhighlight> #: 说明: #* “-t”:参数用来指定 image 文件的名字,后面还可以用冒号“:”指定标签; #** 如果不指定,默认的标签就是 latest; #* 最后的点“.”:表示 Dockerfile 文件所在的路径是当前路径。 # '''查看本地镜像''': #: 如果运行成功,就可以看到新生成的 image 文件 koa-demo 了: #: <syntaxhighlight lang="bash" highlight=""> $ docker image ls </syntaxhighlight> === 生成容器 === # '''docker container run''': #: 该命令会从 image 文件生成容器: #: <syntaxhighlight lang="bash" highlight=""> $ 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 </syntaxhighlight> #: 说明: #* “-p”参数:容器的 3000 端口映射到本机的 8000 端口。 #* “-it”参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。 #* “koa-demo:0.0.1”:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。 #* “/bin/bash”:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。 #: 如果一切正常,运行上面的命令以后,就会返回一个命令行提示符(容器内部的 Shell 提示符): #: <syntaxhighlight lang="bash" highlight=""> root@66d80f4aaf1e:/app# </syntaxhighlight> # 执行下面的命令: #: <syntaxhighlight lang="bash" highlight=""> root@66d80f4aaf1e:/app# node demos/01.js </syntaxhighlight> #: 这时,Koa 框架已经运行起来了。打开本机的浏览器,访问 http://127.0.0.1:8000 ,网页显示"Not Found",这是因为这个 demo 没有写路由。 如上,Node 进程运行在 Docker 容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)。 停止容器: # Ctrl + c 停止 Node 进程,然后按下 Ctrl + d (或者输入 exit)退出容器: #* 也可以用 docker container kill 终止容器运行: #*: <syntaxhighlight lang="bash" highlight=""> # 在本机的另一个终端窗口,查出容器的 ID $ docker container ls # 停止指定的容器运行 $ docker container kill [containerID] </syntaxhighlight> 删除容器文件: # 容器停止运行之后,并不会消失,用下面的命令删除容器文件: #: <syntaxhighlight lang="bash" highlight=""> # 查出容器的 ID $ docker container ls --all # 删除指定的容器文件 $ docker container rm [containerID] </syntaxhighlight> #* 也可以使用 docker container run 命令的 --rm 参数,在容器终止运行后自动删除容器文件。 #*: <syntaxhighlight lang="bash" highlight=""> $ docker container run --rm -p 8000:3000 -it koa-demo /bin/bash </syntaxhighlight> === CMD 命令 === 上一节的例子里面,容器启动以后,需要手动输入命令 node demos/01.js。 我们可以把这个命令写在 Dockerfile 里面,这样容器启动以后,这个命令就已经执行了,不用再手动输入了: : <syntaxhighlight lang="bash" highlight=""> FROM node:8.4 COPY . /app WORKDIR /app RUN npm install --registry=https://registry.npm.taobao.org EXPOSE 3000 CMD node demos/01.js </syntaxhighlight> : 说明:“CMD node demos/01.js”表示容器启动后自动执行“node demos/01.js”; 现在,启动容器可以使用下面的命令: <syntaxhighlight lang="bash" highlight=""> $ docker container run --rm -p 8000:3000 -it koa-demo:0.0.1 </syntaxhighlight> '''RUN 与 CMD 命令的区别?''' # RUN 命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件; # CMD 命令则是在容器启动后执行。 * 另外,一个 Dockerfile 可以包含多个 RUN 命令,但是只能有一个 CMD 命令。 * 指定了 CMD 命令以后,docker container run 命令就不能附加命令了(比如前面的 /bin/bash),否则它会覆盖 CMD 命令。 === 发布 image 文件 === 容器运行成功后,就确认了 image 文件的有效性。这时,我们就可以考虑把 image 文件分享到网上,让其他人使用。 # 首先,去 hub.docker.com 或 cloud.docker.com 注册一个账户。 # 用以下命令登录: #: <syntaxhighlight lang="bash" highlight=""> $ docker login </syntaxhighlight> # 为本地的 image 标注用户名和版本: #: <syntaxhighlight lang="bash" highlight=""> $ docker image tag [imageName] [username]/[repository]:[tag] # 实例 $ docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1 </syntaxhighlight> #* 也可以不标注用户名,重新构建一下 image 文件: #*: <syntaxhighlight lang="bash" highlight=""> $ docker image build -t [username]/[repository]:[tag] . </syntaxhighlight> # 发布 image 文件: #: <syntaxhighlight lang="bash" highlight=""> $ docker image push [username]/[repository]:[tag] </syntaxhighlight> 发布成功以后,登录 hub.docker.com 或 cloud.docker.com,就可以看到已经发布的 image 文件。 == 常用命令 == 除以上使用到的命令以外,还有几个 Docker 常用的命令: # '''docker container start''': #: 前面的 docker container run 命令是新建容器,每运行一次,就会新建一个容器。同样的命令运行两次,就会生成两个一模一样的容器文件。如果希望重复使用容器,就要使用 docker container start 命令,它用来'''启动已经生成、已经停止运行的容器文件'''。 #: <syntaxhighlight lang="bash" highlight=""> $ docker container start [containerID] </syntaxhighlight> # '''docker container stop''': #: 前面的 docker container kill 命令终止容器运行,相当于向容器里面的主进程发出 SIGKILL 信号。而 docker container stop 命令也是用来终止容器运行,相当于向容器里面的主进程发出 '''SIGTERM''' 信号,然后过一段时间再发出 '''SIGKILL''' 信号。 #: <syntaxhighlight lang="bash" highlight=""> $ docker container stop [containerID] </syntaxhighlight> #* 这两个信号的差别是,应用程序收到 SIGTERM 信号以后,可以自行进行收尾清理工作,但也可以不理会这个信号。如果收到 SIGKILL 信号,就会强行立即终止,那些正在进行中的操作会全部丢失。 # '''docker container logs''': #: docker container logs 命令用来查看 docker '''容器的输出''',即容器里面 Shell 的标准输出。 #* 如果 docker run 命令运行容器的时候,没有使用 -it 参数,就要用这个命令查看输出。 #: <syntaxhighlight lang="bash" highlight=""> $ docker container logs [containerID] </syntaxhighlight> # '''docker container exec''': #: docker container exec 命令用于'''进入一个正在运行的 docker 容器'''。 #* 如果 docker run 命令运行容器的时候,没有使用 -it 参数,就要用这个命令进入容器。一旦进入了容器,就可以在容器的 Shell 执行命令了。 #: <syntaxhighlight lang="bash" highlight=""> $ docker container exec -it [containerID] /bin/bash </syntaxhighlight> # '''docker container cp''': #: docker container cp 命令用于从'''正在运行'''的 Docker 容器里面,'''将文件拷贝到本机'''。下面是拷贝到当前目录的写法: #: <syntaxhighlight lang="bash" highlight=""> $ docker container cp [containID]:[/path/to/file] . </syntaxhighlight>
返回至“
Docker:基础
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息