本指南包含docker基础理论知识点,主要用于忽悠面试官,如有失败,概不负责。
背景
各位程序员在开发过程中经常会出现在自己机子上跑得好好的程序,放到服务器上或者测试机子上就挂了,因为程序运行需要的环境发生了变化导致各种bug。那么如果能把程序连同运行的环境一起打包呢?
docker等容器就提供了这样的解决方案。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,结合jenkins持续集成就可以一键部署,大大简化了操作。
docker和虚拟机
上面的解决方案听起来就像装了个虚拟机,把程序运行在虚拟机上,那docker和虚拟机有什么区别呢?
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。操作系统其磁盘占用至少几十G起步,内存要几个G起步。启动时要从头到尾把该检测的都检测了该加载的都加载上,这个过程非常缓慢。
而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟,因此容器要比传统虚拟机更为轻便。每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
容器和镜像
(这个简单的问题竟然真的被问了两次)
镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。 它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。 可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
docker是怎么工作的
实际上docker使用了常见的CS架构,也就是client-server模式,docker client负责处理用户输入的各种命令,比如docker build、docker run,真正工作的其实是server,也就是docker demon,值得注意的是,docker client和docker demon可以运行在同一台机器上。
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。守护进程和客户端可以运行在同一台机器上。
docker容器之间怎么隔离
Linux中的PID、IPC、网络等资源是全局的,而NameSpace机制是一种资源隔离方案,在该机制下这些资源就不再是全局的了,而是属于某个特定的NameSpace,各个NameSpace下的资源互不干扰。
虽然有了NameSpace技术可以实现资源隔离,但进程还是可以不受控的访问系统资源,比如CPU、内存、磁盘、网络等,为了控制容器中进程对资源的访问,Docker采用control groups技术(也就是cgroup),有了cgroup就可以控制容器中进程对系统资源的消耗了,比如你可以限制某个容器使用内存的上限、可以在哪些CPU上运行等等。
有了这两项技术,容器看起来就真的像是独立的操作系统了。
联合文件系统(UnionFS)
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。UnionFS是一种分层、轻量级并且高性能的文件系统。联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Dockerfile
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。每条指令都会创建一个新的镜像层,并对镜像进行提交。