一、Docker的介绍
1、为什么需要Docker?
(1)环境配置问题
“小张,快来看看,你给我的程序为什么跑不起来?是不是出bug了?”测试小刘喊了一声。小张一听,怒火中烧——你可以怼我,但不能说我的程序有问题。小张放下手中的活,过去一看,发现程序运行的环境出了问题,但是在交付之前自己电脑上是完全ok的。于是小张在小刘的电脑上又再次配置了一次环境。
上述情况在实际中很常见,在项目开发过程中,我们会接触到很多的环境,如:自己写程序的开发环境、测试运行的测试环境以及对外使用的生产环境。也许在开发啊环境下程序没得问题,可能到了测试或者生产环境就出问题了。如果每次都需要在不同的电脑上去配置环境,这样就很费事。如下图:
这种方式存在一些的问题:
- 资源利用率低下。
- 单台物理机的多应用之间彼此耦合,无法有效隔离。
- 运维部署不方便,且版本管理复杂。
因此,对于开发人员来说,其理想的目标就是一次创建或者配置,之后就可以在任意地方、任意时间让程序正常运行。然而理想很美好,现实却很残酷。开发人员打包好的应用程序可能在运维人员的电脑上无法正常运行或者环境出问题。而Docker将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。
(2)虚拟机资源问题
尽管虚拟机虚拟机通过进程和名称空间隔离技术使得资源隔离,使得不同用户间彼此老死不相往来,但虚拟机是一种重量级的虚拟化方案,存在缺点,如:创建速度慢,迁移起来麻烦,且由于中间加了一层guest os,有了性能损耗。而Docker实现了更轻量的虚拟化,让虚拟化变得轻量了起来,创建一个container仅需秒级即可完成;节省了虚拟机的性能损耗,cpu指令集不再被翻译执行,性能损耗非常少。虽说对于资源的隔离性没有虚拟机那么彻底,安全性上稍差一些,但也基本可以用,不用太担心。
2、什么是Docker?
Docker 是一个开源的应用容器引擎,基于Go语言并遵从 Apache2.0 协议开源。Docker 可以让开发者打包自己的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化,从而可以消除协作编码时“在我电脑上可以正常工作,而在他人电脑上无法工作”的问题。
Java的愿景是“Write Once,Run Anywhere”, 而Docker提出了“Build,Ship,and Run Any App, Anywhere”,即通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的 APP(可以是一个 WEB 应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。如下图:
Docker是容器虚拟化技术,可以有多个容器(可以不同功能)且相互隔离,互不影响。容器没有自己的内核,直接运行于宿主主机的内核。如下图:
3、Docker的架构
Docker中有三个要素,如下:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。如下图:
观察上图,其介绍如下:
概念 | 说明 |
---|---|
Docker镜像(Images) | 用于创建Docker容器的模板 |
Docker容器(Container) | 独立运行的一个或一组应用,是镜像运行时的实体 |
Docker客户端(Client) | Docker客户端通过命令行或者其他工具使用Docker SDK与Docker的守护进程通信 |
Docker 主机(Host) | 一个物理或者虚拟的机器,用于执行Docker守护进程和容器 |
Docker Registry | 用来保存镜像,可以理解为代码控制中的代码仓库。 Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure |
4、虚拟化技术
虚拟化( Virtualization )技术是一个通用的概念, 在不同领域有不同的理解。在计算领 域,一般指的是计算虚拟化( Computing Virtualization ),或通常说的服务器虚拟化。维基百 科上的定义如下:“虚拟化是一种资源管理技术,是将计算机的各种实体资源,如服务器、 网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。”
可见,虚拟化的核心是对资源的抽象,目标往往是为了在同一个主机上同时运行多个系 统或应用,从而提高系统资源的利用率,并且带来降低成本、方便管理和容错容灾等好处。 从大类上分,虚拟化技术可分为基于硬件的虚拟化和基于软件的虚拟化。基于软件的虚拟化从对象所在的层次,又可以分为应用虚拟化和平台虚拟化(通常说的 虚拟机技术即属于这个范畴) 。其中,前者一般指的是一些模拟设备或诸如Wine 这样的软 件。后者又可以细分为如下几个子类:
(1)完全虚拟化。
虚拟机模拟完整的底层硬件环境和特权指令的执行过程,客户操作系统无需进行修改。例如IBM p 和z 系列的虚拟化、VMware Workstation 、VirtuaboX 、QEMU 等。
(2)硬件辅助虚拟化。
利用硬件(主要是CPU )辅助支持(目前x86 体系结构上可用的硬件辅助虚拟化技术包括Intel- T 和AMD-V )处理敏感指令来实现完全虚拟化的功能,客户操作系统元需修改,例如VMware Workstation 、Xen 、KVM。
(3)部分虚拟化。
只针对部分硬件资源进行虚拟化,客户操作系统需要进行修改。现在有些虚拟化技术的早期版本仅支持部分虚拟化。
(4)准虚拟化( paravirtualization ) 。
部分硬件接口以软件的形式提供给客户机操作系统,客户操作系统需要进行修改,例如早期的Xen 。
(5)操作系统级虚拟化。
内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程。容器相关技术即在这个范畴。
因此,Docker 以及其他容器技术,都属于操作系统虚拟化这个范畴,操作系统虚拟化最大的特点就是不需要额外的supervisor 支持。Docker 虚拟化方式之所以有众多优势,这与操作系统虚拟化技术自身的设计和实现是分不开的。
Docker 和传统虚拟化方式的对比:
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程,需要有额外的虚拟机管理应用和虚拟机操作系统层。Docker 容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
- 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
- Docker 容器的启动可以在秒级实现,而传统的虚拟机方式需要数分钟,这相比传统的虚拟机方式要快得多。
- Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
- Docker 通过类似Git 设计理念的操作来方便用户获取、分发和更新应用镜像,存储复用,增量更新。
- Docker 通过Dockerfile 支持灵活的自动化创建和部署机制,提高工作效率,使流程标准化
- Docker 容器除了运行其中应用外,基本不消耗额外的系统资源,保证应用性能的同时,尽量减小系统开销。传统虚拟机方式运行N 个不同的应用就要起N 个虚拟机(每个虚拟机需要单独分配独占的内存、磁盘等资源),而Docker 只需要启动N 个隔离的“很薄的”容器,并将应用放进容器内即可,应用获得的是接近原生的运行性能。
如下图:
如下表:
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
性能 | 接近原生 | 较弱 |
内存代价 | 很小 | 较多 |
硬盘使用 | 一般为MB | 一般为GB |
运行密度 | 单机支持上千个容器 | 一般为几十个 |
隔离性 | 安全隔离 | 完全隔离 |
迁移性 | 优秀 | 一般 |
参考博客:https://www.cnblogs.com/Nicholas0707/p/12506186.html
5、Docker的优点
Docker具有如下几个方面的优势:
(1)更快速的交付和部署
使用Docker ,开发人员可以使用镜像来快速构建一套标准的开发环境;开发完成之后,测试和运维人员可以直接使用完全相同环境来部署代码。只要开发测试过的代码,就可以确保在生产环境无缝运行。Docker 可以快速创建和删除容器,实现快速迭代,大量节约开发、测试、部署的时间。并且,整个过程全程可见,使团队更容易理解应用的创建和工作过程。
(2)更高效的资源利用
Docker 容器的运行不需要额外的虚拟化管理程序(Virtual Machine Manager, VMM ,以及Hypervisor)支持,它是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。跟传统虚拟机方式相比,要提高一到两个数量级。
(3)更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等,同时支持主流的操作系统发行版本。这种兼容性让用户可以在不同平台之间轻松地迁移应用。
(4)更简单的更新管理
使用Dockerfile ,只需要小小的配置修改,就可以替代以往大量的更新工作。并且所有修改都以增量的方式被分发和更新,从而实现自动化并且高效的容器管理。
(5)更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
(6)更快的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
(7)一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这项目在我机器上没问题啊」 这类问题。
Docker在安全性方面还需进一步提升。传统的虚拟机方式提供的是相对封闭的隔离。 Docker利用Linux 系统上的多种防护技术实现了严格的隔离可靠性,并且可以整合众多安全工具。从1.3.0 版本开始, Docker 重点改善了容器的安全控制和镜像的安全机制,极大提高了使用Docker 的安全性。在已知的大规模应用中,目前尚未出现值得担忧的安全隐患。
二、Ubuntu下Docker的安装
1、安装过程
(1)更新ubuntu的apt源索引
sudo apt-get update
(2)安装包允许apt通过HTTPS使用仓库
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
(3)添加Docker官方GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
(4)设置Docker稳定版仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
(5)添加仓库后,更新apt源索引
sudo apt-get update
(6)安装最新版Docker CE(社区版)
sudo apt-get install docker-ce
(7) 检查Docker CE是否安装正确
sudo docker run hello-world
结果如下:
2、Hello-World的运行过程
3、遇到的问题
问题:Unable to find image 'hello-world:latest' loca
原因:Docker服务器在国外,基于网速与“和谐墙”的问题,所以我们在国内操作国外镜像可能无法正常拉取,这需要我们为docker设置国内的阿里云镜像加速器。
解决方案:
(1)创建文件daemon.json文件
vi /etc/docker/daemon.json
(2)配置文件/etc/docker/daemon.json,添加阿里云镜像
{
"registry-mirrors": ["https://alzgoonw.mirror.aliyuncs.com"]
}
(3)保存退出后执行下面的命令,重启Docker服务
systemctl restart docker
sudo systemctl status docker
(4)此时再执行sudo docker run hello-world即可成功。
关于Docker的一些网址: