在 Windows 上部署基于 Docker 的 Web 服务器环境 - 零基础入门

概述

本文将以尽可能通俗易懂、详尽粗浅的语言,主要面向零基础的研发工程师同学,介绍一下如何在 Windows 上搭建基于 Docker 的 Web 服务器环境,Docker 是目前非常热门的技术,它降低了大规模部署服务的难度,提升了集群部署升级的效率。其实它不仅能提升运维的效率,研发工程师使用 Docker 来进行本地服务器环境部署,进而进行 Web 开发也非常合适,用 Docker 来进行服务器环境部署有几个优势:

  1. 可以避免在开发用电脑中安装大量服务器软件 - 这些正常安装的服务器软件很有可能在开机时即启动,占用了大量系统资源,导致日常使用时内存变少,系统性能变差,而使用 Docker 来管理这些服务可以做到按需启动;
  2. 可以在一台电脑上,管理相同服务的多个不同版本 - 同一台电脑可能要进行多个不同应用的开发,而这些不同的应用可能会依赖同一个服务的不同版本,这通过常规的安装途径难以解决,而 Docker 的服务镜像能有效地解决这点,绝大多数 Docker 的服务镜像也提供了多个版本;
  3. 重复部署会非常简单 - 在团队协作中,同一个应用所依赖的服务器环境肯定是一样的,但是却难以避免团队中多个成员的重复部署和配置,而 Docker 可以将部署好的整个服务器环境打包成镜像,成员直接将镜像下载回来,即可将整个服务器环境运行起来,非常方便快捷。同样的,如果自己更换电脑,或者重装系统,原来的服务器环境也可以以最快速度恢复运行;
  4. 可以在 Windows 上运行一个轻量的 Linux 环境 - Windows 上的命令行工具 cmd.exe/PowerShell 和 Linux 有较大差异,而绝大多数开源开发工具都是基于Linux 的,尽管已经有了 Cygwin 和 MinGW 依然难以保证自己需要的工具已经被编译好可用,一套完整的 Linux 环境就能解决这个问题,而 Docker 本身就是基于 Linux,在 Windows 只需要一个 Linux 虚拟机就能解决问题,而且 Docker 的资源隔离策略也可以最大限度减少资源占用。

关于 Docker 原理的文章上 ATA 上已经很多,这篇 《Docker简介》 可以在阅读本文实战之前先了解一下基础概念,本文仅介绍 Docker 的安装和使用。

与 Linux 上运行 Docker 的区别

Docker 本是在 Linux 上使用的应用,后才移植到 Windows 和 Mac OS X 上,在 Windows 上运行 Docker 和在 Linux 唯一不同的问题在于,Docker 所依赖的 cgroups 进程和资源隔离策略在 Windows 并未实现,无法作为 Host 主机,所以依然需要一套在虚拟机中运行的 Linux 系统作为 Host 主机,这样才能运行别的 Container。

这样,Docker 的架构就有点变化了。

Docker 架构图

Docker架构

运行需求

在安装 Docker 之前,我们需要先检查电脑是否符合 Docker 的运行需求。

CPU 和操作系统必须都是 64 位的。

可以通过在“我的电脑”或者“此电脑”上点击鼠标右键,在点击“属性”,打开系统属性进行查看。

系统属性中查看是否支持 64 位

Windows系统

操作系统必须支持 VT 虚拟化技术。

Windows 8 以上系统可以通过“任务管理器”检查,直接在底部任务栏上点击鼠标右键即可打开。

Windows 7 系统需要去 微软官方 下载一份虚拟化检查工具,来检查自己的电脑是否支持虚拟化。

需要说明的是现在新的电脑绝大多数都已经支持了 VT 技术,如果检查该特性未启用,可能是在 BIOS 中尚未开启,在 BIOS 中找一下 Virtualization Technology 将其开启即可。

任务管理器中查看是否支持 VT 技术

任务管理器

安装

Docker 必须在 Linux 上运行,其实自己找一个虚拟机跑一个 Linux 把 Docker 套件下载下来之后都可以运行,而 Docker 官方已经为我们提供了一个非常方便的工具,叫做 Docker Toolbox 包含了 VirtualBox 虚拟机、一个 Docker Host Linux、以及 Docker Compose,直接下载后安装即可,截止本文发布 Docker Toolbox 的最新版本为 1.10.2。**补充:**因为 Amazon S3 国内访问补偿,因此我在淘云盘上也将当前最新版本分享了出来,请点击链接:http://yunpan.alibaba-inc.com/share/link/TH78GoG9v9

在安装过程中,因为 Kitematic 还不成熟,可以取消它的选项,作为服务器环境,只需要 Docker 的命令行工具就够了。

Docker 安装

Docker安装

#使用

启动

安装之后,开始菜单中就会多出三个菜单项,分别是 Git、VirtualBox、以及 Docker,我们需要使用这里的 Docker Quickstart Terminal,这是 Docker 使用的入口。

Docker 菜单

docker_menu

第一次启动 Docker,经过简单的初始化,Docker Client 便启动起来了,它在 Windows 上是使用 MinGW(全称是“Minimalist GNU for Windows”) 运行的一个小的环境,类似 Linux 系统,根据上面的架构图可知,我们对 Docker 的操作皆由它传递给 Docker Daemon,进而操作 Docker Container 的。

Docker 初始化

docker_init

进入 Docker Client Shell

docker_shell

进入 Docker Host [本章可略过不读]

本章与 Docker 使用无关,只是对架构图的实现进行一下说明,普通用户可略过不看。

刚才的 Docker Quickstart Terminal 启动后,其实依然在 Windows 中,但在架构图中我们可以看到有一层 Linux VM,通过下面的命令,就可以直接进入进去,在 Docker Quickstart Terminal 里执行的命令,在 Linux VM 中也同样可以执行,事实上,Docker Quickstart Terminal 对 Container 的操作,经过了一层 Wrapper 的网络通信,再交由 Linux VM 的 Docker Daemond 进行的。

$ docker-machine ssh default

Docker Machine

docker_machine

default 是虚拟机的名字,由 Docker Toolbox 创建,如果打开 Virtualbox,就可以看见它安静地躺在机器列表里。

Virtualbox

Virtualbox

下载镜像

镜像 Image 是 Docker 的第一个概念,Docker 不是虚拟机,而是 Application Container,镜像简单说就是 Container 的内容,Container 都是从镜像中启动,如果是服务器镜像,那可以用它运行起服务,如果是虚拟机镜像,那可以进入其中,进行普通 Linux 的操作,镜像是 Docker 最强大的地方。

所有的镜像,都存放在 Docker Hub 上,进入后可以看见有操作系统的 ubuntu,也有 redis、mysql 一类的服务,甚至还有 node 一类的应用执行环境,各种服务镜像包罗万象,各个服务官方也都在为 Docker 打包,在准备运行一个服务前先去 Docker Hub 上看看,说不定有惊喜。

为了说明方便,我们先使用操作系统包 fedora 来举例。首先使用 pull 命令,经过少许等待后,镜像就能下载下来了。

$ docker pull fedora

docker_pull

其实从 pull 命令上可以看出,Docker 的操作其实和 Git 非常类似,事实上 Docker 镜像就是建立在 Git 上的。

下载指定版本号的镜像

在实际使用过程中,我们经常对服务的版本号有严格要求,Docker 也提供了很简单的下载指定版本号的办法,在每个 Docker Hub 都可以看到不同版本的镜像都提供了很多个版本,而指定版本号其实非常简单,就是在 Image 名称后面,加上冒号,和版本号即可。

$ docker pull fedora:20

检查已经下载好的镜像

我们可以通过 images 命令,来检查镜像是否下载成功,从这里可以看到 fedora 的镜像已经下载成功了。

$ docker images

docker_images

从镜像启动 Container

启动 Fedora 的 Container 其实非常简单,下面的命令即可:

$ docker run -it fedora

这里参数的意思是:

  • -i 即使没有对接(Attach)成功,也保持标准输入接口开启;

  • -t 分配一个终端,没有它的话,就没有 shell 了。

除了这两个参数之外,还有两个映射参数非常常用,用于把 Host 里的资源,映射到 Container 里。

  • -v 目录映射,参数是 "[Host 目录]:[Container 目录]",映射后即可在 Container 里访问 Host 的某个目录,常用于自己的文件、或者代码映射到 Container 中,由 Container 中的服务执行;
  • -p 端口映射,参数是 "[Host 端口]:[Container 端口]",Container 因为是被完全隔离的,如果其中某个服务开启了某个端口,需要从 Client 访问到,则需要通过映射到 Host 上才能访问。

举个例子,我们有个静态的文件,需要被 Container 中的 node-static(一个 Node 编写的静态文件服务器)提供 Web service,则命令变成了(因为 fedora 中没有 node,所以这里换成了我编辑过的镜像 xuqingkuang/nodejs):

$ docker run /p 80:8000 -v /project:/www -it xuqingkuang/nodejs

这个例子,就是把 Container 里的 8000 端口,映射到 Host 的 80 端口,把当前目录下的 /Projects 目录映射到 Container 的 /www,然后 Chrome 透过 Docker 访问 static 提供的 Web 服务。

docker_service

从 Container 中退出

在 Container 的 Shell 中如果直接使用 exit 退出,或者从服务镜像启动的 Container 上按下 Ctrl + C,则会把 Container 停止掉,之前运行的服务也都会随之停止,对于绝大多数服务类型的这样做可能是比较合适的,但是对操作系统镜像,可能依然需要它在后台运行,在合适的时候再切换回去,这里有一个小技巧,是按下 Ctrl + P 键,这时看起来没有任何反应,再按下 Ctrl + Q 键即可 detach 当前的 Container。

这里又需要提到一个用于查看所有 Container 的小命令 - ps-n 参数是为了限制 Container 显示数量,可以看出,第一个 9c1e80 那个 Container 通过 exit 命令退出,它的状态已经变成了 Exited,而 832c07,通过 detach,它依然在后台运行着,状态是 Up。

$ docker ps -n=3

docker_attach

重启已经停止的 Container

每个 Container 变成 Exit 状态后,我们是否有办法重新运行它呢?答案是肯定的,通过 start 命令就可以重新启动它,但是重启后的 Container 是 detach 状态,我们需要通过 attach 命令重新连入 Container。

$ docker start [Container ID]

docker_start

提交对 Container 的修改到镜像中

从刚才的操作我们可以看出,每次通过镜像生成一个 Container 后,都会给它赋予一个独立的 Container ID,所有对 Container 的操作(增加文件、删除文件,安装程序等),都会应用到 Container 里,但不会对镜像产生任何影响,也就是说,如果下次再次从镜像重新 run 一个 Container,那对之前 Container 所做的改动,在新的 Container 中不会生效。

之前有提过 Docker 的高度可定制化,就是本章将阐述的内容,即将 Container 的改动应用到镜像中,这样下次重新运行 Container,或者换了一台电脑将镜像重新 pull 回来,之前的运行环境都能够直接复原。

大致流程上如下:

  1. 注册一个 Docker Hub 账号;
  2. 在自己的 Profile 页面中,Create Repository 建立一个新的镜像仓库(和 Git 很像);
  3. 在 Docker Quickstart Terminal 中通过 login 命令登录 Docker Hub
  4. 然后使用 commit 命令,将对 Container 的修改应用到刚才新建的 Repository,其实该 Repository 就是存放镜像的地方;
  5. 将更改后的镜像 pushDocker Hub 上。

我这儿已经有账号了,就直接从第三步起了,commit 之后可以注意一下返回的 digest,然后通过 images 就会发现,最后一次修改已经变成了新的 digest 了。

$ docker push

docker_push

结尾

看完本文后,运行起了自己的第一个 Docker 容器是否感到一阵激动,是否被 Docker 的便利性所折服?

但是这只是 Docker 的虚拟机用法,这样已经可以将您的服务器环境和操作系统隔离,但这样做会造成镜像越来越大,部署起来越来越慢,Docker 既然被称为“应用容器”,Docker Hub 上提供了大量的服务镜像,其实没打算让用户进入 Container 的 Shell 然后手工装服务器软件,Docker Hub 上的 Linux 发行版镜像,更多地是让用户体验一下该发行版,

那么如何使用才更加正确的呢?这里需要交代一个 Docker 理念,即“服务最小化、细分化”,最小化便于服务的更新升级,细分化降低服务间的耦合性,不会因为升级一个服务而重新更新整个镜像。

下一篇中,将介绍贯彻这两个理念所提供的两个工具:

  1. 负责自定义编译镜像的 Dockerfile;
  2. 能够将应用和多个服务整合起来,为应用提供服务的 Docker Compose。

如欲知更多内容,请参考下一篇《在 Windows 上部署基于 Docker 的 Web 服务器环境进阶 - Dockerfile 和 Docker Compose》

版权所有丨转载请注明出处:https://kxq.io/archives/在windows上部署基于docker的web服务器环境-零基础入门