1. 简介
官方文档地址:https://www.docker.com/get-started
中文参考手册:https://docker_practice.gitee.io/zh-cn/
本笔记参考B站视频:【编程不良人】Docker&Docker-Compose 实战!
Docker中文文档:https://yeasy.gitbook.io/docker_practice/
1.1 什么是Docker
官方定义:
-
帮助开发人员和开发团队构建和发布应用
-
为开发人员和团队提供一个完整容器(container)解决方案
-
docker是一个容器技术
-
运行你的应用不需要你的环境(早起Docker官方定义)
1.2 Docker起源
- 历史
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。
- 开源
Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目 已经超过 5 万 7 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。
- 本质
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
1.3 优势
-
问题1:
在开发的时候,在本机测试环境可以跑,生产环境跑不起来
这里我们拿java Web应用程序举例,我们一个java Web应用程序涉及很多东西,比如jdk、tomcat、mysql等软件环境(配置环境非常繁琐)。当这些其中某一项版本不一致的时候,可能就会导致应用程序跑不起来这种情况。Docker则将程序以及使用软件环境直接打包在一起,无论在那个机器上保证了环境一致。
优势1: 环境一致,高效迁移
-
问题2:
服务器自己的程序挂了,结果发现是别人程序出了问题把内存吃完了,自己程序因为内存不够就挂了
这种也是一种比较常见的情况,如果你的程序重要性不是特别高的话,公司基本上不可能让你的程序独享一台服务器的,这时候你的服务器就会跟公司其他人的程序共享一台服务器,所以不可避免地就会受到其他程序的干扰,导致自己的程序出现问题。Docker就很好解决了环境隔离的问题,别人程序不会影响到自己的程序。
优势2:(操作系统)进程级隔离,容器独立
-
问题3:
公司要搞一个活动,可能会有大量的流量进来,公司需要再多部署几十台服务器
在没有Docker的情况下,要在几天内部署几十台服务器,这对运维来说是一件非常折磨人的事,而且每台服务器的环境还不一定一样,就会出现各种问题,最后部署地头皮发麻。用Docker的话,我只需要将程序打包到镜像,你要多少台服务,我就给力跑多少容器,极大地提高了部署效率。
优势3: 镜像机制,便于部署
1.4 Docker和虚拟机区别
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker
技术比虚拟机技术更为轻便、快捷。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fa3uKNxa-1651432281995)(https://vuepress.mirror.docker-practice.com/assets/img/virtualization.bfc621ce.png)]
由上图可知,Docker省略了Hypervisor
(虚拟层)和Guest OS
(来宾操作系统)。比较上面两张图,我们发现虚拟机是携带操作系统,本身很小的应用程序却因为携带了操作系统而变得非常大,很笨重
。Docker是不携带操作系统的,所以Docker的应用就非常的轻巧。另外在调用宿主机的CPU、磁盘等等这些资源的时候,拿内存举例,虚拟机是利用Hypervisor去虚拟化内存,整个调用过程是虚拟内存->虚拟物理内存->真正物理内存,但是Docker是利用Docker Engine去调用宿主的的资源,这时候过程是虚拟内存->真正物理内存。
传统虚拟机 | Docker容器 | |
---|---|---|
磁盘占用 | 几个GB到几十个GB左右 | 几十MB到几百MB左右 |
CPU内存占用 | 虚拟操作系统非常占用CPU和内存 | Docker引擎占用极低 |
启动速度 | (从开机到运行项目)几分钟 | (从开启容器到运行项目)几秒 |
安装管理 | 需要专门的运维技术 | 安装、管理方便 |
应用部署 | 每次部署都费时费力 | 从第二次部署开始轻松简捷 |
耦合性 | 多个应用服务安装到一起,容易互相影响 | 每个应用服务一个容器,达成隔离 |
系统依赖 | 无 | 需求相同或相似的内核,目前推荐是Linux |
1.5 核心架构和概念
1.镜像 (Image)
是什么
- 一个镜像代表一个应用环境/软件(最精简版linux系统加一个软件),他是一个只读的文件,如 mysql镜像,tomcat镜像,nginx镜像等。
- 镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、依赖(运行时所需的库、环境变量和配置文件)。
为什么这么大
简而言之就是,除了这个软件本身,他的运行环境占了非常多空间。拿Tomcat举例,除了Tomcat本身的代码,还有Tomcat的依赖、基础Linux操作系统和JDK。
StackOverflow🔗:Why are Docker container images so large?
如此一来,不仅用户本地仓库的存储压力非常大,Docker Hub的存储压力也非常大。Docker使用了UnionFS(联合/叠加文件系统)来解决这个问题。
UnionFS
Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。这种文件系统特性:就是一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
- 简而言之就是把公共的部分拆分出来,使用时再联合加载(把各层文件系统叠加起来)
- 拆得越细,复用率就越高
镜像底层原理(了解即可)
docker的镜像实际是由一层一层的文件系统组成。
-
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。在docker镜像的最底层就是bootfs。这一层与Linux/Unix 系统是一样的,包含boot加载器(bootloader)和内核(kernel)。当boot加载完,后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时会卸载bootfs。
-
rootfs(root file system),在bootfs之上,包含的就是典型的linux系统中的/dev,/proc,/bin,/etc等标准的目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu/CentOS等等。
-
我们平时安装进虚拟机的centos都有1到几个GB,为什么docker这里才200MB?对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令,工具,和程序库就可以了,因为底层直接使用Host的Kernal,自己只需要提供rootfs就行了。由此可见不同的linux发行版,他们的bootfs是一致的,rootfs会有差别。因此不同的发行版可以共用bootfs。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNZiuXFP-1651432281998)(https://cdn.jsdelivr.net/gh/zewei94yomi/ImageLoader@master/uPic/1567585172(1)].jpg)
这种分层结构的优点:资源共享
比如:有多个镜像都是从相同的base镜像构建而来的,那么宿主机只需在磁盘中保存一份base镜像。同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。Docker镜像都是只读的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为容器层,容器层之下都叫镜像层。这就是为什么我们在pull镜像的时候,Docker为我们一层层下载,而不是一次下载一个独立的镜像。
2.容器 (Container)
镜像每次运行之后就是产生一个容器,就是正在运行的镜像,特点就是可读可写
3.仓库 (Repository)
用来存放镜像的位置,类似于maven仓库,也是镜像下载和上传的位置。和Maven一样,Docker官方提供了一个远程Web界面仓库:Docker Hub
;同时为了避免重复下载,本地还有一个本地仓库,存储使用过的镜像。
4.DockerFile
docker生成镜像配置文件,用来书写自定义镜像的一些配置
(第六章节有详细讲)
5.tar
一个对镜像打包的文件,日后可以还原成镜像
6.数据卷(Docker Volume)
用来实现容器中数据和宿主机中数据相互映射(同步),减少频繁cp
命令带来的麻烦。
(第五章节有详细讲)
1.6 执行流程
- 在收到run命令后,先去本地仓库查看是否有对应的镜像,有则运行
- 如果没有在本地仓库找到,就去Docker Hub中查找该镜像并下载,然后运行
2. 使用
2.1 Docker引擎安装
a. Mac
官网下载地址:https://docs.docker.com/get-docker/
选择Mac Intel版本,下载,安装,授权,启动 Docker Desktop。
可在命令行查看Docker版本:
docker version
注意Docker分为客户端和服务端,服务端引擎用来运行容器,客户端引擎用来接受、解析命令,并发送给服务端。
测试Docker安装是否成功
$ docker run hello-world
b. Centos7.x
安装docker(centos7.x)
-
卸载原始docker
$ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
-
安装docker依赖
$ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
-
设置docker的yum源
$ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
-
安装最新版的docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
-
指定版本安装docker
$ yum list docker-ce --showduplicates | sort -r $ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io $ sudo yum install docker-ce-18.09.5-3.el7 docker-ce-cli-18.09.5-3.el7 containerd.io
-
启动docker
$ sudo systemctl enable docker $ sudo systemctl start docker
-
关闭docker