Docker原理-理论基础

2 阅读6分钟

0:安装Docker请移步Docker的两种安装Docker 安装(CentOS 环境) 一、在线安装 步骤 1:安装仓库管理工具 yum-uti - 掘金

一:什么是Docker

严格来讲,Docker 就是 Docker 引擎(Docker Engine) 。现在我们说"Docker",指的是一整套广义的产品:

产品是什么
Docker Desktop面向开发者的桌面产品,主要用于 Windows / macOS
Docker Hub公共的容器镜像仓库(默认的镜像来源)
Docker EngineDocker 引擎(真正跑容器的那个东西)

Docker Engine 有两个版本:

版本英文名授权技术支持
社区版docker-ce开源、免费约 4 个月
商业版(企业版)docker-ee闭源、收费12 个月

用Docker做什么:Docker 是一个用容器技术做应用打包和分发的工具,核心价值是让应用在开发、测试、生产环境里表现得一模一样。

Docker的三条核心价值

#价值说明
1环境一致性开发、测试、生产环境有差异。Docker 通过容器封装完整的运行环境,消除了"环境依赖"问题
2资源高效利用相比虚拟机,容器不是一个完整的操作系统,资源占用超低、启动速度快
3部署高效容器可以快速复制、快速启停,天然支持自动化

二:Docker组件与架构

Docker的核心组件

Docker 客户端       (docker 命令)
Docker 守护进程     (dockerd,注意:podman 是没有守护进程的)
Docker 镜像         (Image,模板)
Docker 容器         (Container,实例)
Docker 仓库         (Registry,存镜像的地方)
Dockerfile          (描述"怎么构建镜像"的文件)
Docker Compose      (多容器编排)
Docker 网络         (Network)
Docker 存储         (Volume)

Docker的组件架构:

         用户
          │  敲 docker 命令
          ▼
    Docker 客户端 (client)
          │  REST API
          ▼
   Docker 守护进程 (dockerd)
          │
    ┌─────┴──────┬───────────┐
    ▼            ▼           ▼
  镜像          容器       网络 / 存储
 (Images)   (Containers)
    ▲
    │ 拉取 / 推送
    ▼
  Docker 仓库 (Registry / Docker Hub)

关键理解:我们敲的 docker 命令只是客户端,真正干活的是后台的 dockerd 守护进程。所以看到 Cannot connect to the Docker daemon 时,要去检查 systemctl status docker。

三:镜像与容器

什么是镜像:轻量级,独立、可执行的软件包,连同源码+环境+配置,既可以仓库下载,也可以自己制作。

什么是容器:镜像的运行实例

二者的关系就像类与对象

2:镜像的基本操作

2.1 Docker镜像加速

操作镜像之前(如拉取推送),需要做Docker镜像加速

为什么需要加速: 默认从 Docker Hub 拉镜像,国内网络基本拉不动。必须配镜像加速器

具体过程请移步Docker镜像加速Docker 镜像加速 一、写配置 每个字段什么意思: 字段 作用 registry-mirrors - 掘金

2.2 镜像搜索

方式一:web 搜索(最直观)

打开官方站点 https://hub.docker.com
在搜索栏输入 nginx

方式二:命令行搜索

docker search nginx
docker search centos

2.3 镜像拉取

三种拉法:

docker pull docker.io/library/nginx:1.24.0   # 完整格式(最严格)
docker pull nginx                            # 简写:等价于 nginx:latest,从官方仓库拉
docker pull bitnami/tomcat                   # 第三方镜像(用户名/镜像名)

完整格式的组成(面试可能问) :

docker.io     /  library  /  nginx  :  1.24.0
   仓库地址       命名空间      镜像名      标签

· 省略仓库地址 → 默认 docker.io
· 省略命名空间 → 默认 library(官方镜像)
· 省略标签     → 默认 latest

检验:docker images

预期的一个输出

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        1.24      6c0218f16876   2 years ago    142MB
nginx        latest    fd204fe2f750   10 days ago    161MB
hello-world  latest    e2ac70e7319a   5 months ago   10.1kB

四:容器与虚拟机的区别

1:虚拟机装了完整的操作系统,容器只有应用和依赖(看后面的镜像加载原理)

2:虚拟机是硬件级隔离,容器是进程级别的隔离(看后面的namespace和cgroup)

镜像加载原理(分层存储)

核心:UFS(联合文件系统)

Docker 镜像采用【分层存储】结构,核心技术是 UFS(联合文件系统 Union File System)。
多个层叠加起来,对外看起来像一个完整的文件系统。

镜像的两个"核心层"(课件模型)

层位置内容
bootfs(引导文件系统)最底层包含 bootloader 和 Linux 内核;所有 Linux 发行版的 bootfs 基本一致
rootfs(根文件系统)在 bootfs 之上包含 /bin、/etc、/opt 等目录

Docker 镜像并不包含完整的操作系统,它只提供 rootfs 和应用程序,内核则使用母机(宿主机)的。

分层的好处:资源共享

如果多个镜像基于同一个基础镜像构建,宿主机只需要保留一份基础层。
内存里也只需要加载一次。

举个实例:
  nginx 和 mysql 都基于某个 debian/ubuntu 基础层,
  那么这个基础层在本地只存一份,两个镜像共用。

镜像层与容器层

镜像层是【只读】的。
容器运行时写的数据(装软件、改配置、写日志)落在最上面的【可写层】。

最终的镜像 = 所有层累加
容器       = 只读的镜像层 + 一层可写层

实操:亲眼看一眼镜像的层

docker pull nginx
docker history nginx

预期输出(docker history 会把每一层列出来):

IMAGE          CREATED       CREATED BY                                      SIZE
fd204fe2f750   10 days ago   CMD ["nginx" "-g" "daemon off;"]                0B
<missing>      10 days ago   STOPSIGNAL SIGQUIT                              0B
<missing>      10 days ago   EXPOSE map[80/tcp:{}]                           0B
<missing>      10 days ago   ENTRYPOINT ["/docker-entrypoint.sh"]            0B
<missing>      10 days ago   COPY 30-tune-worker-processes.sh /docke…        4.62kB
...

看什么:每一行就是一层,SIZE 是这一层增加的大小。有些层是 0B(只改了元数据,比如 CMD、EXPOSE)—— 这正好说明"指令不一定产生文件,但一定会产生一层"。

2.4 Namespace 与 Cgroups(容器的两块基石)

Namespace —— 负责"看不见"(隔离)

课件原文:Namespace 是由 Linux 内核提供的一种特性,它能够将一些系统资源包装到一个抽象的空间中,并使得该空间中的进程以为这些资源是系统中仅有的资源。Namespace 是构建容器技术的基石,它使得容器内的进程只能看到容器内的进程和资源,实现与宿主系统以及其他容器的进程和资源隔离。Namespace 按操作的系统资源不同有很多种类,比如 cgroup namespace、mount namespace 等等。

六种 Namespace(面试高频) :

Namespace隔离什么效果
PID进程号容器里有自己的 PID 1,看不到宿主机进程
NET网络有自己的网卡、IP、端口、路由表
MNT挂载点有自己的文件系统视图(根目录不一样)
UTS主机名 / 域名容器可以有自己的 hostname
IPC进程间通信信号量、共享内存互不干扰
USER用户和 UID容器里的 root 可以映射成宿主机的普通用户

Cgroups —— 负责"用多少"(限制)

Cgroups 是资源限制器,作用是限制、统计和隔离进程使用的资源。

能限制哪些资源:

CPU      :能用多少核、占多少比例(cpu、cpuset)
内存      :能用多少内存(memory),超了会被 OOM 杀掉
块设备 IO :读写速率(blkio)
进程数    :最多能起多少进程/线程(pids)