前言:
我自认为我对docker的了解依然处于一个比较初级的阶段,更高级的内容怕说不明白,以至于误导别人,写这个主要是总结一下学习的笔记;
1.什么是docker?
Docker是基于Go语言实现的在2013年发布的云开源项目,它利用了围绕容器这个现有的计算概念,特别是在Linux世界中,这些原始概念被称为cgroups和命名空间。Docker的技术之所以独特是因为它专注于开发人员和系统操作员的需求,以将应用程序依赖项与基础架构分开。
Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
一句话概括,Docker的出现解决了运行环境和配置环境不一致的情况,从而更方便的做持续集成并有助于应用的整体发布。
2.为什么是Docker?
要了解这个问题,我们就需要了解在Docker之前的传统的虚拟机技术是怎样的,我相信大家都有使用过虚拟机软件在自己电脑上虚拟出另外一个操作系统的经历,比如在win上通过vm安装一个linux系统,传统的虚拟机其实是一种带环境安装的解决方案,也就是说,我模拟的是一套完整的操作系统环境,这个系统依然是有它独立的内核,驱动等等。
如图所示:
对于虚拟机中运行的程序而言,由于虚拟机模拟了一整套系统的环境,那么在虚拟机中运行的应用程序是感知不到自己是在虚拟机中运行的,就像和在真实的操作系统中运行一样。
当然,看到这,很多人可能会觉得,这不是挺好的吗,的确,在需求不是很大,比如只需要额外开两三台虚拟机的情况下,这种做法并没有什么明显的短板,但是,由于我们模拟的是一整套操作系统的环境,这就导致了什么问题呢,我们每开一个虚拟机都会额外占用很大一部分资源,尽管你可能两台虚拟机中的linux系统内核是一模一样的,这就造成了对资源的一个很大的浪费,同时呢,由于我们启动虚拟机的时候启动的是一整套操作系统,这就会导致启动变得非常的慢,可能需要几分钟,当然,几分钟并不是很长,可是如果有很多台虚拟机呢?可能当运维工程师好不容易把所有虚拟机启动完成了,发现秒杀活动已经结束了,如此长的启动时间对于很多大规模的应用来说是不能忍的,第三点,就是步骤非常繁琐,我们现在总结一下传统虚拟机最主要的三个缺点:
- 资源占用比较多
- 启动比较慢
- 步骤繁琐
当然,时代再进步,linux也不能看着这些问题放任不管啊,于是linux发展出了另外一项虚拟化技术,即linux容器技术。
linux容器技术是怎么一回事呢,这点和我们在实际开发中抽取公共逻辑的思路是类似的,之前不是开很多虚拟机内核什么的都一样造成资源浪费吗,那我这下把内核单独抽离出来,大家公用,所以linux容器实际上运行的并不是一个完整的操作系统,而是通过进程对不同的容器进行了隔离,容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
如同所示:
由于启动的时候,启动的并不是整套操作系统环境,仅仅是启动应用所需的环境就行了,启动速度自然就比传统的虚拟机快了很多,甚至说可以做到秒启动,同时又解决了资源浪费的问题,而Docker正是基于linux容器技术而衍生出来的开源项目,使其对于广大开发者来说更容易上手,降低了使用的门槛。
3.Docker 具体解决了什么样的问题?
传统的开发中总是会很容易出现这类开发环境和生产环境不一致的问题,而Docker的出现毫无疑问极大地简化了运维工程师的工作量,也大大降低了开发和运维之间撕逼的概率。大家这么来理解:
我们以搬家为例,传统的流程就可以看作是把所有家具一件一件地搬到新的地方,万一哪个家具的摆放位置没记清楚,就有可能导致新家运行不起来(??什么鬼),比如mysql版本没说清楚,而Docker就很简单粗暴,Docker采取的方式就是把整套环境打包给你,也就是直接把整个楼都给你搬过去,问题完美解决。
同时呢,Docker是内核级虚拟化,不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率。
总结起来,docker大概就是以下四个优点:
- 更快的应用交付和部署
- 更便捷的升级和扩缩容
- 更简单的系统运维
- 更高效的计算资源利用
不得不说,实在是太香了。
4.Docker 三要素 镜像 容器 和仓库
Docker 镜像是一个只读的文件系统,包含了应用程序及其依赖项、运行时环境、配置文件等。
Docker 容器则是一个可读写的文件系统,基于镜像创建而来,并运行在隔离的用户空间中。
Docker 仓库是用于存储和组织镜像的地方。仓库可以是公共的(如Docker Hub)或私有的,用户可以通过仓库来分享和获取镜像。
镜像和容器的关系:
当容器启动时,Docker 引擎会在镜像的基础上创建一个新的容器层,并为其分配一个独立的文件系统、网络和进程空间。在容器中,可以修改文件系统、安装应用程序和库、运行进程等。但是这些修改不会影响到原始的镜像文件。
通俗一点讲:docker容器和镜像的关系类似于 Java代码中 类和实例的关系,镜像是一个抽象的概念,可以被多个容器实例化为具体的应用程序运行环境。一个docker容器可以同时用于多个容器的运行,每个容器之间相互独立,互不影响。
Docker d1 = new Docker();
Docker d2 = new Docker();
就像以上两行代码,可以理解为,镜像在这里就是我们的Docker,容器就是一个个Docker类的实例。一个Docker可以创建多个实例,一个镜像也可以创建多个容器。
5.Docker的基础命令
镜像相关命令
列出本地所有的Docker镜像 | docker images |
从仓库下载指定的Docker镜像 | docker pull <镜像名> |
根据Dockerfile构建镜像 | docker build -t <镜像名> <Dockerfile路径> |
删除指定的Docker镜像 | docker rmi <镜像名> |
容器相关命令
列出正在运行的容器 | docker ps |
列出所有的容器 | docker ps -a |
创建并启动一个新的容器 | docker run <镜像名> |
启动已经创建的容器 | docker start <容器ID或名称> |
停止正在运行的容器 | docker stop <容器ID或名称> |
删除指定的容器 | docker rm <容器ID或名称> |
仓库相关命令
在Docker Hub上搜索镜像 | docker search <关键字> |
将镜像推送到指定的仓库 | docker push <镜像名> |
从指定的仓库下载镜像 | docker pull <仓库名>/<镜像名> |
其他常用命令
在运行的容器中执行命令 | docker exec -it <容器ID或名称> <命令> |
查看容器的日志 | docker logs <容器ID或名称> |
获取容器的详细信息 | docker inspect <容器ID或名称> |
使用Docker Compose启动应用程序 | docker-compose up |
这只是Docker的一些基础和常用命令的简要介绍。Docker有更多的功能和选项可供探索,你可以参考Docker官方文档以获取更详细的信息和了解其他命令