强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Alpine Linux 完全指南 / 第 10 章:容器管理

第 10 章:容器管理

在 Alpine Linux 上使用 LXC、Docker 和 Podman 管理容器。

10.1 容器技术概览

技术类型特点适用场景
Docker应用容器镜像标准化、生态完善应用部署、微服务
Podman应用容器无守护进程、rootless安全优先环境
LXC系统容器完整 OS 环境传统应用迁移
┌────────────────────────────────────────────────┐
│              容器技术栈                         │
├──────────┬──────────┬──────────────────────────┤
│  Docker  │  Podman  │          LXC/LXD        │
├──────────┴──────────┴──────────────────────────┤
│              containerd / runc                  │
├────────────────────────────────────────────────┤
│         Linux Kernel (cgroups + namespaces)     │
└────────────────────────────────────────────────┘

10.2 Docker

安装与配置

# 安装 Docker
apk add docker

# 添加用户到 docker 组
addgroup myuser docker

# 开机启动
rc-update add docker boot
rc-service docker start

# 配置 Docker 守护进程
cat > /etc/docker/daemon.json << 'EOF'
{
    "storage-driver": "overlay2",
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "10m",
        "max-file": "3"
    },
    "default-ulimits": {
        "nofile": {
            "Name": "nofile",
            "Hard": 65535,
            "Soft": 65535
        }
    },
    "live-restore": true,
    "userland-proxy": false,
    "iptables": true
}
EOF

rc-service docker restart

Docker 基础操作

# 容器生命周期
docker run -d --name web -p 80:80 nginx        # 后台运行
docker run -it --rm alpine sh                   # 交互式
docker start web                                 # 启动已停止容器
docker stop web                                  # 停止
docker restart web                               # 重启
docker rm web                                    # 删除

# 查看容器
docker ps                                        # 运行中
docker ps -a                                     # 所有
docker logs web                                  # 查看日志
docker logs -f web                               # 跟踪日志
docker exec -it web sh                           # 进入容器
docker inspect web                               # 详细信息
docker stats                                     # 资源使用

# 镜像管理
docker images                                    # 列出镜像
docker pull alpine:3.20                          # 拉取
docker rmi image_id                              # 删除
docker image prune -a                            # 清理未使用

# 网络
docker network ls                                # 列出网络
docker network create mynet                      # 创建网络
docker network inspect mynet                     # 检查

# 数据卷
docker volume create mydata                      # 创建
docker volume ls                                 # 列出
docker volume rm mydata                          # 删除

Docker Compose

# 安装
apk add docker-compose

# docker-compose.yml 示例
cat > docker-compose.yml << 'EOF'
version: "3.8"

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/var/www/html:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - app
    restart: unless-stopped

  app:
    image: node:20-alpine
    working_dir: /app
    volumes:
      - ./app:/app
    command: ["node", "server.js"]
    environment:
      - NODE_ENV=production
      - DB_HOST=db
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mariadb:11
    volumes:
      - db_data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password
      - MYSQL_DATABASE=app
    secrets:
      - db_root_password
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    restart: unless-stopped

volumes:
  db_data:

secrets:
  db_root_password:
    file: ./secrets/db_root_password.txt
EOF

# Docker Compose 命令
docker-compose up -d                             # 启动
docker-compose down                              # 停止删除
docker-compose ps                                # 状态
docker-compose logs -f                           # 日志
docker-compose exec app sh                       # 进入容器
docker-compose pull                              # 拉取新镜像
docker-compose up -d --build                     # 重新构建

10.3 Podman

安装与配置

# 安装 Podman
apk add podman podman-compose

# Podman 无需守护进程,直接使用
# 初始化存储
podman system reset  # 可选:重置存储

# 检查安装
podman info
podman version

Podman 基础操作

# 与 Docker CLI 兼容的命令
podman run -d --name web -p 80:80 nginx:alpine
podman ps -a
podman logs web
podman exec -it web sh
podman stop web
podman rm web

# Rootless 模式(推荐)
# 不需要 root 权限
podman run --rm -it alpine sh

# 生成 systemd 服务文件
podman generate systemd --new --name web > /etc/init.d/web-container
chmod +x /etc/init.d/web-container
rc-update add web-container default

# 或使用 Quadlet(Podman 4.4+)
mkdir -p /etc/containers/systemd
cat > /etc/containers/systemd/web.container << 'EOF'
[Container]
Image=nginx:alpine
PublishPort=80:80
Volume=./html:/var/www/html:ro

[Service]
Restart=always

[Install]
WantedBy=default.target
EOF

Podman vs Docker 对比

特性DockerPodman
守护进程dockerd (需要)无(无守护进程)
Root 权限默认需要支持 rootless
OCI 兼容
Docker Compose原生支持podman-compose
Systemd 集成有限原生支持
安全性
生态极大

10.4 LXC 系统容器

安装 LXC

# 安装 LXC
apk add lxc lxc-templates debootstrap

# 内核配置检查
lxc-checkconfig

# 创建 LXC 配置目录
mkdir -p /etc/lxc

创建容器

# 下载 Alpine 容器模板
lxc-create -t alpine -n mycontainer

# 或下载 Debian 容器
lxc-create -t download -n debian-ct -- \
    --dist debian --release bookworm --arch amd64

# 查看已创建的容器
lxc-ls

# 查看容器信息
lxc-info -n mycontainer

# 启动容器
lxc-start -n mycontainer

# 进入容器
lxc-attach -n mycontainer

# 或使用控制台
lxc-console -n mycontainer

# 停止容器
lxc-stop -n mycontainer

# 删除容器
lxc-destroy -n mycontainer

LXC 网络配置

# /etc/lxc/default.conf
cat > /etc/lxc/default.conf << 'EOF'
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
EOF

# 创建网桥
cat >> /etc/network/interfaces << 'EOF'
auto lxcbr0
iface lxcbr0 inet static
    address 10.0.3.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    post-up iptables -t nat -A POSTROUTING -s 10.0.3.0/24 -o eth0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s 10.0.3.0/24 -o eth0 -j MASQUERADE
EOF

# 容器配置文件 /var/lib/lxc/mycontainer/config
cat > /var/lib/lxc/mycontainer/config << 'EOF'
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.ipv4.address = 10.0.3.100/24
lxc.net.0.ipv4.gateway = 10.0.3.1

lxc.cgroup2.memory.max = 512M
lxc.cgroup2.cpu.max = 50000 100000
EOF

# 开机自启
rc-update add lxc

10.5 容器编排

Docker Compose 完整示例

# 全栈 Web 应用
version: "3.8"

services:
  # 反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - app
    networks:
      - frontend

  # 应用服务
  app:
    build: .
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 256M
    networks:
      - frontend
      - backend
    depends_on:
      - db
      - redis
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # 数据库
  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    networks:
      - backend

  # 缓存
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redisdata:/data
    networks:
      - backend

networks:
  frontend:
  backend:

volumes:
  pgdata:
  redisdata:

secrets:
  db_password:
    file: ./secrets/db_password.txt

10.6 容器安全

# Docker 安全扫描
apk add trivy

# 扫描镜像漏洞
trivy image nginx:alpine
trivy image --severity HIGH,CRITICAL myapp:latest

# Docker Bench Security
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sh docker-bench-security.sh

# 限制容器资源
docker run -d \
    --name secure-app \
    --memory=256m \
    --cpus=0.5 \
    --read-only \
    --tmpfs /tmp \
    --security-opt no-new-privileges \
    --cap-drop ALL \
    --cap-add NET_BIND_SERVICE \
    myapp:latest

# 使用 Seccomp 配置文件
docker run --security-opt seccomp=custom-seccomp.json myapp:latest

10.7 注意事项

⚠️ 安全建议

  • 生产环境使用 rootless 容器(Podman)
  • 定期扫描镜像漏洞(Trivy)
  • 不要在容器中存储敏感数据
  • 使用 Docker secrets 或 Vault 管理密码
  • 限制容器资源(CPU、内存)

💡 性能建议

  • 使用 overlay2 存储驱动
  • 合理设置日志大小限制
  • 使用 --init 参数正确处理信号
  • 清理未使用的容器、镜像和卷

扩展阅读


上一章第 09 章:安全加固 下一章第 11 章:开发环境