Docker?容器是什么?看这篇就够了(精湛通俗易懂)

admin 2025-02-02 25人围观 ,发现104个评论
容器

官网的介绍是这样的:

Dockerisanopenplatformfordevelopersandsysadminstobuild,ship,andrundistributedapplications.

其实看完这句话也不是很明白究竟是啥,可以把它想象成一个用来一种新颖方式实现的超轻量虚拟机,在大概效果上也是正确的。当然在实现的原理和应用上还是和VM有巨大差别的,并且专业的叫法是应用容器(ApplicationContainer)

为啥要用容器

那么应用容器长什么样子呢,一个做好的应用容器长的就好像一个装好了一组特定应用的虚拟机一样。比如我现在想用MySQL那我就找个装好MySQL的容器,运行起来,那么我就可以使用MySQL了。

但是直接装个MySQL不就好了,何必还需要容器这么诡异的概念。话是这么说,可以你要真装MySQL的话可能要再装一堆依赖库,根据你的操作系统平台和版本进行设置,可能还要把配置在重新弄一遍。但是有了容器,你就相当于有了一个可以运行起来的虚拟机,只要你能运行容器,MySQL的配置就全省了。而且一旦你想换台机器,直接把这个容器端起来,再放到另一个机器就好了。硬件,操作系统,运行环境什么的都不需要考虑了。

举个网友的例子,在公司中的一个很大的用途就是可以保证线下的开发环境、测试环境和线上的生产环境一致。网友A在Baidu经常碰到这样的事情,开发把东西做好了给测试去测,一般会给一坨代码和一个介绍上线步骤的上线单。结果代码在测试机跑不起来,开发就跑来跑去看问题,一会儿啊这个配置文件忘了提交了,一会儿啊这个上线命令写错了。找到了一个bug提上去,开发一看,啊我怎么又忘了把这个命令写在上线单上了。类似的事情在上线的时候还会发生,变成啊你这个软件的版本和我机器上的不一样……在北现的时候,由于一个开发直接担任上述三个职位,而且有一套自动化部署的机制所以问题会少一点,但是上线的时候大家还是胆战心惊。

如果利用容器的话,那么开发直接在容器里开发,提测的时候把整个容器给测试,测好了把改动改在容器里再上线就好了。通过容器,整个开发、测试和生产环境可以保持高度的一致。

此外容器也和VM一样具有着一定的隔离性,各个容器之间的数据和内存空间相互隔离,可以保证一定的安全性。

为啥不用VM

那么既然容器和VM这么类似为啥不直接用VM还要整出个容器这么个概念来呢?Docker容器相对于VM有以下几个优点:

启动速度快,容器通常在一秒内可以启动,而VM通常要更久;

资源利用率高,一台普通PC可以跑上千个容器,你跑上千个VM试试;

性能开销小,VM通常需要额外的CPU和内存来完成OS的功能,这一部分占据了额外的资源。

为啥相似的功能在性能上会有如此巨大的差距呢,其实这和他们设计的理念是相关的。

VM的设计图如下:


VM的Hypervisor需要实现对硬件的虚拟化,并且还要搭载自己的操作系统,自然在启动速度和资源利用率以及性能上有比较大的开销。

而Docker的设计图是这样的:


Docker几乎就没有什么虚拟化的东西,并且直接复用了Host主机的OS,在DockerEngine层面实现了调度和隔离重量一下子就降低了好几个档次。Docker的容器利用了LXC,管理利用了namespaces来做权限的控制和隔离,cgroups来进行资源的配置,并且还通过aufs来进一步提高文件系统的资源利用率。

其中的aufs是个很有意思的东西,是UnionFS的一种。他的思想和git有些类似,可以把对文件系统的改动当成一次commit一层层的叠加。这样的话多个容器之间就可以共享他们的文件系统层次,每个容器下面都是共享的文件系统层次,上面再是各自对文件系统改动的层次,这样的话极大的节省了对存储的需求,并且也能加速容器的启动。

说到这里,大家是不是脑海里已经形成了容器是个什么东东了吧?那接下来就在详细的介绍下目前主流的容器技术Docker。

Docker简介

2013年出现,RedHat在6.5版本开始支持docker,使用go语言开发,基于协议,开源软件,项目代码在github维护。

我们具体来看看Docker。

大家需要注意,Docker本身并不是容器,它是创建容器的工具,是应用容器引擎。

想要搞懂Docker,其实看它的两句口号就行。

第一句,是"Build,ShipandRun"。

也就是,"搭建、发送、运行",三板斧。

举个例子:

我来到一片空地,想建个房子,于是我搬石头、砍木头、画图纸,一顿操作,终于把这个房子盖好了。

结果,我住了一段时间,想搬到另一片空地去。这时候,按以往的办法,我只能再次搬石头、砍木头、画图纸、盖房子。

但是,跑来一个老巫婆,教会我一种魔法。

这种魔法,可以把我盖好的房子复制一份,做成"镜像",放在我的背包里。

等我到了另一片空地,就用这个"镜像",复制一套房子,摆在那边,拎包入住。

怎么样?是不是很神奇?

所以,Docker的第二句口号就是:"Buildonce,Runanywhere(搭建一次,到处能用)"。

Docker技术的三大核心概念,分别是:

·镜像(Image)

·容器(Container)

·仓库(Repository)

docker特点

docker容器之间是相互隔离的。

docker比较轻量,启动非常快,秒级实现。

资源利用率比较高,一台机器可以跑上千个docker容器。

内核级别的虚拟化,不需要额外的hypevisor支持。主机的内核版本跟随母机kernel内核版本最低:2.6.32-573.18.1.el6

容易迁移,平台依赖性不强。

更快的交付和部署,一次创建配置,任意地方运行

docker和虚拟机的区别

docker是以进程状态存于系统中

docker容器启动是秒级,虚拟机启动是分钟级。

docker容器的硬盘使用一般为MB,虚拟机一般为GB。

docker单机支持上千个容器,而虚拟机一般有几十个就不错了。

docker核心概念

镜像:是一个只读的模板,类似于安装系统用到的ISO镜像。

容器:容器是镜像产生的一个进程,类似于虚拟机本身。

仓库:存放镜像的一个场所。类似于github的仓库概念。分为公有仓库和私有仓库,本地可以做私有仓库。

最大的公开仓库:dockerhub

国内公开仓库:dockerpool

OPENVZOS模板:

docker的启动centos6
yuminstall-ydocker-ioyuminstall-ydockersudoapt-getinstall-ydocker-iodockerimages
在docker仓库中搜索镜像
[root@localhost~]dockerpullcentos


此时再查看本地镜像


修改镜像名

显示在REPOSITORY列

dockertag原镜像名自定义名

[root@localhost~]cat/etc/redhat-release


此时是不带ifconfig命令的


官方的centos源是默认带yum工具的

下载net-tools

[root@5d25d4c4e905/]dockerrun-itshs_centos/bin/bash[root@localhost~]dockercreate-itshaohs:first
启动关闭一个容器

dockerstartCONTAINER/NAME

dockerstopCONTAINER/NAME


CONTAINER_ID和NAME为dockerps–a出来的第一列和最后的NAMES列


也可以同时启动关闭多个:

[root@localhost~]dockerlogsdetermined_hawking给容器自定义名字

dockerrun–nameweb–itdcentobash

--name给容器自定义名字

导入导出容器
dockerexportCONTAINER_

|dockerimport–自定义镜像名

为什么导入时是镜像名呢?因为容器是作为一个镜像导入的,需要在镜像的基础上,再去产生并dockrun这个容器。

例子如下:


如果shsaaa的镜像导入不进去,多半是因为下载的镜像有问题,或者dockerimages看一下,是不是导入不完全的同名镜像,删除,重新导入。

docker仓库管理下载私有仓库镜像
dockerpullregistry

registry镜像用来创建私有仓库

依托registry镜像来创建容器d
dockerrun–d–p5000:5000registry

-d放到后台运行

-p做一个端口映射,"宿主机端口:容器端口"访问宿主机5000端口,就相当于访问该容器

当dockerps的时候,会在PORTS列显示0.0.0.0:5000-5000/TCP


用:5000测试,会显示

"\"docker-registryserver\""


上传一个镜像到私有仓库

1)首先要给这个镜像做tag

必须带有私有仓库的ip:port,要不然会上传到公有仓库里面去

[root@localhost~]dockertagshao::5000/hong

2)更改https为http

为什么要修改为http呢,因为docker从1.3.x之后,与dockerregistry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报下面的错误。

:5000/centos//错了类似如下Errorresponsefromdaemon:invalidregistrypoint`--:5000`tothedaemon',ifyouhaveaccesstotheregistry'sCAcertificate,noneedfortheflag;simplyplacetheCAcertificateat/etc/docker//172.7.15.106:5000/

为了解决这个问题需要在启动dockerserver时增加启动参数为默认使用http访问。解决办法为:

[root@localhosthome]servicedockerrestart


再启动registry容器

[root@localhosthome]:5000/centos


4)去私有仓库查看镜像

[root@localhosthome]:5000/cent


拉取私有库的镜像

需要指定私有库的地址端口

[root@localhosthome]dockerrun-itd--volumes-fromsleepy_teslashaohs:firstbash

1cfcec3d65b38fb516a6142c8c5a429a8ccd394c7ce589e147cd8832c11995c8

这样,我们就用shaohs:first镜像创建了新的容器,并且使用了sleepy_tesla容器的数据卷

自定义容器name

[root@localhost~]dockerrun-itd-v/data/--nameshao_testv1shaohs:firstbashe285a0fe1309ebeb54ed0d332616fe8f9e03fb58f673278d54c88f64654b973a[root@localhost~]ls/data/

注:这里的/data/是容器的/data目录,并非本地的/data/目录

然后将其他容器挂载该数据卷

[root@localhost~]dockerexec-it85dbash[root@85dee791d2dd/]mkdir/vol_data_backup[root@localhost~]tarcvf/backup//data/tar:Removingleading`/'frommembernames/data//data/test//data/1.txt[root@e2e87d0974ac/]ls/vol_data_backup/
数据卷的恢复

思路:先新建一个数据卷容器,再建一个新的容器并挂在该数据卷容器。然后再把tar包解包。

新建数据卷容器:

[root@localhost~]dockerrun-itd--nameshao_testv8--volumes-fromshao_testv7-v/vol_data_backup/:/backupshaohs:firstbash

23683bceb1e247d8ac1853b051881a4db4181fff7f6cee4ffbff76bba87f02ac

解包:

[root@23683bceb1e2/]brctlshow

或者

ifconfigdocker0

或者

/etc///24/24devdocker0iplinksetdevdocker0up/etc//dockerstartservicedockerstopbrctldelbrdocker0

创建新网桥br0

/24devbr0

查看确认新网桥并启动

iplinksetdevbr0up

配置docker服务,默认连接到网桥br0上,并启动docker

如果是centos

echo'DOCKER_OPTS="-b=br0"'/etc/default/dockercurllocalhost`

宿主机:`dockerrun--itd--c6httpd--linkc6mysql:dbcentos6httpdbash

这样,在web容器里面pingdb和pingc6mysql都是去往3.4这个地址,也就是db容器。

也可以在web容器里面/etc/hosts及env查看到相关信息。

至于这样的方式具体有什么用,目前还不是很清楚。

当时,我们可以针对上面的例子扩展一下:

建立2个容器db和web同时做端口映射来提供服务。

dockerrun-itd--namec6httpd-p10080:80--linkc6mysql:dbcentos6httpdbash
猜你喜欢
    不容错过