过去几年 docker一直在各种技术人员之中流行,但是 docker是什么为什么他这么流行,为什么越来越多的公司在使用它,作为一个技术人员,这么流行并广泛使用的东西,如果你不了解它,那么你就会落后于他人。
那么 docker 到底是什么?为什么会让技术人员如此兴奋。他是一个应用软件吗?还是一个服务,一个桌面软件,还是一个 Cli 工具,当然,他和蓝鲸没什么关系!(此处应该哈哈哈)
在这篇文章中,我会尝试解答下面这些问题?
- 什么是 dokcer?
- 为什么需要 docker?
- 它能解决什么问题?
- 它和虚拟机的区别?
- 何时应该使用它而不是虚拟机?
- docker 中的 images 和 containers 这两个概念分别是什么意思,以及怎么实现的?
我会按照问题的顺序来回答这些问题,但是我解释的每个问题,都要了解之前的概念,如果你没有理解,可以再读几次,我建议这个文章可以读两次来收获你的 “aha moments”。
什么是docker?
在互联网上很多东西都拥有 docker 这个名字,对于新手来说,了解这些意思或非常困难,我们花一点时间来的里了解一下不同的意思。至少知道在我们的文章中,docker 代表着什么。
- Docker, Inc
- Docker engine (community / enterprise )
- Docker for Mac
- Docker for windows
- Docker client
- Docker host
- Docker server
- Docker hub
- Docker registry
- Docker compose
- Docker swarm
- Docker machine
- Docker daemon
这里有很多词,我将给每个词一个简短的定义,让你知道他是什么?
Docker, Inc
Docker 公司2010年在旧金山创立。当时的名字还叫dotCloud,他们当时的主要经营一个 PaaS 类型的业务,有点像Heroku,他们当时主要使用 liunx 容器来支撑这个业务。
2013年的3月,Solomon 在 PyCon 上发布了一款名字叫 docker 的新产品,他在演讲中提到开发docker的动机是为了简化linux容器的复杂度,让每个人都可以轻松使用,于是诞生了docker。
2013年年底的时候,dotCloud 公司将自己的名字更改为 docker ,并且将Paas业务拆分了出去,专心的进行docker 的开发和维护。
docker 是用 go 语言开发,而且就在2017年,docker 公司将 docker 改名为 moby。
Docker sofaware
docker 有两个版本 docker-CE 社区版,和docker-EE 企业版,对于和人和小团队,CE 更适合使用,因此我不会详细介绍 EE, CE 是免费的,EE 是 docker 公司的营收来源。
docker 有两个独立的程序,一个是 docker engine ,即 docker 的守护进程在后台运行,还有 docker 客户端。
Engine / Daemon
Docker Engine 是 docker 的大脑,负责在隔离环境中运行进程,为每个进程生成一个新的容器,分配文件系统,网络接口,IP , NAT。然后运行这个进程。
它管理着镜像和容器,创建删除镜像,启动容器之类的许多其他东西,并且公布了控制守护进程的API 。
Client
docker 客户端提供了cli 来控制 Docker Engine ,本质上他是一个http api的包装器,Engine 和客户端可以位于不同的计算机,你可以使用 bash 的 docker 命令来使用 cli。
对于不同的操作系统,Mac 和 windows,docker 也提供了相应的图形界面,但是主要使用还是通过命令行来进行的,图形界面只能进行一些简单的设置,更新之类的功能。
在 Mac 中 docker 是基于 HyperKit 实现的,windows 中是 Hyper-v 来实现的,并且提供windows容器,你可以在windows中同时运行三个操作系统的容器。
Hub
docker hub 是一个中心化的 docker 镜像中心,大部分开源的镜像都可以在其中找到,比如 ant-design-pro的镜像,使用时只需要简单的 pull,然后 run,就可以快读的部署成功,不需要考虑任何环境的问题,除了 docker。
Registry
Registry 是一个用于创建私有仓库的程序,你可以方便在你的本地创建一个属于你的私有仓库,并且让你的 docker 从这里下载。docker hub 就是一个开放的docker registry 。
Machine
Docker machine 是一个用来管理多台 docker 服务器的工具,你可以通过它来编排多台 docker 服务,启动,检查或者重启他们。而不必一台台的进行处理。
Compose
_
Docker compose 也是一个管理工具,不同的是他是用来管理多个互相依赖的docker 镜像, 你可以通过 YAML文件中配置,在启动的时候他们会按照顺序启动,并且被编排在同一个网络中,比如你的前端 ,后端 ,数据库。你可以通过一个配置,让他以正确的顺序启动。
swarm
Docker swarm 用来管理多个服务器的多个容器。但是是个半成品,实际使用中一般都使用 Google 开源的 Kubernetes,几乎所有的云平台用的都是 Kubernetes,包括阿里云。
Kubernetes 简称 k8s
根据上面的信息我们可以大致的了解到关于 docker 的信息,docker 不是软件是一个平台或者说是技术方案,当人们说起 docker 的时候,一般都是指 docker-ce 或者是 docker-ee。
Docker 是 docker 公司开发,简化了linux 容器的使用,他是由多个运行和管理工具组成的,其中包括:
- Docker engine 负责生成和运行容器
- Docker 客户端是一个独立的程序,用于控制 docker engine.
- Docker compose,docker machine 和 docker swarm 是编排工具,用来管理 docker 容器,在实际使用中几乎是必须要的,除非你想手动管理一个个的容器。
- Docker hub 是一个提供 docker 镜像的的服务,它可以存储我们的镜像,也可以下载别人的镜像。
- Docker 的图形界面可以简化 docker 的配置和使用。适合新手
如果你是个新手,你应该了解各种 docker
如图所示,docker 的服务和客户端并不处于同一个计算机,这样就可以通过一条计算机来管理会很多台服务器,会大大的方便使用。
Virtual Machines
每个使用 docker 的人都会问一个问题,他和虚拟机有什么区别,为什么我会使用 docker 而不是的虚拟机。对于这个问题我们需要先了解一下。
在 docker 之前大家一般使用虚拟机来进行硬件的虚拟化管理。我们很容易从图中看出问题。即每个容器都有自己的内核和 虚拟机,多个虚拟的叠加让硬件的资源有很大的浪费,一旦为一个虚拟机分配了资源,那么即使 虚拟机什么都不做,虚拟机也会保留资源,然而大部分情况下,他可能不需要这么多昂贵的RAM。
另外一个问题是他的启动时间,如果你需要重启虚拟机,那么你需要重启整个内核,并且所有的服务都会停止运行。
Containers to the rescue
简单的讲,容器就是没有内核的虚拟机,它使用操作系统的内核,为了实现这一点,我们需要一个系列的软件和库,允许容器使用 OS 的内核,如果你愿意,还可以将他们链接起来,举个栗子:liblxc 和 libcontainer
libcontainer 由 docker 公司开发,并且在 docker 中使用。
容器有自己的文件系统,ip 和库,二进制文件和服务都安装在容器内,但是系统调用和内核功能都来自底层操作系统。
容器非常轻便,启动和重启也非常的快,因为他们不需要启动内核,他们不会浪费物理资源。因为他们没有单独的内核。
但是有一个缺点是:容器只能运行与底层操作系统相同的容易,你无法再 window 或者 mac 上运行 linux 容器,因为他们都需要 Linux Kennel 才能运行。mac 和 window 用户的解决方案是先安装一个虚拟机,然后在虚拟机中运行 容器( 这也是 docker for windows 和 docker for mac 的主要功能 )。
设置和运行 liunx 的容器并不简单,你需要对 linux 一定的了解,管理他们是一件更加乏味的事情。
正如我上面提到的 docker 公司做的是让 linux 容器变得更加容易使用,由于 docker,你不需要精通 linux ,也可以很方便的使用容器。
容器VS虚拟机
看完上面的文章,你可以认为容器比虚拟机更好,但是并非如此。
容器的目的是在隔离的环境中运行进程,每个 docker 容器就是一个进程。虚拟机则可以模拟任何操作系统,如果你愿意,你甚至可以再 ipad 中装一个 win10,他们不会相互影响。
虚拟机更加安全,因为容器直接调用系统内核,这样带来很多安全漏洞。
一些直接与内核混淆的基本软件应该在虚拟机中沙盒化。
一般情况下,你会在生产环境中看到在虚拟机中运行的 docker,这两者配合的很完美。
Docker 镜像和容器
docker 中引入了几个简化的概念,也可以说他改变了 linux 容器的使用,
docker 的的 linux 容器由名叫 “images” 的模板构成,本质上是一个二进制文件,他保存了 linux 的状态,有点像虚拟机的.vdi
, .vmdk
或 .vhd
文件。
不同的是 docker 中的镜像是只读的,在虚拟机中任何的操作都会保存在镜像中,镜像类似于机器的硬盘。
但是 docke 中图像时只读的,你不能直接运行它,而是复制一个镜像然后运行,每一个运行的镜像示例被称为一个容器。你可以同事运行一个镜像的多个示例,无法发生什么都不会影响它的镜像。
Docker 间通信
一个 docker 容器应该只是运行一个进程,那么自然而然会产生一个问题,如果我们一个应用程序,他有前端,后端和数据库,那么我改如何连接他们,在这种情况下我是没办法访问 localhost的。所以 docker 中为独立容器引入了网络。
网络使用情况的概述如下所示:您创建一个新网络,仅为此网络创建子网。您启动一个容器并将其连接到此网络,并且连接到同一网络的所有容器将能够相互 ping 通,就好像它们位于LAN上一样。然后,您可以从一个容器中运行的一个服务连接到另一个容器中运行的服务,只要它们位于同一网络上即可。
// 创建一个网络
docker network create <name>
// 列出所有网络
docker network list
// 连接到网路
docker run --network <name> <image>
Volumes
容器中是无法保存任何数据的,但是如果我们需要保存一些文件呢,某些容器的运行是有状态的,就像数据库一样,数据需要保存数据,这正是数据库的目的,但是如果我们将其存放在容器中,容器消失,数据也消息,我们就无法在示例中共享任何数据。
为了解决这个问题 docker 引入了Volumes,Volumes允许我们将数据存储在主机上,设置云上,并且将多个容器链接到这个存储上。
docker run -d -v /folder-on-host-machine/data/db:/data/db — net=myTestNetwork mongo
该-v
将 volumes 安装到容器,因此现在主机文件夹/folder-on-host-machine/data/db
和容器之间的数据/data/db
将会被同步,我们可以运行 MongoDB 容器的多个实例,并将它们全部链接到主机上的此卷。如果其中一个实例关闭,另一个实例仍然可用且数据不会丢失,因为数据存储在主机上,而不是存储在容器内。容器本身应该是无状态的。
最后的话
这些就是 docker 中一些主要的概念,简而言之,docker 是一项足以改变世界的技术,彻底改变了我们开发,部署和扩展应用的方式,在本文中我们只是简单介绍,还有更多的等你发现。