当前位置: 首页 > news >正文

Docker学习其一

文章目录

  • 1,Docker概述
    • 1.1为什么会有Docker
    • 1.2Docker的核心能力
  • 2,Docker安装
  • 3,初识Docker
    • 3.1Docker的基本组成
    • 3.2底层原理
      • 3.2.1Docker的工作架构
      • 3.2.2Docker为什么比虚拟机(VM)快
  • 4,常用命令
    • 4.1帮助命令
    • 4.2镜像命令
    • 4.3容器命令
    • 4.4其他命令
  • 5,镜像原理
    • 5.1联合文件系统
    • 5.2镜像分层结构
      • 5.2.1概述
      • 5.2.2知识补充
    • 5.3镜像层解析
    • 5.4镜像的加载流程

1,Docker概述

1.1为什么会有Docker

在传统软件开发与部署中,会存在以下问题:

  • 配置繁琐:部署一个项目需手动安装多种依赖(如 JDK、Redis、MySQL 等),尤其在集群环境中,重复操作效率极低,且易出错。

  • 环境不一致问题:开发环境与生产环境存在差异(如操作系统、依赖版本等),常出现 “本地能运行,上线就报错” 的情况,增加开发与运维的沟通成本。

Docker 的解决方案借鉴了 “集装箱” 思想:将应用程序及其依赖的完整环境(如库、配置文件等)打包成一个标准化的 “镜像”,确保在任何支持 Docker 的环境中都能一致运行,实现 “一次打包,到处运行”。

1.2Docker的核心能力

Docker 的核心特性可总结为:

  1. 轻量高效:容器直接运行在宿主机内核上,无需虚拟硬件和完整操作系统,资源占用远低于虚拟机。
  2. 隔离性:每个容器拥有独立的文件系统、进程空间和网络配置,相互隔离不干扰,确保应用安全运行。
  3. 标准化:镜像作为标准化打包格式,可在任何 Docker 环境中一致运行,消除环境差异。

2,Docker安装

这里使用腾讯云安装,centos。

在 CentOS 系统中配置 Docker CE(社区版)的 yum 仓库

#通过yum-config-manager工具向系统添加一个新的 yum 仓库配置,指向腾讯云镜像源
sudo yum-config-manager --add-repo=https://mirrors.cloud.tencent.com/docker-ce/linux/centos/docker-ce.repo
#将配置文件中所有原来指向download.docker.com(Docker 官方地址)的链接替换为mirrors.tencentyun.com/docker-ce(腾讯云镜像地址)
sudo sed -i "s/download.docker.com/mirrors.tencentyun.com\/docker-ce/g"  /etc/yum.repos.d/docker-ce.repo

安装Docker社区版

sudo yum install -y docker-ce 

执行以下命令,运行 Docker

sudo systemctl start docker

查看安装结果

sudo docker info

返回下面的信息,则安装成功

在这里插入图片描述

接下来使用腾讯云镜像源加速 Docker,否则可能无法pull镜像(显示网络相关报错)。

云服务器 腾讯云软件源加速软件包下载安装和更新_腾讯云

按照官方给的流程走即可

在这里插入图片描述

或者依次执行下述命令

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

测试,,因为我们并没有下载hello-world镜像,所以它找不到,然后会去公有仓库查找,找到后下载并运行。

# 测试
docker run hello-world
# 测试
➜ ~ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/#查看一下下载的镜像
➜ ~ docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
hello-world latest bf756fb1ae65 4 months ago
13.3kB

3,初识Docker

3.1Docker的基本组成

Docker 的基本组成主要包括三个核心部分:镜像(Image)容器(Container)仓库(Repository),它们共同构成了 Docker 的完整生态,确保了容器化应用的构建、运行和分发。镜像是静态模板,容器是镜像的动态运行实例,仓库是镜像的存储和分发平台。

1. 镜像(Image)

  • 本质:镜像可以理解为一个只读的 “模板” 或 “快照”,包含了运行某个应用所需的完整环境(代码、运行时、库、环境变量、配置文件等)。例如,一个tomcat镜像包含了 Tomcat 服务器运行所需的所有文件和依赖。
  • 特性:
    • 镜像不可修改,一旦创建就固定不变(可通过分层机制基于原有镜像创建新镜像)。
    • 一个镜像可以创建多个容器,如同一个模板可以复制出多个实例。
  • 作用:作为容器的 “源头”,容器是通过镜像启动的,镜像确保了容器运行环境的一致性。

2. 容器(Container)

  • 本质:容器是镜像的可运行实例,是动态的、可操作的(启动、停止、删除等)。可以将其理解为一个轻量级的 “独立沙箱”,内部运行着应用程序,且与宿主机及其他容器相互隔离。
  • 特性
    • 容器基于镜像创建,继承镜像的所有内容,并在运行时添加一层可写层(用于临时数据存储)。
    • 每个容器拥有独立的文件系统、进程空间和网络配置,互不干扰。
    • 可视为一个 “简化版的 Linux 系统”(包含内核级隔离,但共享宿主机内核)。
  • 作用:实际运行应用的载体,开发者 / 运维人员通过操作容器来管理应用的生命周期。

3. 仓库(Repository)

  • 本质:仓库是存放和分发镜像的场所,类似代码仓库(如 Git),用于集中管理不同版本的镜像。
  • 分类
    • 公有仓库:公开可访问,如 Docker 官方的Docker Hub(包含大量官方和社区镜像),以及国内的阿里云、腾讯云等容器镜像服务。
    • 私有仓库:企业或个人自建,用于存储私有镜像(如内部项目镜像),确保安全性。
  • 作用:解决镜像的共享和分发问题,开发者可以从仓库拉取镜像到本地使用,也可以将自己构建的镜像推送到仓库供他人使用。

举例:

Tomcat 镜像本质是一个只读的文件集合,包含了 Tomcat 运行所需的所有依赖(如 JDK、Tomcat 安装包、配置文件等),它是静态的。当你通过docker run tomcat命令启动时,Docker 会基于 Tomcat 镜像创建一个新的容器,此时 Tomcat 才真正开始运行。

在这里插入图片描述

3.2底层原理

3.2.1Docker的工作架构

Docker 采用客户端 - 服务器(Client-Server)架构,核心组件包括:

  • Docker Client(客户端):用户交互的入口,通过docker命令(如docker rundocker pull)向服务器发送指令。
  • Docker Daemon(守护进程):运行在宿主机上的后台服务(dockerd),负责接收并执行客户端的指令,管理镜像、容器、网络等 Docker 资源。
  • 通信方式:客户端与守护进程通过 UNIX Socket(本地)或 TCP 网络(远程)进行通信,客户端的所有操作最终由守护进程完成。

简单流程:
用户输入docker run [镜像] → 客户端将指令发送给守护进程 → 守护进程执行创建容器、启动应用等操作 → 结果返回给客户端。

3.2.2Docker为什么比虚拟机(VM)快

Docker 的高效性源于其与传统虚拟机在虚拟化技术上的本质区别,主要体现在两个核心优势:

  1. 更少的抽象层,直接复用宿主机硬件资源
  • 传统虚拟机:需要通过 Hypervisor(虚拟化层,如 VMware、VirtualBox)模拟完整的硬件环境(CPU、内存、磁盘等),然后在虚拟硬件上安装 Guest OS(客户机操作系统),应用运行在 Guest OS 中。这意味着硬件资源需要经过 “宿主机→Hypervisor→Guest OS→应用” 多层抽象,性能损耗较大。
  • Docker 容器:无需 Hypervisor 层,直接基于宿主机的内核运行,容器内的应用直接调用宿主机的硬件资源(通过内核级隔离技术实现资源分配与限制)。抽象层更少,CPU、内存等资源的利用率更高。
  1. 共享宿主机内核,无需单独加载操作系统
  • 传统虚拟机:每个虚拟机都需要完整安装一套 Guest OS(如 Linux、Windows),启动时需经历操作系统内核加载、初始化等流程(分钟级启动),且每个 Guest OS 会占用数百 MB 至数 GB 的磁盘空间。
  • Docker 容器:无需单独的操作系统内核,所有容器共享宿主机的 Host OS 内核。容器启动时,只需加载应用及其依赖(基于镜像),无需启动新的内核,因此启动速度极快(秒级甚至毫秒级),且镜像体积小巧(通常仅数 MB 至数百 MB)。

4,常用命令

4.1帮助命令

docker version         #显示docker版本信息
docker info            #显示docker的系统信息,包括镜像和容器
docker 命令 --help      #帮助命令,可以查看“命令”可以加哪些参数

4.2镜像命令

docker images      #查看本地的所有镜像
docker search      #搜索镜像
docker pull        #下载镜像
docker rmi         #删除镜像# 可选项
-a, --all Show all images (default hides intermediate images) #列出所有镜像
-q, --quiet Only show numeric IDs # 只显示镜像的id
docker images -aq #显示所有镜像的id------------下载镜像 ---------
#docker pull 镜像名[:tag]  tag就是版本  如果不写tag,默认就是latest
#分层下载: docker image 的核心 联合文件系统
docker pull tomcat:8---------------删除镜像----------
docker rmi -f 镜像id                             #删除指定的镜像
docker rmi -f 镜像id 镜像id 镜像id 镜像id          #删除多个指定的镜像
docker rmi -f $(docker images -aq)              #删除全部的镜像,$()表达式

4.3容器命令

docker run    镜像id 新建容器并启动
docker ps     列出所有运行的容器 docker container list
docker rm     容器id 删除指定容器
docker start  容器id #启动容器
docker restart容器id #重启容器
docker stop   容器id #停止当前正在运行的容器
docker kill   容器id #强制停止当前容器
------------启动-------------
docker run [可选参数] image# 参数说明
--name=“Name”   容器名字    tomcat01    tomcat02    用来区分容器
-d      后台方式运行
-it     使用交互方式运行,进入容器查看内容
-p      指定容器的端口     -p 8080:8080-p  ip:主机端口:容器端口-p  主机端口:容器端口(常用)-p  容器端口容器端口
-p      随机指定端口# 测试,启动并进入容器
#-it用于让容器进入交互式运行模式,确保我们能与容器内的终端进行交互
#/bin/bash:容器启动后执行的命令,这部分指定了容器启动后要运行的程序 —— 即启动 bash 终端
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -it centos /bin/bash
[root@74e82b7980e7 /]# ls   # 查看容器内的centos,基础版本,很多命令是不完善的
# 从容器中退回主机
[root@77969f5dcbf9 /]# exit------------查看----------
# docker ps 命令# 列出当前正在运行的容器
-a      # 列出正在运行的容器包括历史容器
-n=?    # 显示最近创建的容器
-q      # 只显示当前容器的编号
-----------退出容器---------
exit            # 直接退出容器并关闭
Ctrl + P + Q    # 容器不关闭退出
-------启动停止------------
docker start 容器id           # 启动容器
docker restart 容器id         # 重启容器
docker stop 容器id            # 停止当前正在运行的容器
docker kill 容器id            # 强制停止当前的容器

4.4其他命令

# 命令 docker run -d 镜像名
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos#从容器中拷贝文件到主机
docker cp 容器id:容器内路径  目的地主机路径

5,镜像原理

5.1联合文件系统

联合文件系统(Union File System,简称 UnionFS),UnionFS 可以把多个不同的文件系统,以分层的方式联合挂载到同一个挂载点,对外呈现为一个统一的文件系统。 从用户角度看,只能看到一个整合后的文件系统,而实际上底层由多个独立的 “层” 组成,这些层按照特定顺序堆叠,各层的文件和目录会被逻辑合并。

在 Docker 中,“多文件系统” 指的是构成镜像和容器的多个独立的文件系统层,这些层通过联合文件系统(UnionFS)的技术被整合为一个统一的视图。

1,什么是多个文件系统?

这里指存储文件和目录的 “独立目录树”(可以理解为一个文件夹及其内部所有文件 / 子文件夹的集合)。

“不同” 体现在:

  • 它们可能存储在不同的物理位置(比如一个在本地硬盘,一个在 U 盘,一个在网络存储);
  • 它们的权限不同(比如有的只读,有的可写);
  • 它们的内容可以重叠(比如都有/test.txt文件,但内容不同)

举例

  • 你电脑里的 “系统文件夹 A”(只读,存放操作系统核心文件);
  • 你自己创建的 “用户文件夹 B”(可写,存放个人文件);
  • 一个外接 U 盘里的 “文件夹 C”(只读,存放备份文件)。
    这三个独立的目录树,就可以看作 UnionFS 中的 “多个不同的文件系统”。

2,什么是 “分层的方式”?

“分层” 是 UnionFS 的核心逻辑,指把多个 “文件系统”(目录树)按固定顺序堆叠

  • 下层的文件系统通常是只读的(比如 Docker 镜像的底层),上层可以是只读或可写的(比如容器的可写层);
  • 当访问文件时,系统会从最上层开始向下查找,找到第一个匹配的文件就返回(上层 “遮盖” 下层同名文件);
  • 当修改文件时,只会影响上层的可写层,下层只读层保持不变(依赖 “写时复制” 机制)。

举例
把前面的 “文件夹 A(下层,只读)”“文件夹 B(中层,可写)”“文件夹 C(上层,只读)” 按顺序堆叠:

  • 如果你找 test.txt,系统会先看上层的 C,如果有就返回 C 的内容;如果 C 没有,就看中层 B;如果 B 也没有,最后看下层 A。
  • 如果你修改 test.txt(假设它在 A 中),系统会先把 A 中的test.txt复制到中层 B(可写层),然后在 B 中修改,A 中的原始文件不变。

3,什么是 “联合挂载”?什么是挂载点?

把前面的 A、B、C 三个文件夹 “联合挂载” 到 /merged 目录。访问 /merged 时,能看到 A、B、C 中所有的文件,用户完全感觉不到背后有多个文件夹,只觉得/merged是一个普通目录。

形象的例子

假设有两个书架,一个是旧书架(只读层),一个是新书架(可写层) 。

旧书架:上面摆满了各种书,这些书你不打算再去修改它们的位置或者内容,就像联合文件系统里的只读层。比如有一本叫《唐诗三百首》的书,放在旧书架的第二层。

新书架:最开始它是空的,你可以根据自己的需求往上面放书或者对书进行调整,这就类似于联合文件系统里的可写层。

现在,你想要整合这两个书架,让它们看起来像一个书架。你把新书架放在旧书架的上面,形成一个整体的 “大书架” 。

如果新书架上没有《唐诗三百首》这本书,当你去 “大书架” 找《唐诗三百首》时,你就会从旧书架上拿到它;但如果你在新书架上也放了一本《唐诗三百首》,那么当你从 “大书架” 找这本书时,拿到的就是新书架上的那本,这就如同联合文件系统里上层文件覆盖下层同名文件的机制。

而如果有一天,你想要修改新书架上的《唐诗三百首》里的书签位置,不需要去动旧书架上的那本,直接在新书架操作就可以,这就类似联合文件系统里写时复制的概念,对上层可写层的操作不会影响到底层只读层。

5.2镜像分层结构

5.2.1概述

Docker 镜像由多层文件系统组成,从下至上分别为:

  • bootfs(引导文件系统):这是镜像的最底层,主要包含 bootloader 和 kernel。在 Docker 容器启动时,Linux 先加载 bootfs,当 boot 加载完成之后整个内核就都在内存中,此时内存的使用权已由 bootfs 转交给内核,系统会卸载 bootfs。在 Docker 镜像中,这一层与典型的 Linux/Unix 系统类似,不过由于容器共享宿主机内核,所以该层相对精简。
  • rootfs(根文件系统):位于 bootfs 之上,包含典型 Linux 系统中的标准目录和文件,如/dev/proc/bin/etc等。不同的 Linux 发行版,rootfs 会有所差别,但 bootfs 基本是一致的,这使得不同发行版的镜像可以公用 bootfs,不同发行版的镜像(如 CentOS、Ubuntu 镜像)差异主要体现在 rootfs 部分。
  • 应用层:在基础的 rootfs 之上,会根据镜像类型添加对应的应用程序、依赖库、配置文件等。例如,在一个 Tomcat 镜像中,会在基础 rootfs 上添加 JDK 运行环境、Tomcat 服务器程序及相关配置文件等。

在这里插入图片描述

5.2.2知识补充

从启动流程看:
通电 → BIOS/UEFI检测硬件 → 运行bootloader(来自bootfs) → 由bootloader加载内核 → 内核接管内存和硬件 → 卸载bootfs → 操作系统正常运行

  1. boot(启动过程)

“boot” 是 “bootstrap”(引导)的简称,指计算机从断电状态到操作系统正常运行的整个启动过程。

  1. bootloader(引导加载程序)

bootloader 是启动过程中第一个运行的程序,相当于 “启动向导”。主要作用是:

  • 计算机通电后,硬件(如主板)会先运行固化在芯片里的 “BIOS/UEFI” 程序,检测硬件是否正常;
  • 硬件检测通过后,BIOS/UEFI 会找到存储设备(如硬盘)上的bootloader并运行它;
  • bootloader 的任务是找到并加载操作系统的核心(即 kernel,内核)。
  1. kernel(内核)

内核是操作系统的核心程序,是硬件与软件之间的 “桥梁”,主要作用是:

  • 管理计算机的硬件资源(如 CPU、内存、硬盘、网卡等);
  • 提供基础功能(如进程调度、文件读写、网络通信等),让应用程序能间接使用硬件。

没有内核,操作系统和应用程序都无法运行。比如 Linux 系统的内核是 “Linux kernel”,Windows 系统也有自己的内核。

  1. “内存的使用权已由 bootfs 转交给内核”

结合 Docker 镜像的bootfs(引导文件系统)来理解:

  • bootfs是镜像最底层,包含 bootloader 和 kernel 的 “启动相关文件”;
  • 当 Docker 容器启动时,会先加载bootfs中的 bootloader,由它负责启动内核(kernel);
  • 内核启动后,会完全接管内存、CPU 等硬件资源的管理(此时计算机的所有操作都由内核调度);
  • 既然内核已经正常工作,bootfs的任务(引导启动)就完成了,所以会被 “卸载”(释放它占用的资源)。

简单说:bootfs就像 “接生婆”,负责把内核 “接生” 到运行状态,之后就功成身退,由内核接管所有工作。

普通 Linux 系统的bootfs包含完整的内核,但 Docker 镜像的bootfs非常精简,因为:

  • 容器不会运行自己的独立内核,而是直接共享宿主机的内核
  • 因此,Docker 镜像的bootfs只需要包含少量引导文件(让容器能 “接入” 宿主机内核),不需要完整内核,这也是 Docker 镜像体积小的原因之一。

5.3镜像层解析

使用docker image inspect nginx命令,查看 nginx 镜像的详细信息。

其中这段 RootFS 信息展示了该镜像的分层存储结构,其中 Layers 列表中的每一项都是一个镜像层的唯一标识(SHA256 哈希值)。这些层按照顺序叠加,共同构成了完整的镜像。

"RootFS": {"Type": "layers","Layers": ["sha256:7cc7fe68eff66f19872441a51938eecc4ad33746d2baa3abc081c1e6fe25988e","sha256:30837a0774b97fd5fd6306e4a67b9dba10fff174d82f0e7d2c6104dc79716fc3","sha256:a6b19c3d00b104e9f5ae798917606b4706bf27748a008a5b44211b801ede45d8","sha256:6b1b97dc92853f9880a37c378d2fe582eaca6567f3962d6d69dcbf35f65d95f9","sha256:5c91a024d899eb09709296029b21f98722fa446ac7e37bb85b36f6484c499a2e","sha256:0662742b23b26cd3b0c231ac4003d7343e3df50c62765b0baf6336c58156fa76","sha256:f17478b6e8f3dcfdeb55c9e82529529ff6a984b3f72daa2fd723435f9ee9f93f"]
},

每个层(sha256:...)都是一个独立的只读文件系统片段,对应镜像构建过程中的一次操作(如 Dockerfile 中的 RUNCOPYADD 等命令):0

  • 底层(第一个层):通常是基础镜像层(如 centosubuntu 等基础系统的核心文件),是整个镜像的 “地基”。
  • 上层(后续层):在基础层之上,每一层对应一次增量修改。例如:
    • 可能是安装依赖(如 RUN yum install wget);
    • 可能是复制应用代码(如 COPY app.jar /app/);

5.4镜像的加载流程

  1. 本地检查:当执行docker rundocker create等基于镜像创建容器的命令时,Docker 首先会检查本地是否存在指定的镜像。
  2. 拉取镜像(若本地没有):如果本地不存在该镜像,Docker 会从配置的镜像仓库(如 Docker Hub、阿里云镜像仓库等)拉取镜像。拉取过程中,会按照镜像的分层结构,依次下载各个镜像层。由于镜像层的复用性,对于已经下载过的层不会重复下载。
  3. 创建容器层:当镜像下载完成或本地已有镜像后,Docker 会基于镜像创建一个可写层(容器层),这个可写层位于所有镜像层之上。容器运行过程中对文件系统的所有修改,如创建新文件、修改已有文件等,都发生在这个可写层中。
  4. 联合挂载:Docker 通过 UnionFS 将镜像的只读层和容器的可写层联合挂载,形成一个统一的文件系统视图,容器内的应用程序就基于这个统一的文件系统视图运行。

至于如何联合挂载不再深究。

http://www.dtcms.com/a/305612.html

相关文章:

  • 【机器学习】pycharm使用SSH SFTP 远程连接 ubuntu服务器 进行开发+调试+数据训练
  • 在VS2022中调试ASP.NET项目时修改DLL或ASPX动态页面的原理及实现方法
  • 【推荐100个unity插件】Unity 创意编程库——Klak插件的使用
  • 计算机网络基础(二) --- TCP/IP网络结构(应用层)
  • 论文Review LSLAM BALM | 经典激光SLAM方案!港大MARS出品!RAL2021 | 激光BA优化
  • DIV 指令概述
  • AWS VPC NAT 网关可观测最佳实践
  • 【iOS】weak修饰符
  • 计算机组成原理(6) - 加法器
  • SpringBoot学习 |springboot概念+微服务架构
  • 【AI】入门级提示词模板:适用于ChatGPT、文心一言等主流模型
  • day25——HTML CSS 前端开发
  • 运维管理系统的优势和缺点
  • springcloud03-Nacos配置中心
  • HTML应用指南:利用POST请求获取全国公牛门店位置信息
  • Python 使用 asyncio 包处理并 发(使用asyncio包编写服务器)
  • WebSocket 简介与在 Vue 中的使用指南
  • LaTeX 创建工程并生成完整文档指南
  • tplink er2260t配置带vlan的pppoe拨号
  • 【人工智能99问】混合专家模型(MoE)是如何训练的?(18/99)
  • Tomcat 服务器日志
  • uvm-tlm-sockets
  • 论文Review 3DGSSLAM S3PO-GS | ICCV 2025 港科广出品!| 高效快速的3DGSSLAM!
  • 适配鸿蒙低性能设备的终极优化方案:从启动到渲染全链路实战
  • 企业级web应用服务器TOMCAT
  • Qt 嵌入式系统资源管理
  • 【GEO从入门到精通】生成式引擎与其他 AI 技术的关系
  • Linux线程同步与互斥(上)
  • HTML5 Web 存储
  • 从结构到交互:HTML5进阶开发全解析——语义化标签、Canvas绘图与表单设计实战