Docker 容器化
引言
在解释docker是什么之前,我们首先应该先了解的是容器化的概念。
什么是容器?就是一个沙箱,在这个沙箱中涵盖了特定应用运行的一切依赖的内容。但他不是一个操作系统,且和底层的操作系统是隔离的。
什么是容器化?容器化就是将软件和应用所需要的所有依赖打包到一个独立的容器中,使得软件能够在不同的计算环境中,高效的、按照预期运行的技术。
先有容器化的概念还是先有的docker?先有的容器化概念,容器化最早提出是在1979年,贝尔实验室发明了chroot,用于将一个进程的文件系统隔离起来,通常认为这是容器技术的开端。
和虚拟化技术有什么联系?有关联也有区别,参考下文“虚化技术”。
Docker 优势
一项技术的优势,通常是在说他解决了传统技术的哪一项痛点,这也是技术持续迭代的一个动力。
传统部署痛点
传统的部署方式通常是在虚拟机上直接部署,如果你有部署过虚拟机服务,你会经历过如下痛点:
1. 环境不一致
主要是设备、系统、工具等方面的差异,举个例子:一般我们在服务器上都是使用Linux的相关版本,所以如果开发使用的是Linux系统,一些脚本等配置都可以无缝迁移,但如果使用windows,我们可能会经历在本地能跑,但是部署到服务器却因为缺少一些信息,无法启动或调用失败的问题。
2. 部署复杂
传统的虚拟机手工部署,在首次部署时,需要安装很多工具包,如果某个步骤出错,就可能会需要我们从头开始排查,耗费比较多的人力成本。后续的部署过程中,以war包为例,如果war包有问题,我们又需要赶紧重新部署旧的服务,否则服务挂了对用户来说太痛了,这个时期的部署一般都选择夜间用户谷期进行。
当然,后来也演化除了一键部署等运维手段,但是依旧有跨环境部署的问题,因为生产环境限制永远要比我们开发测试的环境更高。
3. 资源占用率很高
传统虚拟化技术是模拟完整的操作系统实现相关的隔离,需要提前进行资源的“预分配”,所以这里的资源浪费是比较严重的,一台服务器,可能部署3台虚拟机就到顶了。
4. 扩容效率低
虚拟机部署方式下,我们如果遭遇到突发的大流量,比如某位名人空降微博热搜,这种情况下,大概率是会宕机的(不是DDoS,胜似DDoS),等虚拟机的再扩容启动(虚拟机启动相对耗时较长),这波流量可能就过去了,吃不到。
Docker 的解决方法
对于以上的痛点,Docker 采取了“镜像+容器”的方案来解决,实现了“一次构建,随处运行”。
1. 镜像的本质就是:应用运行时所需要的完整环境快照(包含程序、库、资源、配置文件等),他不包含动态的数据,一旦构建完成,就不会再变了。
由于环境的固化,我们得以实现版本和配置差异的打平,解决了环境不一致的问题。同时由于镜像分层存储的架构设计,使得不同镜像可以复用底层相同的层,从而避免“资源冗余”。
2. 容器的本质则是:一个具有Namespace的进程,它具有自己的文件系统、网络和进程空间。
容器是一个轻量、隔离的执行环境,专门用于运行我们的镜像而不需要考虑能否运行其他应用,同时由于共享操作系统内核,所以他没有内核的开销,不需要安装完整的操作系统,再加上它本身也具有被创建、启动、暂停、停止、删除的能力,所以为什么不能说他是一个轻量化的虚拟机呢?
这些特点使得容器资源占用变低,启动速度更快,从而也使得扩缩容的效率变高。
这里提供一下容器化和虚拟化技术的对比:
|
维度
|
容器化(Containerization)
|
虚拟化(Virtualization)
|
|
隔离级别 |
进程级(共享内核) |
系统级(每个VM有独立内核) |
|
资源抽象 |
抽象应用层(运行时环境、依赖) |
抽象硬件层(CPU、内存、存储、网络) |
|
启动速度 |
秒级(无需加载内核) |
分钟级(需启动完整操作系统) |
|
资源效率 |
高(轻量级) |
低(VM管理程序占用额外资源) |
|
密度 |
单主机可运行数百个容器 |
单主机通常运行数十个VM |
|
隔离强度 |
中等(依赖内核安全机制,存在容器逃逸风险) |
高(完全独立的操作系统环境) |
|
适用场景 |
微服务、DevOps、弹性伸缩、CI/CD |
传统应用迁移、关键业务系统、多租户隔离 |
|
代表技术 |
Docker,Kubernetes,containerd |
VMware vSphere,Hyper-V,KVM,Xen |
Docker 引擎

上文说到容器的本质是一个进程,那么也就是说可以通过操作系统来直接 kill 掉对应的 docker 实例,也可以通过操作系统来启停容器。
理论上来说是这样,但是我们在创建一个 docker 容器的同时,需要需要一个工具帮我们去处理创建该进程所需要准备的东西,以及在创建完成后,可以帮助我们快速的去维护这些容器实例,所以,这样一个工具,就是 Docker 引擎,他能做到的自然是不止我们现在说的这些内容。
从使用层面来说,Docker 引擎是 Docker 的核心组件,但是也不必过于害怕,这也就是一个普通的应用工具,和其他Linux命令一样,只是他的能力聚焦于管理 Docker 核心资源:
镜像(Image)、容器(Container)、网络(Network)、存储卷(Volume)。
Docker 引擎的工作主要是负责管理和运行容器,包含以下几个部分:
- Docker 守护进程:Docker 引擎的后台服务,负责持续运行并处理容器相关的请求,守护进程管理着整个容器的生命周期。
- Docker REST API:提供 HTTP 的 API 接口,通过 HTTP 请求和 Docker 引擎进行交互。
- Docker 命令行工具:cli 工具,可以在命令行直接输入 Docker 命令与 Docker 引擎进行交互。
- 容器与镜像管理:镜像的创建和存储、容器的生命周期管理、容器网络管理。
但整体看下来,不难发现,Docker 引擎所处理的主要就是我们前文所说的两件事情:资源管理和容器的生命周期管理。
在这里的“资源”所指代的范围是比较大的,网络也被认为是一种资源。
在目前的网络上搜索 Docker ,大多数的文章基本是在进行 Docker 的命令行的使用及解释,了解一下就行了,实际使用的时候翻阅也没什么问题:
docker pull
docker run image
docker stop
docker ps
...
Docker 的轻量级
那么 Docker 的轻量级因何而来,为什么他就比虚拟机要轻量?
要理解这个问题,其实也就是一两句话的事情:传统的虚拟机是在一个硬件层之上运行的一个完整的操作系统,而 Docker 则是运行在应用层之上的。不妨想一下,启动电脑快还是启动应用快?
传统虚拟机是通过虚拟化技术将底层的硬件虚拟化为硬件资源池,提供给上层的每个 VM (Virtual Machine,虚拟机)使用,让每个 VM 都认为自己是独立运行在物理机上的。
其后,每个 VM 又是运行的完整的操作系统,仅仅是操作系统+基础服务就需要占用较多的资源,而且这些资源是被 VM 独占的,不可被其他虚拟机复用。
虚拟机启动时,会锁定配置好的资源分配,如VM需要2c4g的基础资源,则会预先锁定,不让其他 VM 使用该资源
这种虚拟化架构实际就是寄居虚拟化,主要分三层:宿主操作系统(Host OS) -> 虚拟机监控程序(Hypervisor) -> 虚拟机(Guest OS),下面是对应的架构图,一个典型的应用就是我们熟知的 VMWare Workstation:

这就是传统虚拟机重的由来。
Docker 的轻量级也并不是因为他解决了这些问题,而是因为他另辟蹊径,不再去模拟一个完整的操作系统,而是基于 Linux 内核的 Namespace、Cgroups以及UnionFS技术,实现从系统级别的隔离转换到了进程级别的隔离,从架构层面抹除了硬件模拟和虚拟机操作系统的开销。
- Namespace 提供资源隔离机制:将 PID、Network、Mount、User 等资源进行命名空间层级的划分,不同的 Namespace 的进程无法互相访问到。
- Cgroups 进行配额限制:避免某一个进程组无限制的消耗资源,同时可以让空闲资源被释放。
- UnionFS 实现镜像分层复用:不同的镜像可复用底层镜像,减少存储的冗余。
这样一来,Docker 虚拟化的架构就变成了:

Docker 与云原生
云原生本质是一种构建和运行应用程序的方法,是以 k8s 为代表的一套技术体系和方法论[3]。这套技术体系是由 “容器化技术、编排调度、服务治理、可观测性” 等技术组成,而其中的容器化技术是云原生的 “基础载体”。而 Docker 则是容器化技术的 “开创者与早期绝对主导者”,也是云原生的核心应用,他通过解决传统部署的痛点问题,使得以容器为基础去构建分布式应用成为可能,从而推动了云原生的普及落地,可以说,如果没有 Docker,那云原生可能发展的不会如此迅速,还需要等待另一个“Docker”技术来推动其发展。
此外,Docker 定义的容器镜像标准,也成为了云原生应用的一个交付载体标准。目前的云原生应用的 CI/CD 标准流程是:代码提交→自动构建 Docker 镜像→镜像推送到仓库→编排工具拉取镜像部署,可以看到,在这个过程中,镜像就是代码到运行时的中间载体,也是我们交付的一个产物标准。
目前 k8s (1.20 以后的版本)已经弃用了对 Docker 的直接支持,转为原生支持 CRI 标准的容器运行时,但是这并不代表着 Docker 已经过时,只是 k8s 从以 Docker 主导转变为了基于 Docker 标准,多工具的生态协同。

总结
Docker 不仅是一项技术创新,更重塑了软件产业的协作模式。Docker 将 Linux 内核的 Namespace、Cgroups、UnionFS 等技术封装成简单易用的工具链条,通过“镜像-容器 ”架构解决了传统部署的行业痛点问题,标准化了应用交付格式,为 k8s 等编排平台提供了基础载体,重塑了软件开发流程,实现“一次构建,到处运行”的理想态,推动了云原生的迅速发展。
未来,随着云原生技术持续演进,Docker 可能也不再是容器领域的唯一焦点,但其倡导的 "标准化、轻量化、可移植" 理念已深刻影响整个行业。无论是作为开发者日常工具,还是云原生基础设施的重要组成部分,Docker 仍会在上云浪潮中扮演关键角色。
参考文档
Docker 容器化的更多相关文章
- 通过 Azure Pipelines 实现持续集成之docker容器化及自动化部署
通过 Azure Pipelines 实现持续集成之docker容器化及自动化部署 Intro Azure DevOps Pipeline 现在对于公开的项目完全免费,这对于开源项目来讲无疑是个巨大的 ...
- 利用 ELK 搭建 Docker 容器化应用日志中心
利用 ELK 搭建 Docker 容器化应用日志中心 概述 应用一旦容器化以后,需要考虑的就是如何采集位于 Docker 容器中的应用程序的打印日志供运维分析.典型的比如SpringBoot应用的日志 ...
- [ci]jenkins-slave-ssh docker容器化-用户名密码
jenkins-slave-ssh docker容器化 架构 参考:https://www.youtube.com/watch?v=OxrBCt1JLuQ https://github.com/Dav ...
- Docker容器化技术(下)
Docker容器化技术(下) 一.Dockerfile基础命令 1.1.FROM - 基于基准镜像 FROM centos #制作基准镜像(基于centos) FROM scratch #不依赖任何基 ...
- Docker容器化技术(上)
目录 Docker容器化技术 一.介绍 二.Docker的发展 三.Docker安装 四.阿里云Docker镜像加速 五.Docker的基本概念 六.命令 七.Docker宿主机与容器通信 八.容器内 ...
- spring boot本地开发与docker容器化部署的差异
spring boot本地开发与docker容器化部署的差异: 1. 文件路径及文件名区别大小写: 本地开发环境为windows操作系统,是忽略大小写的,但容器中区分大小写 2. docker中的容器 ...
- Gogs的Docker容器化部署流程遇到的问题
Gogs的Docker容器化部署流程遇到的问题 最近在学习CI/CD的一些方案,个人比较青睐容器化轻量级.CI方面一开始是想使用gitlab的,但是发现我自己买的服务器配置太低,内存根本不够(大写 ...
- docker容器化python服务部署(supervisor-gunicorn-flask)
docker容器化python服务部署(supervisor-gunicorn-flask) 本文系作者原创,转载请注明出处: https://www.cnblogs.com/further-furt ...
- python + docker, 实现天气数据 从FTP获取以及持久化(五)-- 利用 Docker 容器化 Python 程序
背景 不知不觉中,我们已经完成了所有的编程工作.接下来,我们需要把 Python 程序 做 容器化 (Docker)部署. 思考 考虑到项目的实际情况,“持久化天气”的功能将会是一个独立的功能模块发布 ...
- 详解利用ELK搭建Docker容器化应用日志中心
概述 应用一旦容器化以后,需要考虑的就是如何采集位于Docker容器中的应用程序的打印日志供运维分析.典型的比如SpringBoot应用的日志 收集.本文即将阐述如何利用ELK日志中心来收集容器化应用 ...
随机推荐
- Django数据库配置避坑指南:从初始化到生产环境的实战优化
一.数据库配置 介绍 Django 4.2 支持多种数据库后端 数据库类型 推荐版本 官方支持 驱动 / 后端 默认端口 适用场景 备注 PostgreSQL 12+ psycopg2-binary ...
- Luogu P7503 「HMOI R1」文化课
题传 先想一个巨 shaber 的暴力 DP:设 \(f_{i}\) 为对前 \(i\) 个人分段的最优解,则: \[f_{i}=\max_{0\le j<i}\{f_{j}+\operator ...
- SQL server跨库链接服务器
SQL server进阶技能篇:SQL的跨库查询与链接服务器 - 知乎 (zhihu.com)各位小伙伴们,关于MSSQL的基本技能篇前面一共写了10篇,也基本上算是告一段落,接下来将开始介绍进阶技能 ...
- 线性回归原理推导与应用(二):Python一元线性回归实战
在上一篇文章中我们对一元线性回归模型和方程的原理及公式进行了推导,本篇文章将根据实际数据建立一个一元回归模型,代码基于Python 建模应用 首先导入需要用到的Python库: #一元线性回归 imp ...
- Gym - 101466 & 队内训练#1 题解
A - Gaby And Addition 题意:给n个数,现在规定一个操作是不进位的加法,问两两操作的最小值和最大值. 思路:既然是不进位,那每个位之间就没有影响了.我们现在想要两两操作的值最大的话 ...
- 实战 PCA
简介 PCA code #加载数据 import pandas as pd import numpy as np data = pd.read_csv('iris_data.csv') data.he ...
- MCP快速入门—快速构建自己的服务器
引言 随着大语言模型(LLM)技术的快速发展,如何扩展其能力边界成为开发者关注的重点.MCP(Model Capability Protocol)作为一种协议标准,允许开发者构建自定义服务器来增强LL ...
- 微服务架构PaaS平台,iPaaS平台支撑底座
RestCloud所有产品均基于本微服务架构PaaS平台研发而来,底层PaaS平台是RestCloud所有产品的技术底座,基于本技术底座RestCloud快速研发了所有产品线,通过不断迭代PaaS平台 ...
- unity编辑器绘制扇形
使用 UnityEditor.Handles.DrawSolidArc using UnityEngine; using UnityEditor; public class DrawSectorHan ...
- vant框架中 Tab 标签页 如何绑定事件传递id
<van-tabs @click="getInfo"> <van-tab v-for="(item, i ) in photoList" :k ...