Linux 运维与安全专家 13 · 容器与虚拟化

第 13 章 · 容器与虚拟化

阶段 D预计 6–8 小时现代运维标配

现在装软件、隔离环境、部署发布都绕不开容器。本章讲清:虚拟机和容器到底什么关系、Docker 的核心概念与日常操作、国内镜像加速、compose 编排、无守护进程的 Podman、以及「什么时候用容器、什么时候用虚拟机」。

13.1虚拟机 vs 容器:一个比喻讲透

虚拟机(KVM/VMware) Guest OS(完整系统) Guest OS(完整系统) Hypervisor(虚拟化层) 物理硬件 容器(Docker) 容器 1(App 1) 容器 2(App 2) 容器 3(App 3) 共享宿主内核 虚拟机:每台自带完整操作系统,隔离彻底但开销大;容器:共享内核只隔离进程与文件系统,启动秒级、资源省。

图 13-1 · 虚拟机与容器对比(示意)

关键差异一句话:虚拟机虚拟的是「整台电脑」,容器虚拟的是「运行环境」。容器秒级启动、按 MB 计资源、镜像可复用,是现代应用部署的主流。

13.2Docker 三个核心概念(必须脱口而出)

概念是什么类比
镜像(Image)只读模板:操作系统基础 + 软件 + 配置的打包快照安装光盘 / 类的定义
容器(Container)镜像运行起来的实例,可启动/停止/删除运行中的程序 / 类的实例
仓库(Registry)存镜像的地方(Docker Hub、阿里云镜像仓库、私有仓库)应用商店

镜像名格式:仓库/名称:标签,如 nginx:1.27-alpine(alpine 是精简版)。

13.3安装与国内镜像加速(重点!)

终端 · 官方脚本安装 Docker
# 官方源安装(Ubuntu/Rocky 均适用,国内可能慢)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER    # 当前用户免 sudo 用 docker(重登生效)
docker version                   # 验证
sudo systemctl enable --now docker
/etc/docker/daemon.json · 国内镜像加速
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://dockerproxy.com",
    "https://docker.nju.edu.cn"
  ]
}
# 改完重启:sudo systemctl restart docker
加速源会变动 第三方加速镜像偶有失效,失效了就换列表里的其他源,或改用官方源 + 科学网络。选可信的大厂/高校镜像(第 16 章有清单),别随便用来路不明的加速器。

13.4日常命令(拉/跑/看/停/删五连)

终端 · 五连 + 常用
docker pull nginx:alpine          # 拉镜像
docker run -d --name web -p 8080:80 nginx:alpine   # 跑容器:-d 后台 --name 命名 -p 宿主端口:容器端口
docker ps                         # 运行中的容器(-a 含已停止)
docker logs -f web                # 看容器日志
docker exec -it web /bin/sh       # 进入容器(排障)
docker stop web && docker rm web  # 停止并删除
docker images                     # 本地镜像列表
docker rmi 镜像名                  # 删镜像
docker inspect web                # 容器详情(网络/IP/挂载)
docker stats                      # 容器资源占用(top 的容器版)
端口映射与数据卷 -p 8080:80 表示宿主 8080 → 容器 80;容器删除数据就没了,持久数据必须用卷挂载:-v /data/mysql:/var/lib/mysql(宿主目录:容器目录)。这是「容器化 + 第 3 章 /data 规范」的组合。

13.5Dockerfile 与 Compose:把环境写成代码

Dockerfile · 自定义镜像示例
FROM python:3.12-slim       # 基础镜像
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt   # 构建时执行的命令
COPY app.py .
EXPOSE 8000
CMD ["python", "app.py"]    # 启动命令
# 构建:docker build -t myapp:1.0 .
compose.yml · 一键起整套环境
services:
  web:
    image: nginx:alpine
    ports: ["8080:80"]
    volumes: ["./html:/usr/share/nginx/html"]
  app:
    build: .
    environment:
      - DB_HOST=db
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: change-me
    volumes: ["dbdata:/var/lib/mysql"]
volumes:
  dbdata:
# 一键:docker compose up -d    查看:docker compose ps
# 日志:docker compose logs -f  停止:docker compose down

Compose 的意义:一套环境用一份文本文件声明,新机器 clone 下来一条命令跑起来 —— 这就是「环境即代码」,也是你「每台服务器手动重复配环境」问题的现代解法。

13.6Podman:没有守护进程的 Docker 替代

Podman 兼容 Docker 命令(podman build/run/ps),但不需要常驻守护进程(rootless 模式更安全),Red Hat 系默认推荐,RHEL/Rocky 生态里越来越主流。初学以 Docker 为主,认识 Podman 即可(alias docker=podman 就能无缝过渡)。

13.7KVM / Proxmox:真·虚拟机

13.8怎么选:容器还是虚拟机

场景推荐
部署自己的 Web 服务/数据库/中间件容器(Docker/Podman)
学习不同发行版、模拟多台服务器虚拟机(VMware/VirtualBox 学习;Proxmox 生产)
跑 Windows 或特殊内核需求虚拟机
高隔离合规(客户数据、多租户)虚拟机优先,容器加固后也可
把别人的软件拿来即用(数据库、监控等)容器镜像一条命令(前提:可信官方镜像)

口诀:自己开发部署 → 容器;跑别人整机/特殊系统 → 虚拟机;学习折腾 → 虚拟机做沙盒,容器做生产。

本章自测题

  1. 虚拟机与容器的本质区别是什么?(一句)
  2. 镜像、容器、仓库各是什么?各举一个类比。
  3. 跑一个 nginx 容器并把宿主 8080 映射到容器 80,写出完整命令。
  4. 容器删除后数据会怎样?怎么持久化?
  5. docker ps / logs / exec / stats 各看什么?
  6. Dockerfile 的 FROM/RUN/CMD 各做什么?compose 解决什么问题?
  7. 国内拉镜像慢怎么办?配置在哪?
  8. Podman 与 Docker 的核心区别?
  9. 什么场景必须用虚拟机而非容器?
参考答案
1. 虚拟机虚拟整台电脑(含内核),容器只隔离进程/文件系统共享宿主内核。
2. 镜像=只读模板(光盘);容器=运行实例(程序);仓库=镜像商店(应用商店)。
3. docker run -d --name web -p 8080:80 nginx:alpine
4. 容器删除数据丢失;用 -v 卷挂载持久化(宿主目录:容器目录)。
5. ps 运行容器;logs 日志;exec 进容器执行命令;stats 资源占用。
6. FROM 基础镜像、RUN 构建命令、CMD 启动命令;compose 用一份 yaml 声明整套环境一键起。
7. 配置 /etc/docker/daemon.json 的 registry-mirrors 并重启 docker。
8. Podman 无守护进程、rootless 更安全,命令与 Docker 兼容。
9. 跑 Windows/不同内核发行版、整机隔离合规场景。