Docker 深入理解:从容器原理到生产环境最佳实践

作者:王仕宇(JavaPub)


前言

很多开发者学习 Docker,只停留在:

bash 复制代码
docker run nginx

然后认为 Docker 就是一个启动程序的工具。

但真正进入企业开发之后,你会发现:

  • 为什么 Docker 启动速度这么快?
  • 容器和虚拟机有什么区别?
  • 为什么删除容器数据没了?
  • 为什么线上 Docker 容器会越来越大?
  • 为什么生产环境一定使用 Docker Compose?
  • 为什么 Kubernetes 基于 Docker 思想发展?

理解 Docker 底层原理,才能真正掌握容器化技术。


一、Docker 到底解决了什么问题?

在传统开发模式中:

开发环境:

复制代码
Mac
Node 20
MySQL 8
Redis 7
Python 3.12

测试环境:

复制代码
Linux
Node 18
MySQL 5.7
Redis 6
Python 3.10

生产环境:

复制代码
Linux
Node 16
MySQL 5.7
Redis 6

结果:

开发:

我本地可以运行。

上线:

为什么服务器不能运行?

Docker 解决的问题:

复制代码
应用
+
运行环境
+
依赖

一起打包

形成:

复制代码
Docker Image

无论在哪里:

复制代码
开发机器

服务器

云服务器

Kubernetes

运行结果保持一致。

这就是:

Build Once, Run Anywhere


二、Docker 架构

Docker 主要由三部分组成:

复制代码
        Docker Client

              |
              |

        Docker Daemon

              |
      ----------------

      Image      Container

1. Docker Client

就是我们使用的命令:

bash 复制代码
docker run nginx

实际上发送请求:

复制代码
docker CLI

↓

Docker API

↓

Docker Daemon

2. Docker Daemon

后台服务:

Linux:

bash 复制代码
systemctl status docker

负责:

  • 创建容器
  • 管理镜像
  • 管理网络
  • 管理存储

3. Docker Registry

镜像仓库:

例如:

Docker Hub:

复制代码
hub.docker.com

流程:

复制代码
docker pull nginx


本地没有

↓

Docker Hub下载

↓

保存Image

三、Docker 容器为什么这么快?

很多新人认为:

Docker = 小型虚拟机

实际上不是。


虚拟机架构

传统虚拟机:

复制代码
物理服务器

↓

Hypervisor

↓

Guest OS

↓

应用

例如:

VMware

VirtualBox

需要完整操作系统。


Docker 架构

Docker:

复制代码
服务器

↓

Linux Kernel

↓

Docker

↓

Container

↓

应用

多个容器共享:

  • Linux Kernel
  • 系统资源

所以启动:

虚拟机:

复制代码
分钟级

Docker:

复制代码
秒级

四、Docker 三大核心技术

Docker 能实现隔离,主要依靠 Linux:

  • Namespace
  • Cgroups
  • UnionFS

1. Namespace:隔离环境

Namespace 负责:

看起来像独立系统。

例如:

容器 A:

复制代码
PID:

1 nginx
2 worker

容器 B:

复制代码
PID:

1 mysql

实际上:

宿主机:

复制代码
PID:

100 nginx
200 mysql

但是容器内部认为:

复制代码
自己就是系统

Namespace 类型:

类型 作用
PID 进程隔离
NET 网络隔离
MNT 文件系统隔离
UTS 主机名隔离
IPC 进程通信隔离

2. Cgroups:资源限制

如果一个容器占满 CPU:

服务器可能挂掉。

Cgroups:

控制:

  • CPU
  • 内存
  • IO

例如:

限制 MySQL:

bash 复制代码
docker run \
--memory=512m \
mysql

表示:

最多使用:

复制代码
512MB RAM

限制 CPU:

bash 复制代码
docker run \
--cpus=2 \
nginx

最多:

复制代码
2个CPU核心

3. UnionFS:镜像分层

Docker 镜像不是一个完整文件。

例如:

nginx:

复制代码
Layer 1
Ubuntu

Layer 2
nginx

Layer 3
配置文件

Layer 4
启动脚本

多个镜像共享基础层。

好处:

减少空间。

查看:

bash 复制代码
docker history nginx

五、Docker 镜像到底是什么?

镜像:

本质:

一个只读模板。

例如:

Dockerfile:

dockerfile 复制代码
FROM ubuntu

RUN apt update

RUN apt install nginx

COPY index.html /

CMD nginx

执行:

bash 复制代码
docker build -t my-nginx .

生成:

复制代码
Image

my-nginx

运行:

bash 复制代码
docker run my-nginx

产生:

复制代码
Container

关系:

复制代码
Image

   ↓

Container

类似:

复制代码
类

↓

对象

六、Dockerfile 最佳实践

1. 使用官方基础镜像

推荐:

dockerfile 复制代码
FROM node:20-alpine

不要:

dockerfile 复制代码
FROM ubuntu

自己安装node

原因:

  • 镜像小
  • 安全
  • 快速

2. 减少镜像体积

错误:

dockerfile 复制代码
RUN apt update

RUN apt install xxx

多个 Layer。

优化:

dockerfile 复制代码
RUN apt update \
&& apt install xxx \
&& rm -rf /var/lib/apt/lists/*

3. 使用 .dockerignore

类似:

.gitignore

例如:

复制代码
node_modules

.git

.env

避免进入镜像。


七、Docker 数据持久化

很多新人踩坑:

启动 MySQL:

bash 复制代码
docker run mysql

创建数据:

复制代码
users
orders
products

删除:

bash 复制代码
docker rm mysql

数据全部消失。

原因:

容器是临时的。


解决:

Volume。

结构:

复制代码
宿主机

/data/mysql


      |

      |

容器

/var/lib/mysql

创建:

bash 复制代码
docker volume create mysql-data

使用:

bash 复制代码
docker run \
-v mysql-data:/var/lib/mysql \
mysql

八、Docker 网络原理

容器默认:

复制代码
container network

docker0

查看:

bash 复制代码
ip addr

创建:

复制代码
app

 |

docker network

 |

mysql

推荐:

bash 复制代码
docker network create app-net

启动:

MySQL:

bash 复制代码
docker run \
--network app-net \
mysql

应用:

bash 复制代码
docker run \
--network app-net \
backend

然后:

代码连接:

properties 复制代码
MYSQL_HOST=mysql

不需要写 IP。


九、Docker Compose 企业实践

实际项目:

不会启动:

复制代码
docker run mysql

docker run redis

docker run nginx

而是:

docker-compose.yml

例如:

yaml 复制代码
version: "3"

services:

  mysql:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - mysql-data:/var/lib/mysql


  redis:
    image: redis


  nginx:
    image: nginx
    ports:
      - 80:80


volumes:

  mysql-data:

启动:

bash 复制代码
docker compose up -d

停止:

bash 复制代码
docker compose down

十、生产环境 Docker 优化

1. 不使用 root 用户

Dockerfile:

dockerfile 复制代码
USER app

提高安全性。


2. 健康检查

dockerfile 复制代码
HEALTHCHECK CMD curl http://localhost

Docker 自动判断:

服务是否正常。


3. 日志管理

不要:

复制代码
日志写文件

无限增长

推荐:

复制代码
stdout

↓

Docker logging

↓

ELK

4. 固定版本

不要:

yaml 复制代码
mysql:latest

生产:

yaml 复制代码
mysql:8.0.36

避免升级导致故障。


十一、Docker 常见排查命令

查看日志

bash 复制代码
docker logs -f app

查看资源

bash 复制代码
docker stats

查看详细信息

bash 复制代码
docker inspect app

查看进程

bash 复制代码
docker top app

进入容器

bash 复制代码
docker exec -it app sh

十二、Docker 与 Kubernetes 的关系

Docker:

负责:

复制代码
运行一个容器

Kubernetes:

负责:

复制代码
管理大量 Docker 容器

例如:

100 台服务器:

复制代码
1000 个容器

Kubernetes 自动:

  • 创建
  • 删除
  • 扩容
  • 故障恢复

关系:

复制代码
Docker

↓

Container

↓

Kubernetes

↓

云原生平台

十三、Docker 学习路线

第一阶段

掌握:

复制代码
docker run

docker ps

docker images

docker logs

docker exec

第二阶段

学习:

复制代码
Dockerfile

Volume

Network

Compose

第三阶段

深入:

复制代码
Namespace

Cgroups

镜像优化

安全

CI/CD

Kubernetes

总结

Docker 不只是一个部署工具。

它改变了软件交付方式:

以前:

复制代码
代码

↓

配置环境

↓

部署

↓

解决环境问题

现在:

复制代码
代码

↓

Docker Image

↓

任何服务器运行

对于后端开发者:

Java、Go、Python、Node.js、AI 服务部署,

Docker 已经成为现代工程体系的重要基础。

作者:王仕宇 JavaPub

相关推荐
aiot189189352182 小时前
核芯物联蓝牙AOA高精度定位生态合作案例分享金库定位踩坑实录
大数据·运维·网络·人工智能·蓝牙aoa
TomEval2 小时前
【接口自动化】13 - 接口数据驱动与报告
运维·windows·自动化
程序员无隅2 小时前
Codex 实战:用 AI 写运维脚本
运维·人工智能
Soari2 小时前
Linux 内核对比:PREEMPT_DYNAMIC vs PREEMPT_RT
linux·运维·ubuntu
商业看点解说3 小时前
数据中心运维管理软件平台推荐
运维
网硕互联的小客服3 小时前
服务器可以远程连接,但是为什么无法Ping通?如何解决处理?
运维·服务器
暖核3 小时前
Docker 入门|吃透容器生态与底层原理
运维·docker·容器
滕州市燕猫虎计算机科技工作室个体工商户3 小时前
Docker常用命令
运维·docker·容器
海宇数据3 小时前
零信任架构实战:基于海宇单人婚姻状态查询构建自动化KYC审核网关
运维·人工智能·架构·自动化