跳转至

25 - 容器与虚拟化基础(Docker / Podman / LXC / KVM)

前提条件

  • 已完成 Web、数据库、VPN、高可用配置
  • 以 root 身份登录,或 ops 用户执行 sudo -i 切换至 root 环境
  • 系统运行在 Debian 12 Bookworm
  • VMware Workstation Pro:建议至少 4 核 8 GB 内存(运行多个容器或 KVM 虚拟机)
  • CPU 虚拟化加速已在 VMware 中启用(KVM 需要)

全局参数

主机名 linuxdc,IP 192.168.1.100/24,SSH 端口 2222,运维用户 ops

技术方案对比

技术 隔离级别 内核共享 资源开销 启动时间 推荐场景
Docker 进程级(namespace) 秒级 微服务、CI/CD、Web 应用
Podman 进程级(namespace) 秒级 rootless 安全场景、替代 Docker
LXC 系统级(完整 OS) 秒级 完整系统容器、轻量虚拟机替代
KVM 硬件虚拟化 否(独立内核) 分钟级 完整 OS 隔离、Windows、多内核测试

一、Docker

1. 安装(官方源,避免 Debian 仓库旧版)

apt update
apt install -y ca-certificates curl gnupg

# 导入 Docker 官方 GPG 密钥
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
    | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

# 添加 Docker 软件源
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
  | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable --now docker
docker version
docker run --rm hello-world

检查点

docker run --rm hello-world 输出 Hello from Docker!systemctl status docker 显示 active (running)

将 ops 用户加入 docker 组(免 root 执行 docker 命令):

usermod -aG docker ops
# 需重新登录或执行 newgrp docker 使组成员变更生效

docker 组的安全含义

docker 组成员等同于拥有 root 权限,因为容器可以挂载宿主机根目录。非必要情况下不应将普通用户加入 docker 组,生产中优先使用 Podman rootless 模式。

2. 基础操作

# 拉取镜像
docker pull nginx:latest

# 运行容器(后台模式,宿主机 8080 映射到容器 80)
docker run -d --name my-nginx -p 8080:80 nginx:latest

# 查看运行中的容器
docker ps

# 查看容器日志
docker logs my-nginx

# 进入容器执行命令
docker exec -it my-nginx bash

# 停止并删除容器
docker stop my-nginx
docker rm my-nginx

检查点

curl http://localhost:8080 返回 Nginx 欢迎页 HTML 内容。

3. Docker Compose

创建工作目录和 Compose 文件:

mkdir -p /opt/compose/web
vim /opt/compose/web/docker-compose.yml
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

  db:
    image: mariadb:11
    environment:
      MARIADB_ROOT_PASSWORD: RootPass123!
      MARIADB_DATABASE: appdb
      MARIADB_USER: appuser
      MARIADB_PASSWORD: AppPass123!
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  db_data:
cd /opt/compose/web
mkdir html
echo "<h1>Docker Compose Demo</h1>" > html/index.html

docker compose up -d
docker compose ps
docker compose logs web

检查点

docker compose ps 显示 webdb 两个服务均为 runningcurl http://localhost:8080 返回自定义页面内容。


二、Podman

1. 安装

apt install -y podman
podman --version

2. rootless 模式运行(无需 root)

ops 用户身份执行(不需要 sudo / root):

su - ops

# 运行容器(rootless,进程以 ops 用户身份运行)
podman run -d --name my-nginx -p 8080:80 nginx:latest
podman ps
curl http://localhost:8080
podman stop my-nginx
podman rm my-nginx

检查点

ops 普通用户执行 podman run 成功,无需任何 sudo 提权,curl http://localhost:8080 正常返回。

3. Podman 与 Docker 的命令兼容性

Podman 命令行与 Docker 完全兼容,直接替换即可:

alias docker=podman

podman-compose 替代 docker compose

apt install -y python3-podman-compose
podman-compose up -d

4. Podman 生成 systemd 服务单元

rootless 容器可以生成 systemd 服务,实现开机自启(不依赖守护进程):

# 以 ops 用户执行
podman run -d --name my-nginx -p 8080:80 nginx:latest

# 生成 systemd 用户服务单元文件
podman generate systemd --name my-nginx --files --new
mkdir -p ~/.config/systemd/user
mv container-my-nginx.service ~/.config/systemd/user/

# 启用用户级 systemd 服务
systemctl --user daemon-reload
systemctl --user enable --now container-my-nginx.service

三、LXC

1. 安装

apt install -y lxc lxc-templates

2. 创建并启动容器

# 从 Debian 12 模板创建容器
lxc-create -t download -n web01 -- \
    --dist debian --release bookworm --arch amd64

# 启动容器
lxc-start -n web01

# 查看容器状态和 IP
lxc-info -n web01

3. 在容器内安装服务

# 进入容器
lxc-attach -n web01

# 在容器内执行(与普通 Debian 系统相同)
apt update
apt install -y nginx
systemctl enable --now nginx
exit

从宿主机访问容器:

# 获取容器 IP(通常在 10.0.3.x 网段)
CONTAINER_IP=$(lxc-info -n web01 -iH)
curl http://${CONTAINER_IP}

4. LXC 常用管理命令

命令 说明
lxc-list 列出所有容器及状态
lxc-start -n <name> 启动容器
lxc-stop -n <name> 停止容器
lxc-attach -n <name> 进入容器 Shell
lxc-info -n <name> 查看容器详细信息(含 IP)
lxc-destroy -n <name> 删除容器(不可恢复)
lxc-snapshot -n <name> 创建容器快照

四、KVM

1. 确认硬件虚拟化支持

egrep -c '(vmx|svm)' /proc/cpuinfo
# 输出大于 0 表示支持;VMware 虚拟机中需在 VM Settings → Processors 中勾选 "Virtualize Intel VT-x/EPT"

2. 安装 KVM 及管理工具

apt install -y qemu-kvm libvirt-daemon-system libvirt-clients \
               virtinst bridge-utils
systemctl enable --now libvirtd

将 ops 用户加入相关组:

usermod -aG libvirt ops
usermod -aG kvm ops

3. 创建 KVM 虚拟机(命令行)

virt-install \
    --name       debian12-vm \
    --ram        2048 \
    --vcpus      2 \
    --disk       size=20,format=qcow2 \
    --os-variant debian12 \
    --network    bridge=virbr0 \
    --graphics   none \
    --console    pty,target_type=serial \
    --extra-args 'console=ttyS0,115200n8' \
    --location   'https://deb.debian.org/debian/dists/bookworm/main/installer-amd64/'

网络访问要求

--location 从网络下载安装镜像,需要虚拟机能访问 deb.debian.org。实验环境建议预先下载 ISO 文件后使用 --cdrom /path/to/debian.iso 参数替代。

4. KVM 常用管理命令

命令 说明
virsh list --all 列出所有虚拟机
virsh start <name> 启动虚拟机
virsh shutdown <name> 正常关闭虚拟机
virsh destroy <name> 强制关闭虚拟机
virsh console <name> 连接串口控制台(Ctrl+] 退出)
virsh snapshot-create-as <name> snap1 创建快照

实践任务

  1. 安装 Docker,运行 hello-world 验证,再启动一个 Nginx 容器映射到宿主机 8080 端口
  2. 创建 docker-compose.yml,用 Docker Compose 同时启动 Nginx + MariaDB,确认两个服务均正常运行
  3. 安装 Podman,以 ops 用户(rootless 模式)启动 Nginx 容器,对比与 Docker 的操作差异
  4. 创建一个 LXC 容器 web01,在容器内安装 Nginx,从宿主机访问容器 IP 的 80 端口

自测问题

1. Docker 和 Podman 的最大区别是什么?为什么 Podman 更适合安全敏感环境?

Docker 依赖一个以 root 权限持续运行的守护进程(dockerd),所有容器操作均通过该守护进程执行。守护进程本身存在攻击面,且一旦被攻破,攻击者获得 root 权限。Podman 是无守护进程架构(daemonless),每次运行容器直接 fork 子进程,支持 rootless 模式——容器进程以普通用户身份运行,不需要任何特权。即使容器被攻破,攻击者也只能获得普通用户权限,大幅缩小爆炸半径。此外,Podman 生成的 systemd 服务单元可以作为用户级服务管理,无需系统级守护进程参与。

2. LXC 容器与 Docker 容器的隔离级别有何不同?

两者都使用 Linux 内核的 namespace 和 cgroup 机制,但设计目标不同。LXC 是系统容器,模拟完整的操作系统环境:有独立的 init 进程(systemd/sysvinit)、完整的 /etc、多个系统服务并发运行,更接近轻量级虚拟机,适合需要完整系统环境的场景。Docker 是应用容器,每个容器通常只运行一个前台进程(微服务模式),镜像分层共享,启动更快、镜像更小,专为应用部署和 CI/CD 流程设计。两者的内核隔离级别相近,主要区别在于使用模式和生态定位。

3. KVM 虚拟机启动比容器慢的主要原因是什么?

KVM 虚拟机需要完整模拟独立的硬件环境(虚拟 CPU、内存、磁盘控制器、网卡),并从头执行完整的操作系统启动流程:BIOS/UEFI 初始化 → 引导加载程序 → 内核加载解压 → initramfs → systemd 启动所有系统服务。整个过程通常需要 30 秒到数分钟。容器直接复用宿主机内核,无需模拟硬件,启动仅需创建 namespace 和 cgroup,运行应用进程,通常在 1 秒内完成。

4. 如何让 Docker 容器使用宿主机的网络(--network host 的作用)?

--network host 使容器不创建独立的网络 namespace,直接与宿主机共享网络栈,容器内监听的端口直接绑定在宿主机的网络接口上,无需 -p 端口映射。优点是网络性能最优(无 NAT 开销),容器可直接访问宿主机所有网络接口。缺点是牺牲了网络隔离,容器内的端口冲突会直接影响宿主机,且不同容器之间也可能产生端口冲突。适用于对网络延迟极度敏感的应用(如高性能网络代理),不推荐用于多租户或安全敏感场景。

总结

Docker 是当前应用容器化的事实标准,Podman 以 rootless 和无守护进程特性在安全性上更进一步,两者命令行完全兼容可平滑迁移。LXC 适合需要完整系统级隔离的场景,KVM 提供最强的硬件级隔离,适用于需要独立内核或运行非 Linux 系统的场景。本章建立了容器与虚拟化的基础操作能力,后续可扩展 Docker Compose 编排、Podman Pod、Kubernetes 集群等,向云原生方向演进。