diff --git a/02_basic_concept/README.md b/02_basic_concept/README.md index d82c3ce..93677f7 100644 --- a/02_basic_concept/README.md +++ b/02_basic_concept/README.md @@ -7,3 +7,9 @@ * **仓库** (`Repository`):镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。 理解了这三个概念,就理解了 **Docker** 的整个生命周期。 + +## 本章内容 + +* [Docker 镜像](2.1_image.md) +* [Docker 容器](2.2_container.md) +* [Docker 仓库](2.3_repository.md) diff --git a/07_dockerfile/7.17_multistage_builds.md b/07_dockerfile/7.17_multistage_builds.md index f467390..19d9cc2 100644 --- a/07_dockerfile/7.17_multistage_builds.md +++ b/07_dockerfile/7.17_multistage_builds.md @@ -118,7 +118,7 @@ go/helloworld 2 f7cf3465432c 22 seconds ago 6.47MB go/helloworld 1 f55d3e16affc 2 minutes ago 295MB ``` -## 7.17 使用多阶段构建 +### 7.17.3 使用多阶段构建 为解决以上问题,Docker v17.05 开始支持多阶段构建 (`multistage builds`)。使用多阶段构建我们就可以很容易解决前面提到的问题,并且只需要编写一个 `Dockerfile`: @@ -167,7 +167,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB 很明显使用多阶段构建的镜像体积小,同时也完美解决了上边提到的问题。 -### 7.17.1 只构建某一阶段的镜像 +### 7.17.4 只构建某一阶段的镜像 我们可以使用 `as` 来为某一阶段命名,例如 @@ -181,7 +181,7 @@ FROM golang:alpine as builder $ docker build --target builder -t username/imagename:tag . ``` -### 7.17.2 构建时从其他镜像复制文件 +### 7.17.5 构建时从其他镜像复制文件 上面例子中我们使用 `COPY --from=0 /go/src/github.com/go/helloworld/app .` 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。 diff --git a/09_network/9.3_custom_network.md b/09_network/9.3_custom_network.md index 2091308..bb2194c 100644 --- a/09_network/9.3_custom_network.md +++ b/09_network/9.3_custom_network.md @@ -2,7 +2,7 @@ 在生产环境中,推荐使用用户自定义网络代替默认的 bridge 网络。自定义网络提供了更好的隔离性和服务发现能力。 -### 9.4.1 为什么要用自定义网络 +### 9.3.1 为什么要用自定义网络 默认 bridge 网络存在以下局限,而自定义网络可以很好地解决这些问题: @@ -12,7 +12,7 @@ | 所有容器在同一网络 | 更好的隔离性 | | 需要 --link (已废弃)| 原生支持服务发现 | -### 9.4.2 创建自定义网络 +### 9.3.2 创建自定义网络 使用 `docker network create` 命令可以创建自定义网络: @@ -26,7 +26,7 @@ $ docker network create mynet $ docker network inspect mynet ``` -### 9.4.3 使用自定义网络 +### 9.3.3 使用自定义网络 启动容器时通过 `--network` 参数指定连接的网络: @@ -43,7 +43,7 @@ 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.4.4 容器名 DNS 解析 +### 9.3.4 容器名 DNS 解析 自定义网络自动提供 DNS 服务。Docker 守护进程在 `127.0.0.11` 运行了一个嵌入式 DNS 服务器,容器内的 DNS 请求会被转发到这里: @@ -58,7 +58,7 @@ flowchart LR end ``` -### 9.4.5 常用网络命令 +### 9.3.5 常用网络命令 以下是 Docker 网络管理中常用的命令: diff --git a/09_network/9.4_container_linking.md b/09_network/9.4_container_linking.md index 4678eff..20cfe91 100644 --- a/09_network/9.4_container_linking.md +++ b/09_network/9.4_container_linking.md @@ -2,7 +2,7 @@ 容器之间的网络通信是 Docker 网络的核心功能之一。本节介绍容器互联的几种方式。 -### 9.5.1 同一网络内的容器 +### 9.4.1 同一网络内的容器 同一自定义网络内的容器可以直接通过容器名通信,这是推荐的容器互联方式: @@ -21,7 +21,7 @@ $ docker run -d --name app --network app-net myapp ... ``` -### 9.5.2 连接到多个网络 +### 9.4.2 连接到多个网络 一个容器可以同时连接到多个网络,这对于需要跨网络通信的中间件容器特别有用: @@ -39,7 +39,7 @@ $ docker network connect backend multi-net-container $ docker inspect multi-net-container --format '{{json .NetworkSettings.Networks}}' ``` -### 9.5.3 ⚠️ --link 已废弃 +### 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 5ff940f..5f7727d 100644 --- a/09_network/9.5_port_mapping.md +++ b/09_network/9.5_port_mapping.md @@ -2,7 +2,7 @@ 容器运行在自己的隔离网络环境中 (通常是 Bridge 模式)。为了让外部网络访问容器内的服务,我们需要将容器的端口映射到宿主机的端口。 -### 9.6.1 为什么要映射端口 +### 9.5.1 为什么要映射端口 容器的网络访问规则如下: @@ -21,7 +21,7 @@ flowchart TD --- -### 9.6.2 端口映射方式 +### 9.5.2 端口映射方式 Docker 提供了多种方式来指定端口映射。 @@ -66,7 +66,7 @@ abc123456 0.0.0.0:49153->80/tcp --- -### 9.6.3 查看端口映射 +### 9.5.3 查看端口映射 可以使用以下命令查看容器的端口映射: @@ -92,7 +92,7 @@ abc123456 nginx 0.0.0.0:8080->80/tcp web --- -### 9.6.4 最佳实践与安全 +### 9.5.4 最佳实践与安全 在配置端口映射时,需要注意以下安全事项: @@ -127,7 +127,7 @@ $ docker run -d -p 53:53/udp dns-server --- -### 9.6.5 实现原理 +### 9.5.5 实现原理 Docker 使用 `docker-proxy` 进程 (用户态) 或 `iptables` DNAT 规则 (内核态) 来实现端口转发。 diff --git a/09_network/9.6_network_isolation.md b/09_network/9.6_network_isolation.md index 4da97b4..305118d 100644 --- a/09_network/9.6_network_isolation.md +++ b/09_network/9.6_network_isolation.md @@ -2,7 +2,7 @@ Docker 网络提供了天然的隔离能力,不同网络之间的容器默认无法通信。这是 Docker 网络安全的重要基础。 -### 9.7.1 网络隔离原理 +### 9.6.1 网络隔离原理 不同网络之间默认隔离,容器只能与同一网络中的容器直接通信: @@ -26,7 +26,7 @@ $ docker exec web ping db ping: db: Name or service not known ``` -### 9.7.2 安全优势 +### 9.6.2 安全优势 这种隔离机制带来以下安全优势: @@ -37,7 +37,7 @@ ping: db: Name or service not known | **多租户** | 不同租户的容器在不同网络中完全隔离 | | **最小权限** | 容器只能访问必要的网络资源 | -### 9.7.3 跨网络通信 +### 9.6.3 跨网络通信 如果确实需要某个容器跨网络通信,可以将其同时连接到多个网络: @@ -52,7 +52,7 @@ $ docker network connect backend api 这种方式让你可以精确控制哪些容器可以跨网络通信,遵循最小权限原则。 -### 9.7.4 典型网络架构 +### 9.6.4 典型网络架构 一个典型的多层应用网络架构如下: diff --git a/11_compose/11.9_lnmp.md b/11_compose/11.9_lnmp.md index 2881290..e3a0406 100644 --- a/11_compose/11.9_lnmp.md +++ b/11_compose/11.9_lnmp.md @@ -1,3 +1,38 @@ ## 11.9 实战 LNMP -本项目的维护者 [khs1994](https://github.com/khs1994) 的开源项目 [khs1994-docker/lnmp](https://github.com/khs1994-docker/lnmp) 使用 Docker Compose 搭建了一套 LNMP 环境,各位开发者可以参考该项目在 Docker 或 Kubernetes 中运行 LNMP。 +### 什么是 LNMP + +LNMP 是一个经典的 Web 应用栈,由以下四个开源软件组合而成: + +- **L**:Linux(操作系统) +- **N**:Nginx(Web 服务器) +- **M**:MySQL(数据库服务器) +- **P**:PHP(脚本语言) + +这个组合被广泛用于构建高性能的 Web 应用。 + +### 使用 Docker Compose 部署 LNMP + +本项目的维护者 [khs1994](https://github.com/khs1994) 的开源项目 [khs1994-docker/lnmp](https://github.com/khs1994-docker/lnmp) 使用 Docker Compose 搭建了一套完整的 LNMP 环境。 + +### 参考项目 + +该项目中包含的服务: + +- **Nginx**:Web 服务器,用于处理 HTTP 请求 +- **MySQL/MariaDB**:关系型数据库服务 +- **PHP-FPM**:PHP 处理器,与 Nginx 通过 Fast CGI 协议通信 +- **Redis**:可选的内存缓存服务(用于会话或缓存) + +### 学习资源 + +各位开发者可以参考该项目在以下场景中运行 LNMP: + +- Docker 容器化部署 +- Kubernetes 集群编排 +- 开发环境快速搭建 +- 生产环境配置参考 + +项目地址:https://github.com/khs1994-docker/lnmp + +通过该项目,你可以学习到如何使用 Docker Compose 定义多个相互关联的服务,以及如何在容器化环境中管理应用的生命周期。 diff --git a/12_implementation/12.2_namespace.md b/12_implementation/12.2_namespace.md index 8b9f864..6e91548 100644 --- a/12_implementation/12.2_namespace.md +++ b/12_implementation/12.2_namespace.md @@ -2,9 +2,9 @@ 命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。 -## 12.2 什么是 Namespace +### 12.2.1 什么是 Namespace -> **Namespace 是 Linux 内核提供的资源隔离机制,它让容器内的进程仿佛运行在独立的操作系统中。** Namespace 是容器技术的核心基础之一。它回答了一个关键问题:**如何让一个进程 “以为” 自己独占整个系统?** +> **Namespace 是 Linux 内核提供的资源隔离机制,它让容器内的进程仿佛运行在独立的操作系统中。**Namespace 是容器技术的核心基础之一。它回答了一个关键问题:**如何让一个进程 “以为” 自己独占整个系统?** ```mermaid flowchart LR @@ -26,7 +26,7 @@ flowchart LR H4 -. "(实际是宿主机的 1234)" .- C1 ``` -### 12.2.1 Namespace 的类型 +### 12.2.2 Namespace 的类型 Linux 内核提供了以下几种 Namespace,Docker 容器使用了全部: @@ -42,7 +42,7 @@ Linux 内核提供了以下几种 Namespace,Docker 容器使用了全部: --- -### 12.2.2 PID Namespace +### 12.2.3 PID Namespace PID Namespace 负责进程 ID 的隔离,使得容器内的进程彼此不可见。 @@ -75,7 +75,7 @@ PID USER COMMAND --- -### 12.2.3 NET Namespace +### 12.2.4 NET Namespace NET Namespace 负责网络栈的隔离,包括网卡、路由表和 iptables 规则等。 @@ -110,7 +110,7 @@ flowchart LR --- -### 12.2.4 MNT Namespace +### 12.2.5 MNT Namespace MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的文件系统视图。 @@ -143,7 +143,7 @@ MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的 --- -### 12.2.5 UTS Namespace +### 12.2.6 UTS Namespace UTS Namespace 主要用于隔离主机名和域名。 @@ -169,7 +169,7 @@ UTS = “UNIX Time-sharing System”,是历史遗留的名称。 --- -### 12.2.6 IPC Namespace +### 12.2.7 IPC Namespace IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消息队列。 @@ -190,7 +190,7 @@ IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消 --- -### 12.2.7 USER Namespace +### 12.2.8 USER Namespace USER Namespace 允许将容器内的用户 ID 映射到宿主机的不同用户 ID。 @@ -226,7 +226,7 @@ flowchart LR --- -### 12.2.8 动手实验:体验 Namespace +### 12.2.9 动手实验:体验 Namespace 使用 `unshare` 命令可以在不使用 Docker 的情况下体验 Namespace: @@ -285,7 +285,7 @@ $ ip addr --- -### 12.2.9 Namespace 的局限性 +### 12.2.10 Namespace 的局限性 Namespace 提供了隔离但不是安全边界: diff --git a/12_implementation/12.5_container_format.md b/12_implementation/12.5_container_format.md index 54737b2..eaa11db 100644 --- a/12_implementation/12.5_container_format.md +++ b/12_implementation/12.5_container_format.md @@ -1,3 +1,50 @@ ## 12.5 容器格式 -最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 +### Docker 容器格式的演进 + +最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC 的依赖,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer)。从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 + +### 关键组件说明 + +#### LXC(Linux 容器) + +Docker 早期版本(0.1-0.7)直接使用 LXC 作为容器运行时,利用 Linux Namespaces 和 Cgroups 实现容器隔离。 + +#### libcontainer + +- Docker 自行开发的容器库 +- 提供了容器的通用接口 +- 不依赖于特定的 Linux 容器实现 +- 更灵活和可控 + +#### runC + +- OCI(Open Container Initiative)标准实现 +- 轻量级的容器运行时 +- 独立的二进制文件,可单独使用 +- 基于 libcontainer 发展而来 + +#### containerd + +- Docker 开源的容器运行时 +- 提供了容器的完整生命周期管理 +- 支持 runC 和其他 OCI 兼容的运行时 +- 在 Kubernetes 等编排系统中广泛使用 + +### 容器规范标准 + +Docker 积极参与 Open Container Initiative (OCI) 的制定,推动了以下规范的发展: + +- **Image Spec**:容器镜像格式规范 +- **Runtime Spec**:容器运行时接口规范 +- **Distribution Spec**:容器镜像分发规范 + +### 架构演变的优势 + +从 LXC → libcontainer → runC/containerd 的演变提供了以下优势: + +1. 减少外部依赖 +2. 提高运行效率 +3. 遵循行业标准(OCI) +4. 增强可移植性和互操作性 +5. 支持多种容器运行时选择 diff --git a/14_kubernetes_setup/14.1_kubeadm.md b/14_kubernetes_setup/14.1_kubeadm.md index 8eaab88..5132608 100644 --- a/14_kubernetes_setup/14.1_kubeadm.md +++ b/14_kubernetes_setup/14.1_kubeadm.md @@ -1,4 +1,4 @@ -## 14.1 使用 kubeadm 部署 Kubernetes (CRI 使用 containerd) +## 14.1 使用 kubeadm 部署 Kubernetes `kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令,作为快速创建 `Kubernetes` 集群的最佳实践。 diff --git a/14_kubernetes_setup/14.6_systemd.md b/14_kubernetes_setup/14.6_systemd.md index 2687bdc..bf1d443 100644 --- a/14_kubernetes_setup/14.6_systemd.md +++ b/14_kubernetes_setup/14.6_systemd.md @@ -1,3 +1,67 @@ ## 14.6 一步步部署 Kubernetes 集群 -可以参考 [opsnull/follow-me-install-kubernetes-cluster](https://github.com/opsnull/follow-me-install-kubernetes-cluster) 项目一步步部署 Kubernetes 集群。 +### 概述 + +部署 Kubernetes 集群涉及多个组件的安装和配置,包括 Master 节点和 Worker 节点。本章介绍如何使用 systemd 管理这些服务的生命周期。 + +### Kubernetes 主要组件 + +#### Master 节点组件 + +- **kube-apiserver**:API 服务器,Kubernetes 集群的中心 +- **kube-controller-manager**:控制器管理器 +- **kube-scheduler**:调度器,负责 Pod 调度 +- **etcd**:分布式键值存储,存储集群数据 + +#### Worker 节点组件 + +- **kubelet**:节点代理,管理容器生命周期 +- **kube-proxy**:网络代理,处理服务网络 +- **Container Runtime**:容器运行时(Docker、containerd 等) + +### 使用 systemd 管理 Kubernetes 服务 + +#### 服务单元文件 + +为了让 systemd 管理 Kubernetes 服务,需要创建相应的 `.service` 文件,例如: + +``` +/etc/systemd/system/kubelet.service +/etc/systemd/system/kube-proxy.service +/etc/systemd/system/kube-apiserver.service +``` + +#### 常用命令 + +```bash +# 启动服务 +sudo systemctl start kubelet + +# 停止服务 +sudo systemctl stop kubelet + +# 重启服务 +sudo systemctl restart kubelet + +# 查看服务状态 +sudo systemctl status kubelet + +# 设置开机自启 +sudo systemctl enable kubelet +``` + +### 参考资源 + +详细的部署步骤和配置说明,可以参考以下项目: + +- [opsnull/follow-me-install-kubernetes-cluster](https://github.com/opsnull/follow-me-install-kubernetes-cluster):一个完整的 Kubernetes 集群部署指南项目 + +该项目提供了详细的步骤说明,涵盖 Master 节点、Worker 节点的安装配置,以及如何使用 systemd 管理这些组件的生命周期。 + +### 推荐学习路径 + +1. 理解 Kubernetes 架构和各组件的作用 +2. 准备所需的系统环境(Linux 主机、网络配置等) +3. 按步骤安装各个 Kubernetes 组件 +4. 配置 systemd 服务单元文件 +5. 验证集群健康状态 diff --git a/14_kubernetes_setup/14.8_kubectl.md b/14_kubernetes_setup/14.8_kubectl.md index 0f01b03..6a5aee0 100644 --- a/14_kubernetes_setup/14.8_kubectl.md +++ b/14_kubernetes_setup/14.8_kubectl.md @@ -8,74 +8,74 @@ kubectl [flags] kubectl [command] ``` -## 14.8 get +### 14.8.1 get 显示一个或多个资源 -## 14.8 describe +### 14.8.2 describe 显示资源详情 -## 14.8 create +### 14.8.3 create 从文件或标准输入创建资源 -## 14.8 update +### 14.8.4 update 从文件或标准输入更新资源 -## 14.8 delete +### 14.8.5 delete 通过文件名、标准输入、资源名或者 label selector 删除资源 -## 14.8 logs +### 14.8.6 logs 输出 pod 中一个容器的日志 -## 14.8 rollout +### 14.8.7 rollout 对 Deployment 等资源执行滚动更新/回滚 -## 14.8 exec +### 14.8.8 exec 在容器内部执行命令 -## 14.8 port-forward +### 14.8.9 port-forward 将本地端口转发到 Pod -## 14.8 proxy +### 14.8.10 proxy 为 Kubernetes API server 启动代理服务器 -## 14.8 run +### 14.8.11 run 在集群中使用指定镜像启动容器 -## 14.8 expose +### 14.8.12 expose 将 replication controller service 或 pod 暴露为新的 Kubernetes service -## 14.8 label +### 14.8.13 label 更新资源的 label -## 14.8 config +### 14.8.14 config 修改 Kubernetes 配置文件 -## 14.8 cluster-info +### 14.8.15 cluster-info 显示集群信息 -## 14.8 api-versions +### 14.8.16 api-versions 以 “组/版本” 的格式输出服务端支持的 API 版本 -## 14.8 version +### 14.8.17 version 输出服务端和客户端的版本信息 -## 14.8 help +### 14.8.18 help 显示各个命令的帮助信息 diff --git a/17_ecosystem/README.md b/17_ecosystem/README.md index 783bfc2..1d70ff4 100644 --- a/17_ecosystem/README.md +++ b/17_ecosystem/README.md @@ -2,10 +2,28 @@ 本章将介绍 Docker 和 Kubernetes 之外的容器生态技术。 -- **Fedora CoreOS**:专为容器化工作负载设计的操作系统。 -- **Podman**:兼容 Docker CLI 的下一代无守护进程容器引擎。 -- **Buildah**:无需守护进程的 OCI 容器镜像构建工具。 -- **Skopeo**:远程检查和管理容器镜像的利器。 -- **containerd**:作为现代容器生态基石的核心容器运行时。 -- **安全容器运行时**:通过提供更强隔离性来保证安全的技术方案(如 Kata Containers、gVisor)。 -- **WebAssembly**:一种极具潜力的轻量级跨平台二进制指令格式。 +## 本章内容 + +* [Fedora CoreOS 简介](17.1_coreos_intro.md) + * 专为容器化工作负载设计的操作系统。 + +* [Fedora CoreOS 安装与配置](17.2_coreos_install.md) + * CoreOS 的安装方式与基本配置。 + +* [Podman](17.3_podman.md) + * 兼容 Docker CLI 的下一代无守护进程容器引擎。 + +* [Buildah](17.4_buildah.md) + * 无需守护进程的 OCI 容器镜像构建工具。 + +* [Skopeo](17.5_skopeo.md) + * 远程检查和管理容器镜像的利器。 + +* [containerd](17.6_containerd.md) + * 作为现代容器生态基石的核心容器运行时。 + +* [安全容器运行时](17.7_secure_runtime.md) + * 通过提供更强隔离性来保证安全的技术方案(如 Kata Containers、gVisor)。 + +* [WebAssembly](17.8_wasm.md) + * 一种极具潜力的轻量级跨平台二进制指令格式。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ccd32e2..f5462a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# 如何贡献 +## 如何贡献 领取或创建新的 [Issue](https://github.com/yeasy/docker_practice/issues),如 [issue 235](https://github.com/yeasy/docker_practice/issues/235),添加自己为 `Assignee`。