【docker基础】第九周:Docker安全与镜像优化

📚前言

👀回顾,系统学习docker系列已发布内容:

【docker基础】0、系统学习docker之总计划

【docker基础】第一课、从零开始理解容器技术

【docker基础】第二课:安装、配置与基础命令

【docker基础】第三课:镜像管理与Dockerfile基础

【docker基础】第四课:容器操作与数据管理

【docker基础】第五课:Docker网络详解-CSDN博客

【docker基础】第六课:Web应用与数据库容器部署-CSDN博客

【docker基础】 第七课:Docker Compose 多容器实战-CSDN博客

【docker基础】 第八周:容器监控与应用更新策略-CSDN博客

🔗相关文档:

windows下安装docker

【docker基础】Ubuntu 安装 Docker 超详细小白教程

📒本课学习目标:

  1. Docker 安全 :非特权用户、官方镜像、资源限制、网络隔离
  2. 镜像扫描 :使用 Docker scan 和 Trivy 检查漏洞
  3. 镜像优化 :多阶段构建、使用 alpine、合并命令、清理文件
  4. 安全加固 :只读模式、能力限制、隔离网络

🌍Docker第九周:Docker安全与镜像优化

欢迎来到 Docker 第九周的学习!本周我们将深入学习 Docker 的高级特性,包括容器安全最佳实践和镜像优化技巧。


第一章:Docker 安全基础

1.1 为什么容器安全很重要

容器虽然提供了隔离性,但并非绝对安全。以下是常见的安全风险:

  • 容器逃逸:攻击者从容器内部突破到宿主机
  • 恶意镜像:使用了包含恶意代码的镜像
  • 权限过大:容器以 root 用户运行
  • 网络攻击:容器之间或外部网络的攻击

1.2 容器安全最佳实践

1.2.1 避免使用 root 用户

问题:默认情况下,容器以 root 用户运行,这很危险。

解决方案:在 Dockerfile 中创建非特权用户

复制代码
FROM nginx:latest

# 创建非特权用户
RUN useradd -m appuser

# 切换到非特权用户
USER appuser

# 后续命令将以 appuser 身份执行
CMD ["nginx", "-g", "daemon off;"]

验证

复制代码
docker exec -it mycontainer whoami
# 输出: appuser
1.2.2 使用官方镜像

问题:第三方镜像可能包含恶意代码或漏洞。

解决方案

  • 使用 Docker Hub 官方认证的镜像

  • 优先选择带有 OFFICIAL 标签的镜像

    正确:使用官方镜像

    docker pull nginx:latest

    避免:使用不明来源的镜像

    docker pull randomuser/nginx:latest

1.2.3 限制容器资源

问题:容器可能占用过多资源,影响其他容器或宿主机。

解决方案:使用资源限制参数

复制代码
docker run -d \
  --name myapp \
  --memory=512m \
  --cpus=1 \
  --memory-swap=1g \
  nginx

参数说明

参数 说明
--memory 限制内存使用(如 512m)
--cpus 限制 CPU 使用(如 1 表示1个核心)
--memory-swap 限制交换内存
--pids-limit 限制进程数量
1.2.4 限制容器网络

问题:容器可能被允许访问不必要的网络资源。

解决方案

  • 使用自定义网络隔离容器

  • 限制容器的网络访问

    创建隔离网络

    docker network create --internal secure-network

    运行容器在隔离网络中

    docker run -d --network secure-network --name isolated-app nginx

1.2.5 定期更新镜像

问题:镜像中可能包含已知的安全漏洞。

解决方案:定期更新基础镜像

复制代码
# 更新镜像
docker pull nginx:latest

# 重新构建应用镜像
docker build -t myapp:latest .

第二章:镜像安全扫描

2.1 什么是镜像扫描

镜像扫描是检查 Docker 镜像中安全漏洞的过程。

2.2 使用 Docker 内置扫描工具

复制代码
# 扫描镜像
docker scan myapp:latest

输出示例

复制代码
Testing myapp:latest...

✗ HIGH CVE-2021-3156: sudo vulnerability
  Package: sudo
  Version: 1.8.31-1ubuntu1.2
  Severity: HIGH
  URL: https://security.snyk.io/vuln/SNYK-UBUNTU2004-SUDO-1583796

✗ MEDIUM CVE-2021-23214: systemd vulnerability
  Package: systemd
  Version: 245.4-4ubuntu3.1
  Severity: MEDIUM
  URL: https://security.snyk.io/vuln/SNYK-UBUNTU2004-SYSTEMD-1583795

✓ No critical issues found

2.3 使用第三方扫描工具

Trivy(推荐)

复制代码
# 安装 Trivy
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.19.0 image myapp:latest

输出示例

复制代码
2021-06-01T12:00:00.000+0000    INFO    Detected OS: ubuntu
2021-06-01T12:00:00.000+0000    INFO    Detecting Ubuntu vulnerabilities...
2021-06-01T12:00:00.000+0000    INFO    Number of PLUGINS: 0
2021-06-01T12:00:00.000+0000    INFO    Number of vulnerabilities: 5

+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
|     LIBRARY      | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                 |
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+
| sudo             | CVE-2021-3156    | HIGH     | 1.8.31-1ubuntu1.2 | 1.8.31-1ubuntu1.3 | sudo heap-based buffer overflow       |
| systemd          | CVE-2021-23214   | MEDIUM   | 245.4-4ubuntu3.1  | 245.4-4ubuntu3.2 | systemd out-of-bounds write          |
+------------------+------------------+----------+-------------------+---------------+---------------------------------------+

第三章:Docker 镜像优化

3.1 为什么需要优化镜像

  • 减少存储空间:更小的镜像占用更少的磁盘空间
  • 加快传输速度:更小的镜像下载更快
  • 提高安全性:更小的镜像意味着更少的攻击面

3.2 镜像优化技巧

3.2.1 使用多阶段构建

原理 :在一个 Dockerfile 中使用多个 FROM 指令,只保留最终需要的文件。

示例

复制代码
# 第一阶段:构建阶段
FROM node:14 AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# 第二阶段:运行阶段
FROM nginx:alpine

# 从构建阶段复制产物
COPY --from=builder /app/build /usr/share/nginx/html

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

效果

  • 构建阶段包含 Node.js 环境(约 1GB)
  • 运行阶段只包含 Nginx(约 20MB)
  • 最终镜像大小约 20MB
3.2.2 使用更小的基础镜像

对比

镜像 大小 说明
ubuntu:latest ~72MB 完整的 Ubuntu 系统
alpine:latest ~5MB 最小的 Linux 发行版
debian:latest ~114MB 完整的 Debian 系统
node:14 ~900MB 包含 Node.js 的完整系统
node:14-alpine ~100MB 基于 Alpine 的 Node.js

建议 :优先使用 alpine 版本的镜像

复制代码
# 不好:使用完整镜像
FROM node:14

# 好:使用 alpine 版本
FROM node:14-alpine
3.2.3 合并 RUN 命令

问题 :每个 RUN 命令都会创建一个新的镜像层。

解决方案 :使用 && 合并多个命令

复制代码
# 不好:多个 RUN 命令
RUN apt-get update
RUN apt-get install -y nginx
RUN apt-get clean

# 好:合并为一个 RUN 命令
RUN apt-get update && \
    apt-get install -y nginx && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
3.2.4 使用 .dockerignore 文件

问题:构建上下文可能包含不必要的文件。

解决方案 :创建 .dockerignore 文件

复制代码
# .dockerignore 文件内容
node_modules/
.git/
.vscode/
*.log
.env
build/
dist/
3.2.5 使用 COPY 代替 ADD

问题ADD 会自动解压文件,可能导致意外行为。

解决方案 :优先使用 COPY

复制代码
# 不好:使用 ADD
ADD app.tar.gz /app

# 好:使用 COPY
COPY app.tar.gz /app
RUN tar -xzf /app/app.tar.gz -C /app
3.2.6 清理不必要的文件
复制代码
FROM ubuntu:20.04

RUN apt-get update && \
    apt-get install -y nginx && \
    # 清理 apt 缓存
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    # 删除不必要的文件
    rm -rf /usr/share/doc && \
    rm -rf /usr/share/man

第四章:Docker 安全加固实战

4.1 创建安全的 Dockerfile

复制代码
# 使用最小基础镜像
FROM alpine:3.14

# 创建非特权用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# 安装必要的依赖
RUN apk update && \
    apk add --no-cache nginx && \
    rm -rf /var/cache/apk/*

# 配置 Nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY index.html /usr/share/nginx/html/

# 设置文件权限
RUN chown -R appuser:appgroup /usr/share/nginx/html

# 切换到非特权用户
USER appuser

# 暴露端口
EXPOSE 8080

# 健康检查
HEALTHCHECK --interval=5s --timeout=3s \
  CMD wget -qO- http://localhost:8080 || exit 1

# 启动命令
CMD ["nginx", "-g", "daemon off;"]

4.2 运行安全的容器

复制代码
docker run -d \
  --name secure-app \
  --user appuser \
  --memory=256m \
  --cpus=0.5 \
  --read-only \
  --tmpfs /run \
  --tmpfs /tmp \
  --cap-drop=ALL \
  --network=secure-network \
  secure-app:latest

参数说明

参数 说明
--user 指定运行用户
--read-only 以只读模式运行容器
--tmpfs 创建临时文件系统
--cap-drop=ALL 移除所有 Linux 能力
--network 指定隔离网络

第五章:镜像优化实战

5.1 优化前后对比

优化前的 Dockerfile

复制代码
FROM node:14

WORKDIR /app

COPY . .

RUN npm install
RUN npm run build

EXPOSE 3000

CMD ["npm", "start"]

优化后的 Dockerfile

复制代码
# 构建阶段
FROM node:14-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# 运行阶段
FROM nginx:alpine

COPY --from=builder /app/build /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

5.2 构建并验证

复制代码
# 构建优化前的镜像
docker build -t myapp-before .

# 构建优化后的镜像
docker build -t myapp-after -f Dockerfile.optimized .

# 查看镜像大小
docker images | grep myapp

预期结果

复制代码
REPOSITORY   TAG       IMAGE ID       SIZE
myapp-before latest    abc123def456   900MB
myapp-after  latest    ghi789jkl012   25MB

第六章:Docker Security 命令汇总

6.1 安全相关命令

命令 说明
docker scan 扫描镜像中的安全漏洞
docker run --user 指定容器运行用户
docker run --read-only 以只读模式运行容器
docker run --cap-drop 移除 Linux 能力
docker network create --internal 创建隔离网络

6.2 镜像优化命令

命令 说明
docker build --no-cache 不使用缓存构建镜像
docker images 查看镜像大小
docker history 查看镜像历史
docker save 保存镜像到文件
docker import 从文件导入镜像

第七章:常见问题与解决方案

7.1 问题:容器需要 root 权限

解决方案

  • 尽可能使用非特权用户

  • 如果必须使用 root,限制容器的能力

    docker run -d
    --cap-drop=ALL
    --cap-add=NET_BIND_SERVICE
    nginx

7.2 问题:镜像扫描发现漏洞

解决方案

  1. 更新基础镜像
  2. 更新依赖包
  3. 使用更小的基础镜像

7.3 问题:镜像太大

解决方案

  1. 使用多阶段构建
  2. 使用 alpine 镜像
  3. 清理不必要的文件

本周总结

本周我们学习了:

  1. Docker 安全:非特权用户、官方镜像、资源限制、网络隔离
  2. 镜像扫描:使用 Docker scan 和 Trivy 检查漏洞
  3. 镜像优化:多阶段构建、使用 alpine、合并命令、清理文件
  4. 安全加固:只读模式、能力限制、隔离网络

练习作业

  1. 创建一个安全的 Dockerfile,包含非特权用户和健康检查
  2. 使用多阶段构建优化一个 Node.js 应用
  3. 使用 Trivy 扫描镜像并修复发现的漏洞
相关推荐
时佃鹏2 小时前
银河麒麟 V10 重装打印服务 (CUPS)+ 打印机驱动完整教程
运维·银河麒麟系统
Shepherd06192 小时前
【IT 运维】Apache 使用 mod_remoteip 恢复 Cloudflare 后的真实访客 IP
运维·tcp/ip·apache
王二端茶倒水3 小时前
智慧园区网络运营:认证、分权、运维和安全闭环
运维·物联网·架构
爱就是恒久忍耐3 小时前
现代CMake的build方式
linux·运维·服务器
三8443 小时前
重定向/管道符/通配符/转义字符/VI/VIM
运维·服务器
CodeStats3 小时前
【虚拟机】 从 CPU 指令到虚拟机隔离:虚拟机就是一个“模拟了完整硬件的普通进程”
java·docker
小坏蛋至尊宝4 小时前
如何优化文件传输的性能?
运维·服务器
ai产品老杨4 小时前
突破安防碎片化:基于 Docker 与边缘计算的 AI 视频智能化中台,如何通过 GB28181/RTSP 统一接入与全套源码交付实现二次开发自由?
人工智能·docker·边缘计算
爱学习的程序媛4 小时前
DevOps 深度解析:从文化理念到落地实践
运维·devops