From 1b651e5f8c9ad3e9d7ca165c2c9ab61074499cc5 Mon Sep 17 00:00:00 2001 From: yeasy Date: Wed, 20 May 2026 09:16:36 -0700 Subject: [PATCH] fix(content): refresh Docker and Kubernetes guidance --- 09_network/9.7_advanced_networking.md | 2 +- 11_compose/11.5_compose_file.md | 15 +++++++-------- 13_kubernetes_concepts/13.4_advanced.md | 5 +++++ 14_kubernetes_setup/README.md | 1 + 17_ecosystem/17.6_containerd.md | 2 +- 18_security/18.3_daemon_sec.md | 7 +++++-- 18_security/18.5_other_feature.md | 10 +++++++--- 19_observability/19.1_prometheus.md | 6 +++--- appendix/glossary.md | 2 +- appendix/learning_roadmap.md | 3 ++- 10 files changed, 33 insertions(+), 20 deletions(-) diff --git a/09_network/9.7_advanced_networking.md b/09_network/9.7_advanced_networking.md index baf4dd9..99d8f8f 100644 --- a/09_network/9.7_advanced_networking.md +++ b/09_network/9.7_advanced_networking.md @@ -8,7 +8,7 @@ Overlay 网络在现有网络基础上建立虚拟网络,允许容器跨宿主 #### Overlay 网络工作原理 -Overlay 网络通过隧道封装技术(通常是 VXLAN)将容器网络流量封装在宿主机物理网络的 UDP 数据包中传输。 +Overlay 网络通过隧道封装技术(通常是 VXLAN)将容器网络流量封装在宿主机物理网络的 UDP 数据包中传输。Docker overlay 网络默认使用 `4789/udp` 作为数据通道端口,同时 Swarm 控制面与节点通信还需要相应开放 `2377/tcp`、`7946/tcp` 和 `7946/udp`。 ```text 容器 A (192.168.0.2) diff --git a/11_compose/11.5_compose_file.md b/11_compose/11.5_compose_file.md index 73711a8..f996ad5 100644 --- a/11_compose/11.5_compose_file.md +++ b/11_compose/11.5_compose_file.md @@ -411,14 +411,13 @@ ports: ```yaml services: - -mysql: - image: mysql - environment: - MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password - secrets: - - db_root_password - - my_other_secret + mysql: + image: mysql + environment: + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password + secrets: + - db_root_password + - my_other_secret secrets: db_root_password: diff --git a/13_kubernetes_concepts/13.4_advanced.md b/13_kubernetes_concepts/13.4_advanced.md index baad36f..7d7f70d 100644 --- a/13_kubernetes_concepts/13.4_advanced.md +++ b/13_kubernetes_concepts/13.4_advanced.md @@ -62,6 +62,7 @@ Ingress 资源仍可正常使用,但建议新项目直接采用 Gateway API。 * **PVC (Persistent Volume Claim)**:用户申请存储的声明。 * **PV (Persistent Volume)**:实际的存储资源 (NFS,AWS EBS,Ceph 等)。 * **StorageClass**:定义存储类,支持动态创建 PV。 +* **VolumeAttributesClass**:Kubernetes 1.34 起 GA,用于在 CSI 驱动支持 `ModifyVolume` 时动态调整卷属性,例如性能等级或服务质量参数。 ### 13.4.4 Horizontal Pod Autoscaling @@ -114,3 +115,7 @@ metadata: pod-security.kubernetes.io/enforce: baseline pod-security.kubernetes.io/warn: restricted ``` + +### 13.4.7 Sidecar Containers + +Kubernetes 1.33 起 Sidecar Containers 进入 GA。它们通过 `initContainers` 中带 `restartPolicy: Always` 的容器表达,既保留 init container 的启动顺序,又会在主容器生命周期内持续运行。对于旧集群或不需要启动顺序控制的场景,仍可使用普通多容器 Pod。 diff --git a/14_kubernetes_setup/README.md b/14_kubernetes_setup/README.md index 1315589..6439d5b 100644 --- a/14_kubernetes_setup/README.md +++ b/14_kubernetes_setup/README.md @@ -5,6 +5,7 @@ 你可以使用以下几种方式部署 Kubernetes,接下来的小节会对各种方式进行详细介绍。 * [使用 kubeadm 部署 (CRI 使用 containerd)](14.1_kubeadm.md) + * Kubernetes 也支持 CRI-O 等符合 CRI 的运行时;本文以 containerd 为主线。 * [使用 kubeadm 部署 (使用 Docker)](14.2_kubeadm-docker.md) * [在 Docker Desktop 使用](14.3_docker-desktop.md) * [Kind - Kubernetes IN Docker](14.4_kind.md) diff --git a/17_ecosystem/17.6_containerd.md b/17_ecosystem/17.6_containerd.md index f384b86..190c36d 100644 --- a/17_ecosystem/17.6_containerd.md +++ b/17_ecosystem/17.6_containerd.md @@ -40,7 +40,7 @@ Kubernetes 作为一个容器编排系统,为了屏蔽底层不同容器运行时的实现差异,引入了 CRI(Container Runtime Interface)标准。 - 早期版本中,Kubernetes 默认使用 docker 作为运行时,通过一个名为 `dockershim` 的桥接组件对接 Docker,Docker 再对接 containerd。 -- 随着 containerd 原生支持了 CRI 插件,Kubernetes 开始直接与 containerd 通信,去掉了 `dockershim` 和 `dockerd` 的中间层。这就是为什么从 Kubernetes 1.24+ 开始“弃用 Docker”引发了广泛关注,实际上 Kubernetes 只是弃用 `dockershim`,底层依然在使用从 Docker 基因中诞生的 containerd。参见 [Kubernetes 官方文档](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd)。 +- 随着 containerd 原生支持了 CRI 插件,Kubernetes 开始直接与 containerd 通信,去掉了 `dockershim` 和 `dockerd` 的中间层。这就是为什么从 Kubernetes 1.24+ 开始“弃用 Docker”引发了广泛关注,实际上 Kubernetes 只是弃用 `dockershim`,底层可以使用 containerd、CRI-O 等符合 CRI 的运行时。参见 [Kubernetes 官方文档](https://kubernetes.io/docs/setup/production-environment/container-runtimes/)。 - containerd 2.0+ 移除了已弃用的 CRI v1alpha2 接口,仅保留 CRI v1(Kubernetes 1.26+ 仅支持 CRI v1)。如果集群中仍有依赖 CRI v1alpha2 的组件,升级 containerd 2.x 前需先完成迁移。containerd 2.3+ 是 2.x 系列首个 LTS 版本,支持从 1.7 LTS 直接升级,生产环境推荐使用。详见 [containerd 发布说明](https://github.com/containerd/containerd/releases)。 ### 17.6.3 为什么直接使用 containerd? diff --git a/18_security/18.3_daemon_sec.md b/18_security/18.3_daemon_sec.md index 9dc873b..e1459db 100644 --- a/18_security/18.3_daemon_sec.md +++ b/18_security/18.3_daemon_sec.md @@ -56,7 +56,7 @@ Rootless 模式允许在完全局限于非 `root` 用户的环境中运行 Docke #### 配置运行 Rootless Docker -要在非 root 环境中运行 Docker,只需要简单几步: +要在非 root 环境中运行 Docker,需要先满足宿主机条件:安装 `newuidmap` / `newgidmap`,并在 `/etc/subuid` 与 `/etc/subgid` 中为该用户分配足够的 subordinate UID/GID。若系统级 Docker daemon 仍在运行,命令行也仍可能连到 rootful socket,因此应明确切换 Docker context 或 `DOCKER_HOST`。 1. 安装必要的依赖(通常是 `uidmap` 工具包以便系统支持 `newuidmap` 和 `newgidmap`): ```bash @@ -80,6 +80,9 @@ $ docker version ``` 安装并暴露相应的配置后,该用户的环境将能独立启动属于他自己的 Docker Daemon。即使由于某些未知 0-Day 漏洞使得攻击者突破了容器,他们也只会受限于 `testuser` 这个非特权用户所在的有限系统环境内。 +> [!NOTE] +> Rootless 模式不是无条件替代 rootful Docker。端口绑定、网络、cgroup、存储驱动和系统服务自启动能力都受发行版、内核与 systemd 用户服务配置影响;生产环境应先验证具体工作负载,并用 `loginctl enable-linger ` 等方式显式配置开机自启动。 + ### 18.3.4 授权插件(Authorization Plugin)与访问策略 在企业环境中,对 Docker 守护进程的访问控制往往不仅限于文件系统权限,还需要更细粒度的授权策略。**Authorization Plugin** 机制允许在 API 层级对请求进行拦截和审批。 @@ -110,4 +113,4 @@ $ docker version ### 18.3.5 结语 -保障 Docker 服务端的安全主要是做减法:关闭不必要的网络监听点,严管 Socket 访问权限。而一旦基础系统条件允许,**毫不犹豫地在生产环境启用 Rootless 模式** 将是一项划算的安全加固选择。 +保障 Docker 服务端的安全主要是做减法:关闭不必要的网络监听点,严管 Socket 访问权限。在基础系统、网络和存储约束都验证通过后,Rootless 模式是一项值得优先评估的安全加固选择。 diff --git a/18_security/18.5_other_feature.md b/18_security/18.5_other_feature.md index 6aefe19..2d69054 100644 --- a/18_security/18.5_other_feature.md +++ b/18_security/18.5_other_feature.md @@ -8,7 +8,7 @@ 一个普通的 Linux 内核提供了 300 多个系统调用,而一个正常运行的容器化应用(例如 Nginx 服务)通常只会用到几十个调用,这就给攻击者留下了大量的闲置入口点来进行内核层的缓冲区溢出攻击。 -Docker 默认启用了 Seccomp 并利用预置的 [默认配置文件](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) 将可以利用的系统调用缩减到了不足一半(默认禁用了 44 个危险的系统调用,比如修改时区或重启系统)。 +Docker 默认启用了 Seccomp,并使用预置的 [默认配置文件](https://docs.docker.com/engine/security/seccomp/) 作为 allowlist:默认拒绝未显式允许的系统调用,并额外允许常见应用所需的调用。Docker 官方文档将其描述为默认禁用约 44 个系统调用(内核与 Docker 版本不同会有差异),例如与内核模块、系统重启或特权命名空间操作相关的调用。 如果你对应用的系统调用特征了如指掌,你可以为容器定制专属规则。 @@ -44,8 +44,8 @@ chmod: /etc/passwd: Operation not permitted 在开启了上述机制的机器上: -- **AppArmor**: Docker 为所有启动的应用加载了一个默认的 `docker-default` 模板文件,如果你的某些异常写行为(比如往特殊的内核心脏目录写入配置)不在 AppArmor 许可列表之上,即使拥有物理 Root,写入同样失败。 -- **SELinux**: 所有的 Docker 操作强制附加特殊上下文标识标签。就算把主机的 `/` 绑定给了黑客的某服务,黑客对不属于 Docker 可见的标签的文件进行读写尝试亦会被阻止。 +- **AppArmor**: 在启用 AppArmor 的系统上,Docker 默认为容器加载 `docker-default` profile;如果需要自定义策略,先用 `apparmor_parser` 加载 profile,再通过 `--security-opt apparmor=` 指定。 +- **SELinux**: 在启用 SELinux 集成的系统上,容器与挂载目录需要正确的 SELinux label。绑定挂载时常用 `:z` 表示多个容器共享,`:Z` 表示该挂载只给单个容器使用;不要对 `/home`、`/usr` 等系统目录随意使用 `:Z`,否则可能破坏宿主机标签。 如果想为某些受信任应用施加特定的外部强化文件策略,可以通过如下方法指派规则表: @@ -53,6 +53,10 @@ chmod: /etc/passwd: Operation not permitted $ docker run --rm -it \ --security-opt apparmor=custom-nginx-profile \ nginx + +$ docker run --rm -it \ + -v "$PWD/html":/usr/share/nginx/html:Z \ + nginx ``` ### 18.5.3 容器镜像漏洞静态扫描 diff --git a/19_observability/19.1_prometheus.md b/19_observability/19.1_prometheus.md index f17588f..51424fa 100644 --- a/19_observability/19.1_prometheus.md +++ b/19_observability/19.1_prometheus.md @@ -160,10 +160,10 @@ $ docker compose up -d * **节点 CPU 使用率**:`100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)` * **节点内存使用率**:`(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100` * **节点磁盘空间使用率**:`(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100` -* **容器 CPU**:`sum by (name) (rate(container_cpu_usage_seconds_total[5m]))` -* **容器内存**:`sum by (name) (container_memory_working_set_bytes)` +* **容器 CPU**:`sum by (namespace, pod, container) (rate(container_cpu_usage_seconds_total[5m]))` +* **容器内存**:`sum by (namespace, pod, container) (container_memory_working_set_bytes)` -说明:不同版本的 cAdvisor/Docker 对 label 命名可能存在差异 (如 `name`、`container`、`container_name`),如果查询为空,建议先用 `label_values(container_cpu_usage_seconds_total, __name__)` 或在 Prometheus 的图形界面查看可用 label。 +说明:不同采集路径的 label 命名不同。Docker Compose 中独立部署的 cAdvisor 常见容器标签是 `name`;Kubernetes kubelet 的 `/metrics/cadvisor` 中,`container_cpu_usage_seconds_total` 等稳定指标使用 `container`、`pod`、`namespace`。如果查询为空,先直接查询 `container_cpu_usage_seconds_total` 样本并在 Prometheus 图形界面查看实际 label,不要假设存在 `container_name`。 #### Targets down 排错清单 diff --git a/appendix/glossary.md b/appendix/glossary.md index 091dc16..4fab8bd 100644 --- a/appendix/glossary.md +++ b/appendix/glossary.md @@ -71,7 +71,7 @@ ## S -* **Swarm (Docker Swarm)**:Docker 原生的集群和编排管理工具,可将多个 Docker 主机组合成一个统一的虚拟 Docker 主机池。 +* **Swarm (Docker Swarm)**:Docker 原生的集群和编排管理工具,可将多个 Docker 主机组合成一个统一的虚拟 Docker 主机池。维护节点时通常将节点可用性设为 `Drain`,这只影响 Swarm service 调度,不会停止该节点上独立运行的容器。 ## U diff --git a/appendix/learning_roadmap.md b/appendix/learning_roadmap.md index 952c0df..1a23df8 100644 --- a/appendix/learning_roadmap.md +++ b/appendix/learning_roadmap.md @@ -652,7 +652,8 @@ Host: Overlay: - 跨主机通信,基于 VXLAN -- Swarm 和 Kubernetes 标准 +- Docker overlay 网络默认使用 UDP 4789 传输数据 +- Swarm 标准;Kubernetes 通常由 CNI 插件实现跨主机网络 - 性能略低,支持分布式 macvlan: