在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件
虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化、桌面虚拟化、服务虚拟化、虚拟机等等。
在计算机的世界中,容器拥有一段漫长且传奇的历史。容器与管理程序虚拟化(hypervisor virtualization,HV)有所不同,管理程序虚拟化通过中间层将一台或者多台独立的机器虚拟运行与物理硬件之上,而容器则是直接运行在操作系统内核之上的用户空间。因此,容器虚拟化也被称为“操作系统级虚拟化”,容器技术可以让多个独立的用户空间运行在同一台宿主机上。
由于“客居”于操作系统,容器只能运行与底层宿主机相同或者相似的操作系统,这看起来并不是非常灵活。例如:可以在Ubuntu服务中运行Redhat Enterprise Linux,但无法再Ubuntu服务器上运行Microsoft Windows。
相对于彻底隔离的管理程序虚拟化,容器被认为是不安全的。而反对这一观点的人则认为,由于虚拟容器所虚拟的是一个完整的操作系统,这无疑增大了攻击范围,而且还要考虑管理程序层潜在的暴露风险。
尽管有诸多局限性,容器还是被广泛部署于各种各样的应用场合。在超大规模的多租户服务部署、轻量级沙盒以及对安全要求不太高的隔离环境中,容器技术非常流行。最常见的一个例子就是“权限隔离监牢”(chroot jail),它创建一个隔离的目录环境来运行进程。如果权限隔离监牢正在运行的进程被入侵者攻破,入侵者便会发现自己“身陷囹圄”,因为权限不足被困在容器所创建的目录中,无法对宿主机进一步破坏。
最新的容器技术引入了OpenVZ、Solaris Zones以及Linux容器(LXC)。使用这些新技术,容器不在仅仅是一个单纯的运行环境。在自己的权限类内,容器更像是一个完整的宿主机。对Docker来说,它得益于现代Linux特性,如控件组(control group)、命名空间(namespace)技术,容器和宿主机之间的隔离更加彻底,容器有独立的网络和存储栈,还拥有自己的资源管理能力,使得同一台宿主机中的多个容器可以友好的共存。
容器被认为是精益技术,因为容器需要的开销有限。和传统虚拟化以及半虚拟化相比,容器不需要模拟层(emulation layer)和管理层(hypervisor layer),而是使用操作系统的系统调用接口。这降低了运行单个容器所需的开销,也使得宿主机中可以运行更多的容器。
尽管有着光辉的历史,容器仍未得到广泛的认可。一个很重要的原因就是容器技术的复杂性:容器本身就比较复杂,不易安装,管理和自动化也很困难。而Docker就是为了改变这一切而生的。
Build once,Run anywhere
Docker上手非常快,用户只需要几分钟,就可以把自己的程序“Docker化”。Docker依赖于“写时复制”(copy-on-write)模型,使修改应用程序也非常迅速,可以说达到“随心所致,代码即改”的境界?。
随后,就可以创建容器来运行应用程序了。大多数Docker容器只需要不到1秒中即可启动。由于去除了管理程序的开销,Docker容器拥有很高的性能,同时同一台宿主机中也可以运行更多的容器,使用户尽可能的充分利用系统资源。
使用Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。Docker设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署的生产环境一致性。从而降低那种“开发时一切正常,肯定是运维的问题(测试环境都是正常的,上线后出了问题就归结为肯定是运维的问题)”
Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。(通俗一点说,Docker就像一个盒子,里面可以装很多物件,如果需要这些物件的可以直接将该大盒子拿走,而不需要从该盒子中一件件的取。)
Docker还鼓励面向服务的体系结构和微服务架构。Docker推荐单个容器只运行一个应用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或者服务都可以表示为一系列内部互联的容器,从而使分布式部署应用 程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。(当然,可以在一个容器中运行多个应用程序)
Docker核心组件都有:
l Docker客户端和服务器;
l Docker镜像;
l Registry;
l Docker容器。
Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具Docker以及一整套RESTful API。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。
镜像是构建Docker的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的“构建”部分。镜像是基于联合文件系统的一种层式结构,由一系列指令一步一步构建出来。例如:
l 添加一个文件;
l 执行一个命令;
l 打开一个窗口。
也可以将镜像当作容器的“源代码”。镜像体积很小,非常“便携”,易于分享、存储和更新。
Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的Registry叫做Docker Hub。用户可以在Docker Hub注册账号,分享并保存自己的镜像(说明:在Docker Hub下载镜像巨慢,可以自己构建私有的Registry)。
Docker可以帮助你构建和部署容器,你只需要把自己的应用程序或者服务打包放进容器即可。容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。 容器基于镜像启动,一旦容器启动完成后,我们就可以登录到容器中安装自己需要的软件或者服务。
所以Docker容器就是:
l 一个镜像格式;
l 一些列标准操作;
l 一个执行环境。
Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Dock将
这个模型运用到自己的设计中,唯一不同的是:集装箱运输货物,而Docker运输软件。
和集装箱一样,Docker在执行上述操作时,并不关心容器中到底装了什么,它不管是web服务器,还是数据库,或者是应用程序服务器什么的。所有的容器都按照相同的方式将内容“装载”进去。
Docker也不关心你要把容器运到何方:我们可以在自己的笔记本中构建容器,上传到Registry,然后下载到一个物理的或者虚拟的服务器来测试,在把容器部署到具体的主机中。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分发,并且尽量通用。
使用Docker,我们可以快速的构建一个应用程序服务器、一个消息总线、一套实用工具、一个持续集成(CI)测试环境或者任意一种应用程序、服务或工具。我们可以在本地构建一个完整的测试环境,也可以为生产或开发快速复制一套复杂的应用程序栈。
容器提供了隔离性,结论是,容器可以为各种测试提供很好的沙盒环境。并且,容器本身就具有“标准性”的特征,非常适合为服务创建构建块。Docker的一些应用场景如下:
l 加速本地开发和构建流程,使其更加高效、更加轻量化。本地开发人员可以构建、运行并分享Docker容器。容器可以在开发环境中构建,然后轻松的提交到测试环境中,并最终进入生产环境。
l 能够让独立的服务或应用程序在不同的环境中,得到相同的运行结果。这一点在面向服务的架构和重度依赖微型服务的部署由其实用。
l 用Docker创建隔离的环境来进行测试。例如,用Jenkins CI这样的持续集成工具启动一个用于测试的容器。
l Docker可以让开发者先在本机上构建一个复杂的程序或架构来进行测试,而不是一开始就在生产环境部署、测试。
l 构建一个多用户的平台即服务(PaaS)基础设施
l 为开发、测试提供一个轻量级的独立的沙盒环境
l 提供软件即服务(SaaS)应用程序,例如Memcached即服务
l 高性能、超大规模的宿主机部署
Docker官方建议在Ubuntu中安装,因为Docker是基于Ubuntu发布的,而且一般Docker出现的问题Ubuntu是最先更新或者打补丁的。在很多版本的CentOS中是不支持更新最新的一些补丁包的。
由于我们学习的环境都使用的是CentOS,因此这里我们将Docker安装到CentOS上。注意:这里安装CentOS7.x以上的版本,在7.x之前的版本中,安装前需要安装其他很多的环境。
略,不建议。需要安装额外的环境,例如:安装epel源、安装docker-io等。而且在CentOS6下无法获取Docker镜像。
略。
说明:在Centos7.x中,如果安装的是minimal版的只能通过ip addr命令查看IP地址。如果不是minimal而是DVD的,可以通过ip addr或者ifconfig都可以。
[root@localhost ~]# yum install docker
说明:通过 docker –v查看docker版本。但是通过yum命令安装的Docker不是最新的版本,。
执行如下命令即可安装最新的Docker版本:
l curl -sSL https://get.daocloud.io/docker | sh 查看版本: |
[root@localhost ~]# docker -v
略。
略。
l 开机启动:systemctl enable docker.service/docker l 启动docker:systemctl start docker.service l 停止docker:systemctl stop docker.service l 重启docker:systemctl restart docker.service l 查看docker状态:systemctl status docker.service l 查看docker概要信息:docker info l 查看docker帮助文档:docker --help |
Docker镜像是由文件系统叠加而成(是一种文件的存储形式)。最底端是一个文件引导系统,即bootfs,这很像典型的Linux/Unix的引导文件系统。Docker用户几乎永远不会和引导系统有什么交互。实际上,当一个容器启动后,它将会被移动到内存中,而引导文件系统则会被卸载,以留出更多的内存供磁盘镜像使用。Docker容器启动是需要的一些文件,而这些文件就可以称为Docker镜像。
列出docker下的所有镜像:docker images
l REPOSITORY:镜像所在的仓库名称
l TAG:镜像标签
l IMAGE ID:镜像ID
l CREATED:镜像的创建日期(不是获取该镜像的日期)
l SIZE:镜像大小
这些镜像都是存储在Docker宿主机的/var/lib/docker目录下
为了区分同一个仓库下的不同镜像,Docker提供了一种称为标签(Tag)的功能。每个镜像在列出来时都带有一个标签,例如12.10、12、04等等。每个标签对组成特定镜像的一些镜像层进行标记(比如,标签12.04就是对所有Ubuntu12.04镜像层的标记)。这种机制使得同一个仓库中可以存储多个镜像。
我们在运行同一个仓库中的不同镜像时,可以通过在仓库名后面加上一个冒号和标签名来指定该仓库中的某一具体的镜像,例如docker run --name custom_container_name –i –t docker.io/ubunto:12.04 /bin/bash,表明从镜像Ubuntu:12.04启动一个容器,而这个镜像的操作系统就是Ubuntu:12.04。在构建容器时指定仓库的标签也是一个好习惯。
Docker镜像首页,包括官方镜像和其它公开镜像。Docker Hub上最受欢迎的10大镜像(通过Docker registry API获取不了镜像被pull的个数,只能通过镜像的stars数量,来衡量镜像的流行度。毫无疑问,拥有最高stars数量的库都是官方库)。
国情的原因,国内下载 Docker HUB 官方的相关镜像比较慢,可以使用国内(docker.io)的一些镜像加速器,镜像保持和官方一致,关键是速度块,推荐使用。Mirror与Private Registry的区别:
l Private Registry(私有仓库)是开发者或者企业自建的镜像存储库,通常用来保存企业内部的 Docker 镜像,用于内部开发流程和产品的发布、版本控制。
l Mirror是一种代理中转服务,我们(比如daocloud)提供的Mirror服务,直接对接Docker Hub的官方Registry。Docker Hub 上有数以十万计的各类 Docker 镜像。
l 在使用Private Registry时,需要在Docker Pull 或Dockerfile中直接键入Private Registry 的地址,通常这样会导致与 Private Registry 的绑定,缺乏灵活性。
l 使用 Mirror 服务,只需要在 Docker 守护进程(Daemon)的配置文件中加入 Mirror 参数,即可在全局范围内透明的访问官方的 Docker Hub,避免了对 Dockerfile 镜像引用来源的修改。
l 简单来说,Mirror类似CDN,本质是官方的cache;Private Registry类似私服,跟官方没什么关系。对用户来说,由于用户是要拖docker hub上的image,对应的是Mirror。yum/apt-get的Mirror又有点不一样,它其实是把官方的库文件整个拖到自己的服务器上做镜像,并定时与官方做同步;而Docker Mirror只会缓存曾经使用过的image。
docker pull centos:7(指定version)。
目前国内访问docker hub速度上有点尴尬,使用docker Mirror势在必行。现有国内提供docker镜像加速服务的商家有不少,下面重点介绍几家:
ustc是老牌的linux镜像服务提供者了,还在遥远的ubuntu 5.04版本的时候就在用。ustc的docker镜像加速器速度很不。ustc docker mirror的优势之一就是不需要注册,真正是公共服务啊。https://lug.ustc.edu.cn/wiki/mirrors/help/docker
步骤: 1、 编辑该文件:vim /etc/docker/daemon.json // 如果该文件不存在就手动创建;说明:在centos7.x下,通过vi。 2、 在该文件中输入如下内容: { "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"] } 3、 注意:一定要重启docker systemctl restart docker.service docker pull centos:7 4、 然后通过docker pull命令下载镜像:速度杠杠的。 5、 查看已下载好的镜像 |
DaoCloud也提供了docker加速器,但是跟ustc不同,需要用户注册后才能使用,并且每月限制流量10GB。linux上使用比较简单,一条脚本命令搞定。
官网:https://www.daocloud.io/mirror#accelerator-doc
配置加速器步骤: 1、 执行该命令:curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://{your_id}.m.daocloud.io 2、 实际上面的脚本执行后,改的是/usr/lib/systemd/system/docker.service文件,加了个--registry-mirror参数。如果不执行上面的脚本命令,可以如下直接修改这个文件也可. 3、 重启加载配置。说明:加速效果不是很明显。 l systemctl daemon-reload // 重新加载配置 l systemctl restart docker 4、 下载镜像:以nginx为例 l 执行命令:docker pull daocloud.io/daocloud/nginx-proxy |
阿里云也提供了docker加速器,不过比daocloud更麻烦:不光要注册为阿里云的用户,还得加入开发者平台。不过虽然麻烦,但是它的服务还真是不错,pull速度很溜!配置方法跟daocloud类似,也是开通加速器以后给一个url。
步骤: 1、 同daocloud一样,在该/usr/lib/systemd/system/docker.service文件中添加: --registry-mirror=https://{your_id}.mirror.aliyuncs.com\ 2、 重新加载配置并且重启 3、 下载需要的镜像,例如:docker pull ubuntu |
网易也提供了Docker镜像服务:网易蜂巢(https://c.163.com/hub#/m/home/)。
n NAME:仓库名称
n DESCRIPTION:镜像描述
n STARS:用户评价,反应一个镜像的受欢迎程度
n OFFICIAL:是否官方
n AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的
docker官方和个人发布的镜像由于版本等各种原因,漏洞较多,已统计Docker Hub超过30%的官方镜像包含高危漏洞。此外,由于网络等原因也会造成docker pull下载镜像的速度很慢。基于这种情况,我们可以手动定制docker系统镜像。
构建镜像的方式有两种:
l 使用docker commit命令;
l 使用docker build和Dockerfile文件
这里我们掌握docker commit构建镜像即可。
略。在下一章节中我们会通过commit构建镜像。
Dockerfile使用基本的基于DSL(领域专用语言)语法的指令来构建一个Docker镜像,之后使用docker builder命令基于该Dockerfile中的指令构建一个新的镜像。
创建一个目录并且在里面创建初始的Dockerfile。这里我们创建一个包含web服务器的Docker镜像。
1、 mkdir static_web
2、 cd static_web
3、 touch Dockerfile
创建static_web目录用来保存Dockerfile,这个目录就是我们的构建环境,Docker则称此环境为上下文(context)或者构建上下文(build context)。Docker会在构建镜像时将构建上下文和该上下文中的文件和目录上传到Docker守护进程。这样Docker守护进程就能直接访问你想在镜像中存储的任何代码、文件或者其他数据。
然后编辑该Dockerfile,在Dockerfile中构建一个能作为web服务器的Docker镜像。注意,该Dockerfile是由一系列的指令和参数构成,指令区分大小写。
指令说明:
#:注释
FROM:指定一个已经存在的镜像,后续指令都将基于该镜像执行,这个镜像被称为基础镜像。在运行容器时,必须要指明是基于哪个基础镜像在进行构建。
MAINTAINER:指定Docker镜像的作者以及作者的邮件。如果该镜像出了问题可以找其维护。
RUN:第一个RUN,更新已安装的APT仓库;
RUN:第二个RUN,安装nginx包
RUN:第三个RUN,安装完nginx包后,创建了index.html文件,并且该文件有简单的脚本。(每条RUN指令都会创建一个新的镜像层,如果该指令执行成功,就会将此镜像层提交,之后执行Dockerfile中的下一个命令,这些指令需要运行在支持shell的平台上)
EXPOSE:指定Docker容器内的应用程序将使用该容器的端口。
使用docker build命令来构建新镜像。我们通过指定-t为新镜像设置了仓库和名称,在本例中,仓库名称jamtur01,镜像名称为static_web。强烈建议为自己的镜像设置合适的名称以方便追踪和管理。也可以在构建镜像的过程中为镜像设置一个标签,其使用方法为:“镜像名:标签”,例如:docker build –t = “jamtur01/static_web:v1”,如果没有指定标签,那么Docker将会自动为镜像设置一个为latest标签。
略。
1、 docker rmi $IMAGE_ID:删除指定镜像
2、 docker rmi `docker images -q`:删除所有镜像
l 创建容器常用的参数说明: u 创建容器命令:docker run u -i:表示以“交互模式”运行容器 u -t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。 u --name :表示创建的容器名为my-nginx u -v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。 u -d:在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i -t两个参数,创建后就会自动进去容器)。 u -p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p做多个端口映射 l 创建一个交互式容器 相当于进入了Ubuntu环境。 退出当前容器,该容器也随之停止: l 创建一个守护式容器:如果对于一个需要长期运行的容器来说,我们可以创建一个守护式容器。命令如下: docker run -d -t docker.io/ubuntu /bin/bash l 登录(附着)容器方式: u docker attach container_name 或者 container_id /bin/bash (exit,容器退出) u docker exec –it container_name 或者 container_id /bin/bash(exit,容器正常运行) l 查看所有的容器(启动过的历史容器):docker ps –a l 查看最后一次运行的容器:docker ps –l l 查看正在运行容器:docker ps l 容器命名:docker run --name custom_container_name –i –t docker.io/ubunto /bin/bash l 停止正在运行的容器:docker stop $CONTAINER_NAME/ID l 启动已运行过的容器:docker start $CONTAINER_NAME/ID l 进入守护式容器内部:docker exec -t -i mytomcat1 /bin/bash (如何修改配置) l 深入容器内部:docker inspech mytomcat1(容器名称) 还可以通过-f或者format来选定查看的结果。 docker inspect --format='{{.NetworkSettings.IPAddress}}' container_name/id l 删除所有容器:docker rm `docker ps -a -q` l 删除指定的容器:docker rm $CONTAINER_ID l 查看运行容器的日志:docker logs $CONTAINER_ID |
l 方案一:根据系统镜像创建Docker容器,这个时候Docker就相当于一个虚拟机,然后进入容器部署对应的应用。具体步骤如下:
1、 启动Centos系统镜像的容器my_container;
2、 在该容器中部署应用程序,例如:Tomcat、Nginx等;
3、 将部署完的my_container提交为新的镜像;
4、 然后根据新的镜像去创建容器;
5、 这个镜像可以打包,导入到其他的Docker服务器上
l 方案二:直接通过docker pull拉取别人提交好的tomcat、nginx等应用程序镜像,然后基于这些镜像去创建容器。
l 方案三:通过dockerfile制作自己的应用程序镜像
步骤: 1、 docker pull centos 2、 docker images 3、 创建交互式容器 docker run -i -t -d --name=tomcat -p 8888:8080 tomcat7 /bin/bash 4、 查看启动的docker容器 docker ps 5、 将Tomcat上传到容器中 docker cp apache-tomcat-7.0.47.tar.gz 2ac42653ca6c:/root/ 6、 登陆容器,启动tomcat进程 docker attach tomcat 7、 在容器中安装jdk。 l 安装jdk,步骤略 u 下载:yum install java-1.7.0-openjdk l 查看是否安装成功 8、 登录容器,安装Tomcat 先解压 9、 通过浏览器访问 |
这些容器启动都是基于镜像的,在这些的不管通过哪种部署方式,最底层(基础)镜像都是CentOS。