docker 入门笔记

前言


前端工程师的折腾屎

Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源,Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)。

Docker 的应用场景

  • Web 应用的自动化打包和发布
    - 自动话测试和持续集成、发布
    - 在服务型环境中部署和调整数据库或其他的后台应用
    - 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境

环境配置的难题


软件开发最大的麻烦事之一,就是环境配置。用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来?
用户必须保证两件事:操作系统的设置,各种库和组件的安装。只有它们都正确,软件才能运行。举例来说,安装一个 Python 应用,计算机必须有 Python 引擎,还必须有各种依赖,可能还要配置环境变量。
如果某些老旧的模块与当前环境不兼容,那就麻烦了。开发者常常会说:”它在我的机器可以跑了”(It works on my machine),言下之意就是,其他机器很可能跑不了。
环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。

在教程里面看到这段话,觉得实在是无法把问题说的更加清楚。。。

虚拟机


虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。虽然用户可以通过虚拟机还原软件的原始环境。但是,这个方案有几个缺点。

(1)资源占用多

虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行。

(2)冗余步骤多

虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。

(3)启动慢

启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用程序才能真正运行。

Linux 容器


由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。

Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

由于容器是进程级别的,相比虚拟机有很多优势。

(1)启动快

容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。

(2)资源占用少

容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。

(3)体积小

容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。

Docker 是什么


Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

Docker 的用途


Docker 的主要用途,目前有三大类。

(1)提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。

(2)提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。

(3)组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。

Docker 架构


Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看着一个代码控制中心,用来保存镜像。

Docker 的安装


好啦,终于到我踩坑的地方了。文档教程里面使用的不是 Windows 系统,而且我的 Windows 系统是家庭版。

为了把这个事情说明白,我把安装好的卸载了(ps: 其实是我安装了太久,记不太清楚具体情况了)

Docker 发布了 Docker for Windows 的正式版,但是这个安装的前提条件是系统需要是 Windows 10 Pro。家庭版的话可以通过安装 Docker Toolbox 来学习 docker

Windows 10 家庭版双击安装,稍等片刻桌面会出现以下三个图标。

此时,我们在命令行里面运行下面的命令,验证是否安装成功。

1
2
3
$ docker version
# 或者
$ docker info

Docker 三剑客之 Docker Machine


image 文件


Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

image 是二进制文件。实际开发中,一个 image 文件通常通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。

1
2
3
4
5
# 列出本机所有的 image 文件
$ docker image ls

# 删除 image 文件
$ docker image rm [imageName]

特别提示

如果这个命令运行不通的话

1
2
$ docker image ls
error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/images/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.

可以使用以下命令

1
$ docker-machine ssh

image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零制作。

为了方便共享,image 文件制作完成以后,可以上传到网络上的仓库。Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。此外,出售自己制作的 image 文件也是可以的。

实例:Hello World


下面,我们通过最简单的 image 文件“hello world”,感受以下 Docker。
这个地方其实有一个坑