Docker与容器

Docker与容器

从19年初开始使用Docker到现在差不到两年了,感觉对于Docker的认识还停留在使用的阶段,各个知识点串联度不够,没有形成一个体系,因此打算抽出一些时间来系统学习Docker,以便在后续使用的时候更加得心应手。

写在前面

本篇首先学习Docker是什么,之后会剖析Docker和相关容器技术,以及它在DevOps等运用场景所带来的巨大便利,最后学习Docker在整个虚拟化领域中的技术定位。

虚拟技术

我们知道在主机时代比拼的是单个服务器的性能,如CPU主频和内存的强弱,而在云时代,最为看中的则是凭借虚拟化技术所构建的集群处理能力。从传统来看,虚拟化既可以通过硬件模拟来实现,也可以通过操作系统软件来实现。而容器技术则更优雅,它充分利用了操作系统本身已有的机制和特性,可以实现远超虚拟机的轻量级虚拟化。因此有人甚至将其称为“新一代的虚拟化”技术,并将基于容器打造的云平台亲切的称为“容器云”。

什么是Docker

Docker是基于Go语言开发的开源容器项目,它诞生于2013年。现在主流的操作系统包括Linux的各大发行版、macOS、Windows等都已经支持Docker。

Docker的构想是要实现“Build,Ship and Run Any App,Anywhere”,即通过对应用的封装(Packing)、分发(Distribution)、部署(Deployment)、运行(Runtime)生命周期进行管理,达到应用组件级别的“一次封装,到处运行”。请注意这里的应用组件可以是一个Web应用,一个编译环境,也可以是一套数据库平台服务,甚至是一个操作系统或集群。

基于Linux平台的多项开源技术,Docker提供了高效、敏捷和轻量级的容器方案,并支持部署到本地环境和多种主流云平台。可以说Docker首次为应用的开发、运行和部署提供了“一站式”的实用解决方案。

Linux容器技术

Linux容器技术,即Linux Containers(LXC)技术,IBM DeveloperWorks网站关于容器技术的描述十分准确:“容器有效的将单个操作系统管理的资源划分到孤立的组中,以更好的在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心CPU本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化和系统调用替换中的负载性。”

LXC经历了长期的演化,并集成到主流的Linux内核中,进而成为Linux系统轻量级容器技术的实施标准。

从Linux容器到Docker

在LXC的基础上,Docker进一步优化了容器的使用体验,使其变得大众化。首先,Docker提供了各种容器管理工具(如分发、版本、移植等),让用户无需关注底层的操作,更加简单明了的管理和使用容器:其次,Docker通过引入分层文件系统构建和高效的镜像机制,降低了迁移难度,极大的改善了用户体验,这使得用户操作Docker容器就像操作应用自身一样简单。

通俗的讲,我们可以将Docker容器理解为一种轻量级的沙盒(sandbox)。每个容器内运行着一个应用,不同的容器相互隔离,容器之间也可以通过网络互相通信。容器的创建和停止十分迅速,几乎跟创建和终止原生应用一致;此外容器自身对于系统资源的额外需求也十分有限,远远低于传统的虚拟机。在很多时候,直接将容器当做应用本身也没有任何问题。

使用Docker的原因

Docker容器虚拟化的好处

Docker项目的发起人,Docker公司的CTO认为Docker在正确的地点、正确的时间顺应了正确的趋势---如何正确地构建应用。

我们知道在云时代,开发者创建的应用必须要能很方便的在网络上传播,也就是说应用必须脱离底层物理硬件的限制;同时还必须是“任何时间任何地点”都可以获取到的。因此我们需要一种新型的创建分布式应用程序的方式,快速分发和部署,而这些正是Docker所能提供的最大优势。

举个简单的例子,假设用户视图采用最常见的LAMP(Linux+Apache+Mysql+PHP)组合来构建网站。那么按照传统的做法,首先需要安装Apache、Mysql+PHP以及它们各自所依赖的环境;之后分别对它们进行配置(包括创建合适的用户、配置参数等);经过大量的操作后,还需要进行功能测试,看看是否工作正常;如果不正常还需要进行调式追踪,这就意味着需要花费更多的时间和可能出现一些不可控的风险。如果应用数目变多,那么事情则会变得更加难以处理。

上面倒还好说,假如一旦需要服务器迁移,如从亚马逊迁移到其他云,那么往往需要对每个应用都进行重新部署和调式。这些都是重复性的“体力活”,极大的降低了用户的工作效率。究其根源,是这些应用直接运行在底层操作系统上,无法保证同一份应用在不同的环境中行为一致。

鉴于此种情况,Docker提供了一种更为“聪明”的方式,通过容器来打包应用、解耦应用和运行平台。这也就意味着迁移的时候,只需在新的服务器上启动需要的容器即可,根本不用去理会服务器是否是同一平台等问题。毫无疑问这极大的简化了部署的流程,降低了部署过程中出现问题的风险,最重要的是节省了大量的时间。

Docker在开发和运维中的优势

由于笔者做过运维开发,因此对于Docker在开发和运维中的优势是最能切身感受到的。对于运维开发人员来说,最希望的是一次创建或者配置某个环境后可以做到在任意时间,任意地点让应用能正常运行,而Docker做到了这一点,因此深受广大运维人员的青睐。

总结起来有以下几个方面的优势:

「(1)更快速的交付和部署。」 使用Docker,开发人员可以使用镜像来快速构建一套标准的开发环境;开发完成后,测试和运维人员可以直接使用完全相同的环境来部署代码。这样只要是开发测试过的代码,就可以确保在生产环境中无缝运行。Docker可以快速创建和删除容器,实现快速迭代、节约开发、测试、部署的大量时间,且整个过程全程可见,使团队更容易理解应用的创建和工作过程。

「(2)更高效的资源利用。」 运行Docker容器不需要额外的虚拟化管理程序( Virtual Machine Manager,VMM,以及Hypervisor)的支持,Docker是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。与传统虚拟机方式相比, Docker的性能要提高1~2个数量级。

「(3)更轻松的迁移和扩展。」 Docker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等,同时支持主流的操作系统发行版本。这种兼容性让用户可以在不同平台之间轻松地迁移应用。

「(4)更简单的更新管理。」 使用Dockerfile,只需要小小的配置修改,就能替代以往大量的更新工作。所有修改都以增量的方式被分发和更新,从而实现自动化且高效的容器管理。

Docker与虚拟机比较

Docker作为一种轻量级的虚拟方式,经常用来和传统的虚拟机方式进行对比,这是一个老生常谈的话题,笔者就选择其中的4点进行介绍:

(1)Docker容器很快,启动和停止可以在秒级实现,而传统的虚拟机则少至几分钟,长则半个小时;

(2)Docker容器对于系统资源的需求很少,一台主机可以同时运行上千个Docker容器,据说在IBM服务器上已经实现了同时运行一万个容器实例的可能;但是一台主机最多只能运行8个传统的虚拟机(这已经是性能不错的主机了,笔者电脑似乎运行3个就到头了);

(3)Docker借鉴了Git的设计理念来方便用户获取、分发和更新应用镜像,存储复用,增量更新;

(4)Docker通过Dockerfile支持灵活的自动化创建和部署机制,以提高工作效率,并标准化流程。

关于Docker和传统虚拟机技术的对比,可以看如下表格:

特性

容器

虚拟机

启动速度

秒级

分钟级

性能

接近原生

较差

内存代价

较小

较多

硬盘使用

MB级别

GB级别

运行密度

单机支持上千个容器

一般几十个

隔离性

安全隔离

完全隔离

迁移性

优秀

一般

Docker容器除了运行其中的应用外,基本不消耗额外的系统资源,这样在保证应用性能的同时可以减少系统的开销。

传统的虚拟机如果想运行N个不同的应用,就需要启动N个虚拟机,因为开发者需要为每个虚拟机单独分配独占的内存、磁盘等资源;Docker只需启动N个隔离的容器,然后将应用放进容器即可,这样使得应用可以获得接近于原生的运行性能。

这里需要着重提一下Docker的隔离性,我们知道传统的虚拟机方式采用的是相对封闭的隔离,即操作系统层面是不互通的;而Docker则利用了Linux系统上的多种防护技术实现了严格的隔离,且可以整合众多安全工具。

Docker虚拟机也称轻量级虚拟机,原因在于这些容器中所运行的Linux系统并不是一个独立完整的Linux系统,这些容器其实是共用了一个Linux内核,也就是Docker系统为它们提供的Linux内核。

Docker与虚拟化

虚拟化技术在各个行业都有,在计算机领域一般是指计算虚拟化或者服务虚拟化。这里援引维基百科的解释:

  • 虚拟化:在计算机技术中,虚拟化是一种资源管理技术,是将计算机

也就是说,虚拟化的核心是对资源进行抽象,其目的是为了在同一个主机上同时运行多个系统或者应用,进而提高系统资源的利用率,同时能降低成本,便于管理和带来容错容灾功能。

一般来说,虚拟化技术分为硬件虚拟化和软件虚拟化,其中基于硬件的虚拟化技术不多,如网卡中的单根多IO虚拟化,这种比较深奥,笔者觉得目前还没有到学习它的必要;而基于软件的虚拟化技术则是日常使用最多的,它根据软件虚拟化对象所在的层次,可以划分为应用虚拟化和平台虚拟化(通常所说的虚拟机技术指的就是这个)。

应用虚拟化一般是一些模拟设备或者诸如Wine这样的软件;平台虚拟化可以细分为几个子类:「(1)完全虚拟化。」 虚拟机模拟完整的底层硬件环境和特权指令的执行过程,客户端操作系统无须进行修改。如VMware Workstation,VirtualBox,QEMU等。

「(2)硬件辅助虚拟化。」 利用硬件(主要是CPU)辅助支持(目前x86体系结构上可用的硬件辅助虚拟化技术包括Intel-VT和AMD-V)处理敏感指令来实现完全虚拟化的功能,客户端操作系统无效修改,如VMware Workstation,Xen和KVM。

「(3)部分虚拟化。」 只针对部分硬件资源进行虚拟化,这样使得客户端操作系统需要进行修改。

「(4)超虚拟化。」 部分硬件接口以软件的形式提供为客户机操作系统,客户操作系统需要进行修改,如早期的Xen。

「(5)操作系统级虚拟化」。内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程。前面介绍的容器技术就属于这个范畴。

也就是说Docker以及其他的容器技术都属于操作系统级虚拟化这个范畴,操作系统虚拟化最大的特点就是不需要额外的supervisor支持。Docker虚拟化方式之所以有如此多的优势,这与操作系统虚拟化技术自身的设计和实现是分不开的:

从上图可以看到,左侧的传统的虚拟化方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。而右侧的Docker容器则是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因此占用资源非常少,属于轻量级。

Docker核心概念

前面都是一些比较基础的知识,学习它对于Docker的设计思想会有更深的理解。接下来开始学习Docker中的三大核心概念:镜像、容器和仓库,只有理解了这三个概念才能对Docker容器的整个生命周期有一个较为清晰的认识。

Docker镜像

Docker镜像(Image)类似于虚拟机镜像,如常见的iso格式的系统镜像,你可以将其理解为一个可读的模板,但是这又和iso镜像不同的是,通常Docker镜像中是比较纯净的,一个镜像可以包含一个基本的操作系统,里面仅仅是安装了Nginx应用程序,此时可以称其为一个Nginx镜像。

镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有镜像,用户甚至可以从网上下载已经做好的镜像,并直接使用。

Docker容器

Docker容器(Container)类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。

容器是是从镜像创建的应用运行实例,镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等,容器与容器之间是彼此隔离,互不可见的。

其实你完全可以将容器当做一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间)以及运行在其中的应用程序打包而成的盒子。

「请注意,镜像本身是只读的,容器从镜像启动的时候,会在镜像的最上层创建一个可写层。」

Docker仓库

Docker仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

但是有的时候我们会将Docker仓库和仓库注册服务器(Register)搞混淆,其实这两者是有区别的。仓库注册服务器是存放仓库的地方,其上面往往包括多个仓库。每一个仓库都集中存放某一类镜像,因此往往会包括多个镜像文件,通过使用不同的tag标签来进行区分。

如下图所示的注册服务器,它存放着Ubuntu和CentOS的仓库,而这两个仓库又各自存放着不同版本的操作系统:

根据所储存镜像的公开分享与否,Docker仓库可以分为公开仓库(public)和私有仓库(Private)两种形式。目前最大的公开仓库是官方提供的Docker Hub,里面存放着大量的镜像,国内的很多云服务商也提供了仓库的本地源,以便于我们在国内稳定下载。当然了,Docker也支持用户在本地网络内创建一个只能自己访问的私有仓库,这样用户不希望公开分享自己镜像的时候就可以这样操作。

当用户创建了自己的镜像后,可以使用push命令将其上传到指定的公有仓库或者是私有仓库,这样当用户在下次使用的时候就可以直接从仓库上将之前的镜像给pull下拉,这一点与Git非常相似,因为Docker利用仓库管理镜像的设计理念借鉴了Git代码仓库的管理理念。

安装Docker引擎

Docker引擎是使用Docker容器的核心组件,它可以运行在主流的操作系统上,这里以CentOS安装Docker引擎为例进行介绍。首先点击 这里,访问Docker的官网来查看获取Docker的方式以及Docker支持的平台类型:

目前Docker支持Docker引擎、Docker Hub和Docker Cloud等多种服务。其中Docker引擎包括支持在桌面系统或云平台安装Docker,以及为企业提供简单安全弹性的容器集群的编排和管理;Docker Hub则是官方提供的云托管服务,可以提供公有或者私有的镜像仓库;Docker Cloud是官方提供的容器云服务,可以完成容器的部署与管理,可以完整地支持容器化项目,同时还提供了CI、CD功能。Docker引擎目前分为社区版(CE)和企业版(EE),社区版包括大部分的核心功能,因此正常情况下使用社区版即可。

第一步,使用uname -a命令来查看当前CentOS的内核版本,Docker官方强调至少3.8以上,建议使用3.10及以上内核:

[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-1062.18.1.el7.x86_64 #1 SMP Tue Mar 17 23:49:17 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

第二步,使用yum update命令来升级yum源,请注意切勿在生产环境中升级yum源,因为更新命令会对软件包和内核升级。

第三步,安装需要的软件包,主要是yum-utils、device-mapper-persistent-data和lvm2包,其中yum-utils提供yum-config-manager功能,另外两个是devicemapper驱动依赖的,即便于后续支持devicemapper类型:

[root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

第四步,设置yum源,操作如下:

[root@localhost ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

第五步,查看所有仓库中所有的docker版本,并选择特定版本安装:

[root@localhost ~]# yum list docker-ce --showduplicates | sort -r

第六步,安装Docker,由于repo中默认只开启stable仓库,因此使用yum install docker-ce命令安装的Docker版本是最新版本,即

[root@localhost ~]# yum install docker-ce

第七步,启动Docker和添加为开启自启动:

[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker

第八步,检查安装是否成功(注意client和service这两部分都有,则说明安装成功),可以使用docker version命令来进行验证,如下所示:

请注意第七步和第八步的顺序不能颠倒,否则使用docker version命令时,只会显示Client的信息:

这样我们就完成了docker-ce-19.03.13版本的安装,可以看到Docker的安装还是较为简单的。

配置镜像下载地址

由于docker是在国外,因此镜像下载速度可能不太快,建议使用国内仓库,如DaoCloud。点击这里 DaoCloud,选择加速器:

然后将下面的代码直接放在shell环境中执行:

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

执行结果如下所示:

配置Docker服务

一般来说使用Docker的用户不一定都是root用户,因此为了避免每次使用Docker命令时都需要切换到root用户,可以将当前用户加入安装自动创建的docker用户组,使用的命令如下:

sudo usermod -aG docker USER_NAME

其中的USER_NAME就是当前用户名称,然后退出并重新登录即可。

当开发者在前面设置了docker开机自启动服务时,使用ps -aux|grep docker命令来查看docker是否正在运行时,结果如下所示:

[envythink@localhost ~]$ ps -aux|grep docker
root       1208  0.6  3.9 830056 73384 ?        Ssl  22:32   0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root       1802  0.0  0.0 112824   980 pts/0    S+   22:33   0:00 grep --color=auto docker

你会发现docker服务启动时,实际上调用了dockerd命令,它支持多种启动参数,所以开发者完全可以直接通过执行dockerd命令来启动docker服务,可以使用下面的命令来启动docker服务,开启Debug模式,并监听在本地的2376端口:

[envythink@localhost ~]$ dockerd -D -H tcp://127.0.0.1:2376

当然这些选项是可以写在/etc/docker/daemon.json文件中的,然后由dockerd服务启动时读取:

{
    "debug": true,
    "hosts": ["tcp://127.0.0.1:2376"]
}

对于CentOS和RedHat系统来说,服务通过systemd来管理,配置文件路径为/etc/systemd/system/docker.service.d/docker.conf,当配置发生更新后,需要通过systemctl命令老管理Docker服务,使用的命令如下:

[envythink@localhost ~]$ systemctl daemon-reload
[envythink@localhost ~]$ systemctl start docker.service

如果服务不能正常工作,可以查看Docker服务的日志文件来确定问题,可以使用journalctl -u docker.service命令来进行查看。同时每次重启Docker服务后,可以通过使用docker info命令来查看Docker信息,以确保服务已经正常运行。

小结

本篇学习了虚拟技术、Docker、容器技术、Docker的安装与三个核心概念:镜像、容器、仓库,在后面我们会围绕这三个核心概念来学习Docker的各种操作命令。

本文分享自微信公众号 - 啃饼思录(kbthinking),作者:i思录

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-10-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 浅谈Docker与容器

    Docker 对外宣称的是Build、Ship 和Run,Docker 要解决的核心问题就是快速地干这三件事情。它通过将运行环境和应用程序打包到一起,来解决部署...

    博文视点Broadview
  • Docker容器与容器云

    2.容器云:以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员提供用于构建、发布和运行分布式应用的平台

    硬核项目经理
  • Docker与容器化:2015这股趋势势不可挡

    像云这样重大的IT趋势已经用了一些年头来普及——尽管其中有过一些消长,但是它们向前的脚步不可阻挡。其他一些则似乎是出人意料地完全征服了企业世界。过去12个月,像...

    静一
  • Docker镜像与容器的常用操作

    国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如:

    踏歌行
  • Docker 容器与虚拟机 (VM) 总结

    总结:虚拟机更擅长于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户;而 Docker 通常用于隔离不同的应用 ,例如前端,后端以及数据...

    happyJared
  • .Net Core微服务入门全纪录(八)——Docker Compose与容器网络

    上一篇【.Net Core微服务入门全纪录(七)——IdentityServer4-授权认证】中使用IdentityServer4完成了鉴权中心的搭建,配合网关...

    xhznl
  • Docker端口映射与容器互联

    在前面我们已经掌握了单个容器的管理操作,但是在实际工作中很少是只运行一个容器,而更多的是需要运行多个容器进行协作的情况,因此就需要多个容器之间能够互相访问到对方...

    编程思录
  • docker 镜像与容器的导入导出操作实践

    公司有一台测试服务器,网速比较慢,特别是下载一些国外站点镜像的时候,而我本机则比较快,还有梯子,所以在思考一个问题;是否能在我本地把镜像下载下来,然后复制到测试...

    汤青松
  • 设置与查看Docker容器环境变量

    Huramkin
  • Docker进阶与实战(容器技术系列)

    本书由一个真正钻研容器技术的团队写作,他们不仅仅是在使用Docker,更多的是在探索容器的未来之路,希望把“代码与产品,理论与实践”完美结合。本书内容从Dock...

    用户3157710
  • docker容器与物理机之间拷贝文件的方法

    一般情况下,我们在启动容器的时候可以使用-v参数映射宿主机的文件或者目录到容器里,这样的话,在宿主机相关目录下的文件修改会自动在容器里生效。

    二狗不要跑
  • Docker的镜像与容器常见面试答疑及命令行操作

    要让Docker能够正常工作,需要的是容器和镜像,它们是Docker的地基。镜像是一个模板,是运行一个应用程序所需的文件。容器是由镜像创建的,用来执行隔离的应用...

    角落的白板报
  • 使用docker-compose打包镜像支持与外部docker容器通信的方法

    docker-compose打包的镜像默认网络访问为HOST-ONLY,如果需要与外部容器通信,解决思路就是改变其挂载网卡,增加配置如下:

    飞奔去旅行
  • 你知道Docker容器与主机之间的文件数据如何拷贝吗?

    eg:将主机/www/testFile目录拷贝到容器96f7f14e99ab的/www目录下。 docker cp /www/testFile 96f7f14e...

    软测小生
  • 聊一聊容器与Docker

    通俗一点的解释:容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比...

    叔牙
  • docker 容器

    容器是独立运行的一个或一组应用,以及他们的运行环境,对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。

    dogfei
  • Docker 容器

    -m 内存限额 --memory-swap :内存+swap的限额,不指定默认为内存2倍 如果参数是-1,代表没有限额

    用户5760343
  • Docker容器

    如果容器理解为独立运行的一个或一组应用,以及它们的运行态环境。 而虚拟机则为可理解为跑在上面的应用。

    yaohong
  • Docker容器

    Docker利用容器来开发、运行应用。容器是镜像创建的实例。它可以被启动、开始、停止、删除。每个容器都是 相互隔离的、保证安全的平台。类似安装系统的电脑实体。简...

    清风穆云

扫码关注云+社区

领取腾讯云代金券