Docker(一)

Docker

一:Docker简介

1.Docker是什么?

Docker 是一个容器化平台 ,用于将应用及其依赖打包成一个独立的运行单元,以此来实现通过一次的构建,到处运行

2.为什么需要Docker?

在Docker出现之前,程序员在自己的电脑配置完环境之后,上线到服务器的时候,由于环境的不同,通常会出现一系列大大小小的问题。

例如:

  • 开发环境 ≠ 测试环境 ≠ 生产环境
  • 依赖版本不同
  • 系统配置不同
  • 安装流程复杂

3.Docker 解决了什么问题?

(1)环境一致性

  • 把应用 + 依赖 + 环境全部打包进镜像
  • 不再依赖宿主机环境
    (2)快速部署
  • 通常启动一个容器只需几秒,相比虚拟机就快衡多了
  • 不需要安装一堆环境,大大节省了时间和精力

(3)资源利用率高

对比项 虚拟机 Docker
启动速度 分钟级 秒级
资源占用
结构 操作系统级 进程级

(4)方便扩展和迁移

  • 可以快速复制多个实例
  • 云环境部署非常方便

总之。。
Docker 本质是:对进程进行隔离和封装,让应用运行环境标准化

二:Docker版本

Docker 主要分为社区版(Docker CE)和企业版(Docker EE),其中社区版免费且更新频繁,是开发者最常用的版本。Docker 底层依赖 containerd 和 runc 来完成容器的创建与运行。

(1)Docker CE(Community Edition)社区版

特点:1.免费2.更新快3.适合个人学习、开发环境

(2)Docker EE(Enterprise Edition) 企业版)

特点:1.收费2.提供企业支持3.安全、稳定、合规

(3)Moby(底层项目)Docker 的开源基础项目

三:Docker的官方网站

官方地址

四:容器基础命令详解

1.dd

dd命令可以想象成一个数据搬运工

它的工作流程就三步:输入源 → 按块读取 → 可选转换 → 输出目标

在终端的命令就是

bash 复制代码
dd if=输入源 of=输出目标 [其他参数]

注意:

1.在这里要说明的是,这个和cp很像,但是cp是文件层面的复制,而dd则是字节流/块设备层面的复制

2.它复制的对象不一定是普通文件,输入源可以是 设备文件,输出目标也可以是 设备文件,它是按"块"处理数据,不是按"文本行"处理。

/dev/zero

这里要讲解一下/dev/zero是什么?

/dev/zero 是一个特殊设备,会持续不断地产生空白字符流。于是你把它作为输入源,dd 就能不断读取"0 字节流",再写到目标文件里,于是就得到一个指定大小的空白文件。

命令:

bash 复制代码
dd if=/dev/zero of=test.img bs=1M count=64

意思就是:

  • 从 /dev/zero 读
  • 写到 test.img
  • 每次读写 1M
  • 一共写 64 块

dd参数简单说明

参数说明:

if:输入文件

of:输出文件

ibs:一次读多少字节

obs:一次写多少字节

bs:同时设置读和写的块大小

count:读多少块

skip:输入跳过多少块

seek:输出跳过多少块

conv:转换动作

dd常用参数

1)if=:input file
bash 复制代码
if=/dev/zero

表示输入源

它不一定是真文件,可以是:

  • 普通文件
  • 分区
  • 整块磁盘
  • 特殊设备

常见场景:

从普通文件读取

从 /dev/zero 读取生成空白内容

从磁盘设备读取做备份

2)of=:output file
bash 复制代码
of=fdimage.img

表示输出目标。

也不一定是真文件,也可以是:

  • 普通文件
  • 磁盘设备
  • 分区设备
3)bs=:block size
bash 复制代码
bs=8k

表示一次读写多少字节。

你怎么理解它

它像"水管口径"。

小块:操作次数多,可能慢

大块:操作次数少,通常更快

4)count=:读多少块
bash 复制代码
count=10240

表示只处理这么多块。

真正的大小公式

总大小 = bs × count

比如:

bash 复制代码
dd if=/dev/zero of=test.img bs=1M count=64

就是创建一个 64MB 文件。

5)skip=:输入端跳过多少块

定义是:从输入文件开头跳过若干 block 再读取。

场景

你不想从头读,只想从中间某个位置开始读。

比如:

dd if=file.bin of=part.bin bs=1M skip=10 count=5

意思是:

输入文件前 10MB 不读

从第 11MB 开始读

连续读 5MB

像切一段原始二进制数据。

6)seek=:输出端跳过多少块

定义是:从输出文件开头跳过若干 block,再开始写。

场景

你想把数据写到目标文件的某个偏移位置,而不是从头覆盖。

比如:

bash 复制代码
dd if=patch.bin of=image.bin bs=1M seek=20 count=2

表示把 patch.bin 的内容写到 image.bin 的第 20MB 处。

这个思路本质上就是"按偏移打补丁"。

7)conv=:转换动作

这里列了多个转换选项,都是最常见的:

lcase:大写转小写

ucase:小写转大写

noerror:读错不停止

notrunc:不截断输出文件

sync:块不足时补齐

例如:

bash 复制代码
dd if=testfile_2 of=testfile_1 conv=ucase

2.mkfs

mkfs 本质不是"格式化",而是"在一块空间里建立文件系统结构"

可以酱紫理解~

bash 复制代码
dd:给你一块"空白空间"
mkfs:在这块空间里"建立文件系统规则"

没有 mkfs,这块空间只是"字节容器",不能当磁盘用。

为什么一定要有 mkfs

刚才我们已经通过命令dd创建出来了test.img,,

但是有以下问题:

此时 test.img:

bash 复制代码
 1.没有目录结构
 2.没有 inode
 3.没有文件系统元数据
 4.不能 mount

本质上:

它只是一个 64MB 的"0数组"。

mkfs的用处

bash 复制代码
mkfs -t ext4 test.img

本质是在这个文件里写入:

bash 复制代码
superblock(超级块)
inode 表
block bitmap
数据区布局
文件系统元数据

其实就是:

原始空间 → 变成 ext4 文件系统

进一步理解:

概念 类比
dd 买了一块空硬盘
mkfs 给硬盘分区+格式化
mount 插上电脑并分配盘符

至于mount是什么后面再讲~

总之!

在容器与 Linux 文件系统实验中,dd 与 mkfs 通常组合使用:前者用于创建一块指定大小的原始存储空间(如镜像文件),后者则在该空间中初始化文件系统结构(如 ext4)。

dd 仅提供"字节级存储容器",而 mkfs 则为其赋予"文件系统语义"。只有在完成 mkfs 之后,该空间才能被 mount 挂载并以目录结构形式访问。

因此,mkfs 的本质并不是简单的"格式化",而是构建文件系统元数据结构,使原始存储具备文件管理能力。

3.mount

dd 是造空间,mkfs是造文件系统

现在:mount = 把这个文件系统接入 Linux 的世界

更加细致的理解就是

mount = 把"磁盘内容"映射到"目录树中的某个路径"

Linux 的文件系统

在Linux 的系统里面,它的文件系统是一棵统一的目录树 ,所有磁盘,都要"挂载"到这棵树上!!

概念 类比
磁盘 一个仓库
mount 给仓库开一个门
挂载点目录 门的位置

mount 命令结构

bash 复制代码
mount [设备] [挂载点]
//例子
mount test.img /mnt/test

参数:

  1. -t(类型)
bash 复制代码
mount -t ext4 test.img /mnt/test

指定文件系统类型(一般可以不写)

  1. -o loop(重点)
bash 复制代码
mount -o loop test.img /mnt/test

这个是关键:

把"文件"当成"磁盘设备"

loop 是把文件当成硬盘分区挂载。

总之:

1.mount 命令用于将一个文件系统映射到 Linux 的目录树中,使其可以通过路径访问。

2.与传统认知不同,mount 并不会复制数据,而是建立"访问入口"。在容器技术中,mount namespace 可以让不同进程拥有独立的文件系统视图,从而实现文件系统级别的隔离。

3.在实际实验中,通常结合 dd 创建镜像文件,使用 mkfs 初始化文件系统,再通过 mount 将其挂载到目录中,从而模拟一个完整的磁盘环境。

4.unshare

unshare = 造"隔离环境"(容器雏形)

bash 复制代码
unshare [选项] 程序

直接的理解就是:让子进程不和父进程共享 namespace(命名空间)

什么是 namespace?

namespace就是资源隔离机制

比如可以隔离:

  • 进程(PID)
  • 文件系统(mount)
  • 网络(net)
  • 主机名(UTS)
  • 用户(user)
  • IPC

unshare的作用

它不是"创建容器",而是:给你一个"新的世界视角"

就比如:同一个房子,给你戴上一个VR眼睛,你看到的是另一个世界

实际上:同一个内核,不同 namespace,看到不同资源

一个有关unshare的命令

UTS(主机名隔离)
bash 复制代码
//表示进入一个新环境
unshare -u /bin/bash

此时我们再输入命令:

bash 复制代码
hostname test1
hostname

然后再开一个新的终端~

其实还是原来的名字。

解释:

这里发生了什么?

bash 复制代码
两个进程在同一台机器
但看到不同主机名

这就是:

bash 复制代码
namespace = 视图隔离

unshare 常用参数

1.-u(UTS)

bash 复制代码
unshare -u bash

隔离主机名

2.-p(PID)

bash 复制代码
unshare -p bash

隔离进程空间

但必须配:

bash 复制代码
--fork

否则会报错:

bash 复制代码
Cannot allocate memory

因为:

子进程找不到父进程(PID 不在同一 namespace)

正确写法:

bash 复制代码
unshare --fork --pid bash
  1. --mount
bash 复制代码
unshare --mount bash

隔离文件系统挂载

  1. --mount-proc(非常关键)

如果不挂 /proc

ps 看到的还是宿主机进程

正确组合

bash 复制代码
unshare --fork --pid --mount-proc bash

才是"真正隔离进程空间"

总之:unshare 命令用于在 Linux 中创建新的命名空间,使得运行的程序与父进程在某些资源上不再共享。通过组合不同的 namespace(如 PID、Mount、UTS 等),可以让进程拥有独立的进程视图、文件系统视图和系统标识,从而模拟出类似独立操作系统的运行环境。

在容器技术中,unshare 所体现的 namespace 机制是实现隔离的核心基础,它使得多个进程在同一内核上运行,却彼此"不可见"。

5.虚拟机和容器的区别

容器不是虚拟机

bash 复制代码
虚拟机:虚拟硬件 + 虚拟内核
容器:共享内核 + namespace 隔离
相关推荐
墨雪不会编程2 小时前
C++容器适配器【困难篇】双向队列详解
开发语言·c++
笨笨饿2 小时前
博客目录框架
c语言·开发语言·arm开发·git·嵌入式硬件·神经网络·编辑器
泡泡鱼(敲代码中)2 小时前
C++-string学习笔记
c语言·开发语言·c++·笔记·学习·visualstudio
编程大师哥2 小时前
JAVA 动态代理
java·开发语言
圣光SG2 小时前
Java类与对象及面向对象基础核心详细笔记
java·前端·数据库
xin_yao_xin2 小时前
Linux 下 Docker 安装教程(2026)
linux·运维·docker
白露与泡影2 小时前
从 BIO 到 epoll:高并发 I/O 模型演进与本质分析
java·服务器·数据库
学编程就要猛2 小时前
JavaEE进阶:Spring Boot快速上手
java·spring boot·java-ee
kyle~2 小时前
导航---Small-GICP重定位算法
c++·机器人·ros2·导航