容器技术
容器技术的起源
假设你们公司正在秘密研发下一个“今日头条”APP,我们姑且称为明日头条,程序员自己从头到尾搭建了一套环境开始写代码,写完代码后程序员要把代码交给测试同学测试,这时测试同学开始从头到尾搭建这套环境,测试过程中出现问题程序员也不用担心,大可以一脸无辜的撒娇,“明明在人家的环境上可以运行的”。
测试同学测完后终于可以上线了,这时运维同学又要重新从头到尾搭建这套环境,费了九牛二虎之力搭建好环境开始上线,糟糕,上线系统就崩溃了,这时心理素质好的程序员又可以施展演技了,“明明在人家的环境上可以运行的”。
从整个过程可以看到,不但我们重复搭建了三套环境还要迫使程序员转行演员浪费表演才华,典型的浪费时间和效率,聪明的程序员是永远不会满足现状的,因此又到了程序员改变世界的时候了,容器技术应运而生。
有的同学可能会说:“等等,先别改变世界,我们有虚拟机啊,VMware好用的飞起,先搭好一套虚拟机环境然后给测试和运维clone出来不就可以了吗?”
在没有容器技术之前,这确实是一个好办法,只不过这个办法还没有那么好。
先科普一下,现在云计算其底层的基石就是虚拟机技术,云计算厂商买回来一堆硬件搭建好数据中心后使用虚拟机技术就可以将硬件资源进行切分了,比如可以切分出100台虚拟机,这样就可以卖给很多用户了。
容器技术 VS 虚拟机
我们知道和一个单纯的应用程序相比,操作系统是一个很重而且很笨的程序。
我们知道操作系统运行起来是需要占用很多资源的,大家对此肯定深有体会,刚装好的系统还什么都没有部署,单纯的操作系统其磁盘占用至少几十G起步,内存要几个G起步。
假设我有一台机器,16G内存,需要部署三个应用,那么使用虚拟机技术可以这样划分:
在这台机器上开启三个虚拟机,每个虚拟机上部署一个应用,其中VM1占用2G内存,VM2占用1G内存,VM3占用了4G内存。
我们可以看到虚拟本身就占据了总共7G内存,因此我们没有办法划分出更过虚拟机从而部署更多的应用程序,可是我们部署的是应用程序,要用的也是应用程序而不是操作系统。
如果有一种技术可以让我们避免把内存浪费在“无用”的操作系统上岂不是太香?这是问题一,主要原因在于操作系统太重了。
还有另一个问题,那就是启动时间问题,我们知道操作系统重启是非常慢的,因为操作系统要从头到尾把该检测的都检测了该加载的都加载上,这个过程非常缓慢,动辄数分钟,因此操作系统还是太笨了。
那么有没有一种技术可以让我们获得虚拟机的好处又能克服这些缺点从而一举实现鱼和熊掌的兼得呢?
答案是肯定的,这就是容器技术。
Docker简介
Docker是一个使用Go语言实现的项目,可以帮助我们方便的创建和使用容器。使用Docker技术可以很轻松的解决如下问题:
1. 固话配置,提高效率
Docker提供了一个通用配置文件。初次配置成功后,可以将配置文件固化,碰到相同的需求直接复制即可。
2. 自动化CI/CD流程
Docker提供了一组应用打包构建、传输及部署的方法,以便于用户能够轻松地在容器内运行各种应用,还提供了跨越异构环境以满足一致性的微环境。Docker还可以和Jenkins及GitLab串联,融入项目开发的CI/CD(持续集成与持续发布)流程中,让一键部署成为可能。
3. 应用隔离
比如说服务器上部署了两个服务,Node服务和Java服务,可能会出现两个服务器争夺服务器CPU资源的情况出现。Docker提供了进程级的隔离,可以精细地设置CPU和内存的使用率,更好的利用服务器的资源。
4. 自动化扩容/缩容
很多企业会存在流量不均的场景,比如说京东双十一期间,服务器的自动扩容就很关键。在Docker中,每个容器都可以作为单独的进程运行,可以共享底层的操作系统资源。可以提高容器的启动和停止效率(VMware就很笨重),扩容效率很高。
5. 节省成本,一体化管理
Docker不需要虚拟出整个操作系统,只需要虚拟出一个小规模的环境,可以节省出很多服务器资源。
可以通过下表了解一下虚拟机和容器的区别
特性 | 虚拟机 | 容器 |
隔离级别 | 操作系统级别 | 进程 |
隔离策略 | Hypervisor(虚拟机监控器) | Cgroup(控制组群) |
系统资源 | 5%~15% | 0-5% |
启动时间 | 分钟级 | 秒级 |
镜像存储 | GB~TB | KB~MB |
集群规模 | 上百台 | 上万台 |
高可用策略 | 备份、容灾、迁移 | 弹性、负载、动态 |
在实际应用中,不需要纠结选择虚拟机还是容器,二者存在本质的区别:
1. 虚拟机解决的核心问题是资源调配
2. 容器解决的核心问题是应用开发、测试和部署
依据实际情况选择就好
Docker的基本组成
Docker的三大组成
根据Docker官方提供的架构图来说明,参考下图:
1. 客户端(Client)
Docker客户端作为用户的使用界面,接受用户命令和配置标识,可以执行docker build
、docker pull
、docker run
等命令。
2. 宿主机(Docker Host)
这里主要是Docker daemon(Docker守护程序),用于侦听Docker API请求并管理Docker对象,守护进程也可以与其他守护进程通信以管理Docker服务。
3. 注册表服务(Registry)
Docker注册表用于存储Docker镜像,通常情况下,开发人员构建完Docker镜像后,即可以在当前宿主机上运行容器。一个Docker Registry可以包含多个仓库,每个仓库可包含多个镜像标签,每个标签对应一个Docker镜像。
Docker的三大核心概念
Docker的三大核心概念:镜像(Image)、容器(Container)和仓库(Reponsitory)。
- 镜像从本质上说Docker镜像是一个Linux的文件系统,包含可以运行在Linux内核的程序及相应的数据。因此,通过Docker镜像创建一个容器,就是将镜像定义好的用户空间作为独立隔离的进程运行在宿主机的Linux内核上。镜像有以下两个特征:
- 分层(Layer):一个镜像可以由多个中间层组成,多个镜像可以共享同一中间层。也可以通过在镜像上多添加一层来生成一个新的镜像。
- 只读(Read Only):镜像在构建完成之后,便不可以再修改。多添加一层构建新的镜像,是通过创建一个临时的容器,在容器上修改,从而实现的。
- 容器
容器和镜像的关系,如果面向对象编程中对象与类之间的关系。因为容器是通过镜像创建的,先有镜像才能有容器。而生成的容器是一个独立于宿主机的隔离进程,并且有属于容器自己的网络和命名空间。 - 仓库
镜像仓库的作用类似于Github,主要用于集中存储镜像,可以托管在Docker Hub上。仓库可以分为公共仓库和私有仓库。