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 显示 web 和 db 两个服务均为 running。curl 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 |
创建快照 |
实践任务
- 安装 Docker,运行
hello-world验证,再启动一个 Nginx 容器映射到宿主机8080端口 - 创建
docker-compose.yml,用 Docker Compose 同时启动 Nginx + MariaDB,确认两个服务均正常运行 - 安装 Podman,以
ops用户(rootless 模式)启动 Nginx 容器,对比与 Docker 的操作差异 - 创建一个 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 集群等,向云原生方向演进。