From ae8636e96f11d7e3c34c8996dae0a7c138e41ef0 Mon Sep 17 00:00:00 2001 From: yeasy Date: Tue, 24 Mar 2026 09:27:04 -0700 Subject: [PATCH] Add blank lines around headers --- 01_introduction/1.1_quickstart.md | 2 ++ 01_introduction/1.2_what.md | 1 + 01_introduction/1.3_why.md | 6 +++++ 02_basic_concept/2.1_image.md | 5 ++++ 02_basic_concept/2.2_container.md | 4 +++ 02_basic_concept/2.3_repository.md | 5 ++++ 03_install/3.1_ubuntu.md | 3 +++ 03_install/3.2_debian.md | 3 +++ 03_install/3.3_fedora.md | 4 +++ 03_install/3.4_centos.md | 6 +++++ 03_install/3.5_raspberry-pi.md | 3 +++ 03_install/3.6_offline.md | 9 +++++++ 03_install/3.7_mac.md | 2 ++ 03_install/3.8_windows.md | 1 + 03_install/summary.md | 1 + 04_image/4.1_pull.md | 3 +++ 04_image/4.2_list.md | 7 +++++ 04_image/4.3_rm.md | 8 ++++++ 04_image/4.6_other.md | 1 + 05_container/5.1_run.md | 9 +++++++ 05_container/5.2_daemon.md | 6 +++++ 05_container/5.3_stop.md | 8 ++++++ 05_container/5.4_attach_exec.md | 8 ++++++ 05_container/5.6_rm.md | 6 +++++ 06_repository/6.1_dockerhub.md | 2 ++ 06_repository/6.2_registry.md | 2 ++ 06_repository/6.3_registry_auth.md | 3 +++ 06_repository/6.4_nexus3_registry.md | 1 + 07_dockerfile/7.10_workdir.md | 4 +++ 07_dockerfile/7.11_user.md | 6 +++++ 07_dockerfile/7.12_healthcheck.md | 4 +++ 07_dockerfile/7.13_onbuild.md | 3 +++ 07_dockerfile/7.14_label.md | 2 ++ 07_dockerfile/7.15_shell.md | 3 +++ 07_dockerfile/7.17_multistage_builds.md | 3 +++ .../7.18_multistage_builds_laravel.md | 6 +++++ 07_dockerfile/7.1_run.md | 3 +++ 07_dockerfile/7.2_copy.md | 7 +++++ 07_dockerfile/7.3_add.md | 6 +++++ 07_dockerfile/7.4_cmd.md | 8 ++++++ 07_dockerfile/7.5_entrypoint.md | 7 +++++ 07_dockerfile/7.6_env.md | 8 ++++++ 07_dockerfile/7.7_arg.md | 8 ++++++ 07_dockerfile/7.8_volume.md | 7 +++++ 07_dockerfile/7.9_expose.md | 4 +++ 08_data/8.1_volume.md | 8 ++++++ 08_data/8.2_bind-mounts.md | 9 +++++++ 09_network/9.1_dns.md | 2 ++ 09_network/9.2_network_types.md | 2 ++ 09_network/9.3_custom_network.md | 3 +++ 09_network/9.4_container_linking.md | 2 ++ 09_network/9.5_port_mapping.md | 2 ++ 09_network/9.6_network_isolation.md | 1 + 09_network/9.7_advanced_networking.md | 11 ++++++++ 10_buildx/10.1_buildkit.md | 4 +++ 10_buildx/10.2_buildx.md | 1 + 10_buildx/10.3_multi-arch-images.md | 4 +++ 11_compose/11.2_install.md | 3 +++ 11_compose/11.3_usage.md | 11 ++++++++ 11_compose/11.4_commands.md | 2 ++ 11_compose/11.5_compose_file.md | 27 +++++++++++++++++++ 11_compose/11.6_django.md | 3 +++ 11_compose/11.7_rails.md | 7 +++++ 11_compose/11.8_wordpress.md | 1 + 12_implementation/12.2_namespace.md | 7 +++++ 12_implementation/12.3_cgroups.md | 4 +++ 12_implementation/12.4_ufs.md | 1 + 13_kubernetes_concepts/13.2_concepts.md | 2 ++ 13_kubernetes_concepts/13.4_advanced.md | 1 + 13_kubernetes_concepts/13.5_practice.md | 2 ++ 14_kubernetes_setup/14.1_kubeadm.md | 12 +++++++++ 14_kubernetes_setup/14.2_kubeadm-docker.md | 11 ++++++++ 14_kubernetes_setup/14.4_kind.md | 5 ++++ 14_kubernetes_setup/14.5_k3s.md | 2 ++ 14_kubernetes_setup/14.6_systemd.md | 2 ++ 14_kubernetes_setup/14.7_dashboard.md | 1 + 14_kubernetes_setup/14.8_kubectl.md | 1 + 15_etcd/15.4_etcdctl.md | 4 +++ 16_cloud/16.2_tencentCloud.md | 5 ++++ 16_cloud/16.3_alicloud.md | 8 ++++++ 17_ecosystem/17.2_coreos_install.md | 1 + 17_ecosystem/17.3_podman.md | 8 ++++++ 17_ecosystem/17.4_buildah.md | 1 + 17_ecosystem/17.5_skopeo.md | 1 + 18_security/18.1_kernel_ns.md | 1 + 18_security/18.5_other_feature.md | 1 + 18_security/18.6_image_security.md | 13 +++++++++ 18_security/README.md | 1 + 19_observability/19.1_prometheus.md | 2 ++ 19_observability/19.2_elk.md | 2 ++ .../19.3_performance_optimization.md | 9 +++++++ 20_cases_os/20.1_busybox.md | 1 + 20_cases_os/20.2_alpine.md | 3 +++ 20_cases_os/20.4_centos.md | 1 + 21_case_devops/21.1_devops_workflow.md | 2 ++ 21_case_devops/21.2_github_actions.md | 1 + 21_case_devops/21.3_drone.md | 2 ++ 21_case_devops/21.6_vsCode.md | 1 + 21_case_devops/21.7_practical_examples.md | 7 +++++ CONTRIBUTING.md | 1 + appendix/best_practices.md | 2 ++ appendix/debug.md | 3 +++ appendix/faq/README.md | 5 ++++ appendix/learning_roadmap.md | 10 +++++++ appendix/repo/centos.md | 1 + appendix/repo/minio.md | 3 +++ appendix/repo/mongodb.md | 1 + appendix/repo/nginx.md | 1 + appendix/repo/nodejs.md | 1 + appendix/repo/php.md | 1 + appendix/repo/redis.md | 1 + appendix/repo/ubuntu.md | 1 + 112 files changed, 468 insertions(+) diff --git a/01_introduction/1.1_quickstart.md b/01_introduction/1.1_quickstart.md index 581443b..680b7bc 100644 --- a/01_introduction/1.1_quickstart.md +++ b/01_introduction/1.1_quickstart.md @@ -9,6 +9,7 @@ ```html

Hello, Docker!

``` + ### 1.1.2 编写 Dockerfile 在同级目录下创建一个名为 `Dockerfile` (无后缀) 的文件: @@ -17,6 +18,7 @@ FROM nginx:alpine COPY index.html /usr/share/nginx/html/index.html ``` + ### 1.1.3 构建镜像 打开终端,进入该目录,执行构建命令: diff --git a/01_introduction/1.2_what.md b/01_introduction/1.2_what.md index a2a0537..7be03b2 100644 --- a/01_introduction/1.2_what.md +++ b/01_introduction/1.2_what.md @@ -40,6 +40,7 @@ flowchart LR end A == 一致 ==> C ``` + ### 1.2.3 Docker vs 虚拟机 很多人第一次接触 Docker 时会问:**“这不就是虚拟机吗?”** 答案是:**不是,而且差别很大。** diff --git a/01_introduction/1.3_why.md b/01_introduction/1.3_why.md index c110c41..b849f78 100644 --- a/01_introduction/1.3_why.md +++ b/01_introduction/1.3_why.md @@ -33,6 +33,7 @@ ├── Day 4:问老同事怎么配的,他也忘了 └── Day 5:终于能跑起来了!但不知道为什么…… ``` + #### 场景三:服务器迁移的恐惧 ```bash @@ -41,6 +42,7 @@ 运维:"当时是一个已经离职的同事配的……" 所有人:😱 ``` + ### 1.3.2 Docker 如何解决这些问题 Docker 的出现为上述问题提供了完美的解决方案。它通过 “一次构建,到处运行” 的核心理念,从根本上改变了软件交付的方式。 @@ -54,6 +56,7 @@ flowchart LR test -- "有问题
反馈修改和更新" --> dev test -- "没问题
发布" --> prod["生产环境"] ``` + ### 1.3.3 Docker 的核心优势 除了解决上述痛点,Docker 还拥有诸多显著的技术优势,包括环境一致性、秒级启动、高效的资源利用等。 @@ -76,6 +79,7 @@ $ docker compose up ... ``` + #### 2. 秒级启动 传统虚拟机启动需要几分钟 (引导操作系统),而 Docker 容器启动通常只需要 **几秒甚至几百毫秒**。 @@ -126,6 +130,7 @@ flowchart TD Server2 --- Containers end ``` + #### 4. 持续交付和部署 Docker 完美契合 DevOps 的工作流程: @@ -182,6 +187,7 @@ flowchart TD Worker --> DB end ``` + ### 1.3.4 Docker 不适合的场景 笔者认为,技术选型要客观。Docker 并非银弹,以下场景可能不太适合: diff --git a/02_basic_concept/2.1_image.md b/02_basic_concept/2.1_image.md index c39ede0..b39c161 100644 --- a/02_basic_concept/2.1_image.md +++ b/02_basic_concept/2.1_image.md @@ -79,6 +79,7 @@ flowchart TD AppC --> Ubuntu end ``` + #### 分层是如何工作的? 笔者用一个实际的 Dockerfile 来解释分层: @@ -135,6 +136,7 @@ RUN apt-get update && \ ## 在同一层完成安装、使用、清理 ``` + #### 查看镜像的分层 ```bash @@ -150,6 +152,7 @@ a6bd71f48f68 2 weeks ago CMD ["nginx" "-g" "daemon off;"] 0B 2 weeks ago COPY 30-tune-worker-processes.sh /docker-ent… 4.62kB ... ``` + ### 2.1.5 镜像的标识 Docker 镜像有多种标识方式: @@ -172,6 +175,7 @@ ubuntu:24.04 nginx # 等同于 nginx:latest ``` + #### 2. 镜像 ID:Content-Addressable 标识 每个镜像有一个基于内容计算的唯一 ID: @@ -182,6 +186,7 @@ REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest a6bd71f48f68 2 weeks ago 187MB ubuntu 24.04 ca2b0f26964c 3 weeks ago 78.1MB ``` + #### 3. 镜像摘要 更精确的标识,基于镜像内容的 SHA256 哈希: diff --git a/02_basic_concept/2.2_container.md b/02_basic_concept/2.2_container.md index 9b0ef94..bb55dbf 100644 --- a/02_basic_concept/2.2_container.md +++ b/02_basic_concept/2.2_container.md @@ -92,6 +92,7 @@ flowchart TD ContainerLayer --> ImageLayerN --> ImageLayerN1 --> Dots --> ImageLayer1 ``` + #### Copy-on-Write:写时复制 当容器需要修改镜像层中的文件时: @@ -104,6 +105,7 @@ flowchart TD 读取文件:直接从镜像层读取(共享,高效) 修改文件:复制到容器层,然后修改(只有这个容器能看到修改) ``` + #### ⚠️ 容器存储层的生命周期 > **笔者特别强调**:这是新手最容易踩的坑!**容器存储层与容器生命周期绑定。容器删除,数据就没了!** @@ -122,6 +124,7 @@ $ docker rm abc123 ## 数据丢了!没有任何办法恢复! ``` + #### 正确的数据持久化方式 按照 Docker 最佳实践,容器存储层应该保持 **无状态**。需要持久化的数据应该使用: @@ -190,6 +193,7 @@ $ docker unpause abc123 # 恢复 $ docker rm abc123 # 删除已停止的容器 $ docker rm -f abc123 # 强制删除运行中的容器 ``` + ### 2.2.6 容器与进程的关系 > **核心概念**:容器的生命周期 = 主进程 (PID 1) 的生命周期 diff --git a/02_basic_concept/2.3_repository.md b/02_basic_concept/2.3_repository.md index 71e2c19..de2480c 100644 --- a/02_basic_concept/2.3_repository.md +++ b/02_basic_concept/2.3_repository.md @@ -110,6 +110,7 @@ $ docker pull bitnami/redis # 第三方镜像 $ docker login $ docker push username/myapp:v1.0 ``` + #### 其他公共 Registry 除了 Docker Hub,还有以下几个常见的公共 Registry: @@ -160,6 +161,7 @@ $ docker push localhost:5000/myapp:v1.0 $ docker pull localhost:5000/myapp:v1.0 ``` + #### 企业级解决方案 官方 Registry 功能较为基础,企业环境常用以下方案: @@ -225,6 +227,7 @@ $ docker push registry.example.com/myteam/myapp:v1.0 $ docker logout ``` + ### 2.3.7 镜像的安全性 在使用公共镜像或维护私有镜像时,安全性是不容忽视的重要环节。 @@ -245,6 +248,7 @@ redis # ✅ 官方 bitnami/redis # ⚠️ 需要评估 someuser/myapp # ⚠️ 需要评估 ``` + #### 镜像签名 当前更推荐使用 Sigstore / Notation 体系进行镜像签名与验证。`Docker Content Trust (DCT)` 已进入退场阶段,不建议作为新项目主方案。 @@ -265,6 +269,7 @@ $ cosign generate-key-pair $ cosign sign --key cosign.key $IMAGE $ cosign verify --key cosign.pub $IMAGE ``` + #### 漏洞扫描 ```bash diff --git a/03_install/3.1_ubuntu.md b/03_install/3.1_ubuntu.md index a41f7ed..07e9c2a 100644 --- a/03_install/3.1_ubuntu.md +++ b/03_install/3.1_ubuntu.md @@ -36,6 +36,7 @@ do sudo apt remove $pkg; done ``` + ### 3.1.2 使用 APT 安装 由于 `apt` 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。 @@ -83,6 +84,7 @@ $ sudo apt update $ sudo apt install docker-ce docker-ce-cli containerd.io ``` + ### 3.1.3 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -105,6 +107,7 @@ $ sudo sh get-docker.sh --mirror Aliyun $ sudo systemctl enable docker $ sudo systemctl start docker ``` + ### 3.1.5 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 diff --git a/03_install/3.2_debian.md b/03_install/3.2_debian.md index 02594ac..d2c63b6 100644 --- a/03_install/3.2_debian.md +++ b/03_install/3.2_debian.md @@ -25,6 +25,7 @@ $ sudo apt-get remove docker \ docker-engine \ docker.io ``` + ### 3.2.2 使用 APT 安装 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。 @@ -74,6 +75,7 @@ $ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.io ``` + ### 3.2.3 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -96,6 +98,7 @@ $ sudo sh get-docker.sh --mirror Aliyun $ sudo systemctl enable docker $ sudo systemctl start docker ``` + ### 3.2.5 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 diff --git a/03_install/3.3_fedora.md b/03_install/3.3_fedora.md index 8c8abd7..e07d078 100644 --- a/03_install/3.3_fedora.md +++ b/03_install/3.3_fedora.md @@ -32,6 +32,7 @@ $ sudo dnf remove docker \ docker-engine-selinux \ docker-engine ``` + ### 3.3.2 使用 dnf 安装 使用 dnf 包管理器安装是推荐的方式,便于后续的更行和管理。 @@ -67,6 +68,7 @@ $ sudo dnf config-manager --set-enabled docker-ce-test ```bash $ sudo dnf config-manager --set-disabled docker-ce-test ``` + #### 安装 Docker 更新 `dnf` 软件源缓存,并安装 `docker-ce`。 @@ -84,6 +86,7 @@ docker-ce.x86_64 18.06.1.ce-3.fc28 docker-ce-stable $ sudo dnf -y install docker-ce-18.06.1.ce ``` + ### 3.3.3 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Fedora 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -106,6 +109,7 @@ $ sudo sh get-docker.sh --mirror Aliyun $ sudo systemctl enable docker $ sudo systemctl start docker ``` + ### 3.3.5 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 diff --git a/03_install/3.4_centos.md b/03_install/3.4_centos.md index 6dfa4be..5ddbb7d 100644 --- a/03_install/3.4_centos.md +++ b/03_install/3.4_centos.md @@ -34,6 +34,7 @@ $ sudo yum remove docker \ docker-ce-cli \ containerd.io ``` + ### 3.4.2 使用 yum 安装 使用 yum/dnf 安装是管理 Docker 生命周期的标准方式。 @@ -64,6 +65,7 @@ $ sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.r ```bash $ sudo dnf config-manager --set-enabled docker-ce-test ``` + #### 安装 Docker 更新 `dnf` 软件源缓存,并安装 `docker-ce`。 @@ -71,6 +73,7 @@ $ sudo dnf config-manager --set-enabled docker-ce-test ```bash $ sudo dnf install docker-ce docker-ce-cli containerd.io ``` + ### 3.4.3 CentOS8 额外设置 CentOS 8/Stream 默认使用 `nftables`。Docker 在新版本中已提供 `nftables` 实验支持,但在一些环境下仍可能遇到兼容性问题。若你遇到容器网络异常,可以先切换回 `iptables` 后端: @@ -89,6 +92,7 @@ $ firewall-cmd --permanent --zone=trusted --add-interface=docker0 $ firewall-cmd --reload ``` + ### 3.4.4 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -112,6 +116,7 @@ $ sudo sh get-docker.sh --mirror Aliyun $ sudo systemctl enable docker $ sudo systemctl start docker ``` + ### 3.4.6 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 @@ -192,6 +197,7 @@ EOF ```bash $ sudo sysctl -p ``` + ### 3.4.10 参考文档 * [Docker 官方 CentOS 安装文档](https://docs.docker.com/engine/install/centos/)。 diff --git a/03_install/3.5_raspberry-pi.md b/03_install/3.5_raspberry-pi.md index c98f389..fccece0 100644 --- a/03_install/3.5_raspberry-pi.md +++ b/03_install/3.5_raspberry-pi.md @@ -89,6 +89,7 @@ $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docke # $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/raspbian $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list ``` + #### 安装 Docker 更新 apt 软件包缓存,并安装 `docker-ce`。 @@ -98,6 +99,7 @@ $ sudo apt-get update $ sudo apt-get install docker-ce ``` + ### 3.5.3 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspberry Pi OS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -121,6 +123,7 @@ $ sudo sh get-docker.sh --mirror Aliyun $ sudo systemctl enable docker $ sudo systemctl start docker ``` + ### 3.5.5 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 diff --git a/03_install/3.6_offline.md b/03_install/3.6_offline.md index 4e68de8..bf1b845 100644 --- a/03_install/3.6_offline.md +++ b/03_install/3.6_offline.md @@ -41,6 +41,7 @@ docker-ce.x86_64 3:19.03.2-3.el7 docker-ce-stable docker-ce.x86_64 3:19.03.1-3.el7 docker-ce-stable .... ``` + ##### 下载到指定文件夹 ```bash @@ -74,6 +75,7 @@ Background downloading packages, then exiting: Total 118 MB/s | 87 MB 00:00:00 exiting because "Download Only" specified ``` + ##### 复制到目标服务器之后进入文件夹安装:C-N * 离线安装时,必须使用 rpm 命令不检查依赖的方式安装 @@ -81,6 +83,7 @@ exiting because "Download Only" specified ```bash rpm -Uvh *.rpm --nodeps --force ``` + ##### 锁定软件版本:C-N **下载锁定版本软件** @@ -130,6 +133,7 @@ versionlock deleted: 1 ```bash sudo yum versionlock delete all ``` + #### YUM 本地源服务器搭建安装 Docker ##### 挂载 ISO 镜像搭建本地 File 源 @@ -161,6 +165,7 @@ EOF yum clean all yum install createrepo -y ``` + ##### 根据本地文件搭建 BASE 网络源 ```bash @@ -183,6 +188,7 @@ createrepo /var/www/html/base/ systemctl enable httpd systemctl start httpd ``` + ##### 下载 Docker-CE 镜像仓库 在有网络的服务器上下载 Docker-ce 镜像 @@ -202,6 +208,7 @@ mkdir /tmp/docker-ce/ reposync -r docker-ce-stable -p /tmp/docker-ce/ ``` + ##### 创建仓库索引 把下载的 docker-ce 文件夹复制到离线的服务器 @@ -213,6 +220,7 @@ reposync -r docker-ce-stable -p /tmp/docker-ce/ createrepo /var/www/html/docker-ce/ ``` + ##### YUM 客户端设置:C...N ```bash @@ -239,6 +247,7 @@ proxy=_none_ EOF ``` + ##### Docker 安装:C...N ```bash diff --git a/03_install/3.7_mac.md b/03_install/3.7_mac.md index f23ad8a..43da3cd 100644 --- a/03_install/3.7_mac.md +++ b/03_install/3.7_mac.md @@ -18,6 +18,7 @@ Docker Desktop 为 Mac 用户提供了无缝的 Docker 体验。你可以选择 ```bash $ brew install --cask docker ``` + #### 手动下载安装 如果需要手动下载,请点击以下[链接](https://desktop.docker.com/mac/main/amd64/Docker.dmg)下载 Docker Desktop for Mac。 @@ -63,6 +64,7 @@ $ docker run -d -p 80:80 --name webserver nginx $ docker stop webserver $ docker rm webserver ``` + ### 3.7.4 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。 diff --git a/03_install/3.8_windows.md b/03_install/3.8_windows.md index 40fcd36..46bb8f2 100644 --- a/03_install/3.8_windows.md +++ b/03_install/3.8_windows.md @@ -22,6 +22,7 @@ ```powershell $ winget install Docker.DockerDesktop ``` + ### 3.8.3 在 WSL2 运行 Docker 若你的 Windows 版本为 Windows 10 专业版或家庭版 v1903 及以上版本可以使用 WSL2 运行 Docker,具体请查看 [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl/)。 diff --git a/03_install/summary.md b/03_install/summary.md index a506ea6..429668a 100644 --- a/03_install/summary.md +++ b/03_install/summary.md @@ -19,6 +19,7 @@ Docker 支持在多种平台上安装和使用,选择合适的安装方式是 $ docker version $ docker run --rm hello-world ``` + ### 延伸阅读 - [镜像加速器](3.9_mirror.md):解决国内拉取镜像慢的问题 diff --git a/04_image/4.1_pull.md b/04_image/4.1_pull.md index 1162e35..4d741fd 100644 --- a/04_image/4.1_pull.md +++ b/04_image/4.1_pull.md @@ -9,6 +9,7 @@ ```bash docker pull [选项] [Registry地址/]仓库名[:标签] ``` + #### 镜像名称格式 Docker 镜像名称由 Registry 地址、用户名、仓库名和标签组成。其标准格式如下: @@ -70,6 +71,7 @@ Digest: sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26 Status: Downloaded newer image for ubuntu:24.04 docker.io/library/ubuntu:24.04 ``` + #### 输出解读 | 输出内容 | 说明 | @@ -180,6 +182,7 @@ $ docker images --digests ubuntu REPOSITORY TAG DIGEST IMAGE ID ubuntu 24.04 sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26 ca2b0f26964c ``` + #### 使用摘要拉取 用摘要拉取可确保获取完全相同的镜像: diff --git a/04_image/4.2_list.md b/04_image/4.2_list.md index 91bf5ea..6aacbdb 100644 --- a/04_image/4.2_list.md +++ b/04_image/4.2_list.md @@ -87,6 +87,7 @@ ubuntu 24.04 329ed837d508 78MB ubuntu noble 329ed837d508 78MB ubuntu 22.04 a1b2c3d4e5f6 72MB ``` + #### 按仓库名和标签过滤 ```bash @@ -94,6 +95,7 @@ $ docker images ubuntu:24.04 REPOSITORY TAG IMAGE ID SIZE ubuntu 24.04 329ed837d508 78MB ``` + #### 使用过滤器 --filter | 过滤条件 | 说明 | 示例 | @@ -132,6 +134,7 @@ $ docker images REPOSITORY TAG IMAGE ID SIZE 00285df0df87 342MB ``` + #### 产生原因 1. **镜像重新构建**:新镜像使用了旧镜像的标签,旧镜像标签被移除 @@ -188,11 +191,13 @@ $ docker rmi $(docker images -q) $ docker rmi $(docker images -q redis) ``` + #### 显示完整 ID ```bash $ docker images --no-trunc ``` + #### 显示摘要 ```bash @@ -200,6 +205,7 @@ $ docker images --digests REPOSITORY TAG DIGEST IMAGE ID nginx latest sha256:b4f0e0bdeb5... e43d811ce2f4 ``` + #### 自定义格式 使用 Go 模板语法自定义输出: @@ -220,6 +226,7 @@ redis latest 183MB nginx latest 181MB ubuntu 24.04 78MB ``` + #### 可用模板字段 | 字段 | 说明 | diff --git a/04_image/4.3_rm.md b/04_image/4.3_rm.md index 70483ba..77c9a86 100644 --- a/04_image/4.3_rm.md +++ b/04_image/4.3_rm.md @@ -38,6 +38,7 @@ $ docker rmi 501 Untagged: redis:alpine Deleted: sha256:501ad78535f0... ``` + #### 使用镜像名删除 ```bash @@ -45,6 +46,7 @@ $ docker rmi redis:alpine Untagged: redis:alpine Deleted: sha256:501ad78535f0... ``` + #### 使用摘要删除 摘要删除最精确,适用于 CI/CD 场景: @@ -76,6 +78,7 @@ Deleted: sha256:501ad78535f015d88872e13fa87a828425117e3d28075d0c117932b05bf189b7 Deleted: sha256:96167737e29ca8e9d74982ef2a0dda76ed7b430da55e321c071f0dbff8c2899b Deleted: sha256:32770d1dcf835f192cafd6b9263b7b597a1778a403a109e2cc2ee866f74adf23 ``` + #### Untagged vs Deleted | 操作 | 含义 | @@ -131,6 +134,7 @@ $ docker image prune $ docker image prune -f ``` + #### 删除所有未使用的镜像 ```bash @@ -142,6 +146,7 @@ $ docker image prune -a $ docker image prune -a --filter "until=24h" ``` + #### 按条件删除 ```bash @@ -182,6 +187,7 @@ $ docker rmi nginx $ docker rmi -f nginx ``` + #### 原因二:多个标签指向同一镜像 ```bash @@ -234,6 +240,7 @@ $ docker image prune -f $ docker system prune -a ``` + #### CI/CD 环境 ```bash @@ -241,6 +248,7 @@ $ docker system prune -a $ docker image prune -a --filter "until=72h" -f ``` + #### 查看空间占用 ```bash diff --git a/04_image/4.6_other.md b/04_image/4.6_other.md index 5174c30..a1baa0e 100644 --- a/04_image/4.6_other.md +++ b/04_image/4.6_other.md @@ -34,6 +34,7 @@ $ docker history openvz/ubuntu:16.04 IMAGE CREATED CREATED BY SIZE COMMENT f477a6e18e98 About a minute ago 214.9 MB Imported from http://download.openvz.org/template/precreated/ubuntu-16.04-x86_64.tar.gz ``` + ### 4.6.2 Docker 镜像的导入和导出 `docker save` 和 `docker load` Docker 还提供了 `docker save` 和 `docker load` 命令,用以将镜像保存为一个文件,然后传输到另一个位置上,再加载进来。这是在没有 Docker Registry 时的做法,现在已经不推荐,镜像迁移应该直接使用 Docker Registry,无论是直接使用 Docker Hub 还是使用内网私有 Registry 都可以。 diff --git a/05_container/5.1_run.md b/05_container/5.1_run.md index 43dfb72..66b00c7 100644 --- a/05_container/5.1_run.md +++ b/05_container/5.1_run.md @@ -18,6 +18,7 @@ ```bash docker run [选项] 镜像 [命令] [参数...] ``` + #### 最简单的例子 输出 “Hello World” 后容器自动终止: @@ -53,6 +54,7 @@ root@af8bae53bdd3:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@af8bae53bdd3:/# exit # 退出容器 ``` + ### 5.1.3 docker run 的完整流程 执行 `docker run` 时,Docker 在后台完成以下操作: @@ -73,6 +75,7 @@ flowchart TD Step4["4. 启动容器,执行指定命令"] --> Step5 Step5["5. 命令执行完毕,容器停止"] ``` + ### 5.1.4 常用启动选项 #### 基础选项 @@ -99,6 +102,7 @@ $ docker run -d -P nginx $ docker run -d -p 127.0.0.1:8080:80 nginx ``` + #### 数据卷挂载 ```bash @@ -114,6 +118,7 @@ $ docker run -v /host/path:/container/path nginx $ docker run -v /host/path:/container/path:ro nginx ``` + #### 环境变量 ```bash @@ -125,6 +130,7 @@ $ docker run -e MYSQL_ROOT_PASSWORD=secret mysql $ docker run --env-file .env myapp ``` + #### 资源限制 ```bash @@ -136,6 +142,7 @@ $ docker run -m 512m nginx $ docker run --cpus=1.5 nginx ``` + ### 5.1.5 启动已终止容器 使用 `docker start` 重新启动已停止的容器: @@ -155,6 +162,7 @@ $ docker start myubuntu $ docker start -ai myubuntu ``` + ### 5.1.6 容器内进程的特点 容器内只运行指定的应用程序及其必需资源: @@ -199,6 +207,7 @@ $ docker run -d nginx $ docker run -d -p 80:80 nginx ``` + #### Q:容器内修改的文件丢失 **原因**:未使用数据卷,数据保存在容器存储层 diff --git a/05_container/5.2_daemon.md b/05_container/5.2_daemon.md index eb75698..4a8db71 100644 --- a/05_container/5.2_daemon.md +++ b/05_container/5.2_daemon.md @@ -92,6 +92,7 @@ $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 77b2dc01fe0f ubuntu:24.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute agitated_wright ``` + #### 查看容器输出日志 ```bash @@ -106,6 +107,7 @@ hello world ```bash $ docker container logs -f 77b2dc01fe0f ``` + #### 查看已停止的容器 ```bash @@ -130,6 +132,7 @@ $ docker run -d -p 3306:3306 mysql:8 $ docker run -d -p 6379:6379 redis ``` + #### 2. 调试时先用前台模式 当容器启动有问题时,**去掉 `-d` 参数** 可以直接看到输出和错误: @@ -139,6 +142,7 @@ $ docker run -d -p 6379:6379 redis $ docker run myimage:latest ``` + #### 3. 使用 --rm 自动清理 对于一次性任务,使用 `--rm` 参数让容器退出后自动删除: @@ -151,6 +155,7 @@ Hello, World! ... ``` + #### 4. 配合日志查看 ```bash @@ -170,6 +175,7 @@ $ docker logs -f myapp $ docker logs -t myapp ``` + ### 5.2.6 常见问题排查 #### Q:容器启动后立即退出 diff --git a/05_container/5.3_stop.md b/05_container/5.3_stop.md index d605729..f785065 100644 --- a/05_container/5.3_stop.md +++ b/05_container/5.3_stop.md @@ -21,6 +21,7 @@ ```bash $ docker stop 容器名或ID ``` + #### 工作原理 ```mermaid @@ -29,6 +30,7 @@ flowchart TD A --> B["2. 等待容器优雅退出 (默认 10 秒)"] B --> C["3. 如果超时仍未退出,发送 SIGKILL 强制终止"] ``` + #### 自定义超时时间 ```bash @@ -40,6 +42,7 @@ $ docker stop -t 30 mycontainer $ docker stop -t 0 mycontainer ``` + #### 停止多个容器 ```bash @@ -60,6 +63,7 @@ $ docker stop $(docker ps -q) ```bash $ docker kill 容器名或ID ``` + #### 与 stop 的区别 | 命令 | 信号 | 使用场景 | @@ -127,6 +131,7 @@ $ docker start 容器名或ID $ docker start -ai 容器名 ``` + #### 重启运行中的容器 ```bash @@ -166,11 +171,13 @@ stateDiagram-v2 ```bash $ docker stop $(docker ps -q) ``` + #### 删除所有已停止的容器 ```bash $ docker container prune ``` + #### 停止并删除所有容器 ```bash @@ -204,6 +211,7 @@ FROM node:22 CMD ["node", "server.js"] ``` + #### Q:容器无法停止 ```bash diff --git a/05_container/5.4_attach_exec.md b/05_container/5.4_attach_exec.md index f1c0e5a..1027190 100644 --- a/05_container/5.4_attach_exec.md +++ b/05_container/5.4_attach_exec.md @@ -35,6 +35,7 @@ $ docker exec -it 容器名 /bin/bash $ docker exec -it 容器名 /bin/sh ``` + #### 参数说明 | 参数 | 作用 | @@ -67,6 +68,7 @@ $ docker ps CONTAINER ID IMAGE STATUS NAMES 69d137adef7a ubuntu Up 2 minutes myubuntu ``` + #### 执行单条命令 不进入交互模式,直接执行命令: @@ -84,6 +86,7 @@ $ docker exec myubuntu cat /etc/nginx/nginx.conf $ docker exec -u root myubuntu apt update ``` + #### 只用 -i 不用 -t 的区别 ```bash @@ -112,6 +115,7 @@ root@69d137adef7a:/# # 有提示符 ```bash $ docker attach 容器名 ``` + #### 工作原理 `attach` 会附加到容器的 **主进程** (PID 1) 的标准输入输出: @@ -126,6 +130,7 @@ flowchart LR end Attach["docker attach"] -->|"附加到这里"| P1 ``` + #### docker attach 示例 ```bash @@ -139,6 +144,7 @@ $ docker run -dit --name myubuntu ubuntu $ docker attach myubuntu root@243c32535da7:/# ``` + #### ⚠️ 重要警告 **从 attach 会话中输入 `exit` 或按 `Ctrl+D` 会导致容器停止!** @@ -224,6 +230,7 @@ $ docker exec myapp tail -f /var/log/app.log $ docker exec myapp python manage.py migrate ``` + #### 2. 生产环境避免进入容器 笔者建议:生产环境应尽量避免进入容器直接操作,而是通过: @@ -261,6 +268,7 @@ $ docker debug myapp ```bash $ docker exec -it myapp /bin/sh ``` + #### Q:需要 root 权限 ```bash diff --git a/05_container/5.6_rm.md b/05_container/5.6_rm.md index d0d348a..ace1829 100644 --- a/05_container/5.6_rm.md +++ b/05_container/5.6_rm.md @@ -27,6 +27,7 @@ $ docker rm 容器名或ID $ docker rm mycontainer mycontainer ``` + #### 强制删除运行中的容器 ```bash @@ -73,6 +74,7 @@ Total reclaimed space: 150MB $ docker container prune -f ``` + #### 删除所有容器:包括运行中的 ```bash @@ -85,6 +87,7 @@ $ docker rm $(docker ps -aq) $ docker rm -f $(docker ps -aq) ``` + #### 按条件删除 ```bash @@ -158,6 +161,7 @@ $ docker container prune -f $ docker system prune -f ``` + #### 生产环境 ```bash @@ -171,6 +175,7 @@ $ docker run --rm ubuntu echo "Hello" $ docker container prune --filter "until=168h" # 保留 7 天内的 ``` + #### 完整清理脚本 ```bash @@ -212,6 +217,7 @@ $ docker rm mycontainer $ docker rm -f mycontainer ``` + #### Q:删除后磁盘空间没释放 可能原因: diff --git a/06_repository/6.1_dockerhub.md b/06_repository/6.1_dockerhub.md index b15a2f1..81f364d 100644 --- a/06_repository/6.1_dockerhub.md +++ b/06_repository/6.1_dockerhub.md @@ -37,6 +37,7 @@ centos The official build of CentOS. 7000+ [OK] ```bash $ docker pull nginx:alpine ``` + #### 3. 推送镜像 需要先登录: @@ -108,6 +109,7 @@ $ docker push username/myapp:v1 ```bash $ echo "dckr_pat_xxxxxxx" | docker login --username username --password-stdin ``` + #### 3. 关注镜像漏洞 Docker Hub 会对官方镜像和付费用户的镜像进行安全扫描。在镜像标签页可以看到漏洞扫描结果。 diff --git a/06_repository/6.2_registry.md b/06_repository/6.2_registry.md index 3c1f2dc..4f91d3c 100644 --- a/06_repository/6.2_registry.md +++ b/06_repository/6.2_registry.md @@ -25,6 +25,7 @@ $ docker run -d \ -v /opt/data/registry:/var/lib/registry \ registry ``` + ### 6.2.2 在私有仓库上传、搜索、下载镜像 创建好私有仓库之后,就可以使用 `docker tag` 来标记一个镜像,然后推送它到仓库。例如私有仓库地址为 `127.0.0.1:5000`。 @@ -86,6 +87,7 @@ $ docker image ls REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 127.0.0.1:5000/ubuntu:latest latest ba5877dc9bec 6 weeks ago 192.7 MB ``` + ### 6.2.3 配置非 https 仓库地址 如果你不想使用 `127.0.0.1:5000` 作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。你就得把例如 `192.168.199.100:5000` 这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。 diff --git a/06_repository/6.3_registry_auth.md b/06_repository/6.3_registry_auth.md index e06979f..5f2b0f0 100644 --- a/06_repository/6.3_registry_auth.md +++ b/06_repository/6.3_registry_auth.md @@ -114,6 +114,7 @@ health: interval: 10s threshold: 3 ``` + ### 6.3.3 生成 http 认证文件 ```bash @@ -143,6 +144,7 @@ services: volumes: registry-data: ``` + ### 6.3.5 修改 Hosts 文件 编辑 `/etc/hosts` @@ -150,6 +152,7 @@ volumes: ```bash 127.0.0.1 docker.domain.com ``` + ### 6.3.6 启动 ```bash diff --git a/06_repository/6.4_nexus3_registry.md b/06_repository/6.4_nexus3_registry.md index d0dfad9..9406152 100644 --- a/06_repository/6.4_nexus3_registry.md +++ b/06_repository/6.4_nexus3_registry.md @@ -107,6 +107,7 @@ server { error_page 500 502 503 504 /50x.html; } ``` + ### 6.4.5 Docker 主机访问镜像仓库 如果不启用 SSL 加密可以通过[前面章节](6.2_registry.md)的方法添加非 https 仓库地址到 Docker 的配置文件中然后重启 Docker。 diff --git a/07_dockerfile/7.10_workdir.md b/07_dockerfile/7.10_workdir.md index 1645132..b2956a2 100644 --- a/07_dockerfile/7.10_workdir.md +++ b/07_dockerfile/7.10_workdir.md @@ -30,6 +30,7 @@ COPY . . # 复制到 /app/ RUN cd /app RUN echo "hello" > world.txt # 文件在根目录! ``` + #### 原因分析 ```dockerfile @@ -110,6 +111,7 @@ RUN npm install COPY . . CMD ["node", "server.js"] ``` + #### 2. 使用绝对路径 ```docker @@ -121,6 +123,7 @@ WORKDIR /app WORKDIR app ``` + #### 3. 不要用 RUN cd ```docker @@ -133,6 +136,7 @@ RUN cd /app && echo "hello" > world.txt WORKDIR /app RUN echo "hello" > world.txt ``` + #### 4. 适时重置 WORKDIR ```docker diff --git a/07_dockerfile/7.11_user.md b/07_dockerfile/7.11_user.md index f49df69..62b07cc 100644 --- a/07_dockerfile/7.11_user.md +++ b/07_dockerfile/7.11_user.md @@ -55,6 +55,7 @@ USER appuser CMD ["node", "server.js"] ``` + #### 使用 UID/GID ```docker @@ -80,6 +81,7 @@ USER nonexistent RUN useradd -r -s /bin/false appuser USER appuser ``` + #### 创建用户的方式 **Debian/Ubuntu**: @@ -139,6 +141,7 @@ chown -R redis:redis /data exec gosu redis "$@" ``` + #### 为什么不用 su/sudo | 问题 | su/sudo | gosu | @@ -208,6 +211,7 @@ CMD ["myapp"] CMD ["myapp"] # 以 root 运行 ``` + #### 2. 使用固定 UID/GID 便于在宿主机和容器间共享文件: @@ -219,6 +223,7 @@ RUN addgroup -g 1000 -S appgroup && \ adduser -u 1000 -S -G appgroup appuser USER 1000:1000 ``` + #### 3. 多阶段构建中的 USER ```docker @@ -252,6 +257,7 @@ permission denied: '/app/data.log' ```docker RUN mkdir -p /app/data && chown appuser:appuser /app/data ``` + #### Q:无法绑定低于 1024 的端口 非 root 用户无法绑定 80、443 等端口。 diff --git a/07_dockerfile/7.12_healthcheck.md b/07_dockerfile/7.12_healthcheck.md index 0598474..e71945a 100644 --- a/07_dockerfile/7.12_healthcheck.md +++ b/07_dockerfile/7.12_healthcheck.md @@ -40,6 +40,7 @@ RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ CMD curl -fs http://localhost/ || exit 1 ``` + #### 命令返回值 - `0`:成功 (healthy) @@ -82,6 +83,7 @@ HEALTHCHECK CMD curl -f http://localhost/ || exit 1 HEALTHCHECK CMD wget -q --spider http://localhost/ || exit 1 ``` + #### 数据库 ```docker @@ -93,6 +95,7 @@ HEALTHCHECK CMD mysqladmin ping -h localhost || exit 1 HEALTHCHECK CMD redis-cli ping || exit 1 ``` + #### 自定义脚本 ```docker @@ -178,6 +181,7 @@ $ docker inspect --format '{{json .State.Health}}' mycontainer | jq HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1 ``` + #### 4. 只检查核心依赖 健康检查应主要关注 **当前服务** 是否可用,而不是检查其下游依赖 (数据库等)。下游依赖的检查应由应用逻辑处理。 diff --git a/07_dockerfile/7.13_onbuild.md b/07_dockerfile/7.13_onbuild.md index 8c8fe3f..6d9875e 100644 --- a/07_dockerfile/7.13_onbuild.md +++ b/07_dockerfile/7.13_onbuild.md @@ -76,6 +76,7 @@ FROM 基础镜像 ──build──> 读取基础镜像触发器 ──> 执行 ONBUILD COPY requirements.txt ./ ONBUILD RUN pip install -r requirements.txt ``` + #### 2. 自动编译代码 ```docker @@ -84,6 +85,7 @@ ONBUILD RUN pip install -r requirements.txt ONBUILD COPY . . ONBUILD RUN go build -o app main.go ``` + #### 3. 处理静态资源 ```docker @@ -127,6 +129,7 @@ ONBUILD COPY dist/ /usr/share/nginx/html/ node:20-onbuild python:3.12-onbuild ``` + #### 2. 避免执行耗时操作 尽量不要在 `ONBUILD` 中执行过于耗时或不确定的操作 (如更新系统软件),这会让子镜像构建变得缓慢且不可控。 diff --git a/07_dockerfile/7.14_label.md b/07_dockerfile/7.14_label.md index 4517a8d..c7a7303 100644 --- a/07_dockerfile/7.14_label.md +++ b/07_dockerfile/7.14_label.md @@ -26,6 +26,7 @@ LABEL = = ... LABEL version="1.0" LABEL description="这是一个 Web 应用服务器" ``` + #### 定义多个标签:推荐 ```docker @@ -119,6 +120,7 @@ $ docker inspect nginx --format '{{json .Config.Labels}}' | jq "maintainer": "NGINX Docker Maintainers " } ``` + #### 过滤器 可以使用标签过滤镜像: diff --git a/07_dockerfile/7.15_shell.md b/07_dockerfile/7.15_shell.md index c953aca..d3b2c2b 100644 --- a/07_dockerfile/7.15_shell.md +++ b/07_dockerfile/7.15_shell.md @@ -31,6 +31,7 @@ SHELL ["/bin/bash", "-c"] RUN echo {a..z} ``` + #### 2. 增强错误处理 默认情况下,管道命令 `cmd1 | cmd2` 只要 `cmd2` 成功,整个指令就视为成功。这可能掩盖构建错误。 @@ -51,6 +52,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN wget -O - https://invalid-url | tar xz ``` + #### 3. Windows 环境 在 Windows 容器中,经常需要在 `cmd` 和 `powershell` 之间切换。 @@ -122,6 +124,7 @@ RUN echo "Using sh again" ```docker SHELL ["/bin/bash", "-o", "pipefail", "-c"] ``` + #### 2. 明确意图 如果由于脚本需求必须更改 shell,最好在 Dockerfile 中显式声明,而不是依赖默认行为。 diff --git a/07_dockerfile/7.17_multistage_builds.md b/07_dockerfile/7.17_multistage_builds.md index 5b59282..49e5ad4 100644 --- a/07_dockerfile/7.17_multistage_builds.md +++ b/07_dockerfile/7.17_multistage_builds.md @@ -46,6 +46,7 @@ CMD ["./app"] ```bash $ docker build -t go/helloworld:1 -f Dockerfile.one . ``` + ### 7.17.2 分散到多个 Dockerfile 另一种方式,就是我们事先在一个 `Dockerfile` 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 `Dockerfile` 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。 @@ -110,6 +111,7 @@ REPOSITORY TAG IMAGE ID CREATED SIZE go/helloworld 2 f7cf3465432c 22 seconds ago 6.47MB go/helloworld 1 f55d3e16affc 2 minutes ago 295MB ``` + ### 7.17.3 使用多阶段构建 为解决以上问题,Docker v17.05 开始支持多阶段构建 (`multistage builds`)。使用多阶段构建我们就可以很容易解决前面提到的问题,并且只需要编写一个 `Dockerfile`: @@ -168,6 +170,7 @@ FROM golang:alpine as builder ```bash $ docker build --target builder -t username/imagename:tag . ``` + ### 7.17.5 构建时从其他镜像复制文件 上面例子中我们使用 `COPY --from=0 /go/src/github.com/go/helloworld/app .` 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。 diff --git a/07_dockerfile/7.18_multistage_builds_laravel.md b/07_dockerfile/7.18_multistage_builds_laravel.md index 7374604..c4b9649 100644 --- a/07_dockerfile/7.18_multistage_builds_laravel.md +++ b/07_dockerfile/7.18_multistage_builds_laravel.md @@ -54,6 +54,7 @@ server { } } ``` + ### 7.18.2 前端构建 第一阶段进行前端构建。 @@ -74,6 +75,7 @@ RUN set -x ; cd /app \ && mkdir -p public \ && npm run production ``` + ### 7.18.3 安装 Composer 依赖 第二阶段安装 Composer 依赖。 @@ -93,6 +95,7 @@ RUN set -x ; cd /app \ --no-scripts \ --prefer-dist ``` + ### 7.18.4 整合以上阶段所生成的文件 第三阶段对以上阶段生成的文件进行整合。 @@ -118,6 +121,7 @@ RUN set -x ; cd ${LARAVEL_PATH} \ && chmod -R 777 storage \ && php artisan package:discover ``` + ### 7.18.5 最后一个阶段构建 NGINX 镜像 ```docker @@ -128,6 +132,7 @@ ARG LARAVEL_PATH=/app/laravel COPY laravel.conf /etc/nginx/conf.d/ COPY --from=laravel ${LARAVEL_PATH}/public ${LARAVEL_PATH}/public ``` + ### 7.18.6 构建 Laravel 及 Nginx 镜像 使用 `docker build` 命令构建镜像。 @@ -137,6 +142,7 @@ $ docker build -t my/laravel --target=laravel . $ docker build -t my/nginx --target=nginx . ``` + ### 7.18.7 启动容器并测试 新建 Docker 网络 diff --git a/07_dockerfile/7.1_run.md b/07_dockerfile/7.1_run.md index 03acf58..5308458 100644 --- a/07_dockerfile/7.1_run.md +++ b/07_dockerfile/7.1_run.md @@ -55,6 +55,7 @@ RUN apt-get update && \ apt-get install -y nginx && \ rm -rf /var/lib/apt/lists/* ``` + #### 2. 清理缓存 在安装完软件后,立即清除缓存,可以显著减小镜像体积。 @@ -103,6 +104,7 @@ RUN touch hello.txt WORKDIR /app RUN touch hello.txt ``` + #### Q:环境变量不生效? ```docker @@ -136,6 +138,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ RUN --mount=type=cache,target=/go/pkg/mod \ go build -o app ``` + #### 2. 挂载密钥 安全地使用 SSH 密钥或 Token,而不将其记录在镜像中。 diff --git a/07_dockerfile/7.2_copy.md b/07_dockerfile/7.2_copy.md index 84f813f..699e5de 100644 --- a/07_dockerfile/7.2_copy.md +++ b/07_dockerfile/7.2_copy.md @@ -23,6 +23,7 @@ COPY package.json /app/ COPY config.json /app/settings.json ``` + #### 复制多个文件 ```docker @@ -35,6 +36,7 @@ COPY package.json package-lock.json /app/ COPY *.json /app/ COPY src/*.js /app/src/ ``` + #### 复制目录 ```docker @@ -77,6 +79,7 @@ COPY app[0-9].js /app/ # app0.js ~ app9.js ```docker COPY app.js /usr/src/app/ ``` + #### 相对路径:基于 WORKDIR ```docker @@ -84,6 +87,7 @@ WORKDIR /app COPY package.json ./ # 复制到 /app/package.json COPY src/ ./src/ # 复制到 /app/src/ ``` + #### 自动创建目录 如果目标目录不存在,Docker 会自动创建: @@ -174,6 +178,7 @@ RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html ``` + #### 使用 --link 优化缓存 ```docker @@ -227,6 +232,7 @@ COPY . . COPY . . RUN npm install ``` + #### 2. 使用 .dockerignore ```docker @@ -238,6 +244,7 @@ COPY . . ... ``` + #### 3. 明确复制路径 ```docker diff --git a/07_dockerfile/7.3_add.md b/07_dockerfile/7.3_add.md index ac951de..d604063 100644 --- a/07_dockerfile/7.3_add.md +++ b/07_dockerfile/7.3_add.md @@ -51,6 +51,7 @@ ADD 会识别并解压以下格式: FROM scratch ADD ubuntu-noble-core-cloudimg-amd64-root.tar.gz / ``` + #### 解压过程 ```bash @@ -76,6 +77,7 @@ app.tar.gz 包含: /app/ 目录结果: ADD https://example.com/app.zip /app/app.zip ``` + #### 为什么不推荐 | 问题 | 说明 | @@ -127,6 +129,7 @@ ADD rootfs.tar.gz / ADD dist.tar.gz /app/ ``` + #### ❌ 不适合使用 ADD ```docker @@ -180,6 +183,7 @@ ADD app.tar.gz /app/ COPY . /app/ ``` + #### 2. 仅在需要解压时使用 ADD ```docker @@ -187,6 +191,7 @@ COPY . /app/ ADD app.tar.gz /app/ ``` + #### 3. 不要用 ADD 下载文件 ```docker @@ -198,6 +203,7 @@ ADD https://example.com/file.tar.gz /tmp/ RUN curl -fsSL https://example.com/file.tar.gz | tar -xz -C /app ``` + #### 4. 解压后清理 ```docker diff --git a/07_dockerfile/7.4_cmd.md b/07_dockerfile/7.4_cmd.md index 4430d89..ec6f9e4 100644 --- a/07_dockerfile/7.4_cmd.md +++ b/07_dockerfile/7.4_cmd.md @@ -111,6 +111,7 @@ CMD ["/bin/bash"] + cat /etc/os-release CMD service nginx start ``` + #### 原因分析 ```bash @@ -126,6 +127,7 @@ CMD service nginx start ↓ 6. 容器主进程(sh)退出 → 容器停止 ``` + #### 正确做法 ```docker @@ -153,6 +155,7 @@ CMD ["curl", "-s", "http://example.com"] $ docker run myimage # 执行默认命令 $ docker run myimage curl -v ... # 完全覆盖 ``` + #### 搭配 ENTRYPOINT ```docker @@ -182,6 +185,7 @@ CMD ["python", "app.py"] CMD ["sh", "-c", "echo $PATH && python app.py"] ``` + #### 2. 确保应用在前台运行 ```docker @@ -196,6 +200,7 @@ CMD ["java", "-jar", "app.jar"] CMD service nginx start CMD systemctl start nginx ``` + #### 3. 使用双引号 ```docker @@ -207,6 +212,7 @@ CMD ["node", "server.js"] CMD ['node', 'server.js'] ``` + #### 4. 配合 ENTRYPOINT 使用 ```docker @@ -233,6 +239,7 @@ $ docker run myapp --port 9000 CMD ["echo", "first"] CMD ["echo", "second"] # 只有这个生效 ``` + #### Q:如何在 CMD 中使用环境变量? ```docker @@ -244,6 +251,7 @@ CMD echo "Port is $PORT" CMD ["sh", "-c", "echo Port is $PORT"] ``` + #### Q:为什么我的容器不响应 Ctrl+C? 可能是使用了 shell 格式,信号被 sh 吃掉了: diff --git a/07_dockerfile/7.5_entrypoint.md b/07_dockerfile/7.5_entrypoint.md index d9fa714..bf98988 100644 --- a/07_dockerfile/7.5_entrypoint.md +++ b/07_dockerfile/7.5_entrypoint.md @@ -95,6 +95,7 @@ exec: "-i": executable file not found ... ``` + #### 使用 ENTRYPOINT 解决 ```docker @@ -111,6 +112,7 @@ HTTP/1.1 200 OK ... 当前 IP:61.148.226.66 ``` + #### 交互图示 ```bash @@ -160,6 +162,7 @@ fi exec "$@" ``` + #### 工作流程 ```bash @@ -173,6 +176,7 @@ docker-entrypoint.sh redis-server docker-entrypoint.sh bash └─ exec gosu redis redis-server └─ exec bash (以 redis 用户运行) (以 root 用户运行) ``` + #### 关键点 1. **exec “$@”**:用传入的参数替换当前进程,确保信号正确传递 @@ -261,12 +265,14 @@ ENTRYPOINT ["python", "app.py"] ENTRYPOINT python app.py ``` + #### 2. 提供有意义的默认参数 ```docker ENTRYPOINT ["nginx"] CMD ["-g", "daemon off;"] ``` + #### 3. 入口脚本使用 exec ```bash @@ -278,6 +284,7 @@ CMD ["-g", "daemon off;"] exec "$@" ``` + #### 4. 处理信号 确保 ENTRYPOINT 脚本能正确传递信号: diff --git a/07_dockerfile/7.6_env.md b/07_dockerfile/7.6_env.md index be32312..a27e0ac 100644 --- a/07_dockerfile/7.6_env.md +++ b/07_dockerfile/7.6_env.md @@ -21,6 +21,7 @@ ENV = = ... ENV NODE_VERSION 20.10.0 ENV APP_ENV production ``` + #### 设置多个变量 ```docker @@ -53,6 +54,7 @@ WORKDIR $APP_HOME COPY . $APP_HOME ``` + #### 2. 容器运行时使用 ```docker @@ -106,6 +108,7 @@ $ docker run -e APP_ENV=development -e DEBUG=true myimage $ docker run --env-file .env myimage ``` + #### .env 文件格式 ```bash @@ -165,6 +168,7 @@ RUN apt-get install nginx=${NGINX_VERSION} RUN apt-get install nginx=1.25.0 ``` + #### 2. 不要存储敏感信息 ```docker @@ -178,6 +182,7 @@ ENV DB_PASSWORD=secret123 ... ``` + #### 3. 为应用提供合理默认值 ```docker @@ -185,6 +190,7 @@ ENV APP_ENV=production \ APP_PORT=8080 \ LOG_LEVEL=info ``` + #### 4. 使用有意义的变量名 ```docker @@ -215,12 +221,14 @@ CMD ["python", "app.py", "--port", "$PORT"] CMD ["sh", "-c", "python app.py --port $PORT"] ``` + #### Q:如何查看容器的环境变量 ```bash $ docker inspect mycontainer --format '{{json .Config.Env}}' $ docker exec mycontainer env ``` + #### Q:多行 ENV 还是多个 ENV ```docker diff --git a/07_dockerfile/7.7_arg.md b/07_dockerfile/7.7_arg.md index 2d9a615..e0222bb 100644 --- a/07_dockerfile/7.7_arg.md +++ b/07_dockerfile/7.7_arg.md @@ -43,6 +43,7 @@ ARG NODE_VERSION=20 FROM node:${NODE_VERSION}-alpine RUN echo "Using Node.js $NODE_VERSION" ``` + #### 构建时覆盖 ```bash @@ -72,6 +73,7 @@ FROM ${REGISTRY}/${IMAGE_NAME}:20 RUN echo $REGISTRY # 输出空 ``` + #### FROM 之后重新声明 ```docker @@ -84,6 +86,7 @@ FROM node:${NODE_VERSION}-alpine ARG NODE_VERSION RUN echo "Node version: $NODE_VERSION" ``` + #### 多阶段构建中的 ARG ```docker @@ -116,6 +119,7 @@ FROM alpine:${ALPINE_VERSION} ```bash $ docker build --build-arg ALPINE_VERSION=3.18 . ``` + #### 2. 设置软件版本 ```docker @@ -123,6 +127,7 @@ ARG NGINX_VERSION=1.25.0 RUN curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -xz ``` + #### 3. 配置构建环境 ```docker @@ -135,6 +140,7 @@ RUN if [ "$ENABLE_DEBUG" = "true" ]; then \ npm install --production; \ fi ``` + #### 4. 配置私有仓库 ```docker @@ -199,6 +205,7 @@ ARG NODE_VERSION=20 ARG NODE_VERSION ``` + #### 2. 不要用 ARG 存储敏感信息 ```docker @@ -211,6 +218,7 @@ RUN echo "password=$DB_PASSWORD" > /app/.env ... ``` + #### 3. 使用 ARG 提高构建灵活性 ```docker diff --git a/07_dockerfile/7.8_volume.md b/07_dockerfile/7.8_volume.md index cbf1e7c..e3d16c0 100644 --- a/07_dockerfile/7.8_volume.md +++ b/07_dockerfile/7.8_volume.md @@ -47,6 +47,7 @@ flowchart LR FROM mysql:8.0 VOLUME /var/lib/mysql ``` + #### 定义多个卷 ```docker @@ -67,6 +68,7 @@ $ docker volume ls DRIVER VOLUME NAME local a1b2c3d4e5f6... # 自动创建的匿名卷 ``` + #### 2. 可被命名卷覆盖 ```bash @@ -74,6 +76,7 @@ local a1b2c3d4e5f6... # 自动创建的匿名卷 $ docker run -v mysql_data:/var/lib/mysql mysql:8.0 ``` + #### 3. 可被 Bind Mount 覆盖 ```bash @@ -120,12 +123,14 @@ VOLUME /data FROM postgres:16 VOLUME /var/lib/postgresql/data ``` + #### 日志目录 ```docker FROM nginx VOLUME /var/log/nginx ``` + #### 上传文件目录 ```docker @@ -212,6 +217,7 @@ $ docker run -v mysql_data:/var/lib/mysql mysql:8.0 FROM postgres:16 VOLUME /var/lib/postgresql/data ``` + #### 2. 不要在 VOLUME 后修改目录 ```docker @@ -225,6 +231,7 @@ RUN cp init-data.json /app/data/ RUN mkdir -p /app/data && cp init-data.json /app/data/ VOLUME /app/data ``` + #### 3. 文档中说明 VOLUME 用途 ```docker diff --git a/07_dockerfile/7.9_expose.md b/07_dockerfile/7.9_expose.md index 67d8211..549a4e2 100644 --- a/07_dockerfile/7.9_expose.md +++ b/07_dockerfile/7.9_expose.md @@ -44,6 +44,7 @@ EXPOSE 80 443 $ docker inspect nginx --format '{{.Config.ExposedPorts}}' map[80/tcp:{}] ``` + #### 2. 配合 -P 使用 使用 `docker run -P` 时,Docker 会自动映射 EXPOSE 的端口到宿主机随机端口: @@ -75,6 +76,7 @@ flowchart TD Run["docker run -p
实际端口映射
宿主机 ←→ 容器"] Expose ~~~ Run ``` + #### 没有 EXPOSE 也能 -p ```docker @@ -145,6 +147,7 @@ EXPOSE 5432 FROM redis EXPOSE 6379 ``` + #### 2. 使用明确的协议 ```docker @@ -160,6 +163,7 @@ EXPOSE 53/udp EXPOSE 53/tcp 53/udp ``` + #### 3. 与应用实际端口保持一致 ```docker diff --git a/08_data/8.1_volume.md b/08_data/8.1_volume.md index 14614c1..66b0614 100644 --- a/08_data/8.1_volume.md +++ b/08_data/8.1_volume.md @@ -41,6 +41,7 @@ graph TD Lifecycle[生命周期 = 容器生命周期] -.-> Container Delete[容器删除] -->|导致| DataLost[数据丢失 ❌] ``` + #### 数据卷:推荐 ```mermaid @@ -65,6 +66,7 @@ graph TD ```bash $ docker volume create my-vol ``` + #### 列出所有数据卷 ```bash @@ -74,6 +76,7 @@ local my-vol local postgres_data local redis_data ``` + #### 查看数据卷详情 ```bash @@ -182,6 +185,7 @@ $ docker run -d \ -v postgres_data:/var/lib/postgresql/data \ postgres:16 ``` + #### 场景二:多容器共享数据 ```bash @@ -201,6 +205,7 @@ $ docker run --rm \ -v shared-data:/data \ alpine cat /data/log.txt ``` + #### 场景三:配置文件持久化 ```bash @@ -227,6 +232,7 @@ $ docker volume rm my-vol $ docker rm -v container_name ``` + #### 清理未使用的数据卷 ```bash @@ -279,6 +285,7 @@ $ docker run --rm \ -v $(pwd):/backup:ro \ alpine tar xzf /backup/my-vol-backup.tar.gz -C /target ``` + #### 备份脚本示例 ```bash @@ -331,6 +338,7 @@ $ docker run -v /host/path:/app/data nginx ```bash $ docker inspect container_name --format '{{json .Mounts}}' | jq ``` + #### Q:数据卷的数据在哪里? ```bash diff --git a/08_data/8.2_bind-mounts.md b/08_data/8.2_bind-mounts.md index 82c0f46..04820b7 100644 --- a/08_data/8.2_bind-mounts.md +++ b/08_data/8.2_bind-mounts.md @@ -58,6 +58,7 @@ $ docker run -d \ --mount type=bind,source=/宿主机路径,target=/容器路径 \ nginx ``` + #### 使用 -v:简写 ```bash @@ -65,6 +66,7 @@ $ docker run -d \ -v /宿主机路径:/容器路径 \ nginx ``` + #### 两种语法对比 | 特性 | --mount | -v | @@ -97,6 +99,7 @@ $ echo "Hello" > src/index.html ... ``` + #### 场景二:配置文件挂载 ```bash @@ -106,6 +109,7 @@ $ docker run -d \ --mount type=bind,source=/path/to/nginx.conf,target=/etc/nginx/nginx.conf,readonly \ nginx ``` + #### 场景三:日志收集 ```bash @@ -115,6 +119,7 @@ $ docker run -d \ --mount type=bind,source=/var/log/myapp,target=/app/logs \ myapp ``` + #### 场景四:共享 SSH 密钥 ```bash @@ -227,6 +232,7 @@ $ docker run -u root ... $ docker run -u $(id -u):$(id -g) ... ``` + #### Q:macOS/Windows 性能问题 在 Docker Desktop 上,Bind Mount 性能较差 (需要跨文件系统同步): @@ -253,6 +259,7 @@ $ docker run -v /host/path:/container/path:cached myapp $ docker run -v $(pwd):/app -p 3000:3000 node npm run dev ``` + #### 2. 生产环境使用 Volume ```bash @@ -260,11 +267,13 @@ $ docker run -v $(pwd):/app -p 3000:3000 node npm run dev $ docker run -v mysql_data:/var/lib/mysql mysql ``` + #### 3. 配置文件使用只读挂载 ```bash $ docker run -v /config/nginx.conf:/etc/nginx/nginx.conf:ro nginx ``` + #### 4. 注意路径安全 ```bash diff --git a/09_network/9.1_dns.md b/09_network/9.1_dns.md index 4ff418c..7a92863 100644 --- a/09_network/9.1_dns.md +++ b/09_network/9.1_dns.md @@ -49,6 +49,7 @@ Docker 守护进程在 `127.0.0.11` 运行了一个 DNS 服务器。容器内的 $ docker run -it --dns=114.114.114.114 ubuntu cat /etc/resolv.conf nameserver 114.114.114.114 ``` + #### 2. --dns-search 指定 DNS 搜索域。例如设置为 `example.com`,则 `ping host` 会尝试解析 `host.example.com`。 @@ -56,6 +57,7 @@ nameserver 114.114.114.114 ```bash $ docker run --dns-search=example.com myapp ``` + #### 3. --hostname 与 -h 设置容器的主机名。 diff --git a/09_network/9.2_network_types.md b/09_network/9.2_network_types.md index 35bdfbd..fd20155 100644 --- a/09_network/9.2_network_types.md +++ b/09_network/9.2_network_types.md @@ -9,6 +9,7 @@ abc123... bridge bridge local def456... host host local ghi789... none null local ``` + ### 9.2.1 网络类型对比 各网络类型的特点和适用场景如下: @@ -52,6 +53,7 @@ $ docker run -it --network none alpine ip addr 1: lo: ... inet 127.0.0.1/8 scope host lo ``` + ### 9.2.5 数据流向 容器网络中的数据流向可以分为以下几种情况: diff --git a/09_network/9.3_custom_network.md b/09_network/9.3_custom_network.md index d778da8..d35d358 100644 --- a/09_network/9.3_custom_network.md +++ b/09_network/9.3_custom_network.md @@ -25,6 +25,7 @@ $ docker network create mynet $ docker network inspect mynet ``` + ### 9.3.3 使用自定义网络 启动容器时通过 `--network` 参数指定连接的网络: @@ -41,6 +42,7 @@ $ docker exec web ping db PING db (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.083 ms ``` + ### 9.3.4 容器名 DNS 解析 自定义网络自动提供 DNS 服务。Docker 守护进程在 `127.0.0.11` 运行了一个嵌入式 DNS 服务器,容器内的 DNS 请求会被转发到这里: @@ -55,6 +57,7 @@ flowchart LR Web["web
172.18.0.2"] -- "DNS: 'db' → 172.18.0.3" --> DB["db
172.18.0.3"] end ``` + ### 9.3.5 常用网络命令 以下是 Docker 网络管理中常用的命令: diff --git a/09_network/9.4_container_linking.md b/09_network/9.4_container_linking.md index 451cf43..59344e7 100644 --- a/09_network/9.4_container_linking.md +++ b/09_network/9.4_container_linking.md @@ -20,6 +20,7 @@ $ docker run -d --name app --network app-net myapp ... ``` + ### 9.4.2 连接到多个网络 一个容器可以同时连接到多个网络,这对于需要跨网络通信的中间件容器特别有用: @@ -37,6 +38,7 @@ $ docker network connect backend multi-net-container $ docker inspect multi-net-container --format '{{json .NetworkSettings.Networks}}' ``` + ### 9.4.3 ⚠️ --link 已废弃 `--link` 是 Docker 早期用于容器互联的方式,**已经被废弃**,不建议在新项目中使用。请使用自定义网络替代: diff --git a/09_network/9.5_port_mapping.md b/09_network/9.5_port_mapping.md index f64cef2..ddea50f 100644 --- a/09_network/9.5_port_mapping.md +++ b/09_network/9.5_port_mapping.md @@ -75,6 +75,7 @@ $ docker port mycontainer 80/tcp -> 0.0.0.0:8080 80/tcp -> [::]:8080 ``` + #### docker ps 运行 `docker ps` 可以查看到所有容器的端口映射列表: @@ -101,6 +102,7 @@ abc123456 nginx 0.0.0.0:8080->80/tcp web $ docker run -d -p 127.0.0.1:3306:3306 mysql ``` + #### 2. 避免端口冲突 如果宿主机 8080 已经被占用了,容器将无法启动。 diff --git a/09_network/9.6_network_isolation.md b/09_network/9.6_network_isolation.md index 7d86be1..3df6fbc 100644 --- a/09_network/9.6_network_isolation.md +++ b/09_network/9.6_network_isolation.md @@ -25,6 +25,7 @@ $ docker run -d --name db --network backend postgres $ docker exec web ping db ping: db: Name or service not known ``` + ### 9.6.2 安全优势 这种隔离机制带来以下安全优势: diff --git a/09_network/9.7_advanced_networking.md b/09_network/9.7_advanced_networking.md index f3ef1a5..8f73005 100644 --- a/09_network/9.7_advanced_networking.md +++ b/09_network/9.7_advanced_networking.md @@ -29,6 +29,7 @@ veth 对 ↓ 容器 B (192.168.0.3,不同宿主机) ``` + #### 创建和使用 Overlay 网络 **Docker Swarm 模式下的 Overlay 网络:** @@ -73,6 +74,7 @@ docker exec container1 curl http://container2 # 检查网络配置 docker network inspect custom-overlay ``` + #### Overlay 网络性能优化 ```bash @@ -107,6 +109,7 @@ networks: driver_opts: com.docker.network.driver.mtu: 1450 ``` + ### 9.7.2 CNI 插件生态概览 容器网络接口(CNI)是容器编排平台(尤其是 Kubernetes)的标准化网络接口。不同的 CNI 插件提供不同的网络能力。 @@ -255,6 +258,7 @@ Docker 内嵌 DNS 服务器 (127.0.0.11) ↓ DNS 响应 → 容器缓存 → 应用 ``` + #### 配置容器 DNS **在运行时指定 DNS:** @@ -317,6 +321,7 @@ networks: "registry-mirrors": ["https://mirror.example.com"] } ``` + #### 自定义服务发现 **使用 Docker 内建 DNS 的服务发现:** @@ -361,6 +366,7 @@ services: # frontend 容器可以直接访问 http://backend:8080 # backend 容器可以直接访问 postgres://database:5432 ``` + #### DNS 性能优化 ```bash @@ -393,6 +399,7 @@ kubectl patch deployment -n kube-system coredns --patch '{ } }' ``` + ### 9.7.4 网络策略实践 网络策略定义了容器间的流量控制规则,是微服务架构中的安全基础。 @@ -473,6 +480,7 @@ spec: - protocol: TCP port: 443 ``` + #### 微服务网络策略示例 ```yaml @@ -597,6 +605,7 @@ spec: - protocol: TCP port: 5432 ``` + #### 使用 Calico/Cilium 的高级网络策略 **L7 应用层策略(仅 Cilium 支持):** @@ -630,6 +639,7 @@ spec: sourceIPs: - "10.0.0.0/8" ``` + ### 9.7.5 跨主机容器通信方案对比 #### 方案对比表 @@ -661,6 +671,7 @@ helm install cilium cilium/cilium --namespace kube-system # 5. 需要多云/跨域:使用 Weave ``` + ### 9.7.6 网络故障排查 **常见网络问题诊断:** diff --git a/10_buildx/10.1_buildkit.md b/10_buildx/10.1_buildkit.md index 85c5c73..449135f 100644 --- a/10_buildx/10.1_buildkit.md +++ b/10_buildx/10.1_buildkit.md @@ -110,6 +110,7 @@ RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \ RUN --mount=type=bind,from=php:alpine,source=/usr/local/bin/docker-php-entrypoint,target=/docker-php-entrypoint \ cat /docker-php-entrypoint ``` + #### `RUN --mount=type=tmpfs` 该指令可以将一个 `tmpfs` 文件系统挂载到指定位置。 @@ -120,6 +121,7 @@ RUN --mount=type=bind,from=php:alpine,source=/usr/local/bin/docker-php-entrypoin RUN --mount=type=tmpfs,target=/temp \ mount | grep /temp ``` + #### `RUN --mount=type=secret` 该指令可以将一个文件 (例如密钥) 挂载到指定位置。 @@ -133,6 +135,7 @@ RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \ ```bash $ docker build -t test --secret id=aws,src=$HOME/.aws/credentials . ``` + #### `RUN --mount=type=ssh` 该指令可以挂载 `ssh` 密钥。 @@ -151,6 +154,7 @@ $ ssh-add ~/.ssh/id_rsa (Input your passphrase here) $ docker build -t test --ssh default=$SSH_AUTH_SOCK . ``` + ### 10.1.2 使用 `docker compose build` 与 BuildKit Docker Compose 同样支持 BuildKit,这使得多服务应用的构建更加高效。 diff --git a/10_buildx/10.2_buildx.md b/10_buildx/10.2_buildx.md index 3adc697..764ae6e 100644 --- a/10_buildx/10.2_buildx.md +++ b/10_buildx/10.2_buildx.md @@ -26,6 +26,7 @@ $ docker buildx bake $ docker buildx bake web ``` + #### 生成 SBOM Buildx 支持在构建时直接生成 SBOM (Software Bill of Materials),这对于软件供应链安全至关重要。 diff --git a/10_buildx/10.3_multi-arch-images.md b/10_buildx/10.3_multi-arch-images.md index afa17ea..1be0715 100644 --- a/10_buildx/10.3_multi-arch-images.md +++ b/10_buildx/10.3_multi-arch-images.md @@ -39,6 +39,7 @@ $ docker manifest inspect hello-world ] } ``` + ### 10.3.2 使用 `docker buildx` 构建多架构镜像 `docker buildx` 是构建多架构镜像的最佳实践工具,它屏蔽了底层的复杂性,提供了一键构建多架构镜像的能力。 @@ -53,6 +54,7 @@ $ docker manifest inspect hello-world $ docker buildx create --name mybuilder --use $ docker buildx inspect --bootstrap ``` + #### 构建和推送 使用 `docker buildx build` 命令并指定 `--platform` 参数,可以同时构建支持多种架构的镜像。`--push` 参数会将构建好的镜像和 manifest list 推送到 Docker 仓库。 @@ -96,6 +98,7 @@ COPY bin/dist-${TARGETOS}-${TARGETARCH} /dist ENTRYPOINT ["/dist"] ``` + ### 10.3.3 使用 `docker manifest`:底层工具 除了 `docker buildx`,我们也可以直接操作 Manifest List 来手动组合不同架构的镜像。 @@ -120,6 +123,7 @@ $ docker manifest create your-username/my-app:latest \ $ docker manifest push your-username/my-app:latest ``` + #### 检查 manifest list 你可以使用 `docker manifest inspect` 来查看一个 manifest list 的详细信息,如上文所示。 diff --git a/11_compose/11.2_install.md b/11_compose/11.2_install.md index be2685e..c62ca72 100644 --- a/11_compose/11.2_install.md +++ b/11_compose/11.2_install.md @@ -30,17 +30,20 @@ $ curl -SL https://github.com/docker/compose/releases/download/v5.1.0/docker-com ```bash $ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose ``` + ### 11.2.2 测试安装 ```bash $ docker compose version Docker Compose version v5.1.0 ``` + ### 11.2.3 bash 补全命令 ```bash $ curl -L https://raw.githubusercontent.com/docker/compose/v5.1.0/contrib/completion/bash/docker-compose | sudo tee /etc/bash_completion.d/docker-compose > /dev/null ``` + ### 11.2.4 卸载 如果是二进制包方式安装的,删除二进制文件即可。 diff --git a/11_compose/11.3_usage.md b/11_compose/11.3_usage.md index f8b330d..c7c140b 100644 --- a/11_compose/11.3_usage.md +++ b/11_compose/11.3_usage.md @@ -37,6 +37,7 @@ def hello(): if __name__ == "__main__": app.run(host="0.0.0.0", debug=True) ``` + #### Dockerfile 编写 `Dockerfile` 文件,内容为 @@ -48,6 +49,7 @@ WORKDIR /code RUN pip install redis flask CMD ["python", "app.py"] ``` + #### compose.yaml 编写 `compose.yaml` 文件,这是 Compose 推荐使用的主模板文件 (也兼容 `docker-compose.yml` 等历史文件名)。 @@ -62,6 +64,7 @@ services: redis: image: "redis:alpine" ``` + #### 运行 compose 项目 ```bash @@ -77,11 +80,13 @@ $ docker compose up ```bash $ docker compose up -d ``` + #### 停止 ```bash $ docker compose stop ``` + #### 进入服务 ```bash @@ -90,31 +95,37 @@ $ docker compose exec redis sh 127.0.0.1:6379> get hits "9" ``` + #### 查看日志 ```bash $ docker compose logs -f ``` + #### 构建镜像 ```bash $ docker compose build ``` + #### 启动服务 ```bash $ docker compose start ``` + #### 运行一次性命令 ```bash $ docker compose run web python app.py ``` + #### 验证 Compose 文件 ```bash $ docker compose config ``` + #### 删除项目 ```bash diff --git a/11_compose/11.4_commands.md b/11_compose/11.4_commands.md index 0734334..4fcd408 100644 --- a/11_compose/11.4_commands.md +++ b/11_compose/11.4_commands.md @@ -13,6 +13,7 @@ Docker Compose 提供了丰富的命令来管理项目和容器。本节将详 ```bash docker compose [-f=...] [options] [COMMAND] [ARGS...] ``` + ### 11.4.2 命令选项 * `-f, --file FILE` 指定使用的 Compose 模板文件。默认会自动识别 `compose.yaml` (也兼容 `docker-compose.yml` 等),并且可以多次指定。 @@ -74,6 +75,7 @@ docker compose [-f=...] [options] [COMMAND] [ARGS...] ```bash $ docker compose kill -s SIGINT ``` + #### `logs` 格式为 `docker compose logs [options] [SERVICE...]`。 diff --git a/11_compose/11.5_compose_file.md b/11_compose/11.5_compose_file.md index c94940b..3ae9ecb 100644 --- a/11_compose/11.5_compose_file.md +++ b/11_compose/11.5_compose_file.md @@ -52,6 +52,7 @@ build: - alpine:latest - corp/web_app:3.14 ``` + ### 11.5.2 `cap_add, cap_drop` 指定容器的内核能力 (capacity) 分配。 @@ -68,6 +69,7 @@ cap_add: cap_drop: - NET_ADMIN ``` + ### 11.5.3 `command` 覆盖容器启动后默认执行的命令。 @@ -75,6 +77,7 @@ cap_drop: ```yaml command: echo "hello world" ``` + ### 11.5.4 `configs` `configs` 来自 Compose Specification。它在 Swarm 中是原生对象;在本地 `docker compose` 模式下通常以文件挂载的形式实现,具体能力取决于 Compose 版本与运行平台。 @@ -88,6 +91,7 @@ command: echo "hello world" ```yaml cgroup_parent: cgroups_1 ``` + ### 11.5.6 `container_name` 指定容器名称。默认将会使用 `项目名称_服务名称_序号` 这样的格式。 @@ -109,6 +113,7 @@ container_name: docker-web-container devices: - "/dev/ttyUSB1:/dev/ttyUSB0" ``` + ### 11.5.9 `depends_on` 解决容器的依赖、启动先后的问题。以下例子中会先启动 `redis` `db` 再启动 `web` @@ -140,6 +145,7 @@ dns: - 8.8.8.8 - 114.114.114.114 ``` + ### 11.5.11 `dns_search` 配置 `DNS` 搜索域。可以是一个值,也可以是一个列表。 @@ -151,6 +157,7 @@ dns_search: - domain1.example.com - domain2.example.com ``` + ### 11.5.12 `tmpfs` 挂载一个 tmpfs 文件系统到容器。 @@ -161,6 +168,7 @@ tmpfs: - /run - /tmp ``` + ### 11.5.13 `env_file` 从文件中获取环境变量,可以为单独的文件路径或列表。 @@ -184,6 +192,7 @@ env_file: PROG_ENV=development ``` + ### 11.5.14 `environment` 设置环境变量。你可以使用数组或字典两种格式。 @@ -204,6 +213,7 @@ environment: ```bash y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF ``` + ### 11.5.15 `expose` 暴露端口,但不映射到宿主机,只被连接的服务访问。 @@ -215,6 +225,7 @@ expose: - "3000" - "8000" ``` + ### 11.5.16 `external_links` > 注意:不建议使用该指令。 @@ -227,6 +238,7 @@ external_links: - project_db_1:mysql - project_db_1:postgresql ``` + ### 11.5.17 `extra_hosts` 类似 Docker 中的 `--add-host` 参数,指定额外的 host 名称映射信息。 @@ -242,6 +254,7 @@ extra_hosts: 8.8.8.8 googledns 52.1.157.61 dockerhub ``` + ### 11.5.18 `healthcheck` 通过命令检查容器是否健康运行。 @@ -253,6 +266,7 @@ healthcheck: timeout: 10s retries: 3 ``` + ### 11.5.19 `image` 指定为镜像名称或镜像 ID。如果镜像在本地不存在,`Compose` 将会尝试拉取这个镜像。 @@ -262,6 +276,7 @@ image: ubuntu image: orchardup/postgresql image: a4bc65fd ``` + ### 11.5.20 `labels` 为容器添加 Docker 元数据 (metadata) 信息。例如可以为容器添加辅助说明信息。 @@ -272,6 +287,7 @@ labels: com.startupteam.department: "devops department" com.startupteam.release: "rc3 for v1.0" ``` + ### 11.5.21 `links` > 注意:不推荐使用该指令。容器之间应通过 Docker 网络 (networks) 进行互联。 @@ -300,6 +316,7 @@ options: max-size: "200k" max-file: "10" ``` + ### 11.5.23 `network_mode` 设置网络模式。使用和 `docker run` 的 `--network` 参数一样的值。 @@ -311,6 +328,7 @@ network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]" ``` + ### 11.5.24 `networks` 配置容器连接的网络。 @@ -327,6 +345,7 @@ networks: some-network: other-network: ``` + ### 11.5.25 `pid` 跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程 ID 来相互访问和操作。 @@ -334,6 +353,7 @@ networks: ```yaml pid: "host" ``` + ### 11.5.26 `ports` 暴露端口信息。 @@ -370,6 +390,7 @@ secrets: my_other_secret: external: true ``` + ### 11.5.28 `security_opt` 指定容器模板标签 (label) 机制的默认属性 (用户、角色、类型、级别等)。例如配置标签的用户名和角色名。 @@ -379,6 +400,7 @@ security_opt: - label:user:USER - label:role:ROLE ``` + ### 11.5.29 `stop_signal` 设置另一个信号来停止容器。在默认情况下使用的是 SIGTERM 停止容器。 @@ -386,6 +408,7 @@ security_opt: ```yaml stop_signal: SIGUSR1 ``` + ### 11.5.30 `sysctls` 配置容器内核参数。 @@ -399,6 +422,7 @@ sysctls: - net.core.somaxconn=1024 - net.ipv4.tcp_syncookies=0 ``` + ### 11.5.31 `ulimits` 指定容器的 ulimits 限制值。 @@ -412,6 +436,7 @@ sysctls: soft: 20000 hard: 40000 ``` + ### 11.5.32 `volumes` 数据卷所挂载路径设置。可以设置为宿主机路径 (`HOST:CONTAINER`) 或者数据卷名称 (`VOLUME:CONTAINER`),并且可以设置访问模式 (`HOST:CONTAINER:ro`)。 @@ -436,6 +461,7 @@ services: volumes: mysql_data: ``` + ### 11.5.33 其它指令 此外,还有包括 `domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir` 等指令,基本跟 `docker run` 中对应参数的功能一致。 @@ -487,6 +513,7 @@ stdin_open: true ```yaml tty: true ``` + ### 11.5.34 读取变量 Compose 模板文件支持动态读取主机的系统环境变量和当前目录下的 `.env` 文件中的变量。 diff --git a/11_compose/11.6_django.md b/11_compose/11.6_django.md index 2f3e281..13e6820 100644 --- a/11_compose/11.6_django.md +++ b/11_compose/11.6_django.md @@ -298,6 +298,7 @@ $ docker compose exec db psql -U django_user -d django_db $ docker compose ps $ docker compose logs db ``` + #### Q2:代码修改没有生效 **可能原因**: @@ -313,6 +314,7 @@ $ docker compose logs db $ sudo chown -R $USER:$USER . ``` + ### 11.6.11 开发 vs 生产:关键差异 笔者特别提醒,本节的配置是 **开发环境** 配置。生产环境需要以下调整: @@ -340,6 +342,7 @@ services: # ... ``` + ### 11.6.12 延伸阅读 - [Compose 模板文件详解](11.5_compose_file.md):深入理解 Compose 文件的所有配置项 diff --git a/11_compose/11.7_rails.md b/11_compose/11.7_rails.md index 208b536..4e09869 100644 --- a/11_compose/11.7_rails.md +++ b/11_compose/11.7_rails.md @@ -88,6 +88,7 @@ gem 'rails', '~> 7.1' ```bash $ touch Gemfile.lock ``` + ### 11.7.5 步骤 3:创建 compose.yaml 配置如下: @@ -157,6 +158,7 @@ compose.yaml bin db public ```bash $ docker compose build ``` + ### 11.7.8 步骤 6:配置数据库连接 修改 `config/database.yml`: @@ -196,6 +198,7 @@ web-1 | => Run `bin/rails server --help` for more startup options web-1 | Puma starting in single mode... web-1 | * Listening on http://0.0.0.0:3000 ``` + ### 11.7.10 步骤 8:创建数据库 在另一个终端执行: @@ -230,6 +233,7 @@ $ docker compose exec web rails generate scaffold Post title:string body:text $ docker compose exec web bash ``` + ### 11.7.12 常见问题 #### Q:数据库连接失败 @@ -240,6 +244,7 @@ $ docker compose exec web bash $ docker compose ps $ docker compose logs db ``` + #### Q:server.pid 文件导致启动失败 错误信息:`A server is already running` @@ -249,6 +254,7 @@ $ docker compose logs db ```bash $ docker compose exec web rm -f tmp/pids/server.pid ``` + #### Q:Gem 安装失败 可能需要更新 bundler 或清理缓存: @@ -256,6 +262,7 @@ $ docker compose exec web rm -f tmp/pids/server.pid ```bash $ docker compose run --rm web bundle update ``` + ### 11.7.13 开发 vs 生产 | 配置项 | 开发环境 | 生产环境 | diff --git a/11_compose/11.8_wordpress.md b/11_compose/11.8_wordpress.md index 79d1672..4749fe5 100644 --- a/11_compose/11.8_wordpress.md +++ b/11_compose/11.8_wordpress.md @@ -154,6 +154,7 @@ $ docker exec wordpress_db mysqldump -u wordpress -pwordpress wordpress > backup networks: - wp_net ``` + #### 2. 使用 Nginx 反向代理 在生产环境中,不要直接暴露 WordPress 端口,而是通过 Nginx 进行反向代理并配置 SSL。 diff --git a/12_implementation/12.2_namespace.md b/12_implementation/12.2_namespace.md index 9a82663..d837ada 100644 --- a/12_implementation/12.2_namespace.md +++ b/12_implementation/12.2_namespace.md @@ -25,6 +25,7 @@ flowchart LR H4 -. "(实际是宿主机的 1234)" .- C1 ``` + ### 12.2.2 Namespace 的类型 Linux 内核提供了以下几种 Namespace,Docker 容器使用了全部: @@ -65,6 +66,7 @@ PID USER COMMAND 1 root nginx: master process ← 在容器内是 PID 1 2 root nginx: worker process ``` + #### PID 关键点 - 容器内的 PID 1 进程特殊重要——它是容器的主进程,退出则容器停止 @@ -99,6 +101,7 @@ flowchart LR H2 <--> C2 ``` + #### NET 关键点 - 每个容器有独立的网卡、IP、路由表、iptables 规则 @@ -129,6 +132,7 @@ MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的 │ └── merged/ ────┼─── 这个目录成为容器的 / └── ... └── ... ``` + #### 与 chroot 的区别 | 特性 | chroot | MNT Namespace | @@ -212,6 +216,7 @@ flowchart LR C1 -- 映射 --> H1 C2 -- 映射 --> H2 ``` + #### 安全意义 容器内的 root 用户可以映射为宿主机上的普通用户,即使容器被突破,攻击者在宿主机上也只有普通权限。 @@ -243,6 +248,7 @@ $ exit $ hostname my-server ``` + #### 实验 2:PID Namespace ```bash @@ -261,6 +267,7 @@ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 8960 4516 pts/0 S 10:00 0:00 /bin/bash root 8 0.0 0.0 10072 3200 pts/0 R+ 10:00 0:00 ps aux ``` + #### 实验 3:NET Namespace ```bash diff --git a/12_implementation/12.3_cgroups.md b/12_implementation/12.3_cgroups.md index 25e8663..422c7e8 100644 --- a/12_implementation/12.3_cgroups.md +++ b/12_implementation/12.3_cgroups.md @@ -117,6 +117,7 @@ $ docker run --device-read-bps /dev/sda:10mb myapp $ docker run --device-write-iops /dev/sda:100 myapp ``` + #### 进程数限制 ```bash @@ -165,6 +166,7 @@ abc123 Exited (137) 5 seconds ago hopeful_darwin ... ``` + #### CPU 限制验证 ```bash @@ -253,11 +255,13 @@ services: $ docker run -m 1g myapp ``` + #### 2. 为关键应用设置 CPU 保证 ```bash $ docker run --cpus=2 --cpu-shares=2048 critical-app ``` + #### 3. 监控资源使用 ```bash diff --git a/12_implementation/12.4_ufs.md b/12_implementation/12.4_ufs.md index 40d2a7e..06040eb 100644 --- a/12_implementation/12.4_ufs.md +++ b/12_implementation/12.4_ufs.md @@ -197,6 +197,7 @@ RUN apt-get update && \ apt-get install -y nginx && \ rm -rf /var/lib/apt/lists/* ``` + #### 2. 避免在容器中写入大量数据 容器层的写入性能低于直接写入。大量数据应使用: diff --git a/13_kubernetes_concepts/13.2_concepts.md b/13_kubernetes_concepts/13.2_concepts.md index 771e33f..91e8ec7 100644 --- a/13_kubernetes_concepts/13.2_concepts.md +++ b/13_kubernetes_concepts/13.2_concepts.md @@ -65,6 +65,7 @@ status: - type: Ready status: "True" ``` + #### 节点控制器 在 Kubernetes 控制平面中,节点控制器 (Node Controller) 负责管理节点的生命周期,主要包含: @@ -81,6 +82,7 @@ $ kubectl cordon worker-1 ## 排空节点上的 Pod $ kubectl drain worker-1 --ignore-daemonsets ``` + ### 13.2.2 容器组 在 Kubernetes 中,使用的最小调度单位是容器组 (Pod),它是创建、调度、管理的最小单位。一个 Pod 包含一个或多个紧密协作的容器,它们共享网络命名空间和存储卷。 diff --git a/13_kubernetes_concepts/13.4_advanced.md b/13_kubernetes_concepts/13.4_advanced.md index 8a7b46f..9b6d967 100644 --- a/13_kubernetes_concepts/13.4_advanced.md +++ b/13_kubernetes_concepts/13.4_advanced.md @@ -52,6 +52,7 @@ spec: type: Utilization averageUtilization: 50 ``` + ### 13.4.5 ConfigMap 与 Secret * **ConfigMap**:存储非机密的配置数据 (配置文件、环境变量)。 diff --git a/13_kubernetes_concepts/13.5_practice.md b/13_kubernetes_concepts/13.5_practice.md index aae23d5..46de7df 100644 --- a/13_kubernetes_concepts/13.5_practice.md +++ b/13_kubernetes_concepts/13.5_practice.md @@ -40,6 +40,7 @@ spec: ```bash kubectl apply -f nginx-deployment.yaml ``` + ### 13.5.3 步骤 2:创建 Service 创建一个名为 `nginx-service.yaml` 的文件: @@ -82,6 +83,7 @@ kubectl apply -f nginx-deployment.yaml ```bash kubectl rollout status deployment/nginx-deployment ``` + ### 13.5.5 步骤 4:清理资源 练习结束后,记得清理资源: diff --git a/14_kubernetes_setup/14.1_kubeadm.md b/14_kubernetes_setup/14.1_kubeadm.md index 7872a82..634b807 100644 --- a/14_kubernetes_setup/14.1_kubeadm.md +++ b/14_kubernetes_setup/14.1_kubeadm.md @@ -17,6 +17,7 @@ $ sudo apt install containerd.io $ sudo yum install containerd.io ``` + ### 14.1.2 配置 containerd 新建 `/etc/systemd/system/cri-containerd.service` 文件 @@ -230,6 +231,7 @@ oom_score = 0 base_image_size = "" async_remove = false ``` + ### 14.1.3 安装 **kubelet**、**kubeadm**、**kubectl**、**cri-tools**、**kubernetes-cni** 需要在每台机器上安装以下的软件包: @@ -253,6 +255,7 @@ $ sudo apt-get install -y kubelet kubeadm kubectl cri-tools kubernetes-cni $ sudo apt-mark hold kubelet kubeadm kubectl ``` + #### CentOS/Fedora ```bash @@ -270,6 +273,7 @@ EOF $ sudo yum install -y kubelet kubeadm kubectl cri-tools kubernetes-cni ``` + ### 14.1.4 修改内核的运行参数 #### 加载内核模块 @@ -283,6 +287,7 @@ EOF $ sudo modprobe overlay $ sudo modprobe br_netfilter ``` + #### 禁用 swap:必须 kubelet 默认要求禁用 swap,否则可能导致初始化失败或节点无法加入集群。 @@ -303,6 +308,7 @@ EOF $ sysctl --system ``` + ### 14.1.5 配置 kubelet 为了让 kubelet 正确运行,我们需要对其进行一些必要的配置。 @@ -325,6 +331,7 @@ ExecStartPre=-/sbin/modprobe ip_vs_sh ```bash $ sudo systemctl daemon-reload ``` + ### 14.1.6 部署 安装配置完成后,我们将分别在 Master 节点和 Worker 节点上进行部署操作。 @@ -373,6 +380,7 @@ Then you can join any number of worker nodes by running the following on each as kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe ``` + #### node 工作节点 在 **另一主机** 重复 **部署** 小节以前的步骤,安装配置好 kubelet。根据提示,加入到集群。 @@ -387,6 +395,7 @@ $ kubeadm join 192.168.199.100:6443 \ --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe \ --cri-socket /run/cri-containerd/cri-containerd.sock ``` + ### 14.1.7 查看服务 所有服务启动后,通过 `crictl` 查看本地实际运行的容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 @@ -394,6 +403,7 @@ $ kubeadm join 192.168.199.100:6443 \ ```bash CONTAINER_RUNTIME_ENDPOINT=/run/cri-containerd/cri-containerd.sock crictl ps -a ``` + #### 主节点服务 * `apiserver` 是整个系统的对外接口,提供 RESTful 方式供客户端和其它组件调用; @@ -437,6 +447,7 @@ $ kubectl get node -o yaml | grep CIDR ```bash $ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.28.1/Documentation/kube-flannel.yml ``` + ### 14.1.10 master 节点默认不能运行 pod 如果用 `kubeadm` 部署一个单节点集群,默认情况下无法使用,请执行以下命令解除限制 @@ -454,6 +465,7 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master- ... ``` + ### 14.1.11 参考文档 * [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) diff --git a/14_kubernetes_setup/14.2_kubeadm-docker.md b/14_kubernetes_setup/14.2_kubeadm-docker.md index d7d987c..fd080f8 100644 --- a/14_kubernetes_setup/14.2_kubeadm-docker.md +++ b/14_kubernetes_setup/14.2_kubeadm-docker.md @@ -44,6 +44,7 @@ $ sudo systemctl start cri-docker $ sudo /usr/local/bin/cri-dockerd --version ``` + #### CentOS/Fedora ```bash @@ -66,6 +67,7 @@ $ sudo systemctl daemon-reload $ sudo systemctl enable cri-docker $ sudo systemctl start cri-docker ``` + ### 14.2.3 安装 **kubelet**、**kubeadm**、**kubectl** 需要在每台机器上安装以下的软件包: @@ -89,6 +91,7 @@ $ sudo apt-get install -y kubelet kubeadm kubectl $ sudo apt-mark hold kubelet kubeadm kubectl ``` + #### CentOS/Fedora ```bash @@ -106,6 +109,7 @@ EOF $ sudo yum install -y kubelet kubeadm kubectl ``` + ### 14.2.4 修改内核的运行参数 #### 加载内核模块 @@ -119,6 +123,7 @@ EOF $ sudo modprobe overlay $ sudo modprobe br_netfilter ``` + #### 禁用 swap:必须 kubelet 默认要求禁用 swap,否则可能导致初始化失败或节点无法加入集群。 @@ -139,6 +144,7 @@ EOF $ sysctl --system ``` + ### 14.2.5 配置 kubelet 为了让 kubelet 正确运行,我们需要对其进行一些必要的配置。 @@ -161,6 +167,7 @@ ExecStartPre=-/sbin/modprobe ip_vs_sh ```bash $ sudo systemctl daemon-reload ``` + ### 14.2.6 部署 安装配置完成后,我们将分别在 Master 节点和 Worker 节点上进行部署操作。 @@ -205,6 +212,7 @@ Then you can join any number of worker nodes by running the following on each as kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe ``` + #### node 工作节点 在 **另一主机** 重复 **部署** 小节以前的步骤,安装配置好 kubelet。根据提示,加入到集群。 @@ -213,6 +221,7 @@ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ $ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe ``` + ### 14.2.7 查看服务 所有服务启动后,查看本地实际运行的 Docker 容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 @@ -260,6 +269,7 @@ $ kubectl get node -o yaml | grep CIDR ```bash $ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.28.1/Documentation/kube-flannel.yml ``` + ### 14.2.10 master 节点默认不能运行 pod 如果用 `kubeadm` 部署一个单节点集群,默认情况下无法使用,请执行以下命令解除限制 @@ -277,6 +287,7 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master- ... ``` + ### 14.2.11 参考文档 * [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) diff --git a/14_kubernetes_setup/14.4_kind.md b/14_kubernetes_setup/14.4_kind.md index 645fb02..5e0bf4c 100644 --- a/14_kubernetes_setup/14.4_kind.md +++ b/14_kubernetes_setup/14.4_kind.md @@ -20,6 +20,7 @@ Kind 是一个二进制文件,并在 PATH 中即可使用。以下是不同系 ```bash brew install kind ``` + #### Linux / Windows 可以下载二进制文件: @@ -31,6 +32,7 @@ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind ``` + ### 14.4.3 创建集群 最简单的创建方式: @@ -43,6 +45,7 @@ kind create cluster ```bash kind create cluster --name my-cluster ``` + ### 14.4.4 与集群交互 Kind 会自动将 kubeconfig 合并到 `~/.kube/config`。 @@ -51,6 +54,7 @@ Kind 会自动将 kubeconfig 合并到 `~/.kube/config`。 kubectl cluster-info --context kind-kind kubectl get nodes ``` + ### 14.4.5 高级用法:配置集群 创建一个 `kind-config.yaml` 来定制集群,例如映射端口到宿主机: @@ -72,6 +76,7 @@ nodes: ```bash kind create cluster --config kind-config.yaml ``` + ### 14.4.6 删除集群 ```bash diff --git a/14_kubernetes_setup/14.5_k3s.md b/14_kubernetes_setup/14.5_k3s.md index d82352d..e7c9d88 100644 --- a/14_kubernetes_setup/14.5_k3s.md +++ b/14_kubernetes_setup/14.5_k3s.md @@ -32,6 +32,7 @@ sudo k3s kubectl get nodes NAME STATUS ROLES AGE VERSION k3s-master Ready control-plane,master 1m v1.35.1+k3s1 ``` + ### 14.5.3 快速使用 K3s 内置了 `kubectl` 命令 (通过 `k3s kubectl` 调用),为了方便,通常会建立别名或配置 `KUBECONFIG`。 @@ -45,6 +46,7 @@ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get pods -A ``` + ### 14.5.4 清理卸载 ```bash diff --git a/14_kubernetes_setup/14.6_systemd.md b/14_kubernetes_setup/14.6_systemd.md index 579772a..413a5b1 100644 --- a/14_kubernetes_setup/14.6_systemd.md +++ b/14_kubernetes_setup/14.6_systemd.md @@ -30,6 +30,7 @@ /etc/systemd/system/kube-proxy.service /etc/systemd/system/kube-apiserver.service ``` + #### 常用命令 ```bash @@ -48,6 +49,7 @@ sudo systemctl status kubelet # 设置开机自启 sudo systemctl enable kubelet ``` + ### 参考资源 详细的部署步骤和配置说明,可以参考以下项目: diff --git a/14_kubernetes_setup/14.7_dashboard.md b/14_kubernetes_setup/14.7_dashboard.md index 2789e16..dc630c3 100644 --- a/14_kubernetes_setup/14.7_dashboard.md +++ b/14_kubernetes_setup/14.7_dashboard.md @@ -11,6 +11,7 @@ ```bash kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml ``` + ### 14.7.2 访问 通过命令行代理访问,执行以下命令: diff --git a/14_kubernetes_setup/14.8_kubectl.md b/14_kubernetes_setup/14.8_kubectl.md index 766933f..6a5aee0 100644 --- a/14_kubernetes_setup/14.8_kubectl.md +++ b/14_kubernetes_setup/14.8_kubectl.md @@ -7,6 +7,7 @@ kubectl [flags] kubectl [command] ``` + ### 14.8.1 get 显示一个或多个资源 diff --git a/15_etcd/15.4_etcdctl.md b/15_etcd/15.4_etcdctl.md index 5ed6715..cf639a0 100644 --- a/15_etcd/15.4_etcdctl.md +++ b/15_etcd/15.4_etcdctl.md @@ -80,6 +80,7 @@ OPTIONS: --user="" username[:password] for authentication (prompt if password is not supplied) -w, --write-out="simple" set the output format (fields, json, protobuf, simple, table) ``` + ### 15.4.1 数据库操作 数据库操作围绕对键值和目录的 CRUD (符合 REST 风格的一套操作:Create) 完整生命周期的管理。 @@ -94,6 +95,7 @@ etcd 在键的组织上采用了层次化的空间结构 (类似于文件系统 $ etcdctl put /testdir/testkey "Hello world" OK ``` + #### get 获取指定键的值。例如 @@ -119,6 +121,7 @@ hello $ etcdctl del testkey 1 ``` + ### 15.4.2 非数据库操作 #### watch @@ -133,6 +136,7 @@ PUT testkey 2 ``` + #### member 通过 `list`、`add`、`update`、`remove` 命令列出、添加、更新、删除 etcd 实例到 etcd 集群中。 diff --git a/16_cloud/16.2_tencentCloud.md b/16_cloud/16.2_tencentCloud.md index b14d960..1775d01 100644 --- a/16_cloud/16.2_tencentCloud.md +++ b/16_cloud/16.2_tencentCloud.md @@ -35,6 +35,7 @@ export KUBECONFIG=/path/to/kubeconfig.yaml kubectl cluster-info ``` + #### 2. 部署容器应用 创建 Deployment 部署应用: @@ -67,6 +68,7 @@ kubectl apply -f deployment.yaml kubectl get pods kubectl get svc ``` + #### 3. 管理镜像 通过腾讯云容器镜像服务 (TCR) 存储和管理私有镜像: @@ -81,6 +83,7 @@ docker tag my-app:latest ccr.ccs.tencentyun.com/namespace/my-app:latest # 推送镜像到腾讯云 docker push ccr.ccs.tencentyun.com/namespace/my-app:latest ``` + ### 腾讯云 Docker 镜像加速器配置 为了加快镜像拉取速度,腾讯云提供了镜像加速服务。配置方法如下: @@ -116,6 +119,7 @@ sudo systemctl restart docker # 查看镜像源是否生效 docker info | grep -A 5 "Registry Mirrors" ``` + #### Windows/Mac 配置 对于 Docker Desktop,在设置界面中: @@ -167,6 +171,7 @@ docker push ccr.ccs.tencentyun.com/my-namespace/my-app:v1.0 FROM ccr.ccs.tencentyun.com/my-namespace/my-app:v1.0 RUN echo "使用腾讯云镜像作为基础镜像" ``` + #### TKE 集群中使用 TCR 镜像 配置镜像拉取凭证后,在 Deployment 中直接引用 TCR 镜像: diff --git a/16_cloud/16.3_alicloud.md b/16_cloud/16.3_alicloud.md index 8b84ca9..0c2ae26 100644 --- a/16_cloud/16.3_alicloud.md +++ b/16_cloud/16.3_alicloud.md @@ -37,6 +37,7 @@ export KUBECONFIG=/path/to/kubeconfig.yaml kubectl get nodes ``` + #### 2. 部署容器应用 通过 Deployment 部署应用示例: @@ -73,6 +74,7 @@ kubectl apply -f deployment.yaml kubectl get pods -o wide kubectl logs ``` + #### 3. 暴露服务 创建 Service 暴露应用: @@ -96,6 +98,7 @@ spec: kubectl apply -f service.yaml kubectl get svc web-service ``` + ### 阿里云 Docker 镜像加速器配置 为了加快从阿里云镜像源拉取官方镜像的速度,可以配置镜像加速器。阿里云为容器服务 ACK 用户提供了免费的镜像加速服务。 @@ -132,6 +135,7 @@ sudo systemctl restart docker ```bash docker info | grep -A 5 "Registry Mirrors" ``` + #### Windows/Mac 配置 在 Docker Desktop 的 Settings 中: @@ -146,6 +150,7 @@ docker info | grep -A 5 "Registry Mirrors" docker pull nginx:latest time docker pull alpine:latest ``` + ### 阿里云容器镜像服务:ACR 阿里云容器镜像服务 (ACR, Container Registry) 是企业级的容器镜像存储和分发平台: @@ -183,6 +188,7 @@ FROM registry.cn-hangzhou.aliyuncs.com/myapp/my-app:v1.0 COPY . /app RUN echo "已成功使用阿里云镜像" ``` + #### ACK 集群中使用 ACR 镜像 在 ACK 集群中,需要先配置镜像拉取凭证(Secret),然后在 Deployment 中引用: @@ -233,6 +239,7 @@ spec: - web topologyKey: kubernetes.io/hostname ``` + #### 创建镜像拉取凭证 在 ACK 集群中创建 Secret,用于拉取私有镜像: @@ -249,6 +256,7 @@ kubectl create secret docker-registry acr-secret \ kubectl get secret acr-secret kubectl describe secret acr-secret ``` + #### ACR 优势 - 在 ACK 集群中与镜像仓库无缝集成,简化身份认证 diff --git a/17_ecosystem/17.2_coreos_install.md b/17_ecosystem/17.2_coreos_install.md index d554d1c..0489835 100644 --- a/17_ecosystem/17.2_coreos_install.md +++ b/17_ecosystem/17.2_coreos_install.md @@ -26,6 +26,7 @@ passwd: ```bash $ docker run -i --rm quay.io/coreos/fcct:v0.5.0 --pretty --strict < example.fcc > example.ign ``` + ### 17.2.4 挂载 ISO 启动虚拟机并安装 > 虚拟机需要分配 3GB 以上内存,否则会无法启动。 diff --git a/17_ecosystem/17.3_podman.md b/17_ecosystem/17.3_podman.md index bfaef79..8c5aa41 100644 --- a/17_ecosystem/17.3_podman.md +++ b/17_ecosystem/17.3_podman.md @@ -22,6 +22,7 @@ Podman 支持多种操作系统,安装过程也相对简单。 ```bash $ sudo yum -y install podman ``` + #### macOS macOS 上需要安装 Podman Desktop 或通过 Homebrew 安装: @@ -31,6 +32,7 @@ $ brew install podman $ podman machine init $ podman machine start ``` + ### 17.3.3 基本使用 `podman` 的命令行几乎与 `docker` 完全兼容,大多数情况下,你只需将 `docker` 替换为 `podman` 即可。 @@ -42,16 +44,19 @@ $ podman machine start $ podman run -d -p 80:80 nginx:alpine ``` + #### 列出容器 ```bash $ podman ps ``` + #### 构建镜像 ```bash $ podman build -t myimage . ``` + ### 17.3.4 Pods 的概念 与 Docker 不同,Podman 支持“Pod”的概念 (类似于 Kubernetes 的 Pod),允许你在同一个网络命名空间中运行多个容器。 @@ -65,6 +70,7 @@ $ podman pod create --name mypod -p 8080:80 $ podman run -d --pod mypod --name webbing nginx ``` + ### 17.3.5 迁移到 Podman 如果你习惯使用 `docker` 命令,可以简单地设置别名: @@ -72,6 +78,7 @@ $ podman run -d --pod mypod --name webbing nginx ```bash $ alias docker=podman ``` + #### Systemd 集成 Podman 可以生成 systemd 单元文件,让容器像普通系统服务一样管理。 @@ -89,6 +96,7 @@ $ podman generate systemd --name myweb --files --new $ systemctl --user enable --now container-myweb.service ``` + #### Podman Compose 虽然 Podman 兼容 Docker Compose,但在某些场景下你可能需要明确使用 `podman-compose`。 diff --git a/17_ecosystem/17.4_buildah.md b/17_ecosystem/17.4_buildah.md index c32fd1a..ed7df2d 100644 --- a/17_ecosystem/17.4_buildah.md +++ b/17_ecosystem/17.4_buildah.md @@ -30,6 +30,7 @@ $ sudo dnf install -y buildah $ sudo apt-get update $ sudo apt-get -y install buildah ``` + ### 基础用法示例 #### 1. 从现有的 Dockerfile 构建镜像 diff --git a/17_ecosystem/17.5_skopeo.md b/17_ecosystem/17.5_skopeo.md index dd3c6be..20c2df8 100644 --- a/17_ecosystem/17.5_skopeo.md +++ b/17_ecosystem/17.5_skopeo.md @@ -35,6 +35,7 @@ $ sudo apt-get -y install skopeo ```bash $ brew install skopeo ``` + ### 基础用法示例 #### 1. 远程检查镜像 diff --git a/18_security/18.1_kernel_ns.md b/18_security/18.1_kernel_ns.md index 4048b40..5581be9 100644 --- a/18_security/18.1_kernel_ns.md +++ b/18_security/18.1_kernel_ns.md @@ -60,6 +60,7 @@ dockremap:165536:65536 ```bash $ sudo systemctl restart docker ``` + #### 验证映射效果 我们可以运行一个简单的容器并执行 `sleep` 命令,同时在宿主机上观察进程的所有者: diff --git a/18_security/18.5_other_feature.md b/18_security/18.5_other_feature.md index 4c1f08f..8106a60 100644 --- a/18_security/18.5_other_feature.md +++ b/18_security/18.5_other_feature.md @@ -53,6 +53,7 @@ $ docker run --rm -it \ --security-opt apparmor=custom-nginx-profile \ nginx ``` + ### 18.5.3 容器镜像漏洞静态扫描 现代防护的防御已经不仅仅在运行阶段,而向“左”延伸至了构建与分发时期控制。很多安全隐患并不是用户代码中的直接逻辑异常,而是打包环境或者引入库的基础 `APT` 安装层面潜伏了开源界众所周知的历史漏洞。 diff --git a/18_security/18.6_image_security.md b/18_security/18.6_image_security.md index c63c0ae..3e2605f 100644 --- a/18_security/18.6_image_security.md +++ b/18_security/18.6_image_security.md @@ -41,6 +41,7 @@ trivy image --severity HIGH,CRITICAL \ --exit-code 1 \ myregistry.com/myapp:v1.0.0 ``` + #### Grype - 支持多种软件包的扫描器 Grype 由 Anchore 开发,支持更广泛的软件包管理器和语言。 @@ -67,6 +68,7 @@ grype sbom:sbom.json # 扫描特定目录 grype dir:/path/to/app ``` + #### Snyk - 完整的安全平台 Snyk 提供了商业级的安全扫描服务,特别适合企业环境。 @@ -130,6 +132,7 @@ syft dir:/path/to/app -o json > sbom.json # 从 OCI 镜像档案生成 syft oci-archive:image.tar -o json > sbom.json ``` + #### CycloneDX 与 SPDX 格式 两种主流的 SBOM 格式: @@ -173,6 +176,7 @@ syft oci-archive:image.tar -o json > sbom.json ] } ``` + #### SBOM 的应用场景 **漏洞关联:** @@ -249,6 +253,7 @@ cosign verify myregistry.com/myapp:v1.0.0 \ --certificate-identity https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main \ --certificate-oidc-issuer https://token.actions.githubusercontent.com ``` + #### Docker Content Trust 与 Notary Docker Content Trust 使用 Notary 实现镜像签名,是 Docker 官方的签名解决方案。 @@ -276,6 +281,7 @@ docker push --disable-content-trust myregistry.com/myapp:v1.0.0 # 查看签名信息 docker inspect --format='{{.RepoDigests}}' myregistry.com/myapp:v1.0.0 ``` + ### 18.6.4 供应链安全最佳实践 #### 1. 基础镜像安全 @@ -289,6 +295,7 @@ RUN apt-get update && apt-get install -y curl FROM ubuntu:22.04@sha256:a6d2b38300ce017add71440577d5b0a90460d0e6e0e14...(完整 64 位哈希) RUN apt-get update && apt-get install -y curl=7.68.0-1ubuntu1 ``` + #### 2. 构建时扫描 在 Dockerfile 中集成安全扫描: @@ -308,6 +315,7 @@ RUN go build -o app . FROM alpine:3.17@sha256:abcd1234...(请替换为实际完整的 64 位摘要哈希) COPY --from=builder /app/app /app ``` + #### 3. 运行时镜像扫描策略 ```bash @@ -320,6 +328,7 @@ trivy image --severity HIGH,CRITICAL \ # 定期扫描已部署的镜像 trivy image --scanners vuln,misconfig registry:5000/myapp:latest ``` + #### 4. 镜像仓库安全配置 **Harbor(私有镜像仓库)的安全扫描:** @@ -335,6 +344,7 @@ trivy: scan_on_push: true # 推送时自动扫描 scan_all: true # 扫描仓库中的所有镜像 ``` + #### 5. 政策执行 在 Kubernetes 环境中使用 Admission Webhook 强制镜像签名和扫描: @@ -359,6 +369,7 @@ webhooks: admissionReviewVersions: ["v1"] sideEffects: None ``` + ### 18.6.5 CI/CD 中集成安全扫描 #### GitHub Actions 工作流示例 @@ -445,6 +456,7 @@ jobs: push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest ``` + #### GitLab CI 工作流示例 ```yaml @@ -509,6 +521,7 @@ push: only: - main ``` + ### 18.6.6 常见问题与最佳实践 **Q: 扫描报告中有过时的 CVE,如何处理?** diff --git a/18_security/README.md b/18_security/README.md index 813261d..e014fdf 100644 --- a/18_security/README.md +++ b/18_security/README.md @@ -23,6 +23,7 @@ flowchart LR Proc --> Mech end ``` + ## 本章内容 本章涵盖 Docker 安全的多个层面,从内核隔离机制到运行时防护和供应链安全。 diff --git a/19_observability/19.1_prometheus.md b/19_observability/19.1_prometheus.md index 644be04..8e9862e 100644 --- a/19_observability/19.1_prometheus.md +++ b/19_observability/19.1_prometheus.md @@ -48,6 +48,7 @@ scrape_configs: rule_files: - /etc/prometheus/rules.yml ``` + #### 2. 编写 Docker Compose 文件 创建 `compose.yaml` (或 `docker-compose.yml`): @@ -105,6 +106,7 @@ networks: volumes: prometheus_data: ``` + #### 3. 启动服务 ```bash diff --git a/19_observability/19.2_elk.md b/19_observability/19.2_elk.md index 767549e..352110d 100644 --- a/19_observability/19.2_elk.md +++ b/19_observability/19.2_elk.md @@ -71,6 +71,7 @@ volumes: networks: logging: ``` + #### 2. 配置 Fluentd 创建 `fluentd/conf/fluent.conf`: @@ -101,6 +102,7 @@ networks: ``` + #### 3. 配置应用容器使用 fluentd 驱动 启动一个测试容器,指定日志驱动为 `fluentd`: diff --git a/19_observability/19.3_performance_optimization.md b/19_observability/19.3_performance_optimization.md index 35792e5..bc20b89 100644 --- a/19_observability/19.3_performance_optimization.md +++ b/19_observability/19.3_performance_optimization.md @@ -91,6 +91,7 @@ done # MEM % 接近 100%:容器即将 OOM,需要增加内存或排查内存泄漏 # 如果 NET I/O 中 dropped 为非零:网络拥塞或丢包 ``` + ### 19.3.3 cAdvisor 容器监控系统 cAdvisor 是 Google 开发的容器监控工具,提供比 `docker stats` 更详细的性能数据。 @@ -150,6 +151,7 @@ scrape_configs: - targets: ['localhost:8080'] metrics_path: '/metrics' ``` + ### 19.3.4 Prometheus 容器监控配置 使用 Prometheus 和 node-exporter 进行长期的容器性能监控。 @@ -275,6 +277,7 @@ container_memory_cache_bytes / container_memory_usage_bytes # 按镜像统计容器数 count(container_memory_usage_bytes) by (image) ``` + ### 19.3.5 容器 OOM 排查与内存限制调优 #### OOM 问题诊断 @@ -293,6 +296,7 @@ docker logs 2>&1 | grep -i "out of memory\|oom" dmesg | grep -i "oom\|kill" journalctl -u docker -n 100 | grep -i "oom" ``` + #### 内存泄漏检测 使用专项工具分析应用内存使用: @@ -347,6 +351,7 @@ jstat -gc 1000 # 每秒采样一次 # S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU # 6144 6144 0 6144 39424 12288 149504 84320 50552 47689 6464 5989 ``` + #### 内存限制最佳实践 ```bash @@ -385,6 +390,7 @@ services: memory: 2G memory_reservation: 1G # 预留 1GB,允许突发到 2GB ``` + ### 19.3.6 镜像体积优化与多阶段构建 #### 镜像体积分析工具 @@ -411,6 +417,7 @@ chmod +x hadolint # 检查 Dockerfile 最佳实践 ./hadolint Dockerfile ``` + #### 多阶段构建最佳实践 **Go 应用的最小化镜像构建:** @@ -528,6 +535,7 @@ EXPOSE 5000 CMD ["python", "app.py"] ``` + #### 镜像体积优化检查清单 ```bash @@ -558,6 +566,7 @@ RUN apt-get update && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* ``` + ### 19.3.7 常见性能问题及解决方案 **问题 1: 容器频繁被 OOM 杀死** diff --git a/20_cases_os/20.1_busybox.md b/20_cases_os/20.1_busybox.md index 60ab74b..815dcaf 100644 --- a/20_cases_os/20.1_busybox.md +++ b/20_cases_os/20.1_busybox.md @@ -30,6 +30,7 @@ $ docker image ls REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE busybox latest e72ac664f4f0 6 weeks ago 2.433 MB ``` + ### 20.1.3 运行 busybox 启动一个 `busybox` 容器,并在容器中执行 `grep` 命令。 diff --git a/20_cases_os/20.2_alpine.md b/20_cases_os/20.2_alpine.md index e47a13e..c2c2ae2 100644 --- a/20_cases_os/20.2_alpine.md +++ b/20_cases_os/20.2_alpine.md @@ -25,6 +25,7 @@ debian latest 4d6ce913b130 84.98 MB ubuntu latest b39b81afc8ca 188.3 MB centos latest 8efe422e6104 210 MB ``` + ### 20.2.2 获取并使用官方镜像 由于镜像很小,下载时间往往很短,读者可以直接使用 `docker run` 指令直接运行一个 `Alpine` 容器,并指定运行的 Linux 指令,例如: @@ -33,6 +34,7 @@ centos latest 8efe422e6104 210 MB $ docker run alpine echo '123' 123 ``` + ### 20.2.3 迁移至 Alpine 基础镜像 目前,大部分 Docker 官方镜像都已经支持 `Alpine` 作为基础镜像,可以很容易进行迁移。 @@ -60,6 +62,7 @@ $ apk --update add --no-cache RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \ && apk add --no-cache ``` + ### 20.2.4 相关资源 * `Alpine` 官网:https://www.alpinelinux.org/ diff --git a/20_cases_os/20.4_centos.md b/20_cases_os/20.4_centos.md index 172fac3..ae54d52 100644 --- a/20_cases_os/20.4_centos.md +++ b/20_cases_os/20.4_centos.md @@ -28,6 +28,7 @@ Status: Downloaded newer image for centos:7 [root@43eb3b194d48 /]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) ``` + ### 20.4.2 Fedora 系统简介 下图直观地展示了本节内容: diff --git a/21_case_devops/21.1_devops_workflow.md b/21_case_devops/21.1_devops_workflow.md index bcf1bf7..e167044 100644 --- a/21_case_devops/21.1_devops_workflow.md +++ b/21_case_devops/21.1_devops_workflow.md @@ -35,6 +35,7 @@ WORKDIR /app COPY --from=builder /app/main . CMD ["./main"] ``` + #### 2. GitLab CI 配置 GitLab CI(`.gitlab-ci.yml`)配置如下: @@ -74,6 +75,7 @@ deploy_staging: only: - develop ``` + ### 21.1.3 最佳实践 1. **不可变基础设施**:一旦镜像构建完成,在各个环境(Dev、Staging、Prod)中都应该使用同一个镜像 tag(通常是 commit hash),而不是重新构建。 diff --git a/21_case_devops/21.2_github_actions.md b/21_case_devops/21.2_github_actions.md index 20c7274..f11e1fe 100644 --- a/21_case_devops/21.2_github_actions.md +++ b/21_case_devops/21.2_github_actions.md @@ -46,6 +46,7 @@ jobs: with: args: go version ``` + ## 21.2.3 参考资料 * [Actions Docs](https://docs.github.com/en/actions) diff --git a/21_case_devops/21.3_drone.md b/21_case_devops/21.3_drone.md index 1c6d282..584c3d4 100644 --- a/21_case_devops/21.3_drone.md +++ b/21_case_devops/21.3_drone.md @@ -70,6 +70,7 @@ trigger: ├── .drone.yml └── app.go ``` + ## 21.3.3 推送项目源代码到 GitHub ```bash @@ -79,6 +80,7 @@ git commit -m "test drone ci" git push origin master ``` + ## 21.3.4 查看项目构建过程及结果 打开我们部署好的 `Drone` 网站或者 Drone Cloud,即可看到构建结果。 diff --git a/21_case_devops/21.6_vsCode.md b/21_case_devops/21.6_vsCode.md index cdf5bf9..7e266a3 100644 --- a/21_case_devops/21.6_vsCode.md +++ b/21_case_devops/21.6_vsCode.md @@ -39,6 +39,7 @@ VS Code 会拉取镜像并启动容器,随后你就可以在容器内运行: ```bash go test ./... ``` + ## 21.6.3 结合 Docker Compose(可选) 如果项目同时依赖数据库/缓存(例如 Postgres/Redis),可以使用 `dockerComposeFile` diff --git a/21_case_devops/21.7_practical_examples.md b/21_case_devops/21.7_practical_examples.md index d05408c..f52d333 100644 --- a/21_case_devops/21.7_practical_examples.md +++ b/21_case_devops/21.7_practical_examples.md @@ -120,6 +120,7 @@ require ( // 如果需要依赖 ) ``` + #### 带依赖的 Go 应用 **应用代码(使用 Gin 框架):** @@ -182,6 +183,7 @@ EXPOSE 8080 CMD ["./app"] ``` + ### 21.7.2 Rust 应用的最小化镜像构建 Rust 因其性能和安全性在系统级应用中备受青睐。 @@ -273,6 +275,7 @@ curl http://localhost:8080/health | jq . # Rust 应用通常比 Go 更小:5-20MB(取决于依赖) docker images rust-app ``` + ### 21.7.3 数据库容器化最佳实践 #### PostgreSQL 生产部署 @@ -455,6 +458,7 @@ services: volumes: postgres_data: ``` + #### MySQL/MariaDB 部署 ```dockerfile @@ -495,6 +499,7 @@ server_id = 1 log_bin = mysql-bin binlog_format = ROW ``` + #### Redis 缓存部署 ```dockerfile @@ -545,6 +550,7 @@ client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 ``` + ### 21.7.4 微服务架构的 Docker Compose 编排 **三层微服务架构示例:** @@ -736,6 +742,7 @@ server { } } ``` + ### 21.7.5 使用 VS Code Dev Containers Dev Containers 让整个开发环境容器化,提升团队一致性。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e1f8f8..88dbf9e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,6 +33,7 @@ $ git rebase upstream/master $ git push -f origin master ``` + ## 排版规范 本开源书籍遵循[中文排版指南](https://github.com/mzlogin/chinese-copywriting-guidelines)规范。 diff --git a/appendix/best_practices.md b/appendix/best_practices.md index 98b5b38..73c4667 100644 --- a/appendix/best_practices.md +++ b/appendix/best_practices.md @@ -44,6 +44,7 @@ RUN apt-get update && apt-get install -y \ mercurial \ subversion ``` + #### 构建缓存 在镜像的构建过程中,Docker 会遍历 `Dockerfile` 文件中的指令,然后按顺序执行。在执行每条指令之前,Docker 都会在缓存中查找是否已经存在可重用的镜像,如果有就使用现存的镜像,不再重复创建。如果你不想在构建过程中使用缓存,你可以在 `docker build` 命令中使用 `--no-cache=true` 选项。 @@ -300,6 +301,7 @@ $ docker run postgres postgres --help ```bash $ docker run --rm -it postgres bash ``` + #### VOLUME `VOLUME` 指令用于暴露任何数据库存储文件,配置文件,或容器创建的文件和目录。强烈建议使用 `VOLUME` 来管理镜像中的可变部分和用户可以改变的部分。 diff --git a/appendix/debug.md b/appendix/debug.md index 16af33a..61ecb95 100644 --- a/appendix/debug.md +++ b/appendix/debug.md @@ -22,6 +22,7 @@ $ sudo kill -SIGHUP $(pidof dockerd) $ sudo dmesg |grep dockerd $ sudo dmesg |grep runc ``` + ### Docker 不响应时处理 可以杀死 dockerd 进程查看其堆栈调用情况。 @@ -29,6 +30,7 @@ $ sudo dmesg |grep runc ```bash $ sudo kill -SIGUSR1 $(pidof dockerd) ``` + ### 重置 Docker 本地数据 *注意,本操作会移除所有的 Docker 本地数据,包括镜像和容器等。* @@ -43,6 +45,7 @@ $ docker system prune ```bash $ sudo rm -rf /var/lib/docker ``` + ### 常见故障排查 #### 容器启动失败 diff --git a/appendix/faq/README.md b/appendix/faq/README.md index 21237ea..64170aa 100644 --- a/appendix/faq/README.md +++ b/appendix/faq/README.md @@ -52,6 +52,7 @@ ```bash docker inspect --format '{{ .State.Pid }}' ``` + ### 如何获取某个容器的 IP 地址? 答:可以使用 @@ -59,6 +60,7 @@ docker inspect --format '{{ .State.Pid }}' ```bash docker inspect --format '{{ .NetworkSettings.IPAddress }}' ``` + ### 如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变? 答:使用以下命令启动容器可以使容器 IP 固定不变 @@ -68,6 +70,7 @@ $ docker network create -d bridge --subnet 172.25.0.0/16 my-net $ docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox ``` + ### 如何临时退出一个正在交互的容器的终端,而不终止它? 答:按 `Ctrl-p Ctrl-q`。如果按 `Ctrl-c` 往往会让容器内应用进程终止,进而会终止容器。 @@ -123,6 +126,7 @@ tmpfs 48G 228K 48G 1% /dev/shm lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker [root@s26 lib]# service docker start ``` + ### 使用内存和 swap 限制启动容器时候报警告:“WARNING:Your kernel does not support cgroup swap limit。WARNING:Your kernel does not support swap limit capabilities。Limitation discarded。”? 答:这是因为系统默认没有开启对内存和 swap 使用的统计功能,引入该功能会带来性能的下降。要开启该功能,可以采取如下操作: @@ -198,6 +202,7 @@ $ sudo ip netns show ```bash $ sudo ip netns exec 1234 ifconfig eth0 172.17.0.100/16 ``` + ### 如何获取容器绑定到本地那个 veth 接口上? 答:Docker 容器启动后,会通过 veth 接口对连接到本地网桥,veth 接口命名跟容器命名毫无关系,十分难以找到对应关系。 diff --git a/appendix/learning_roadmap.md b/appendix/learning_roadmap.md index 1845d15..135c03d 100644 --- a/appendix/learning_roadmap.md +++ b/appendix/learning_roadmap.md @@ -53,6 +53,7 @@ Docker 安装配置 3. 提交修改为新镜像 4. 推送镜像到 Docker Hub(需创建账户) ``` + #### 第二阶段:核心开发(2-6 周) **学习目标:** @@ -135,6 +136,7 @@ Docker Compose - 数据持久化 - 备份恢复策略 ``` + #### 第三阶段:生产优化(6-12 周) **学习目标:** @@ -248,6 +250,7 @@ CI/CD 集成 - 部署有状态应用 - 配置持久化存储 ``` + #### 第四阶段:专家深造(12+ 周) **学习目标:** @@ -376,6 +379,7 @@ Kubernetes 进阶 (Week 24-36) ├── 成本优化 └── 开源贡献 ``` + ### 推荐学习资源 #### 官方文档 @@ -475,6 +479,7 @@ docker volume / network / service docker compose up / down / logs / ps docker stats / events / inspect ``` + #### Kubernetes 认证 **认证路径:** @@ -561,6 +566,7 @@ A(要点): 4. SELinux / AppArmor(强制访问控制) ``` + #### Dockerfile 面试题 **Q4: 如何优化 Docker 镜像大小?** @@ -614,6 +620,7 @@ CMD ["--port", "8000"] # 运行 docker run image --debug 会执行: # python app.py --debug ``` + #### 网络和存储面试题 **Q6: Docker 网络驱动的区别?** @@ -664,6 +671,7 @@ tmpfs: - 用于临时文件、敏感数据 - 性能最好,重启丢失 ``` + #### 安全和生产面试题 **Q8: 如何提高 Docker 安全性?** @@ -758,6 +766,7 @@ A(要点): 5. 触发 ArgoCD / Flux 自动部署 6. 监控部署状态 ``` + ### 学习进度跟踪模板 ```markdown @@ -805,6 +814,7 @@ A(要点): - [ ] 监控和日志系统 - [ ] CI/CD 流程实现 ``` + ### 快速参考速查表 **常用命令速查:** diff --git a/appendix/repo/centos.md b/appendix/repo/centos.md index 8453c43..2fce379 100644 --- a/appendix/repo/centos.md +++ b/appendix/repo/centos.md @@ -25,6 +25,7 @@ $ docker run --name rocky -it rockylinux:9 bash ```bash $ docker run --name centos -it centos:7 bash ``` + ### Dockerfile 请到 [CentOS 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/centos) 查看。 diff --git a/appendix/repo/minio.md b/appendix/repo/minio.md index 44a88a1..4ccb4a5 100644 --- a/appendix/repo/minio.md +++ b/appendix/repo/minio.md @@ -13,6 +13,7 @@ MinIO 是一个非常轻量的服务,可以很简单的和其他应用的结 ```bash $ docker run -d -p 9000:9000 -p 9090:9090 minio/minio server /data --console-address ':9090' ``` + ### 离线部署 许多生产环境是一般是没有公网资源的,这就需要从有公网资源的服务器上把镜像导出,然后导入到需要运行镜像的内网服务器。 @@ -33,6 +34,7 @@ $ docker save -o minio.tar minio/minio:latest ```bash $ docker load -i minio.tar ``` + #### 运行 minio - 把 `/mnt/data` 改成要替换的数据目录 @@ -49,6 +51,7 @@ $ sudo docker run -d -p 9000:9000 -p 9090:9090 --name minio1 \ --restart=always \ minio/minio server /data --console-address ':9090' ``` + #### 访问 web 管理页面 打开 `http://:9090` 访问 Web 控制台。 diff --git a/appendix/repo/mongodb.md b/appendix/repo/mongodb.md index fe363b1..dbc7a1c 100644 --- a/appendix/repo/mongodb.md +++ b/appendix/repo/mongodb.md @@ -33,6 +33,7 @@ $ docker run -it --rm \ mongo \ sh -c 'exec mongo "some-mongo:27017/test"' ``` + ### Dockerfile 请到 [Mongo 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/mongo) 查看。 diff --git a/appendix/repo/nginx.md b/appendix/repo/nginx.md index eb8b060..e09ad6e 100644 --- a/appendix/repo/nginx.md +++ b/appendix/repo/nginx.md @@ -39,6 +39,7 @@ $ docker run -d \ -v /path/nginx.conf:/etc/nginx/nginx.conf:ro \ nginx ``` + ### Dockerfile 请到 [Nginx 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/nginx) 查看。 diff --git a/appendix/repo/nodejs.md b/appendix/repo/nodejs.md index 3e428d1..8f50b25 100644 --- a/appendix/repo/nodejs.md +++ b/appendix/repo/nodejs.md @@ -35,6 +35,7 @@ $ docker run -it --rm \ node:20-alpine \ node your-daemon-or-script.js ``` + ### Dockerfile 请到 [Node 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/node) 查看。 diff --git a/appendix/repo/php.md b/appendix/repo/php.md index 32a02fc..2d7e5ba 100644 --- a/appendix/repo/php.md +++ b/appendix/repo/php.md @@ -13,6 +13,7 @@ ```bash $ docker run -it --rm -v "$PWD":/app -w /app php:alpine php your-script.php ``` + ### Dockerfile 请到 [PHP 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/php) 查看。 diff --git a/appendix/repo/redis.md b/appendix/repo/redis.md index bc7fec7..59cd4e6 100644 --- a/appendix/repo/redis.md +++ b/appendix/repo/redis.md @@ -40,6 +40,7 @@ $ docker run -it --rm \ redis \ sh -c 'exec redis-cli -h some-redis' ``` + ### Dockerfile 请到 [Redis 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/redis) 查看。 diff --git a/appendix/repo/ubuntu.md b/appendix/repo/ubuntu.md index 9b221b7..f2a6b63 100644 --- a/appendix/repo/ubuntu.md +++ b/appendix/repo/ubuntu.md @@ -14,6 +14,7 @@ $ docker run --name some-ubuntu -it ubuntu:20.04 root@523c70904d54:/# ``` + ### Dockerfile 请到 [Ubuntu 官方镜像文档目录](https://github.com/docker-library/docs/tree/master/ubuntu) 查看。