Docker
简介
Docker是一个用Golang语言实现的开源项目,通过Docker可以将程序以及程序依赖的环境以及组件都打包到容器(Docker Container)。
Docker可以屏蔽底层硬件的差异,Docker的配置文件Dockerfile可以在不同的操作系统,不同的硬件平台实现快速打包部署等功能。
Docker最初是dotCloud公司的内部项目,dotCloud公司在2008年由Kamel Founadi、Sebastien Pahl共同创建,目标是利用容器技术方便构建"大规模的创新工具"。
2013年3月20日,dotCloud发布了Docker的首个版本,并将其开源。此项技术能够将Linux容器中的应用代码打包并轻松的在服务器之间迁移。2013年3月25日dotCloud加入linux基金会。docker官方博客提到,docker使用了许多linux社区开发的软件和技术,因此linux社区的发展和壮大对docker来讲也是非常重要的。
2013年9月,红帽公司成为Docker的主要合作伙伴,利用Docker来支撑其OpenShift云业务。随后,谷歌、亚马逊以及DigitalOcean也迅速的在其云服务平台提供了Docker的支持。主流云厂商的加入,加速了Docker的发展进度。同年12月底,DotCloud Inc则更名为Docker Inc,全力推进Docker的研发工作。
2014年6月的DockerCon大会上Docker正式发布了Docker 1.0 版本。会议上同时发布Docker Image的镜像仓库Docker Hub。同样在2014年6月,基于google公司的Borg系统的Kubernetes发布。
2015年6月,由Docker、IBM、微软、红帽及Google等厂商所组成的开放容器项目OCP联盟成立,该项目旨在建立软件容器的通用标准。OCP成立于Linux基金会之下,其使命是使用户和公司能够继续创新和开发基于容器的解决方案。
2016年6月的DockerCon上,Docker宣布了Open Container Initiative的正式成立。OCI意在业界一起合作,开发一个开放的、标准的容器格式和runtime。OCI也属于Linux基金会的协作项目,一直秉承着开放的模式来管理。
2016年,OCI标准制定后,Docker 将 containerd 独立拆分,并将其捐赠给了社区。将这个组件分解为一个单独的项目,使得 docker 将容器的管理功能移出 docker 的核心引擎并移入一个单独的守护进程(即 containerd)。
2017 年于 Austin 举办的 DockerCon 上开源Docker项目正式命名为 Moby 项目。与此同时,Docker公司也将Docker拆分为Docker-CE免费版和Docker-EE商业版。
后来Docker项目加入了linux基金会。
容器
Docker专注于解决服务/应用之间的隔离问题,传统上该问题的解决方案都是虚拟机技术。
和虚拟机通过操作系统实现隔离不同,容器技术只隔离应用程序的运行时环境但容器之间可以共享同一个操作系统,这里的运行时环境指的是程序运行依赖的各种库以及配置。
docker基于linux内核的cgroup,namespace以及AUFS类的Union FS等技术,对进程进行了封装隔离,实现了轻量级的虚拟化。
容器更加的轻量级且占用的资源更少,与操作系统通用几G的内存占用相比,容器技术一般只需要几M空间,因此我们可以在同样规格的硬件上部署大量容器,而且不同于操作系统数分钟的启动时间容器几乎瞬时启动,容器技术为打包服务栈提供了一种更加高效的方式。
docker里面重要的概念包括dockerfile,image以及container。
dockerfile
dockerfile是用来构建镜像的文本文件,文件包含了构建镜像的指令。常用的指令如下:
指令 | 作用 |
---|---|
FROM | 指定当前镜像是基于哪个镜像的 |
RUN | 构建镜像时需要运行的指令 |
EXPOSE | 当前容器对外暴露的端口号 |
WORKDIR | 指定在创建容器后终端默认登录进来的工作目录 |
ENV | 用于在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝到镜像 |
COPY | 拷贝文件和目录到镜像 |
VOLUME | 容器数据卷,用于数据持久化 |
CMD | 指定一个容器启动时要运行的命令 |
ENTRYPOINT | 指定一个容器启动时要运行的命令,ENTRYPOINT指令对于命令的覆盖是比CMD指令更加复杂,通常用于比较固定的命令 |
image
使用Dockerfile构建镜像的过程中,每执行一条指令都会基于之前的镜像构建一个新的镜像,所以镜像是层层叠加构成的。
分层的优点如下:
共享资源,当多个镜像基于同样的镜像构建,Docker host只需要加载一份基础镜像就可以为所有的容器提供服务。
当容器启动时,一个新的可写层被加载到镜像的顶层,这一层通常被成为“容器层”。
对容器的改动,无论添加、删除、还是修改文件都只会发生在容器层中。
容器层是可写的,镜像层是只读的。
只有当需要修改时才赋值一份数据,这种特性被称为Copy-On-Write。
仓库集中存储了镜像文件,其中registry是仓库主服务器,目前最大的公开仓库是docker Hub,存放了数量庞大的镜像供用户下载。
container
Docker容器是基于镜像创建的执行实例,它可以被启动,开始、停止、删除。每个容器相互隔离,具有自己的文件系统,进程系统,网络系统等,可以视为一个轻量级的linux运行环境。
容器基于linux的namespace实现。namespace经常翻译为名字空间,命名空间内的资源对其他命名空间不可见。
目前namespace可以隔离的资源包括文件系统,进程,CPU,网络等。
和linux系统类似,Docker中有一个很特殊的进程,PID为1的进程,也就是docker的主进程,该进程通过Dockerfile文件中的ENTRYPOINT或者CMD指令进行指定,当主进程退出的时候,容器所拥有的PID命名空间会被销毁,容器的生命周期也就结束了,这也是容器的主进程不能后台启动的原因。
原理
跨平台
虚拟化
Docker采用了CS即client-server模式进行实现,docker client负责处理用户输入的各种命令,例如docker build,docker run等,server即docker demon负责真正执行。
不同于传统的虚拟机技术通过宿主机的能力接口实现虚拟层操作系统,Docker容器技术基于操作系统的namespace技术,实现了一个自治隔离的系统,例如容器内有一个pid为1的进程,是基于linux内核支持的PID命名空间实现的,Docker可以在容器内启动新线程,命名空间隔离下的容器彼此看不到对方的进程,但是宿主机可以看到运行在其上所有容器的内部进程。
Docker基于Linux内核的一些功能实现:
- Namespace
Namespace是一种资源隔离机制,可以把Linux下PID,IPC,网络等全局资源隔离在特定的Namespace,不同Namespace下的资源不会相互影响。
- Control groups
Namespace实现了资源在不同命名空间下的隔离,但是进程可以不受控的访问CPU,内存,网络,磁盘等系统资源,Docker采用cgroup即crontrol groups技术可以实现对资源消耗的管控。Docker没有完整实现操作系统,最终是运行在宿主机上,Docker甚至可以不包含任何操作系统的东西,一个空的镜像可以只是一个简单的文件系统。当然一般情况下,Docker会基于某个linux发行版构建,会带上一些发行版的打包工具等,例如基于ubuntu构建的镜像一般可以使用apt-get来安装软件。但是即便如此,ubuntu也不会实现发行版的功能或者附带实现,这些命令最终是通过宿主机的linux内核来运行的。
因为依赖linux内核功能,所以Docker只能运行在linux系统上,window和mac下的Docker其实是跑在虚拟机上面。
安装
yum install docker
使用
Compose
Docker容器的最佳实践是每个容器运行单个进程,但是实际场景中,一个服务的启动往往需要和其他进程配合使用,例如LAMP架构,apache,memcached,php等几个进程经常需要配合使用。
源码安装
Docker compose可以用于多容器的管理。
[root@VM-0-5-centos yum.repos.d]# curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 11.1M 100 11.1M 0 0 5714k 0 0:00:02 0:00:02 --:--:-- 9.8M
[root@VM-0-5-centos yum.repos.d]#
[root@VM-0-5-centos yum.repos.d]# chmod +x /usr/local/bin/docker-compose
[root@VM-0-5-centos yum.repos.d]#
[root@VM-0-5-centos yum.repos.d]# docker-compose --version
docker-compose version 1.23.1, build b02f1306
安装包
sudo yum install epel-release
sudo yum install -y python-pip
sudo yum -y install python36-devel
sudo pip install docker-compose
mac版本的docker默认带有compose