提出背景-容器
假设一个程序员在开发一个app时,在自己电脑上从头到尾搭建了一套环境,而在测试时需要在另一台电脑上进行,最终运行时又需要在第三台电脑上运行。一般的方式是分别在测试电脑与运行电脑上再重新搭建这套环境,但是这样一是搭建了3次环境,耗费时间;第二是由于硬件的以及操作系统的不同,可能即使搭建了相同的环境,相同的程序也无法正确运行。
这时提出,可以使用虚拟机来解决该问题,只需要开发人员配置好一套虚拟机环境然后clone给测试与运维,在容器技术出现前,这的确是一种好方法,但是该方法也存在缺陷。为了运行这一个应用程序,需要运行一台虚拟机,而对比一个应用,操作系统占用的资源其实更多,这样即浪费了存储也浪费了内存,并且虚拟机软件的启动也很慢,虚拟机软件的大小也不小。
具体而言,在学过了操作系统之后可以知道,计算机的系统其实分为内核和用户,其中后者通过系统调用的方式访问前者。虽然内核的程序并不大,但是通常需要维护许多数据结构,导致需要占用大量资源。虚拟机就是完全模拟了内核和其上的用户程序,而容器则是使用宿主机的内核,从而减少了资源开销。
于是,提出是否存在一种方法,即轻量又能隔离环境?
容器-docker
容器技术,可以视为一种“轻量化的虚拟机”,即隔离各应用的环境,但是又使用同一操作系统,而docker就是一种容器技术的实现。
docker中有三个关键概念:Dockerfile,image,container
其中image可以理解为类似操作系统的iso镜像文件,使用docker engine(类似vmware)可以实例化一个container(虚拟机实例)。而dockerfile则是说明如何构建一个image
举例说明
一般使用时,在工作文件夹下创建一个Dockerfile文件。内容首先 FROM 指明基础镜像,如果本地没有则可以从服务器下载。WORKDIR指明镜像(虚拟机)工作文件夹/app,之后都默认在该文件夹下。COPY . .将当前文件夹系下所有文件拷贝到/app下。RUN指令来运行指令。通过上述命令即可完成docker镜像的创建。
而使用CMD在 镜像运行起来后的容器 中运行命令
然后使用docker build -t docker_name .来构建镜像image,其中-t参数说明image名,.指明在当前文件夹下搜索dockerfile。第一次运行时会比较慢,因为docker会下载各种文件并按照操作构建,但是之后docker会将操作缓存在本地,第二次build时便会更快。
在build之后便可以docker run -p local_port:docker_port -d docker_name,直接通过已经构建的image来运行一个container。其中-d是指在后台运行,不在命令行输出运行过程;-p是指定将docker的一个端口映射到本地的一个端口。
额外操作
docker中的数据是在docker容器关闭后是不会保存的,就像是删除了虚拟机一样;此外,docker容器应该是“无状态”的,以便于迁移等。所以可以将容器数据保存在外部。docker中,可以创建一个数据卷,在容器启动时将该数据卷挂载到docker的文件目录下(像是外接了一个硬盘);并且,一个数据卷可以挂载在多个容器下,以实现分布式存储
docker volume create volume_name来创建一个数据卷,之后启动容器时添加-v参数,例如docker run -v volume_name:/path docker_name将数据卷挂载
docker-compose
通过docker,现在可以在环境中运行一个应用,但是如果有多个应用该怎么办?一种方法是在一个container中运行多个应用,但是存在一些问题,如应用之间要求的环境不同;当一个应用出问题时,需要停下整个环境来调试。所以通常是每个container中运行一个应用,但是要启动多个container需要多次docker run,很不方便。可以使用sh文件来完成,而官方则是提供了专用的工具docker-compose,来一次性打开多个docker。
docker-compose根据docker-compose.yml文件来运行
其中version与docker-engine版本有关,在services下可以打开多个container,如web,db;其中可以指定不同的镜像来源,如build,image。
完成后使用docker-compose up -d来运行该文件启动所有容器;要停止则使用docker-compose down。
额外内容
docker文件结构
一个容器中的文件结构和linux基本一致
不同版本image
docker和虚拟机不同,依旧是使用宿主机的内核,所以对于构建使用的image基础的linux版本有要求。一般来说,宿主机的高版本内核可以兼容docker的低版本镜像,反之则一般不行。
daemon.json文件
docker engine的配置文件,可以用于设置docker image的存储位置,image的大小,网络配置等