一、Docker简介
1.1 Docker概述
Docker是一个开源的应用容器引擎,使用Go语言编写。让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。几乎没有性能开销,可以很容易的在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包装系统。
1.2 Docker容器技术和Vmware虚拟机的对比
容器是一个应用层抽象,用于将代码和依赖资源打包在一起,多个容器可以在同一台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行,不占用任何其他可执行文件的内存,是一个轻量级程序。与虚拟机相比,容器占用的空间较少(容器镜像大小通常只有几十兆),瞬间(秒级)即可完成启动。
虚拟机(VM)是一个物理硬件层抽象,运行一个完整的客户操作系统。用于将一台服务器变成多态服务器,管理程序允许多个VM在一台机器上运行,每个VM都包含一整套操作系统,一个或多个应用,必要的二进制文件和库资源,因此占用大量空间,而且VM启动也十分缓慢。
1.3 Docker容器相关技术
Docker是基于Linux内置的Namespace和Cgroups等系统内隔离机制而抽象出来的一种轻虚拟化技术。
Docker使用的容器技术依赖于Linux内核特性:Nmamespaces和Cgroups(Control)。
1.3.1 Namespaces命名空间
Namespaces是很多编程语言都包含了命名空间的概念,可以认为命名空间是一种封装的概念,封装本身实现的是代码隔离。
在操作系统中,命名空间提供了系统资源(包括进程、文件系统和网络等)的隔离,实现轻量级虚拟化服务。在同一个命名空间下的进程可以感知彼此的变化,而不同命名空间的进程一无所知。这样,就可以让容器中的进程产生一种错觉:仿佛自己置身于一个独立的系统环境中,以此达到独立和隔离的目的。
Namespace使用了五种命名空间:
- PID(Process ID):提供进程隔离
- NET(Network):用来管理网络接口
- IPC(Inter Process Commun):用来管理跨进程通信的访问
- MNT(Mount):用来管理挂载点,也就是文件系统相关的隔离
- UTS(Unix Timesharing System):用来隔离内核和版本标识
1.3.2 Cgroups控制组
Cgroups是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理资源的机制。Cgroups就是为实现容器技术而生。
Cgroups作用
- 用来提供资源限制(比如Memery子系统可以为进程组设定一个内存使用的上限,一旦进程组使用的内存达到了限额,再申请内存就会触发OOM的消息)
- 优先级设定:通过分配的CPU时间片数量及硬盘IO带宽大小,实际上就相当于控制了进程运行的优先级
- 资源统计:可以计算系统的资源使用量,如CPU使用时长、内存用量等等,非常适用于计费系统
- 进程控制:可以对进程组执行挂起、恢复等操作
二、docker核心概念
- Docker Client客户端
- Docker Daemon守护进程
- Docker Image镜像
- Docker Container容器
- Docker Registry仓库
2.1 Docker架构
Docker使用C/S架构。Docker客户端向Docker服务端(也就是Docker守护进程)发出请求,守护进程处理完所有的工作并返回结果。Docker客户端对守护进程的访问既可以在本地,也可以通过远程来访问。
Remote API:Restful风格API,支持STDIN、STDOUT、STDERR来进行通讯与交互
客户端和服务端通过socket进行连接。有三种连接方式:unix:///var/run/docker.sock(默认)、tcp://host:post、fd://socketfd
2.2 Images镜像
镜像是Docker容器的基石,容器基于镜像启动和运行。
Docker镜像是一个层叠的只读文件系统,最低端为一个引导文件系统(即bootfs),Docker用户几乎永远不会和引导文件有交互。实际上,当一个容器启动后,它将被移动到内存中,而引导文件系统则会被卸载。
Docker镜像的第二层为root文件系统(rootfs)。它位于引导文件系统之上。root文件系统可以是一种或多种的操作系统,如Ubuntu、CentOS,在传统的Linux引导过程中,root文件系统会最先以只读的方式加载。当引导结束并完成了完整性检查后,它才会被切换为读写模式。但是在Docker里,root文件系统永远只能是只读状态,并且Docker利用联合加载技术,又会在root文件系统之上加载更多的只读文件系统。
union mount(联合加载技术)指一次同时加载多个只读文件系统到root文件系统之上,但在外围只能看到一个文件系统。联合加载会将各层文件系统叠加到一起,让最终的文件系统会包含所有的底层文件和目录。Docker将这样的文件系统称为镜像。
一个镜像可以放到另一个镜像的顶部,下面的镜像称为父镜像,最底部的镜像称为基础镜像,也就是root文件系统。
2.3 Container容器
Docker容器通过镜像来启动。容器中可以运行客户的一个或多个进程。
当一个容器启动时,Docker会在该镜像的最顶层加载一个读写文件系统(也就是一个可写的文件层)。在Docker中运行的程序就是在这个层中进行执行的。当Docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上。比如,如果向修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层,该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏,这是Docker的一个重要机制:写时复制。
每个只读镜像层都是只读的,并且以后永远不会变化。当创建一个新容器时,Docker会构建出一个镜像站,就像图中所表现的,在栈的最顶层,添加可写层,这个读写层加上下面的镜像层以及一些配置数据就构成了容器。
2.4 镜像和容器的关系
镜像和容器好比是对象和类的关系。
镜像可以理解为一个系统镜像,容器是镜像在运行时的一个状态。
如果拿虚拟机做一个比喻的话,镜像就是关机状态下的磁盘文件,容器就是虚拟机运行时的磁盘文件,包含内存数据。
2.5 Docker Registry仓库
Docker仓库来保存用户构建的镜像。仓库分为公有(如Docker Hub)和私有两种。
三、Docker安装
3.1 Ubuntu安装Docker
1.安装前需检查内核版本(需高于3.10)
ycy@ubuntu18:~$ uname -r
5.0.0-20-generic
2.apt-get方式安装
ycy@ubuntu18:~$ sudo apt-get install docker.io -y
ycy@ubuntu18:~$ source /etc/bash_completion.d/docker.io#更新配置
3.测试docker版本
运行docker --version,查看docker版本
运行docker info(或docker version),查看有关dockers系统信息,包括镜像和容器数