带着心中的一点疑惑,让我们一起来学习Docker吧。在没有虚拟化技术的原始时代,我们仔细想想。在没有计算虚拟化技术的“古老”时代,如果我们要部署一个应用程序(Application),一般的步骤是什么?第一步肯定是先准备一台物理服务器,然后在物理服务器上安装操作系统(OperatingSystem)。操作系统可用后,我们将在操作系统上安装并运行我们的应用程序。这个过程可以用如下图来表示:物理服务器部署应用图那么,这种做法有什么问题呢?其实在物理机上部署应用有以下缺点:部署速度很慢:因为我们要先准备好硬件服务器,然后安装操作系统,再部署应用,而且应用还有很多依赖软件,所以这个过程比较慢。成本很高:主要原因是物理服务器的成本太高。即使部署一个简单的应用程序,也需要服务器。资源浪费:如果应用过于简单,很容易浪费CPU、内存等硬件资源。迁移扩容速度太慢:如果需要迁移或扩容应用,必须准备其他物理服务器。该过程繁琐且缓慢。那么有什么办法可以解决这些问题呢?答案是虚拟化技术。在使用虚拟机部署应用程序的时代,什么是虚拟化技术?说到计算机虚拟化技术,我们马上就会想到虚拟机。虚拟机允许我们在物理计算机上模拟多台机器。简单理解,Virtualization技术就是通过中间的虚拟软件层Hypervisor,将一台物理计算机上的CPU、内存等硬件资源隔离开来,虚拟出多个虚拟服务器。这样一台物理服务器就可以安装多个应用程序,实现资源利用。且多个应用相互隔离,如下图:虚拟机上的应用部署图虚拟机的优点是可以将资源分配给不同的虚拟机,最大限度的利用硬件资源,直接在一台物理机上部署应用,虚拟机更容易扩展应用程序。云服务:通过虚拟机将不同的物理资源虚拟化,可以快速构建云服务。虚拟机的缺点虚拟机的缺点是对物理服务器资源的消耗。我们在物理服务器上创建虚拟机时,需要虚拟出一套硬件,并在上面运行完整的操作系统。每个虚拟机占用大量的服务器资源。什么是码头工人?与虚拟机的笨重相比,Docker更加轻量,不会占用过多的系统资源。Docker是使用流行的Golang语言开发的。其技术核心是Linux内核中的Cgroup、Namespace和类AUFS的UnionFS技术。这些技术在Linux内核中已经存在多年,所以严格来说Docker并不是一项完全创新的技术。Docker通过这些Linux底层技术对Linux进程进行封装和隔离,被隔离的进程也称为容器,完全独立于宿主进程。因此,Docker是容器技术的一种实现,也是一种操作系统层面的虚拟化,与通过一套硬件在虚拟机上安装操作系统是完全不同的。docker容器与系统关系示意图Docker与虚拟机对比Docker在操作系统进程层面是隔离的,而虚拟机是在物理资源层面隔离的。两者完全不同。此外,我们还可以通过下面的对比,了解两者的根本区别。容器和虚拟机的对比【来自《Docker-从入门到实践》】从上面容器和虚拟机的对比,我们明白了容器技术的优势。容器解决了开发和生产环境的问题。开发环境和生产环境体现了开发人员和运维人员之间的矛盾。或许我们经常听到开发人员对运维人员说这样一句话:“在我的电脑上运行的很好,但是到了你的时候出了问题,一定是你的问题”,而运维人员却认为是开发者的问题,开发者需要在本地安装各种测试环境,所以项目开发的软件和依赖越多,安装的环境就越复杂。同样,运维人员需要为开发者开发的项目提供生产环境.运维人员除了要处理好软件之间的依赖关系,还需要考虑安装的软件和硬件之间的兼容性问题,仅此而已,所以我们经常看到开发和运维互相推诿,这个问题怎么解决呢?容器是一个很好的解决方案,容器可以成为开发运维之间的沟通语言ce,因为容器就像一个容器,提供一个软件运行的最小环境,把应用和它需要的环境打包成一个镜像,方便开发和运维之间的沟通和传递。Docker的版本Docker分为两个版本:社区版(CE)和企业版(EE)。社区版可以免费使用,企业版需要付费使用。版。DockerCE有3个更新通道,分别是stable、test和nightly。stable为稳定版本,test为测试后的预发布版本,nightly为开发中下个版本正式发布的版本。我们可以根据自己的需要定制。下载并安装。如何安装Docker?好了,通过前面的介绍,我们应该对Docker有了一个初步的了解,下面让我们开始Docker的学习之旅吧。学习Docker的第一步是从安装Docker运行环境开始。我们以安装Docker的社区版(CE)为例。Docker社区版提供MacOS、MicrosoftWindows、Linux(Centos、Ubuntu、Fedora、Debian)等操作系统的安装包,也支持在AWSCloud等云服务器上安装。在Windows系统上安装DockerDesktopforWindowsDocker提供了Windows的桌面应用管理安装包(DockerDesktopforWindows),但是对系统有如下要求:必须是64位的Windows10专业版、企业版、教育版,构建于15063或更高版本,在BIOS中启用虚拟化。通常,默认情况下启用虚拟化。至少4GB内存。CPU支持SLAT。如果操作系统满足以上要求,可以直接下载安装包直接安装。安装成功后,Docker不会自动启动。我们需要自己启动它。我们可以在开始菜单中找到Docker,如下图,点击开始即可启动。DockerToolbox如果系统不满足以上要求,比如你使用的是Windows7操作系统,这时候想要使用Docker就需要使用DockerToolbox。DockerToolbox是Docker提供的用于在较旧的MacOS和Windows系统上安装Docker环境的工具集。DockerToolbox包括docker-cli(我们在终端中使用的docker命令行工具)、docker-compose(多容器管理工具)、docker-mecahine、VirtualBox(虚拟机)、Kitematic(dockerGUI管理工具)。本质上是使用DockerToolbox来安装Docker环境,其实就是在VirtualBox中创建一个Linux虚拟机,并在虚拟机上安装Docker。此外,WindowsHyper-V模块(Windows操作系统的虚拟化技术)将在安装过程中启用。这里需要注意的一点是,如果启用了Hyper-V,VirtualBox将不再生效。在MacOS上的安装与Windows操作系统相同。Docker还为MacOS提供了桌面应用程序(DockerDesktopforMac)。比较简单。从docker官网下载Dokcer.dmg进行安装,打开Docker.dmg,如下图提示:直接拖动Docker图标即可完成安装。对于较老的MacOS操作系统,也可以像Windows一样使用DockerToolbox,具体可以参考上面的介绍。MacOS安装完成后,在Application中找到Docker图标,双击打开启动Docker,如下:在Linux操作系统上安装Linux,主要以Centos7为例,其他Linux系统分发版本,如Ubuntu、Debian、Fedora等,可以自行查看Docker的官方文档。删除旧版本的docker可能有些Linux预装了Docker,但是一般版本都比较旧,所以可以执行下面的代码来删除旧版本的Docker。$sudonfremovedocker\docker-client\docker-client-latest\docker-common\docker-latest\docker-latest-logrotate\docker-logrotate\docker-selinux\docker-engine-selinux\docker-engine复制代码指定安装version$sudoyum-config-manager\--add-repo\https://download.docker.com/linux/centos/docker-ce.repo复制代码使用yuminstalldocker$sudoyuminstalldocker-cedocker-ce-clicontainerd.iocopycodestartdockerserver#启动dockerdaemon$sudosystemctlstartdocker复制代码测试是否安装成功通过以上方法安装完Docker后,我们可以通过以下方法检查是否安装成功。打印docker版本#打印docker版本$dockerversion复制代码拉取镜像并运行容器#拉取hello-world镜像dockerpullhello-world#使用hello-world运行一个容器dockerrunhello-world复制代码运行上面的命令后,如果有如下如果出现如图所示的输出,则表示安装成功。Docker的基本概念是镜像(Image)、容器(Container)和仓库(Repository)。这三个是docker中最基本最核心的概念。掌握和理解这三个概念是学习docker的关键。镜像(Image)什么是Docker镜像?Docker本质上是运行在Linux操作系统上的应用程序,Linux操作系统分为内核空间和用户空间。无论是Centos还是Ubuntu,都是在启动内核后通过挂载Root文件系统来提供用户空间。Docker镜像是一个根文件系统。Docker镜像是一个特殊的文件系统,提供容器运行所需的程序、库、资源、配置等文件,还包含一些为运行时准备的配置参数(如匿名卷、环境变量、用户、ETC。)。图像是一个静态概念,不包含任何动态数据,构建后其内容不会发生变化。下面的命令是对镜像的一些基本操作,如下:查看镜像列表#列出所有镜像下面的命令还可以查看本地的镜像列表,写法比较简洁。#列出所有镜像dockerimages复制代码从仓库拉取镜像我们已经演示了使用dockerpull命令拉取hello-world镜像,当然使用dockerimagepull命令也是一样的。一般情况下,镜像默认是从DockerHub中拉取的。DockerHub是Docker官方提供的镜像仓库服务(DockerRegistry)。有大量官方或第三方的图片供我们使用。比如我们可以在命令行输入如下命令直接拉取一个Centos镜像:dockerpullcentoscopycodedockerpull命令的完整写法如下:dockerpull[option][DockerRegistryaddress[:portnumber]/]warehousename[:label]copycode拉取一个镜像,需要指定DockerRegistry的地址和端口号。默认是DockerHub。您还需要指定仓库名称和标签。仓库名和标签唯一确定一张图片,标签可以省略。如果省略,则默认使用latest作为标签名称。另外,仓库名由作者名和软件名组成。那么,上面我们使用的是centos,因为省略了作者名,而作者名library表示的是Docker官方镜像,所以上面的命令相当于:dockerpulllibrary/centos:latest复制代码因此,如果你拉一个非官方的第三方image,需要指定完整的仓库名,如下:dockerpullmysql/mysql-server:latest复制运行镜像的代码使用dockerrun命令,可以通过镜像创建容器,如下:dockerrun-itcentos/bin/bash复制删除镜像的代码当本地有一些镜像我们不需要的时候,我们也可以删除镜像以节省存储空间,但是需要注意的是如果使用该镜像创建的容器不是已删除,图像不允许被删除。#image_name表示镜像名称,image_id表示镜像iddockereimagermimage_name/image_id复制代码删除镜像的快捷命令:dockerrmiimage_name/image_id复制代码OK,这里简单介绍一下Docker镜像的相关知识,有机会的话,我们会单独写一篇文章来讲,尤其是构建Docker镜像的相关知识,很有必要深入研究一下。容器(Container)Docker的镜像是生成容器的模板。图像是分层的。镜像和容器的关系就是面向对象编程中类和对象的关系。我们定义每一个类,然后使用类创建一个对象,对应到Docker的使用,就是构建每一个镜像,然后使用镜像创建我们需要的容器。有两种方法可以启动和停止容器。一个是我们已经介绍过的。使用dockerrun命令通过镜像创建一个全新的容器,如下:dockerrunhello-world复制代码另一种启动容器的方式是启动一个已经停止运行的容器:#container_id表示容器的iddockerstartcontainer_id复制代码要停止正在运行的容器,可以使用dockercontainerstop或dockerstop命令,如下:#container_id表示容器的iddockerstopcontainer_id复制代码查看所有容器如果想查看本地所有容器,可以使用docker容器ls命令:#查看所有容器dockercontainerls复制代码查看所有容器也有简洁的写法,如下:#查看所有容器dockerps复制代码删除容器我们也可以使用docker容器rm命令,或者dockerrm命令的简洁写法删除容器,但是不允许删除正在运行的容器,所以如果要删除,必须先停止容器。#container_id表示容器id,通过dockerps可以看到容器id$dockerrmcontainer_id复制代码当我们需要批量删除所有容器时,可以使用如下命令:#删除所有容器dockerrm$(dockerps-q)复制代码#删除所有退出的容器dockercontainerprune将代码复制到容器中#进入容器,container_id表示容器id,command表示linux命令,比如/bin/bashdockerexec-itcontainer_idcommand复制代码仓库(Repository)在前面的例子中,我们使用了两个构建图像的方法。构建完成后,可以在本地运行镜像生成容器,但是如果在更多的服务器上运行镜像呢?显然,这时候我们需要一个服务,让我们可以集中存储和分发图片,就像Github允许我们自己存储和分发代码一样。DockerHub是Docker提供的官方DockerRegistry,用于存储和分发镜像。它也是默认注册表。它的URL是https://hub.docker.com。之前我们使用dockerpull命令从DockerHub拉取镜像。DockerHub有许多其他开发者提供的官方或其他高质量镜像供我们使用。当然,如果我们要将自己构建的镜像上传到DockerHub,我们需要在DockerHub上注册一个账号,然后将我们在本地构建的镜像发送到DockerHub的仓库中。DockerRegistry包含很多仓库,每个仓库对应多个标签,不同的标签对应一个软件的不同版本。Docker的组成和结构安装并启动Docker后,我们就可以使用docker命令在命令行中对docker进行操作了。比如我们使用如下命令打印docker的版本信息。dockerverion复制代码结果如下:从上图我们可以看到显示了两部分信息:Client和Server。这是因为Docker和大多数服务端软件(如MySQL)一样,采用C/S架构模式,即通过客户端调用服务端,而我们正好是服务端和客户端在同一台机器上..因此,我们可以用下图来表示Docker的架构,DOCKER_HOST是Docker服务器,Clinet是我们在命令中使用的docker命令。DockerEnginedockerserver为客户端提供容器、镜像、数据卷、网络管理等功能。其实这些功能都是由DockerEngine实现的。dockerd:服务器守护进程。客户端dockerCli:命令行接口RESTAPI:除了cli命令行接口,还可以通过RESTAPI调用docker。下面是DockerEngine的示例图:总结作为开发者,总是需要安装各种各样的开发环境。另外,一个技术团队在开发一个项目的过程中,往往需要统一开发环境,这可能会避免一些环境不一致带来的问题。虽然使用虚拟机可以解决以上问题,但是虚拟机过于笨重,对宿主机的资源消耗太大。Docker作为一种轻量级的容器技术,可以轻松解决上述问题,让开发环境的安装和应用的部署变得非常简单,而且使用Docker比在虚拟机中安装操作系统要简单的多。
