背景
在印象里,学习了 spring boot 之后,我们项目的 mysql 数据库都是用 docker 容器跑的。
参与了团队的那么多项目,几乎每个项目都有自己的 docker 配置文件。而启动开发环境时也少不了 docker compose up
以创建 docker 容器的步骤。
后来再成熟一些了,接触到了 CI/CD
部分的内容,发现项目在服务器上的打包、发布也依赖 docker 容器而进行。
这样看来,docker 似乎始终贯穿在我们 web 开发的各个生命周期中。
虽然接触和使用 docker 也已经有一段时间了,但多数时候都只停留一般使用和报错搜错的阶段。
对于 docker 的一些基础知识和理论,也是时候该学习和梳理一下了。
什么是 docker
docker 是一种轻量级的虚拟化技术。
可以理解为是运行在操作系统里的电脑。
这就有人说了,这不就是虚拟机吗?使用 VM 也可以在操作系统里的跑操作系统。
其实把 docker 理解为虚拟机最开始也是我的想法。但后来发现,docker 可比虚拟机方便太多了。
先看看 docker 官网 对 docker 的描述:
在看看 docker 和传统虚拟机的区别:
传统虚拟机的 Hypervisor 需要实现对硬件的虚拟化,并且还要搭载自己的操作系统,其中虚拟机操作系统占用内存是比较大的,一个操作系统有好几个G,所以在启动速度、资源利用率以及性能上有非常大的开销。
但是 docker 技术的出现,则省去了操作系统这一层,实现多个容器之间相互隔离且共用了宿主操作系统和运行时库。
所以 docker 相对于传统虚拟机有以下几个优点:
- 启动速度快。docker 容器的运行属于进程级别的,启动和停止都在秒级。
- 资源利用率高。既然是进程级,那么就意味着一台电脑可以跑十几甚至几十个 docker 容器(实际上也确实是这么做的,团队服务器上就跑着很多个 docker 容器)。而一台电脑要是跑上十个 VM 虚拟机,这不得卡成 ppt 。
- 性能开销小。 VM 通常需要额外的 CPU 和内存来完成 OS 的功能,这一部分占据了额外的资源。
再简单看下 docker 的技术架构:
docker 的技术架构我们当前阶段暂时不用深入研究,我们只需要知道它是基于 linux 内核的即可。
所以,docker 原生态是不能直接在 windows 平台上运行的。想在 windows 安装 docker 时就会发现,需要先安装 wsl
环境。
上图中的 images、 continer 就是 docker 三个重要概念中的两个。
docker 三个重要概念
我们需要知道 docker 的三个重要的基本概念:镜像、容器、仓库。
镜像
我们可以在团队项目的 docker 配置文件中几乎都可以看到对镜像的配置:
我们可以用面向对象思想中的 类
和 对象
之间的关系做类比。
我们知道 类
是一个图纸,是抽象的,而 对象
则是根据图纸而创建出来的实例,是具象的。
在这里,镜像就可以理解为一个抽象的 类
,而下面要说的容器则是根据镜像而创建出来的具象的 对象
。
比如想上图的配置,配置了镜像为 mysql ,所以执行 docker compose up
后就会根据 mysql 镜像创建出运行着 mysql 服务的 docker 容器。
还有一点,镜像是分层的。
- 有基础镜像,仅仅包含操作系统,比如 ubuntu 镜像。
- 有中间件镜像,比如 mysql 等数据库镜像。
- 最后是应用镜像,就是指具体的应用服务了。
如下图:
红圈就是基础镜像 ubuntu 操作系统;蓝圈就是中间件镜像 mysql 数据库;;绿圈就是
应用镜像。
容器
docker 容器就如上面所说,是根据镜像而创建出来的具象的 对象
。也是我们经常直接对 docekr 进行操作的对象。
容器就像是一个个独立的封闭的集装箱,容器之间互不影响。但是容器也需要对外提供服务,所以docker 允许公开容器的特定端口,在启动 docker 的时候,我们就可以将容器的特定端口映射到宿主机上面的任意一个端口.所以,如果几个服务都需要相同的端口,那么容器的对外端口是虽然一样,但是映射到宿主机上面就是任意端口,就不会产生冲突。
比如,mysql 默认端口是 3306 。那么如果像前文背景中提到的, mysql 数据库用 docker 容器来跑,然后在通过端口映射来使用的话。如下图:
我们只需要再创建并启动一个 docker 容器,映射到不同端口(3311、3312 ......),就可以在一台设备上跑多个带着数据库服务的 api 项目了。
仓库
docker 仓库也类似于 npm 、 mvn 这样的包管理库,只不过它是管理镜像的仓库。
docker 仓库存在公有和私有之分,公有仓库 docker hub 提供了非常多的镜像文件,这些镜像直接拉取下来就可以运行了。我们也可以上传自己的镜像到 docker hub 上面。同时也可以自己搭建私有仓库用于团队项目管理。
docker 的应用
docker 的生命周期
- 开发构建镜像并将镜像 push 到 docker 仓库。
- 测试或者运维从 docker 仓库拷贝一份镜像到本地。
- 通过镜像文件创建并启动 docker 容器以提供服务。
对开发人员而言
- 利用 docker 容器在一台机器上启动多个服务。
- 自动化测试的环境的快速搭建。
- 提高软件更新发布及部署的效率。
对测试、运维人员而言
- 保持测试时与开发时环境一致。
- 测试环境的快速搭建。
- 解决不同环境之间的迁移问题。
docker 常用命令
// 查看Docker版本信息
docker version
// 查看Docker版本信息
docker -v
// 启动Docker
systemctl start docker
// 关闭docker
systemctl stop docker
// 重启docker服务
service docker restart
// 拉取镜像
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
// 列出镜像
docker image ls
// 删除镜像
docker rmi <镜像Id>
// 导出镜像
docker save
// 导入镜像
docker load
// 新建并启动
docker run [镜像名/镜像ID]
// 启动已终止容器
docker start [容器ID]
// 列出本机运行的容器
docker ps
// 列出本机所有的容器(包括停止和运行)
docker ps -a
// 停止运行的容器
docker stop [容器ID]
// 杀死容器进程
docker kill [容器ID]
// 重启容器
docker restart [容器ID]
// 删除容器
docker rm [容器ID]
希望这篇文章对你有帮助!
参考资料
https://cloud.tencent.com/developer/article/1006116