Docker 安全最佳实践
容器安全是生产环境部署的关键考量。本章将详细介绍 Docker 的安全机制和最佳实践,帮助你构建安全的容器化应用。
安全概述
Docker 安全涉及四个主要领域:
- 内核安全:Linux 内核的命名空间(Namespaces)和控制组(Cgroups)
- 守护进程安全:Docker Daemon 的攻击面
- 容器配置安全:容器的默认配置和自定义配置
- 内核加固特性:AppArmor、SELinux、Seccomp 等安全模块
容器安全架构
内核安全机制
命名空间(Namespaces)
命名空间提供了容器的第一层隔离。每个容器拥有独立的:
| 命名空间类型 | 隔离内容 | 说明 |
|---|---|---|
| PID | 进程 ID | 容器内进程独立编号 |
| NET | 网络栈 | 独立网络接口、路由表 |
| MNT | 挂载点 | 独立文件系统视图 |
| IPC | 进程间通信 | 独立消息队列、信号量 |
| UTS | 主机名和域名 | 独立主机名 |
| USER | 用户和用户组 | 独立用户 ID 映射 |
命名空间隔离效果:
# 在容器内查看进程
docker run -it alpine ps aux
# 只能看到容器内的进程
# 在主机上查看
ps aux | grep docker
# 可以看到容器进程,但属于不同的命名空间
网络隔离:
# 每个容器拥有独立的网络栈
docker run -d --name web nginx
docker exec web ip addr
# 容器有独立的 IP 地址和网络接口
控制组(Cgroups)
Cgroups 实现资源限制和审计,防止单个容器耗尽系统资源:
# 限制容器内存
docker run -d --memory="512m" --memory-swap="1g" nginx
# 限制 CPU 使用
docker run -d --cpus="1.5" --cpuset-cpus="0,1" nginx
# 限制 IO
docker run -d --device-read-bps=/dev/sda:10mb nginx
# 查看容器资源使用
docker stats
Cgroups 的安全作用:
- 防止 DoS 攻击:限制单个容器的资源使用
- 公平调度:确保多个容器公平分享资源
- 资源审计:记录资源使用情况
Linux Capabilities
什么是 Capabilities?
传统的 Linux 权限模型是二元的:root(超级用户)或非 root。Capabilities 将 root 权限分解为细粒度的权限单元,实现了更精细的访问控制。
常用的 Capabilities:
| Capability | 说明 | 风险级别 |
|---|---|---|
| CAP_NET_BIND_SERVICE | 绑定 1024 以下端口 | 低 |
| CAP_NET_RAW | 使用原始套接字 | 中 |
| CAP_SYS_ADMIN | 系统管理操作 | 高 |
| CAP_CHOWN | 修改文件所有者 | 低 |
| CAP_DAC_OVERRIDE | 绕过文件权限检查 | 中 |
| CAP_KILL | 发送信号给其他进程 | 中 |
| CAP_SETUID/SETGID | 修改进程 UID/GID | 中 |
Docker 默认 Capabilities
Docker 默认使用白名单方式,只保留必要的 Capabilities:
# 查看容器默认的 capabilities
docker run --rm alpine capsh --print
# 输出示例
Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
管理容器 Capabilities
删除不需要的 Capabilities:
# 删除所有 capabilities
docker run --rm --cap-drop=ALL alpine capsh --print
# 删除特定 capability
docker run --rm --cap-drop=NET_RAW alpine capsh --print
# 只保留需要的 capabilities
docker run --rm --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
添加 Capabilities:
# 添加特定 capability
docker run --cap-add=NET_ADMIN alpine
# 添加所有 capabilities(不推荐)
docker run --privileged alpine
最佳实践示例:
# Web 服务器只需要绑定特权端口的能力
docker run -d \
--name web \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
-p 80:80 \
nginx
# 需要修改网络配置的容器
docker run -d \
--name network-tool \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
network-tool
非 Root 用户运行容器
为什么使用非 root 用户?
默认情况下,容器内的 root 用户与主机的 root 用户共享 UID 0。如果容器被攻破,攻击者可能获得主机的 root 权限。
在 Dockerfile 中配置非 root 用户
# 创建专用用户和组
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 或指定 UID/GID
RUN groupadd -g 1000 appuser && \
useradd -u 1000 -g appuser -m appuser
# 设置工作目录权限
WORKDIR /app
COPY --chown=appuser:appuser . .
# 切换到非 root 用户
USER appuser
# 启动应用
CMD ["node", "server.js"]
完整示例:
FROM node:18-alpine
# 安装依赖阶段
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# 复制应用代码
COPY --chown=nextjs:nodejs . .
# 切换用户
USER nextjs
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
# 启动命令
CMD ["node", "server.js"]
运行时指定用户
# 以特定用户运行
docker run -d --user 1000:1000 nginx
# 使用用户名
docker run -d --user appuser:appgroup myapp
# 以只读文件系统运行
docker run -d --read-only --user 1000:1000 myapp
用户命名空间
用户命名空间将容器内的 root 用户映射到主机上的非特权用户,提供额外的安全层。
启用用户命名空间
配置 Docker Daemon:
# /etc/docker/daemon.json
{
"userns-remap": "default"
}
或指定特定用户:
{
"userns-remap": "dockremap:dockremap"
}
创建映射用户:
# 创建用户和组
sudo useradd -r -s /bin/false dockremap
# 配置 subuid 和 subgid
echo "dockremap:100000:65536" | sudo tee -a /etc/subuid
echo "dockremap:100000:65536" | sudo tee -a /etc/subgid
# 重启 Docker
sudo systemctl restart docker
效果:
- 容器内的 root (UID 0) 映射到主机的 dockremap 用户 (UID 100000)
- 容器内的进程在主机上以非特权用户身份运行
- 即使容器被攻破,也无法获得主机 root 权限
Seccomp 安全配置
什么是 Seccomp?
Seccomp(Secure Computing Mode)限制容器可以使用的系统调用,减少内核攻击面。
Docker 默认 Seccomp 配置
Docker 默认应用 Seccomp 配置文件,阻止危险的系统调用:
# 查看默认配置
docker info | grep -i seccomp
# 输出示例
Security Options:
seccomp
Profile: builtin
默认阻止的系统调用:
kexec_load、kexec_file_load:加载新内核init_module、finit_module:加载内核模块acct:启用/禁用进程记账swapon、swapoff:管理交换空间- 等约 44 个危险系统调用
自定义 Seccomp 配置
禁用 Seccomp(不推荐):
docker run --security-opt seccomp=unconfined alpine
使用自定义配置文件:
docker run --security-opt seccomp=/path/to/seccomp.json alpine
示例 Seccomp 配置:
{
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": ["kexec_load"],
"action": "SCMP_ACT_ERRNO"
}
]
}
AppArmor 和 SELinux
AppArmor(Ubuntu/Debian)
AppArmor 通过配置文件限制程序的访问权限:
查看 AppArmor 状态:
# 检查 AppArmor 是否启用
docker info | grep -i apparmor
# 查看加载的配置文件
sudo aa-status
使用自定义 AppArmor 配置:
# 创建配置文件
sudo aa-genprof /path/to/binary
# 运行容器时指定配置
docker run --security-opt apparmor=your-profile myapp
SELinux(CentOS/RHEL)
SELinux 提供强制访问控制:
查看 SELinux 状态:
# 检查 SELinux 是否启用
getenforce
# 查看 Docker SELinux 配置
docker info | grep -i selinux
使用 SELinux 标签:
# 使用 svirt 标签
docker run --security-opt label=level:s0:c100,c200 myapp
# 禁用 SELinux 标签(不推荐)
docker run --security-opt label=disable myapp
守护进程安全
Docker Daemon 攻击面
Docker Daemon 以 root 权限运行,具有以下安全风险:
- TCP 端口暴露:远程 API 访问可能导致权限提升
- 镜像加载:恶意镜像可能包含漏洞
- 特权容器:可以访问主机资源
安全配置
限制 Docker Daemon 访问:
# 只允许特定用户组访问 Docker socket
sudo usermod -aG docker $USER
# 配置 daemon.json
{
"hosts": ["unix:///var/run/docker.sock"],
"tls": false
}
启用 TLS 加密:
# 生成证书
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
# 配置 daemon.json
{
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"],
"tls": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
"tlsverify": true
}
客户端配置:
# 配置环境变量
export DOCKER_HOST=tcp://your-host:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/path/to/certs
Rootless 模式
Rootless 模式允许非 root 用户运行 Docker Daemon,从根本上降低安全风险。在这种模式下,Docker Daemon 和容器都不以 root 权限运行。
Rootless 模式的优势
| 特性 | 传统模式 | Rootless 模式 |
|---|---|---|
| Daemon 权限 | root | 普通用户 |
| 容器进程权限 | root(容器内) | 用户映射 |
| 安全风险 | 高(Daemon 被攻破可获得主机 root) | 低(仅普通用户权限) |
| 适用场景 | 生产环境 | 开发环境、多租户环境 |
安装 Rootless Docker
前置条件:
# 安装 uidmap(用于用户命名空间映射)
sudo apt-get install -y uidmap
# 确认内核支持用户命名空间
cat /proc/sys/kernel/unprivileged_userns_clone
# 应输出 1
安装步骤:
# 方式一:使用官方安装脚本
curl -fsSL https://get.docker.com/rootless | sh
# 方式二:手动安装
# 下载 Docker 二进制文件
curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-24.0.7.tgz | tar xz
# 设置环境变量
export PATH=/home/$USER/bin:$PATH
export DOCKER_HOST=unix:///run/user/$UID/docker.sock
配置环境变量(持久化):
# 添加到 ~/.bashrc 或 ~/.profile
export PATH=/home/$USER/bin:$PATH
export DOCKER_HOST=unix:///run/user/$UID/docker.sock
启动 Rootless Docker:
# 启动 daemon
dockerd-rootless.sh
# 或使用 systemd 服务
systemctl --user start docker
systemctl --user enable docker
Rootless 模式的限制
Rootless 模式有一些功能限制:
| 功能 | 支持情况 |
|---|---|
| 镜像存储 | ✅ 支持 |
| 容器运行 | ✅ 支持 |
| 端口映射 | ⚠️ 仅支持 > 1024 端口 |
| ping 命令 | ⚠️ 需要配置 |
| 卷挂载 | ⚠️ 仅能访问用户有权限的文件 |
| privileged 模式 | ❌ 不支持 |
| AppArmor | ❌ 不支持 |
解决端口限制:
# 允许非特权端口(需要 root 执行一次)
sudo sysctl net.ipv4.ip_unprivileged_port_start=80
# 持久化配置
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/50-unprivileged-ports.conf
启用 ping 支持:
# 允许非特权用户使用 ping
sudo sysctl -w net.ipv4.ping_group_range="0 2000000"
验证 Rootless 模式
# 确认 Daemon 以非 root 运行
ps aux | grep dockerd
# 应显示普通用户而非 root
# 确认容器进程权限
docker run --rm alpine id
# 输出应为映射后的 UID,而非 0
镜像安全
使用可信镜像
镜像来源分类:
| 类型 | 说明 | 安全级别 |
|---|---|---|
| Docker Official Images | Docker 官方维护 | 最高 |
| Verified Publisher | 验证发布者 | 高 |
| Docker-Sponsored OSS | Docker 赞助的开源项目 | 中高 |
| 社区镜像 | 社区贡献 | 需评估 |
验证镜像来源:
选择镜像时,优先考虑以下来源:
| 类型 | 说明 | 安全级别 |
|---|---|---|
| Docker Official Images | Docker 官方维护 | 最高 |
| Verified Publisher | 验证发布者 | 高 |
| Docker-Sponsored OSS | Docker 赞助的开源项目 | 中高 |
| 社区镜像 | 社区贡献 | 需评估 |
从 Docker Engine v29 开始,Docker Content Trust (DCT) 已从 Docker CLI 中移除。DCT 原用于验证镜像签名,但现在推荐使用以下替代方案:
- Docker Scout:检测镜像漏洞和验证镜像来源
- cosign:Sigstore 项目提供的镜像签名工具
- Notary:CNCF 项目,用于镜像签名和验证
使用 Docker Scout 验证镜像:
# 快速查看镜像安全信息
docker scout quickview nginx:latest
# 查看镜像详细信息(包括来源验证)
docker scout cves nginx:latest
# 查看镜像基础信息和建议
docker scout recommendations nginx:latest
# 比较两个镜像版本
docker scout compare nginx:1.25 nginx:1.26
# 只显示严重和高危漏洞
docker scout cves --only-severe nginx:latest
# 输出 SARIF 格式(用于 CI/CD)
docker scout cves --format sarif --output results.sarif nginx:latest
Docker Scout 订阅等级:
| 等级 | 功能 | 适用场景 |
|---|---|---|
| Docker Free | 基础扫描、快速查看 | 个人开发者 |
| Docker Pro | 高级 CVE 详情、策略检查 | 专业开发者 |
| Docker Team | 团队管理、策略配置 | 开发团队 |
| Docker Business | 企业级功能、SSO | 企业组织 |
安装 cosign:
# macOS
brew install cosign
# Linux
curl -O https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
# Windows (使用 winget)
winget install sigstore.cosign
# 验证安装
cosign version
生成密钥对:
# 生成密钥对(会提示输入密码)
cosign generate-key-pair
# 输出文件:
# cosign.key - 私钥(妥善保管)
# cosign.pub - 公钥(用于验证)
# 使用 KMS 生成密钥
cosign generate-key-pair k8s://namespace/secret-name
cosign generate-key-pair aws-kms://alias/key-name
cosign generate-key-pair gcp-kms://projects/...
签名镜像:
# 使用本地密钥签名
cosign sign --key cosign.key docker.io/myorg/myapp:latest
# Keyless 签名(使用 OIDC 身份验证,推荐)
cosign sign docker.io/myorg/myapp:latest
# 会打开浏览器进行身份验证
# 添加注释
cosign sign -a author=devops -a version=1.0 docker.io/myorg/myapp:latest
# 使用 KMS 密钥签名
cosign sign --key aws-kms://alias/my-key docker.io/myorg/myapp:latest
cosign sign --key gcp-kms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key docker.io/myorg/myapp:latest
验证镜像:
# 使用公钥验证
cosign verify --key cosign.pub docker.io/myorg/myapp:latest
# Keyless 验证(验证 Sigstore 签名)
cosign verify docker.io/myorg/myapp:latest
# 验证特定注释
cosign verify -a author=devops --key cosign.pub docker.io/myorg/myapp:latest
# 验证多个签名者
cosign verify --key cosign.pub --key another.pub docker.io/myorg/myapp:latest
在 CI/CD 中使用:
# GitHub Actions 示例
name: Sign and Push Image
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:latest
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Sign Image
run: |
cosign sign --yes ghcr.io/${{ github.repository }}:latest
- name: Verify Signature
run: |
cosign verify ghcr.io/${{ github.repository }}:latest
策略执行:
在 Kubernetes 中可以使用策略控制器强制验证镜像签名:
# Kyverno 策略示例
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signatures
spec:
validationFailureAction: enforce
background: false
rules:
- name: verify-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "docker.io/myorg/*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
Notary 项目:
Notary 是 Docker Content Trust (DCT) 的底层实现,基于 The Update Framework (TUF) 规范。虽然 DCT 已从 Docker CLI 移除,但 Notary 项目仍在活跃开发中:
# 安装 Notary CLI
# 从 https://github.com/theupdateframework/notary/releases 下载
# 初始化信任(首次使用)
notary init docker.io/myorg/myapp
# 添加签名密钥
notary key generate docker.io/myorg/myapp
# 发布签名
notary publish docker.io/myorg/myapp
# 验证镜像
notary verify docker.io/myorg/myapp latest
cosign vs Notary 对比:
| 特性 | cosign | Notary |
|---|---|---|
| 签名存储 | 镜像仓库(OCI Artifact) | 独立服务器 |
| Keyless 签名 | 支持(Sigstore OIDC) | 不支持 |
| 密钥管理 | 本地文件、KMS、K8s Secret | 本地文件、YubiKey |
| 透明日志 | 内置 Rekor | 无 |
| 易用性 | 简单 | 较复杂 |
| 推荐场景 | 新项目、CI/CD | 已有 DCT 遗留系统 |
镜像扫描
使用 Docker Scout 扫描漏洞:
# 快速扫描
docker scout quickview nginx:latest
# 详细扫描
docker scout cves nginx:latest
# 查看修复建议
docker scout recommendations nginx:latest
使用 Trivy 扫描:
# 安装 Trivy
brew install trivy # macOS
# 扫描镜像
trivy image nginx:latest
# 输出到文件
trivy image --output results.json nginx:latest
最小化基础镜像
# 不推荐:使用完整镜像
FROM ubuntu:22.04
# 推荐:使用精简镜像
FROM ubuntu:22.04-minimal
# 更推荐:使用 Alpine
FROM alpine:3.18
# 生产环境:使用 distroless
FROM gcr.io/distroless/static-debian12
镜像大小对比:
| 基础镜像 | 大小 | 安全性 |
|---|---|---|
| ubuntu:22.04 | ~77MB | 中 |
| debian:slim | ~74MB | 中 |
| alpine:3.18 | ~5MB | 高 |
| distroless/static | ~2MB | 最高 |
网络安全
网络隔离
# 使用内部网络(无法访问外网)
docker network create --internal internal-net
# 运行容器
docker run -d --network internal-net myapp
# 分离前端和后端网络
docker network create frontend
docker network create --internal backend
docker run -d --name web --network frontend nginx
docker run -d --name api --network frontend --network backend myapi
docker run -d --name db --network backend mysql
端口安全
# 仅绑定到本地接口
docker run -d -p 127.0.0.1:8080:80 nginx
# 使用反向代理暴露服务
# nginx.conf
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
限制网络能力
# 禁止修改网络配置
docker run --cap-drop=NET_ADMIN --cap-drop=NET_RAW myapp
# 使用只读文件系统防止修改
docker run --read-only --tmpfs /tmp myapp
敏感数据管理
Docker Secrets
Docker Secrets 用于安全地管理敏感数据:
在 Swarm 中使用:
# 创建 secret
echo "my_secret_password" | docker secret create db_password -
# 在服务中使用
docker service create \
--name app \
--secret db_password \
-e DB_PASSWORD_FILE=/run/secrets/db_password \
myapp
在 Docker Compose 中使用:
services:
app:
image: myapp
secrets:
- db_password
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt
避免硬编码敏感信息
不推荐:
# 不要这样做
services:
app:
environment:
- DATABASE_PASSWORD=secret123 # 明文密码
推荐方式:
# 使用环境变量文件
services:
app:
env_file:
- .env # 添加到 .gitignore
# 或使用 Docker Secrets
services:
app:
secrets:
- db_password
安全配置清单
Dockerfile 安全清单
# ✅ 使用最小化基础镜像
FROM alpine:3.18
# ✅ 指定镜像版本和摘要
# FROM alpine:3.18@sha256:...
# ✅ 创建非 root 用户
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
# ✅ 只安装必要的包
RUN apk add --no-cache nodejs npm
# ✅ 设置适当的文件权限
COPY --chown=appuser:appgroup . /app
# ✅ 切换到非 root 用户
USER appuser
# ✅ 声明健康检查
HEALTHCHECK --interval=30s CMD wget -q --spider http://localhost:3000/health
# ✅ 不暴露不必要的端口
EXPOSE 3000
# ✅ 使用 exec 格式
CMD ["node", "server.js"]
运行时安全清单
docker run -d \
--name myapp \
--user 1001:1001 \ # 非 root 用户
--read-only \ # 只读文件系统
--cap-drop=ALL \ # 删除所有能力
--cap-add=NET_BIND_SERVICE \ # 只添加需要的能力
--security-opt=no-new-privileges \ # 禁止提权
--security-opt seccomp=unconfined \ # 使用 seccomp
--memory="512m" \ # 内存限制
--cpus="0.5" \ # CPU 限制
--pids-limit=100 \ # 进程数限制
--tmpfs /tmp \ # 临时目录
myapp:latest
Docker Compose 安全配置
services:
app:
image: myapp:latest
user: "1001:1001"
read_only: true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
security_opt:
- no-new-privileges:true
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
tmpfs:
- /tmp
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
安全监控
日志审计
# 启用 Docker 审计日志
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
# 查看容器日志
docker logs myapp
# 使用 journald 日志驱动
docker run -d --log-driver=journald myapp
运行时监控
# 查看容器资源使用
docker stats
# 查看容器进程
docker top myapp
# 查看容器事件
docker events --filter container=myapp
# 使用 Falco 监控异常行为
falco -r /etc/falco/falco_rules.yaml
安全检查命令汇总
# 检查 Docker 版本和配置
docker version
docker info
# 检查容器安全配置
docker inspect --format='{{.HostConfig.SecurityOpt}}' myapp
docker inspect --format='{{.HostConfig.CapAdd}}' myapp
docker inspect --format='{{.HostConfig.CapDrop}}' myapp
# 检查容器用户
docker inspect --format='{{.Config.User}}' myapp
# 检查镜像漏洞
docker scout quickview myapp:latest
# 检查容器进程
docker exec myapp ps aux
# 检查容器网络
docker network inspect bridge
参考资源
小结
Docker 安全涉及多个层面:
- 内核安全机制:命名空间隔离、Cgroups 资源限制、Capabilities 权限控制
- 非 root 用户运行:Dockerfile 中创建用户,运行时指定用户
- Seccomp 和 AppArmor/SELinux:系统调用过滤和强制访问控制
- 守护进程安全:TLS 加密通信、Rootless 模式
- 镜像安全:使用可信镜像、漏洞扫描、最小化基础镜像
- 网络安全:网络隔离、端口绑定限制
- 敏感数据管理:Docker Secrets 安全存储
练习
- 创建一个使用非 root 用户的 Dockerfile
- 配置容器只保留必要的 Capabilities
- 使用 Docker Scout 扫描镜像漏洞
- 使用 cosign 验证镜像签名
- 设计一个包含前后端分离的安全网络架构