mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-27 20:25:48 +00:00
Fix and update
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
## 日志管理
|
||||
# 日志管理
|
||||
|
||||
在容器化环境中,日志管理比传统环境更为复杂。容器是短暂的,意味着容器内的日志文件可能会随着容器的销毁而丢失。因此,我们需要一种集中式的日志管理方案来收集、存储和分析容器日志。
|
||||
|
||||
### Docker 日志驱动
|
||||
## Docker 日志驱动
|
||||
|
||||
Docker 提供了多种日志驱动(Log Driver)机制,允许我们将容器日志转发到不同的后端。
|
||||
|
||||
@@ -15,7 +15,7 @@ Docker 提供了多种日志驱动(Log Driver)机制,允许我们将容器
|
||||
* `gelf`: 支持 GELF 协议的日志后端(如 Graylog)。
|
||||
* `awslogs`: 发送到 Amazon CloudWatch Logs。
|
||||
|
||||
### 日志管理方案
|
||||
## 日志管理方案
|
||||
|
||||
对于大规模的容器集群,我们通常会采用 EFK (Elasticsearch + Fluentd + Kibana) 或 ELK (Elasticsearch + Logstash + Kibana) 方案。
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
## ELK/EFK 堆栈
|
||||
|
||||
## ELK/EFK 堆栈
|
||||
|
||||
ELK (Elasticsearch, Logstash, Kibana) 是目前业界最流行的开源日志解决方案。而在容器领域,由于 Fluentd 更加轻量级且对容器支持更好,EFK (Elasticsearch, Fluentd, Kibana) 组合也变得非常流行。
|
||||
|
||||
### 方案架构
|
||||
@@ -13,8 +15,14 @@ ELK (Elasticsearch, Logstash, Kibana) 是目前业界最流行的开源日志解
|
||||
|
||||
### 部署流程
|
||||
|
||||
### 部署流程
|
||||
|
||||
我们将使用 Docker Compose 来一键部署整个日志堆栈。
|
||||
|
||||
#### 1. 编写 docker-compose.yml
|
||||
|
||||
1. 编写 docker-compose.yml 配置如下:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
@@ -117,7 +125,7 @@ docker run -d \
|
||||
#### 4. 在 Kibana 中查看日志
|
||||
|
||||
1. 访问 `http://localhost:5601`。
|
||||
2. 进入 **Management** -> **Kibana** -> **Index Patterns**。
|
||||
2. 进入 **Management**->**Kibana**->**Index Patterns**。
|
||||
3. 创建新的 Index Pattern,输入 `docker-*` (我们在 fluent.conf 中配置的前缀)。
|
||||
4. 选择 `@timestamp` 作为时间字段。
|
||||
5. 去 **Discover** 页面,你就能看到 Nginx 容器的日志了。
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
## 容器监控
|
||||
# 容器监控
|
||||
|
||||
容器化技术的普及使得应用部署变得更加灵活和高效,但也给监控带来了新的挑战。
|
||||
|
||||
在传统架构中,我们通常关注主机的 CPU、内存、磁盘 IO 等指标。而在容器环境下,除了主机层面的监控,我们更关注容器级别的资源使用情况、服务的运行状态以及编排系统的健康状况。
|
||||
|
||||
### 常见的监控方案
|
||||
## 常见的监控方案
|
||||
|
||||
目前主流的容器监控方案包括:
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
## Prometheus + Grafana
|
||||
|
||||
## Prometheus + Grafana
|
||||
|
||||
Prometheus 和 Grafana 是目前最流行的开源监控组合,前者负责数据采集与存储,后者负责数据可视化。
|
||||
|
||||
[Prometheus](https://prometheus.io/) 是一个开源的系统监控和报警工具包。它受 Google Borgmon 的启发,由 SoundCloud 在 2012 年创建。
|
||||
|
||||
### 架构简介
|
||||
@@ -13,6 +17,8 @@ Prometheus 的主要组件包括:
|
||||
|
||||
### 快速部署
|
||||
|
||||
### 快速部署
|
||||
|
||||
我们可以使用 Docker Compose 快速部署一套 Prometheus + Grafana 监控环境。
|
||||
|
||||
#### 1. 准备配置文件
|
||||
@@ -90,6 +96,8 @@ networks:
|
||||
|
||||
#### 3. 启动服务
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ docker-compose up -d
|
||||
```
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
## 安全
|
||||
# 安全
|
||||
|
||||
容器安全是生产环境部署的核心考量。本章介绍 Docker 的安全机制和最佳实践。
|
||||
|
||||
### 容器安全的本质
|
||||
## 容器安全的本质
|
||||
|
||||
> **核心问题**:容器共享宿主机内核,隔离性弱于虚拟机。如何在便利性和安全性之间取得平衡?
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
|
||||
---
|
||||
|
||||
### 核心安全机制
|
||||
## 核心安全机制
|
||||
|
||||
#### 1. 命名空间(Namespace)
|
||||
### 1. 命名空间(Namespace)
|
||||
|
||||
提供进程、网络、文件系统等资源的隔离:
|
||||
|
||||
@@ -40,22 +40,25 @@
|
||||
|
||||
详见 [命名空间](../13_implementation/13.2_namespace.md) 章节。
|
||||
|
||||
#### 2. 控制组(Cgroups)
|
||||
### 2. 控制组(Cgroups)
|
||||
|
||||
限制容器的资源使用,防止资源耗尽攻击:
|
||||
|
||||
```bash
|
||||
## 限制内存(超出会被 OOM Kill)
|
||||
|
||||
$ docker run -m 512m myapp
|
||||
|
||||
## 限制 CPU
|
||||
|
||||
$ docker run --cpus=1.5 myapp
|
||||
|
||||
## 限制磁盘 I/O
|
||||
|
||||
$ docker run --device-write-bps /dev/sda:10mb myapp
|
||||
```
|
||||
|
||||
#### 3. 能力机制(Capabilities)
|
||||
### 3. 能力机制(Capabilities)
|
||||
|
||||
Linux 将 root 权限拆分为多个细粒度的能力。Docker 默认禁用危险能力:
|
||||
|
||||
@@ -69,62 +72,74 @@ Linux 将 root 权限拆分为多个细粒度的能力。Docker 默认禁用危
|
||||
|
||||
```bash
|
||||
## 删除所有能力,只添加需要的
|
||||
|
||||
$ docker run --cap-drop=all --cap-add=NET_BIND_SERVICE myapp
|
||||
|
||||
## 查看容器的能力
|
||||
|
||||
$ docker exec myapp cat /proc/1/status | grep Cap
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 镜像安全
|
||||
## 镜像安全
|
||||
|
||||
#### 使用可信镜像
|
||||
### 使用可信镜像
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
## ✅ 使用官方镜像
|
||||
|
||||
$ docker pull nginx
|
||||
|
||||
## ✅ 使用经过验证的镜像
|
||||
|
||||
$ docker pull bitnami/nginx
|
||||
|
||||
## ⚠️ 谨慎使用未知来源镜像
|
||||
|
||||
$ docker pull randomuser/suspicious-image
|
||||
```
|
||||
|
||||
#### 漏洞扫描
|
||||
### 漏洞扫描
|
||||
|
||||
扫描镜像中的已知安全漏洞:
|
||||
|
||||
```bash
|
||||
## Docker Scout(官方工具)
|
||||
|
||||
$ docker scout cves nginx:latest
|
||||
$ docker scout recommendations nginx:latest
|
||||
|
||||
## Trivy(开源工具)
|
||||
|
||||
$ trivy image nginx:latest
|
||||
|
||||
## Snyk(商业工具)
|
||||
|
||||
$ snyk container test nginx:latest
|
||||
```
|
||||
|
||||
#### 镜像签名验证
|
||||
### 镜像签名验证
|
||||
|
||||
使用 Docker Content Trust (DCT) 验证镜像来源:
|
||||
|
||||
```bash
|
||||
## 启用镜像签名验证
|
||||
|
||||
$ export DOCKER_CONTENT_TRUST=1
|
||||
|
||||
## 此后的 pull/push 会验证签名
|
||||
|
||||
$ docker pull myregistry/myimage:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 运行时安全
|
||||
## 运行时安全
|
||||
|
||||
#### 1. 非 root 用户运行
|
||||
### 1. 非 root 用户运行
|
||||
|
||||
> 笔者强调:这是最重要的安全实践之一。
|
||||
|
||||
@@ -132,14 +147,17 @@ $ docker pull myregistry/myimage:latest
|
||||
FROM node:22-alpine
|
||||
|
||||
## 创建非 root 用户
|
||||
|
||||
RUN addgroup -g 1001 appgroup && \
|
||||
adduser -u 1001 -G appgroup -D appuser
|
||||
|
||||
## 设置工作目录权限
|
||||
|
||||
WORKDIR /app
|
||||
COPY --chown=appuser:appgroup . .
|
||||
|
||||
## 切换用户
|
||||
|
||||
USER appuser
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
@@ -151,27 +169,37 @@ CMD ["node", "server.js"]
|
||||
$ docker run -u 1001:1001 myapp
|
||||
```
|
||||
|
||||
#### 2. 只读文件系统
|
||||
### 2. 只读文件系统
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
## 根文件系统只读
|
||||
|
||||
$ docker run --read-only myapp
|
||||
|
||||
## 需要写入的目录使用 tmpfs
|
||||
|
||||
$ docker run --read-only --tmpfs /tmp --tmpfs /var/run myapp
|
||||
```
|
||||
|
||||
#### 3. 禁用特权模式
|
||||
### 3. 禁用特权模式
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
## ❌ 绝对不要在生产环境使用
|
||||
|
||||
$ docker run --privileged myapp
|
||||
|
||||
## ✅ 只添加必要的能力
|
||||
|
||||
$ docker run --cap-add=SYS_TIME myapp
|
||||
```
|
||||
|
||||
#### 4. 限制资源
|
||||
### 4. 限制资源
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ docker run \
|
||||
@@ -182,75 +210,98 @@ $ docker run \
|
||||
myapp
|
||||
```
|
||||
|
||||
#### 5. 网络隔离
|
||||
### 5. 网络隔离
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
## 禁用网络(适用于不需要网络的任务)
|
||||
|
||||
$ docker run --network=none myapp
|
||||
|
||||
## 使用自定义网络隔离
|
||||
|
||||
$ docker network create --internal isolated_net
|
||||
$ docker run --network=isolated_net myapp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Dockerfile 安全实践
|
||||
## Dockerfile 安全实践
|
||||
|
||||
#### 1. 使用精简基础镜像
|
||||
### 1. 使用精简基础镜像
|
||||
|
||||
Dockerfile 内容如下:
|
||||
|
||||
```dockerfile
|
||||
## ✅ 好:使用精简镜像
|
||||
|
||||
FROM node:22-alpine # ~50MB
|
||||
FROM gcr.io/distroless/nodejs # ~20MB
|
||||
|
||||
## ❌ 差:使用完整镜像
|
||||
|
||||
FROM node:22 # ~1GB
|
||||
FROM ubuntu:24.04 # ~78MB
|
||||
```
|
||||
|
||||
#### 2. 多阶段构建
|
||||
### 2. 多阶段构建
|
||||
|
||||
Dockerfile 内容如下:
|
||||
|
||||
```dockerfile
|
||||
## 构建阶段
|
||||
|
||||
FROM node:22 AS builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN npm install && npm run build
|
||||
|
||||
## 生产阶段(不包含开发依赖和源码)
|
||||
|
||||
FROM node:22-alpine
|
||||
COPY --from=builder /app/dist /app
|
||||
USER node
|
||||
CMD ["node", "/app/server.js"]
|
||||
```
|
||||
|
||||
#### 3. 不存储敏感信息
|
||||
### 3. 不存储敏感信息
|
||||
|
||||
Dockerfile 内容如下:
|
||||
|
||||
```dockerfile
|
||||
## ❌ 错误:敏感信息写入镜像
|
||||
|
||||
ENV DB_PASSWORD=secret123
|
||||
COPY .env /app/
|
||||
|
||||
## ✅ 正确:运行时传入
|
||||
|
||||
## docker run -e DB_PASSWORD=xxx 或使用 Docker Secrets
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
|
||||
#### 4. 固定依赖版本
|
||||
### 4. 固定依赖版本
|
||||
|
||||
Dockerfile 内容如下:
|
||||
|
||||
```dockerfile
|
||||
## ✅ 固定版本
|
||||
|
||||
FROM node:22.12.0-alpine3.21
|
||||
RUN apk add --no-cache curl=8.5.0-r0
|
||||
|
||||
## ❌ 使用 latest
|
||||
|
||||
FROM node:latest
|
||||
RUN apk add curl
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 安全扫描清单
|
||||
## 安全扫描清单
|
||||
|
||||
部署前检查:
|
||||
|
||||
@@ -267,9 +318,9 @@ RUN apk add curl
|
||||
|
||||
---
|
||||
|
||||
### 高级安全方案
|
||||
## 高级安全方案
|
||||
|
||||
#### Seccomp 系统调用过滤
|
||||
### Seccomp 系统调用过滤
|
||||
|
||||
限制容器可以使用的系统调用:
|
||||
|
||||
@@ -277,7 +328,7 @@ RUN apk add curl
|
||||
$ docker run --security-opt seccomp=/path/to/profile.json myapp
|
||||
```
|
||||
|
||||
#### AppArmor / SELinux
|
||||
### AppArmor / SELinux
|
||||
|
||||
使用强制访问控制:
|
||||
|
||||
@@ -285,48 +336,51 @@ $ docker run --security-opt seccomp=/path/to/profile.json myapp
|
||||
$ docker run --security-opt apparmor=docker-default myapp
|
||||
```
|
||||
|
||||
#### 安全容器(gVisor / Kata)
|
||||
### 安全容器(gVisor / Kata)
|
||||
|
||||
需要更强隔离时:
|
||||
|
||||
```bash
|
||||
## 使用 gVisor 运行时
|
||||
|
||||
$ docker run --runtime=runsc myapp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 软件供应链安全
|
||||
## 软件供应链安全
|
||||
|
||||
随着软件供应链攻击日益频繁,仅保障运行时安全已不足够。
|
||||
|
||||
#### 1. SBOM (软件物料清单)
|
||||
### 1. SBOM(软件物料清单)
|
||||
|
||||
SBOM 类似于食品的配料表,列出了容器镜像中包含的所有软件包及其版本。
|
||||
|
||||
- **生成 SBOM**: 使用 `docker buildx build --sbom` 或 `docker scout sbom`。
|
||||
- **管理 SBOM**: 确保持续监控 SBOM 中的组件是否存在新披露的漏洞。
|
||||
|
||||
#### 2. 镜像签名 (Sigstore / Notary v2)
|
||||
### 2. 镜像签名(Sigstore / Notary v2)
|
||||
|
||||
确保镜像在构建后未被篡改,且确实来自可信的发布者。
|
||||
|
||||
- **Cosign**: Sigstore 项目的一部分,用于签署和验证容器镜像。
|
||||
```bash
|
||||
## 签署镜像
|
||||
|
||||
$ cosign sign --key cosign.key myimage:tag
|
||||
|
||||
## 验证镜像
|
||||
|
||||
$ cosign verify --key cosign.pub myimage:tag
|
||||
```
|
||||
|
||||
#### 3. SLSA (Supply-chain Levels for Software Artifacts)
|
||||
### 3. SLSA(Supply-chain Levels for Software Artifacts)
|
||||
|
||||
遵循 SLSA 框架,确保构建过程的完整性,例如使用 GitHub Actions 等受控环境进行构建,而非在开发者本地机器上构建发布。
|
||||
|
||||
---
|
||||
|
||||
### 本章小结
|
||||
## 本章小结
|
||||
|
||||
| 安全措施 | 重要程度 | 实现方式 |
|
||||
|---------|---------|---------|
|
||||
@@ -337,7 +391,7 @@ $ cosign verify --key cosign.pub myimage:tag
|
||||
| 最小能力 | ⭐⭐ | `--cap-drop=all` |
|
||||
| 镜像签名 | ⭐⭐ | Docker Content Trust |
|
||||
|
||||
### 延伸阅读
|
||||
## 延伸阅读
|
||||
|
||||
- [命名空间](../13_implementation/13.2_namespace.md):隔离机制详解
|
||||
- [控制组](../13_implementation/13.3_cgroups.md):资源限制详解
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
## 内核能力机制
|
||||
|
||||
## 内核能力机制
|
||||
|
||||
Docker 利用 Linux 的能力机制(Capabilities)来限制容器的权限,从而提高系统的安全性。
|
||||
|
||||
[能力机制(Capability)](https://man7.org/linux/man-pages/man7/capabilities.7.html) 是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制。
|
||||
Linux 内核自 2.2 版本起就支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
## 内核命名空间
|
||||
|
||||
## 内核命名空间
|
||||
|
||||
命名空间(Namespace)是 Linux 容器隔离的基础,它确保了容器内的进程无法干扰主机或其他容器。
|
||||
|
||||
Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。当用 `docker run` 启动一个容器时,在后台 Docker 为容器创建了一个独立的命名空间和控制组集合。
|
||||
|
||||
命名空间提供了最基础也是最直接的隔离,在容器中运行的进程不会被运行在主机上的进程和其它容器发现和作用。
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
## 其它安全特性
|
||||
|
||||
## 其它安全特性
|
||||
|
||||
除了上述机制,Linux 内核还提供了一系列安全增强功能,可以进一步保护容器环境。
|
||||
|
||||
除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, Seccomp, SELinux, GRSEC 等。
|
||||
|
||||
Docker 当前默认只启用了能力机制。用户可以采用多种方案来加强 Docker 主机的安全,例如:
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
## 总结
|
||||
|
||||
## 总结
|
||||
|
||||
Docker 的安全性依赖于多层隔离机制的协同工作,同时需要用户遵循最佳实践。
|
||||
|
||||
总体来看,Docker 容器还是十分安全的,特别是在容器内不使用 root 权限来运行进程的话。
|
||||
|
||||
另外,用户可以使用现有工具,比如 [Apparmor](https://docs.docker.com/engine/security/apparmor/), [Seccomp](https://docs.docker.com/engine/security/seccomp/), SELinux, GRSEC 来增强安全性;甚至自己在内核中实现更复杂的安全机制。
|
||||
|
||||
Reference in New Issue
Block a user