Docker 从 0 入门|吃透容器生态、架构与 Dockerfile 实战

一、容器生态系统 (001‑003)

容器技术是云计算之后热门的 IT 技术,Docker 的普及让容器走入广大开发者和运维的视野。学习容器不要一上来就敲命令,先建立整体认知,就像旅游先看城市地图,理清分层、各组件职责,避免学习迷路。

容器生态分为三大板块:容器核心技术、容器平台技术、容器支持技术

1. 容器核心技术

负责让容器能够在单机主机上运行起来。

  1. 容器规范 OCI:由 Docker、Google、CoreOS 等厂商联合制定,包含 runtime spec 运行时规范、image format spec 镜像格式规范,保证不同容器实现之间可移植、互相兼容。代表项目 rkt、podman、containerd。
  2. 容器 runtime:容器真正运行环境,和操作系统内核深度交互。类比 Java 里 JVM,容器程序就像 Java 应用。主流实现:lxc(Docker 早期底层)、runc(Docker 现在默认 runtime,符合 OCI)、rkt。
  3. 容器管理工具:对外提供 CLI 交互,对内调用 runtime。Docker Engine 就是 Docker 的管理工具,包含后台守护进程 daemon 和命令行 cli。
  4. 容器定义工具:定义容器内容属性,用来保存、共享、重建容器。Dockerfile 用来构建镜像,镜像就是容器模板。
  5. Registries 镜像仓库:存放镜像。Docker Hub 是公共仓库;Docker Registry 可搭建私有仓库;Quay.io 是第三方公共镜像仓库。
  6. 容器 OS:专门运行容器的操作系统,体积小启动快。典型:CoreOS、Atomic、Ubuntu Core。

2. 容器平台技术

解决集群分布式环境下容器运行的问题,单机容器靠核心技术,多机器集群靠平台技术。

  1. 容器编排引擎:微服务场景,大量容器需要动态创建、调度、迁移、销毁。主流:Docker Swarm、Kubernetes、Mesos+Marathon。负责调度、集群管理、服务发现。
  2. 容器管理平台:封装编排引擎,提供 UI、应用一键部署,如 Rancher、ContainerShip。
  3. 基于容器的 PaaS:面向开发人员,不用关心底层基础设施,专注业务开发,Deis、Flynn、Dokku 属于这类。

3. 容器支持技术

配套支撑容器基础设施运行。

  • 容器网络:docker network、flannel、weave、calico,解决容器之间、容器外部网络连通隔离。
  • 服务发现:容器 IP 会动态变化,etcd、consul、zookeeper 保存服务地址信息,供客户端查询访问。
  • 监控:docker 自带 ps/top/stats,还有 sysdig、cAdvisor、Weave Scope。
  • 数据管理、日志管理、容器安全扫描,都是生产环境必不可少的组成部分。

二、Docker 安装与第一个容器 (004‑005)

实验环境采用 CentOS Stream8,克隆虚拟机,配置静态 IP。 Docker 由两部分:Docker Engine 服务端 dockerd,Docker‑cli 客户端。

安装步骤简述

  1. 配置阿里云 Docker 软件源
  2. 安装 docker‑ce 服务端,设置开机自启并启动服务
  3. 配置镜像加速器(阿里云 / 华为云 SWR),修改/etc/docker/daemon.json配置registry‑mirrors,重载 systemd,重启 docker,使用docker info校验加速器是否生效。

运行第一个容器

复制代码
docker run hello-world

执行逻辑:本地找不到镜像 → 去镜像仓库拉取镜像 → 基于镜像启动容器,输出提示信息。

再运行 httpd 网页容器做端口映射:

复制代码
docker run -d -p 80:80 httpd

把容器 80 端口映射宿主机 80,浏览器访问服务器 IP,看到It works!说明 web 容器正常。

Docker C/S 分离部署

Docker 是典型 C/S 架构,客户端 cli 和服务端 daemon 可以分开部署。

  1. docker_server 节点:修改 docker.service,dockerd 监听‑H tcp://0.0.0.0:2375,开放远程 API。

  2. docker_client 节点:只安装 docker‑ce‑cli 客户端,不安装完整 docker‑ce。

  3. 客户端远程调用服务端执行命令:

    docker -H 192.168.108.30 run hello-world

镜像、容器全部存储在 server 服务端机器,client 只发送指令。

三、什么是容器?容器与虚拟机对比 (006)

容器发展简史

容器思想很早就存在:chroot、FreeBSD Jail,后续 Linux VServer,Solaris Zone,Google cgroups,LXC,直到 2013 年 Docker 诞生,把容器普及开来。

What 什么是容器

容器是轻量级、可移植、自包含的软件打包技术。把应用连同依赖库一起打包,开发环境打包好,测试、生产环境直接运行,无需修改。

容器 = 应用程序 + 全部依赖库。 容器运行在宿主机用户空间,共享宿主机 Linux 内核。

容器 vs 虚拟机

表格

项目 虚拟机 容器
内核 拥有独立完整内核 共享宿主机内核
启动速度 分钟级 秒级甚至毫秒级
隔离 硬件级完全隔离 进程级别隔离 (namespace/cgroup)
资源开销 大,每个虚拟机完整 OS 很小,只是宿主机进程
单机实例数量 几十台 上千个容器
镜像 完整操作系统镜像,GB 级别 分层镜像,MB 级别

虚拟机通过 Hypervisor 虚拟化硬件;容器直接复用宿主机内核,利用 namespace 做隔离,cgroups 做资源限制。

Why 为什么用容器

传统开发会遇到环境矩阵难题:多个业务服务,需要部署到开发、测试、多套生产环境,每个环境配置非常麻烦。

现实世界的集装箱 解决了货运的 N×M 匹配难题:不管什么货物统一装进标准集装箱,卡车、火车、轮船通用搬运。Docker 借鉴这个思想,把软件打包成 "软件集装箱",实现一次构建,到处运行

开发:Build Once, Run Anywhere 运维:Configure Once, Run Anything 消除开发、测试、生产环境不一致问题。

四、Docker 架构详解 (007‑008)

Docker 采用C/S 客户端‑服务端架构

  1. Docker Client 客户端:就是 docker 命令行,用户输入 docker 指令。
  2. Docker Daemon 服务端 (dockerd):后台守护进程,真正干活,管理镜像、容器、网络、卷。客户端通过 REST API 和 daemon 通信,可以本地 socket,也可以远程 tcp。
  3. Image 镜像:只读模板,创建容器的模板。
  4. Container 容器:镜像的运行实例,可读写。
  5. Registry 镜像仓库:存放镜像,Docker Hub 是默认公共仓库。

组件协同流程,以docker run -d -p 80:80 httpd为例

  1. 用户在客户端执行 docker run;
  2. 请求发送给 dockerd 守护进程;
  3. daemon 本地查找 httpd 镜像,本地不存在;
  4. daemon 向 Registry 拉取 httpd 镜像;
  5. 镜像下载保存本地;
  6. daemon 基于镜像创建容器,设置端口映射,启动容器。

五、镜像内部结构 (009‑012)

最小镜像 hello‑world

hello‑world 镜像体积只有十几 KB。Dockerfile:

复制代码
FROM scratch
COPY hello /
CMD ["/hello"]

FROM scratch代表从零开始构建,镜像里面只有一个 hello 可执行程序,没有 /bin、/usr 这些系统目录,只用来验证 docker 环境。

base 基础镜像

base 镜像含义:①scratch 从零构建;②其他镜像可以以此为基础扩展。 常见 centos、ubuntu、alpine 都属于 base 镜像。

重点:容器镜像只有 rootfs,没有内核! bootfs 是内核文件系统,宿主机 Linux 内核;rootfs 是用户态文件系统,包含 /bin/etc /dev 目录。容器复用宿主机 kernel。 无论容器镜像是 centos7 还是 ubuntu,执行 uname‑r 看到的内核版本永远是宿主机的内核,容器内部不能修改升级内核。如果业务对内核版本强依赖,应该选择虚拟机。

镜像分层与写时复制 Copy‑on‑Write

Docker 镜像是多层只读堆叠,每一条 Dockerfile 指令生成一层镜像。 多个镜像如果共用 base 基础层,磁盘和内存只存一份,实现资源共享。

镜像层全部只读;容器启动,会在最顶层增加一层可读写容器层。 所有新增、修改、删除文件全部发生在最上层读写层;下层镜像层永远不变。修改底层文件会触发写时复制:把对应文件复制到上层容器层再修改,底层原始数据保持原样。

两种创建镜像方式

  1. docker commit:启动容器,手动修改容器环境,把容器提交保存成镜像。 缺点:手工操作,构建过程不可审计,不推荐生产使用,但可以帮助理解底层原理。
  2. Dockerfile 构建镜像(官方推荐):用文本文件记录每一步构建指令,可复用、可审计。

六、Dockerfile 构建镜像 (013‑017)

Dockerfile 是描述镜像构建步骤的文本文件。 规则:

  1. 指令大写,参数跟随;
  2. 从上往下顺序执行;
  3. #是注释;
  4. 每一条指令生成一个镜像层

构建命令:

复制代码
docker build -t 镜像名:tag -f Dockerfile路径 上下文路径

.代表当前目录作为构建上下文,docker 会把上下文全部文件传给 daemon,不要把 / 根目录当做上下文,避免文件过多拖慢构建。

Docker 镜像缓存

构建镜像时,如果指令和上一次构建完全一致,直接复用缓存镜像层,提升构建速度。 只要某一层发生改动,该层上面所有层缓存全部失效 。 构建禁用缓存:docker build --no-cache

调试 Dockerfile

build 中途某条指令报错,已经构建成功的镜像层会保留。直接运行上一步成功的镜像,复现操作排查错误。

Dockerfile 常用指令

  1. FROM:指定基础镜像,必须是 Dockerfile 第一条有效指令;scratch 代表空白镜像。
  2. MAINTAINER:设置镜像作者信息。
  3. COPY src dest:把构建上下文文件复制到镜像内部,只做复制,不解压。
  4. ADD src dest:复制文件,如果源是压缩包会自动解压到目标路径。
  5. ENV key value 设置环境变量,后续指令、容器运行时都可以读取。
  6. WORKDIR /xxx 设置后续 RUN/CMD/ENTRYPOINT 等指令的工作目录,目录不存在自动创建。
  7. EXPOSE 80:声明容器打算监听的端口,只是文档声明,不会自动做端口映射。
  8. VOLUME:声明数据卷,实现容器数据持久化。

RUN / CMD / ENTRYPOINT 重点区分

  1. RUN :构建镜像阶段执行命令,执行结束生成新镜像层。常用于安装软件包。 两种写法:shell 格式 RUN apt install vim;exec 数组格式RUN ["apt","install","vim"]
  2. CMD :容器启动阶段执行默认命令。
  • docker run 后面追加命令参数,会直接覆盖替换 CMD;
  • 多个 CMD 只有最后一条生效。 格式:exec 数组格式(推荐)CMD ["echo","hello"];shell 格式。
  1. ENTRYPOINT:容器启动运行程序,不会被 docker run 参数覆盖;run 后面传入的参数会当做参数传给 ENTRYPOINT。 可以配合 CMD 设置默认参数。

    ENTRYPOINT ["/bin/echo","Hello"]
    CMD ["world"]

直接运行容器输出Hello worlddocker run 镜像 gqd输出Hello gqd

shell 格式的 ENTRYPOINT 会忽略 CMD 和 run 传入参数,写服务镜像优先选择 exec 数组格式。

几个实操案例要点

  1. 制作带 ssh 的 centos 镜像:安装 openssh‑server,生成 ssh 密钥,设置 root 密码,CMD ["/usr/sbin/sshd","‑D"]前台运行 sshd 服务。
  2. 自定义 httpd 镜像:把本地 index.html 复制进镜像,httpd 前台启动。
  3. 制作 jdk8 镜像:ADD 把 jdk 压缩包导入镜像,配置 JAVA_HOME 系列环境变量。

Dockerfile 不要把多个独立软件安装拆分成多个 RUN,尽量合并 && 减少镜像层数,同时要注意 apt/yum 更新和安装写在同一个 RUN,避免缓存带来版本老旧问题。

相关推荐
风123456789~1 小时前
【架构专栏】8.2-8.3 系统架构评估、ATAM评估实践
架构
Runwise创新社区1 小时前
Anthropic多智能体架构怎么落地?Lead Agent、共享记忆与并行任务的设计边界
人工智能·架构·多智能体
海宇数据2 小时前
零信任架构实战:基于海宇对外投资历史查询服务构建自动化异动企业筛查网关
运维·人工智能·架构·自动化
Brilliantwxx2 小时前
【STM32】 I2C协议和设备主从( 图解 + 面试题 )
stm32·单片机·嵌入式硬件·架构
QQ_21696290962 小时前
基于微服务架构的店铺管理系统的设计与实现
大数据·spring boot·后端·spring·微服务·小程序·架构
putItInYourHand2 小时前
Docker Compose 部署 Mosquitto MQTT Broker 完整实战指南
运维·docker·容器
头茬韭菜11 小时前
第 1 篇:「Glass-Box 的骨架」——全景架构与六层数据流水线
架构·agent·semantica
生活爱好者!11 小时前
哇!影视新玩法!docker部署NEOWATCH NAS
运维·docker·容器
奔跑的架构师12 小时前
[A-50]ARMv9/v8-DVFS系统架构
linux·arm开发·架构·系统架构·arm