本文作为Docker基础系列第一篇文章,将详细阐述和分析三个问题:Docker是什么?为什么要用Docker?如何快速掌握Docker技术?
本系列文章中Docker的用法演示是基于CentOS7进行,因此假设读者已经掌握了初步的Linux知识,如果你对Linux最基本的常用命令及操作还不太熟悉,请参考我之前写的Linux入门系列教程。
用简单的一句话来概况:Docker就是一种容器虚拟化技术。
要了解Docker为什么会出现,它解决了什么样的问题,那就要回顾下虚拟化技术及Docker的发展历程。
ps:相信大家如果安装或使用过虚拟机VMware,或许你已经遇到过虚拟化技术的问题。正如我的Linux入门系列文章中的“linux入门系列1–环境准备及linux安装”中的3.2.1提到,你可能会遇到***“此主机至此Interl VT-x,但Interl VT-x处于禁用状态“***这个问题,如果要在VMware中安装Linux,那就要在BIOS中开启虚拟化支持。
虚拟化技术是一个通用的概念,不同领域可以有不同的理解。而在计算机领域中通常是指计算虚拟化或服务器虚拟化,它的核心是对资源进行抽象,以能在同一个主机上同时运行多个系统或软件应用为目标,从而提高服务器系统资源的利用率,降低成本,方便对应用的生命周期进行管理。
虚拟化技术分类总体上分为2大类:基于硬件的虚拟化***和***基于软件的虚拟化。
真正意义上基于硬件的虚拟化并不多见,而基于软件的虚拟化从对象所在的层次,又可以分为***应用虚拟化***和***平台虚拟化***。应用虚拟化一般是指通过软件去模拟设备,而我们通常所说的虚拟化技术大多数情况下指的是平台虚拟化技术。
平台虚拟化又可以细分为以下几类:
虚拟机模拟完的底层硬件环境和特权指的执行过程,客户操作系统无须进行修改。比如:VirtualBox、VMware Workstation
利用硬件主要是CPU来辅助支持处理敏感指令来实现完全虚拟化的功能,客户操作系统无须修改 。目前86体系结构上可用的硬件辅助虚拟化技术包括Intel-VT和AMD-V。 比如:VMware Workstation、Xen、KVM
只针对部分硬件资源进行虚拟化,客户操作系统需要进行修改。
部分硬件接口以软件的形式提供给客户机操作系统, 客户操作系统需要进行修改。
内核通过创建多个虚拟的操作系统实例(包括内核和库)来隔离不同的进程。我们通常所说的容器相关技术属于此分类,而Docker则是这众多容器技术中的一种。
如果要说Docker与虚拟化技术之间的关系,我认为可以概括为:虚拟化技术经过发展,从以前通过硬件层面来实现虚拟化的传统方式,逐步演变为当今流行的基于操作系统层面的容器化方式。而Docker则作为容器化技术的佼佼者脱颖而出。
Docker是基于Go语言实现的开源容器项目,Docker项目已加入Linux基金会,并遵循Apache协议, 全部开源代码均在https://github.com/docker项目仓库进行维护。
正如官方网站所说,Docker的理念就是***“Build Ship and Run Any App, Anywhere”***,即通过对应用的封装( Packaging )、分发( Distribution )、部署( Deployment )、运行( Runtime )生命周期进行管理,简单说就是***一次封装 ,到处运行***。
Docker目前已得到各大主流操作系统的支持,包括Linux各大发行版、Windows、MacOS等均可以安装使用。同时各大云服务提供商如IBM、Amazon、Azure等云平台均提供对Docker的集成支持。
那么Docker为什么会发展的如此迅速呢?
正如Docker创始人说的,Docker只是在正确的时间和正确的地点做了正确的事情,它的出现并非偶然,它其实也是站在了前人LXC的肩膀上发展而来。LXC(Linux Containers)也就是平常说的Linux容器技术,对于LXC更多细节就不多说了,简单说就是LXC经过长期的发展,踩了很多坑,然后被集成到了主流Linux的内容中,正是这样才为Docker的诞生铺平了前期的道路。
Docker在LXC的基础上,进一步优化了容器的使用体验,才使得容器化技术得到普及。比如它提供了各种容器管理工具来实现应用的分发、版本移植等,让用户无需关注底层操作;同时也引入分层文件系统和高效的镜像机制,极大的降低迁移难度。早期Docker是直接基于LXC的,到0.9版本之后开发了libcon-tainer项目作为更广泛的容器驱动实现,从而替换掉了LXC的实现,试图让容器的支持不再局限于Linux操作系统,而是更安全、更开放、更具扩展性。
正是基于Linux平台上的多项开源技术,Docker提供了高效、敏捷和轻量级的容器方案,并支持部署到本地环境和多种主流云平台。可以说Docker首次为应用的开发 、运行和部署提供了“ 一站式”的实用解决方案。
Docker包含三大核心概念:镜像、容器、仓库,基础部分功能都是围绕他们进行展开,因此先有个简单的印象即可。
可以简单理解为一个只读的模板或者应用程序及其环境的打包,后边的容器就是通过它来进行创建。它类似于虚拟机镜像,如果你有面向对象的编程经验,也可以把它理解为一个实体类(Class)。
简单理解为一个沙盒,用来运行和隔离我们开发的应用程序。你可以理解为正在运行的一个虚拟机,也可以理解为通过实体类Clss创建的一个对象。镜像是静态的,容器是动态的。
仓库就是集成存放镜像的地方,Docker仓库类似于代码仓库,如果你有Git和Maven的使用经验,那就很好理解了。
官方提供的仓库为Docker Hub,但有时候国外网速不太理想,因此国内云厂商如阿里云、网易云等也提供了镜像仓库的本地源,当然也可以自己搭建私有仓库。
要搞清楚我们为什么要用Docker,那就来先看看Docker都能干些啥?
正如Docker的理念宣言:一次打包,处处运行。由于Docker镜像是将我们开发的应用程序和他运行所需的环境一起打包,它带来的好处非常明显,尤其是快速部署和分发能力。
举个简单的例子,假设我们之前开发了某个软件部署在了某一台服务器上,但是因为种种原因,我们希望把该软件部署到另外一台服务器上。通常情况下我们需要怎么做呢?我们需要登录到新的服务器上,按照之前的方法重复部署一次运行环境,然后运行观察结果,还担心环境的变化带来未知的影响。那如果是用Docker会怎么样呢?我们只需要把相应的镜像下载下来然后运行起来即可。快速且省心。
还记得前面系列文章的LNMP环境搭建吗?“linux入门系列20–Web服务之LNMP架构实战”,是不是感觉非常麻烦呢?这个过程少说也得半小时,如果我们换为Docker进行部署的话,也就分分钟就可以搞定。后文会演示采用Docker的方式来部署LNMP,到时候会有一个非常直观的对比,相信你一定会爱上Docker。
采用Docker可以做到一次打包,处处运行。
由于镜像中已经包含了环境,因此不会存在开发人员本地开发运行没问题,但是交给运维人员运行就有问题的情况。同时它使得迁移、扩展和更新管理变得更加容易,极大减少了重复劳动、有效解放了运维人员。
容器化技术在性能上完胜虚拟机。
Docker容器除了运行其中的应用外,基本不消耗额外的系统资源,在保证应用性能的同时,尽量减小系统开销。
传统虚拟机方式运行N个不同的应用就要启用N个虚拟机,每个虚拟机需要单独分配独占的内存、磁盘等资源,而Docker只需要启动N个容器,并将应用放进容器内即可。
它的启动速度、性能、内存代价、迁移性等都完胜虚拟机。
微服务架构是当前软件开发领域的热点技术之一,如果你是开发人员或者了解开发技术,相信你一定听过单体应用和微服务这二个名词。
在软件架构演进过程中,曾经一个归档包(如war包)包含了所有应用程序的功能,比如一个Web系统我们所有功能模块都放在一起,通常就称为单体应用。尽管你可以在项目内部进行了模块化开发,但是所有业务功能都包含在一个项目中,这样复杂度高、部署麻烦,可靠性也差。比如只修改了其中很小一个功能也得重新部署;其中某一小部分出现问题也会导致整个系统出现问题。
为了解决这些情况,于是就产生了微服务架构。如果是Java开发,那主要就是指Spring Boot和Spring Cloud技术栈。微服务就是要求功能拆分,业务单一,把复杂系统拆分为各个可靠的小模块,这虽然有很多优势,但同时也增加了运维和管理的难度。
虽然微服务架构容器一旦非常多的时候,管理起来有点麻烦,但Docker能很好的对各个容器进行管理、弹性扩容等,因此往往会采用SpringBoot+SpringCloud+Docker的微服务架构模式。
在传统的大数据架构中都通常会部署Hadoop、Hbase、Kafka、Zookeeper、Flink、Spark等等集群,如果都手动或者采用脚本去进行管理效率非常低,并且应对弹性扩容或缩容、迁移的情景是控制还需要做些额外的工作,而如果采用Docker进行管理和容器化的部署,这一切将会变得更加简单。
这一部分的演示将会在后续分享完大数据相关知识后在返回来进行对比,敬请期待。
Docker容器技术以及在各大企业中得到了充分的验证,如:京东618、美团点评、腾讯、新浪、蘑菇街等等。
2016年京东弹性云团队,从1万Docker到15万,从试水部分应用到承担全部流量,经过了618的严格考验。
2015年,美团云团队开始试水Docker容器集群管理平台,经过一些列的优化和完善,前该平台为美团点评的外卖、酒店、到店、猫眼等十几个事业部提供容器计算服务,承载线上业务数百个,业务类型涵盖Web、数据库、缓存、消息队列等。
腾讯2014年10月份正式上线 Docker,其基于 Yarn 的代号为Gaia的调度平台可以同时兼容 Docker 和非Docker 类型的应用,其上层业务包括离线、实时以及在线 service 服务,如 Hadoop MR、Spark、Storm、Hive 以及腾讯内部的 Lhotse、Hermes、广点通等业务。
新浪微博的DCP是基于Docker的混合云架构,在2014年做了Docker容器化,2015年做了私有云+混合云以及还有动态调度,在2016年从容应对十亿级PV、千亿级数据、2000台以上的服务器规模、20个以上的大小服务模块、百亿级数据Hbase存储、千台以上的Docker混合云集群。
蘑菇街的私有云项目于2014年圣诞节期间上线,把应用进行拆分,变成一个个微服务,实现PaaS基于应用的部署和发布。经历了 几次双11大促,已经逐渐形成了一定的规模。
https://www.docker.com/
从官网可以看到Docker分为社区版(CE)和企业版(EE),一般情况下使用社区版即可。
https://labs.play-with-docker.com/
该网站是Docker船长为了帮助大家学习Docker而花了几天时间开发的一款基于浏览器的产品,play-with-docker,人称PWD,它是一个Docker的演练场。
它可以让用户在几秒钟内在浏览器中体验免费的Alpine Linux虚拟机,运行Docker命令,可以构建、运行Docker容器,甚至可以在Docker Swarm模式下创建集群,除了演练场之外,PWD还包含了一个由大量Docker labs实例和测试。
如果你只是想快速体验一下Docker,你甚至都不用本地装环境就可以马上体验,注册一个账户或者直接用Docker Hub的账户即可登录进入体验。
正如前文提到支持Linux、Windows、MacOS等,但生产环境我们一般是在Linux中使用,因此本文将演示在Centos7下Docker的安装和使用。
Docker的安装也非常简单,只需要按照官网提示操作即可。
官网介绍的安装有三种:rpm、yum、脚本方式
接下来采用YUM的方式进行安装
配置好IP地址,同时为了减少干扰,关闭防火墙和SELinux。
如果你的系统比较老旧需要yum更新一下,此步骤不是必须的。
[root@docker ~]# yum update -y
[root@docker ~]# yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
...省略部分输出内容
Complete!
[root@docker ~]#
[root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
...省略部分输出内容
repo saved to /etc/yum.repos.d/docker-ce.repo
[root@docker ~]#
此处直接用官方的仓库https://download.docker.com/linux/centos/docker-ce.repo,如果你网速慢也可以换成国内的仓库,如阿里云的。
[root@docker ~]# yum install docker-ce
...省略部分输出内容
Complete!
[root@docker ~]#
安装过程中按3次y进行确认即可。此过程跟网速有关,一般10多分钟即可安装完成。
由于该命令后没有带具体的版本号,因此默认的tag为lastest,所以不同时间去执行有可能版本会不一样,生产环境建议带上指定的版本号。
安装完成后Docker是没有启动的,因此需要先启动Docker,并设为开机启动。可以通过systemctl status docker查看Docker的状态。
[root@docker ~]# systemctl start docker
[root@docker ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@docker ~]# systemctl status docker
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-02-26 21:39:22 CST; 1min 30s ago
Docs: https://docs.docker.com
Main PID: 57003 (dockerd)
CGroup: /system.slice/docker.service
...省略部分内容
可以看到处于running状态,至此docker安装并启动成功。
查看版本信息
[root@docker ~]# docker -v
Docker version 19.03.6, build 369ce74a3c
查看docker安装信息
[root@docker ~]# docker info
...省略部分内容
Docker Root Dir: /var/lib/docker
...省略部分内容
可以看到默认的安装路径为***/var/lib/docker***。
我们通过Docker Hub上官方提供的现成的***hello-world镜像***来创建一个容器,创建容器使用docker run 命令,该容器的功能就是创建并启动后输出helloworld字样。
[root@docker ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:fc6a51919cfeb2e6763f62b6d9e8815acbf7cd2e476ea353743570610737b752
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
[root@docker ~]#
可以看到容器成功运行了,并且输出了hello from docker!
此时采用***docker images***命令查看本地的镜像,可以看到一个名为hello-world的镜像。
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 14 months ago 1.84kB
[root@docker ~]#
运行一个容器,实际上就是运行容器内部的程序,就像我们平时做helloworld程序,我们需要用java或者其他语言进行开发,然后打包为jar文件,然后通过java命令执行。每次需要运行该程序都需要做手动执行命令,而在docker中,我们把helloworld对应的jar包打包到容器中,只需要run容器,程序就可以立即执行,是不是很方便呢?
我们分析一下***hello-world容器运行的原理***:首先我们看到“Unable to find image ‘hello-world:latest’ locally”这样的提示,说明本地没有这个hello-world镜像,他会自动从Docker Hub仓库去下载该镜像,然后在创建容器并运行容器内的helloworld程序,这个过程都是自动化完成的。
并且启动的这个容器其实就相当于是一个小型的linux系统,但是启动的非常快,几秒钟就启动并运行了,这也正是之前谈到的和虚拟机相比的优势。
至于它为什么这么快?以及这个容器内究竟有什么东西?可以执行哪些docker命令?在后续文章中你将找到答案。
这样Docker环境就准备好了,下一篇文章开始,我们正式来演示Docker中各种命令的使用方法。