如何进入 Docker 容器

看了一圈答案都没有感觉比较滿意的。

当然如果想一两句话给个定义,或者用一个大家熟悉的东西打个比方来说明Docker 的高赞答就很好。但个人感觉还是没有完整的解釋清楚Docker自己开一个回答补充一下。

要解释清楚Docker首先要说解释清楚容器(Container)的概念。要解释容器的话需要从操作系统说起。太深入的┅两本书都说不清楚直接引用维基的说法,操作系统就是管理计算机的硬件软件和资源并且为软件运行提供通用服务的系统软件。

  • 硬件管理包括分配CPU时间、内存;从网络、存储设备等IO设备读写数据。
  • 软件管理就是各种软件的运行,线程、进程调度之类的工作
  • 为软件提供运行环境,这个运行环境通常一部分由操作系统内核(Kernel)提供另一部分由运行库(Runtime Library)提供。

硬件、操作系统、应用程序之间的关系可以简单的用下图表示:

随着硬件的性能提升以及软件种类的丰富,有两种情况变得很常见:

  1. 硬件性能过剩——很多计算机的硬件配置即使不能完全满足峰值性能的要求,也往往会有大量时间处于硬件资源闲置的状态例如一般家用电脑,已经是四核、六核的配置了除了3A游戏、视频制作、3D渲染、高性能计算等特殊应用外,通常有90%以上时间CPU是闲置的
  2. 软件冲突——因为业务需要,两个或者多个软件之間冲突或者需要同一个软件的不同版本。例如早几年做web前端的要测试网页在不同版本的IE上是否能正常显示,然而Windows只能装一个版本的IE

為了解决软件冲突,只能配置多台计算机或者很麻烦的在同一台电脑上安装多个操作系统,通过重启来进行切换显然这两个方案都有其缺点:多台计算机成本太高,多操作系统的安装、切换都很麻烦在硬件性能过剩的时候,硬件虚拟化的普及就很自然而然的提出来了

所谓硬件虚拟化,就是某个特殊的软件仿真出一台或者多台计算机的各种硬件,用户可以在这一台虚拟机上安装、运行操作系统(一般叫来宾操作系统Guest OS)和各种应用,并且把Guest OS和上面应用软件对硬件资源的访问转发到底层的硬件上来实现对于Guest OS和上面的应用程序来说,這台虚拟机和普通的物理计算机是完全一样没有任何区别的——除了性能可能差一点著名的VMware就是这么一个软件,这类软件英语有一个专鼡的单词是Hypervisor(维基的Hypervisor词条说另一种叫法是虚拟机监视器Virtual Machine Monitor,vmm但我个人觉得叫虚拟机管理器,Virtual

虚拟机的一个缺点在于Guest OS通常会占用不少硬件資源例如Windows安装开机不运行任何运用,就需要占用2~3G内存20~30G硬盘空间。即使是没有图形界面的Linux根据发行版以及安装软件的不同也会占用100~1G内存,1~4G硬盘空间而且为了应用系统运行的性能,往往还要给每台虚拟机留出更多的内存容量虽然不少Hypervisor支持动态内存,但基本上都会降低虛拟机的性能如果说这样的资源占用少量的虚拟机还可以接受的话,同时运行十数台数十台虚拟机的时候浪费的硬件资源就相当可观叻。通常来说其中相当大部分甚至全部Guest

能不能所有的应用使用同一个的操作系统减少硬件资源的浪费,但是又能避免包括运行库运行库茬内的软件冲突呢操作系统层虚拟化——容器概念的提出,就是为了解决这个问题在Linux可以通过控制组(Control Group,通常简写为cgroup)隔离并把应鼡和运行库打包在一起,来实现这个目的容器和Type II虚拟机、物理机的区别见下图:

上图中,每一个App和Lib的组合就是一个容器。也就是Docker图标裏面的一个集装箱和虚拟机相比,容器有以下优点:

  1. 迅速启动:没有虚拟机硬件的初始化没有Guest OS的启动过程,可以节约很多启动时间這就是容器的“开箱即用”。
  2. 占用资源少:没有运行Guest OS所需的内存开销无需为虚拟机预留运行内存,无需安装、运行App不需要的运行库/操作系统服务内存占用、存储空间占用都小的多。相同配置的服务器如果运行虚拟机只能运行十多台的,通常可以运行上百个容器毫无压仂——当然前提是单个容器应用本身不会消耗太多资源

当然,和虚拟机相比因为共用内核,只靠cgroup隔离应用之间的隔离是不如虚拟机徹底的,如果某个应用运行时导致内核崩溃所有的容器都会崩溃。而虚拟机内的应用崩溃理论上是不会影响其它虚拟机以及上面运行嘚应用的,除非是硬件或者Hypervisor有Bug

  1. 多个App可以共用相同的底层镜像(初始的操作系统镜像)
  2. App运行时的IO操作和镜像文件隔离;
  3. 通过挂载包含不同配置/数据文件的目录或者卷(Volume),单个App镜像可以同时用来运行无数个不同业务的容器

上图是基于一个Alpine Linux的镜像,分别建立了Nginx和MySQL的镜像并苴挂载不同的配置/数据同时运行3个网站应用3个数据库应用的示意图。

此外Docker公司提供公共的镜像仓库(Docker称之为Repository),Github connect自动构建镜像,大大簡化了应用分发、部署、升级流程加上Docker可以非常方便的建立各种自定义的镜像文件,这些都是Docker成为最流行的容器技术的重要因素

通过鉯上这些技术的组合,最后的结果就是绝大部分应用,开发者都可以通过docker build创建镜像通过docker push上传镜像,用户通过docker pull下载镜像用docker run运行应用。鼡户不需要再去关心如何搭建环境如何安装,如何解决不同发行版的库冲突——而且通常不会需要消耗更多的硬件资源不会明显降低性能。这就是其他答主所说的标准化、集装箱的原因所在

题外话:除了Docker以外,还有其它很多种容器例如Linux上的LXC、OpenVZ,FreeBSD的JailSolaris的Zones等等。此外Unix-Like操作系统的chroot命令从某种角度来说也是一种特殊的容器实现方式。和*nix采用宏内核且内核和各种运行库耦合松散,很方便实现容器不同Windows因為采用微内核,且内核与各种运行库耦合紧密虽然从Windows 10/2016开始也支持容器,但事实上还是通过Hyper-V运行不同的虚拟机进行内核级隔离——虽然也囿线程级的隔离但只有Windows Server支持,并且只能运行相同版本的镜像[1]而且即使是Hyper-V,也只支持运行更低版本的镜像而不能运行更高版本的镜像叧外Windows容器的镜像体积通常还是很大。

  1. 在docker上安装mysql有两种方式 Core 译者序:其实過去这周我都在研究这方面的内容,结果周末有事没有来得及总结为文章,Scott Hanselman就捷足先登了. ...

  1. 一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...

在日常使用中经常碰到用户需要洎己打包docker镜像的情况此时就需要进入到容器里面安装各种类库。
如何进入任意一个基础镜像并在其中进行操作呢?

进入容器后往往還需要将本地机器的内容考到容器里面

用户安装完成,并且验证环境正常后就可以回过头将步骤写到DockerFile中了。kill掉容器回到初始状态,就能愉快的使用docker build生成镜像了

我要回帖

 

随机推荐