自己动手写 Docker

自己动手写 Docker
编辑推荐
√ 经阿里云战火洗礼,将容器|Go|新规范和开源项目精密地融为一体。
√ 容器编排至佳实践与生产环境容器化,是迈向高阶应用的重大课题。
√ 理解容器底层实现原理,是攀登效用极限及创造其扩展应用的基石。
√ 造轮子可取之义在于知其所以然——全局、脉络、趋势及其特殊性。
内容简介
《自己动手写 Docker》在详细分析 Docker 所依赖的技术栈的基础上,一步一步地通过代码实例,让读者可以自己循序渐进地用 Go 语言构建出一个容器的引擎。不同于其他 Docker 原理介绍或代码剖析的书籍,《自己动手写 Docker》旨在提供给读者一条动手路线,一步一步地实现 Docker 的隔离性,构建 Docker 的镜像、容器的生命周期及 Docker 的网络等。《自己动手写 Docker》涉及的代码都托管在 GitHub 上,读者可以对照书中的步骤从代码层面学习构建流程,从而精通整个容器技术栈。《自己动手写 Docker》也对目前业界容器技术的方向和实现做了简单介绍,以加深读者对容器生态的认识和理解。
《自己动手写 Docker》适合对容器技术已经使用过或有一些了解,希望更深层次掌握容器技术原理和至佳实践的读者。
作者简介
陈显鹭
阿里云高级研发工程师,对 Docker 有深入研究,是 Docker 多个项目的 Contributor,专注于容器技术的编排与基础环境研究。爱好折腾源代码,热爱开源文化并积极参与社区开源项目的研发。
王炳燊
阿里云研发工程师,具有丰富的 Linux 开发经验,对 Docker 有深入研究,多次提交 Docker Patch。目前从事阿里云容器服务网络方案的设计与实现,专注于容器技术的基础环境研究。
秦妤嘉
阿里云高级研发工程师、DevOps 工程师,有丰富的容器化持续集成和持续交付开发实战经验,进行过 Jenkins 源码分析改造和 Jenkins 插件开发。目前从事阿里云容器服务持续集成和持续交付方案的设计和实现。
目录
第 1 章容器与开发语言 1
-
1.1Docker 1
-
1.1.1 简介 1
-
1.1.2 容器和虚拟机比较 2
-
1.1.3 容器加速开发效率 3
-
1.1.4 利用容器合作开发 4
-
1.1.5 利用容器快速扩容 4
-
1.1.6 安装使用 Docker 4
-
1.2Go 5
-
1.2.1 描述 5
-
1.2.2 安装 Go 6
-
1.2.3 配置 GOPATH 6
-
1.3 小结 7
第 2 章基础技术 8
-
2.1Linux Namespace 介绍 8
-
2.1.1 概念 8
-
2.1.2UTS Namespace 10
-
2.1.3IPC Namespace 11
-
2.1.4PID Namespace 13
-
2.1.5Mount Namespace 14
-
2.1.6User Namespace 16
-
2.1.7Network Namespace 18
-
2.2Linux Cgroups 介绍 20
-
2.2.1 什么是 Linux Cgroups 20
-
2.2.2Docker 是如何使用 Cgroups 的 24
-
2.2.3 用 Go 语言实现通过 cgroup 限制容器的资源 25
-
2.3Union File System 26
-
2.3.1 什么是 Union File System 26
-
2.3.2AUFS 27
-
2.3.3Docker 是如何使用 AUFS 的 27
-
2.3.4 自己动手写 AUFS34
-
2.4 小结 37
第 3 章构造容器 38
-
3.1 构造实现 run 命令版本的容器 38
-
3.1.1Linux proc 文件系统介绍 38
-
3.1.2 实现 run 命令 39
-
3.2 增加容器资源限制 45
-
3.2.1 定义 Cgroups 的数据结构 45
-
3.2.2 在启动容器时增加资源限制的配置 51
-
3.3 增加管道及环境变量识别 53
-
3.4 小结 58
第 4 章构造镜像 59
-
4.1 使用 busybox 创建容器 59
-
4.1.1busybox 59
-
4.1.2pivot_root 60
-
4.2 使用 AUFS 包装 busybox 63
-
4.3 实现 volume 数据卷 67
-
4.4 实现简单镜像打包 75
-
4.5 小结 77
第 5 章构建容器进阶 78
-
5.1 实现容器的后台运行 78
-
5.2 实现查看运行中容器 82
-
5.2.1 准备数据 82
-
5.2.2 实现 mydocker ps 87
-
5.3 实现查看容器日志 90
-
5.4 实现进入容器 Namespace 93
-
5.4.1setns 94
-
5.4.2Cgo 94
-
5.4.3 实现命令 94
-
5.5 实现停止容器 100
-
5.6 实现删除容器 104
-
5.7 实现通过容器制作镜像 105
-
5.8 实现容器指定环境变量运行 117
-
5.8.1 修改 runCommand 117
-
5.8.2 修改 Run 函数 117
-
5.8.3 修改 NewParentProcess 函数 118
-
5.8.4 修改 mydocker exec 命令 119
-
5.9 小结 121
第 6 章容器网络 122
-
6.1 网络虚拟化技术介绍 122
-
6.1.1Linux 虚拟网络设备 122
-
6.1.2Linux 路由表 124
-
6.1.3Linux iptables 126
-
6.1.4Go 语言网络库介绍 127
-
6.2 构建容器网络模型 128
-
6.2.1 模型 128
-
6.2.2 调用关系 130
-
6.3 容器地址分配 137
-
6.3.1bitmap 算法介绍 138
-
6.3.2 数据结构定义 138
-
6.3.3 地址分配的实现 140
-
6.3.4 地址释放的实现 142
-
6.3.5 测试 142
-
6.4 创建 Bridge 网络 144
-
6.4.1Bridge Driver Create 实现 144
-
6.4.2Bridge Driver 初始化 Linux Bridge 流程 144
-
6.4.3Bridge Driver Delete 实现 148
-
6.4.4 测试 148
-
6.5 在 Bridge 网络创建容器 149
-
6.5.1 挂载容器端点的流程 150
-
6.5.2 测试 156
-
6.6 容器跨主机网络 159
-
6.6.1 跨主机容器网络的 IPAM 160
-
6.6.2 跨主机容器网络通信的常见实现方式 161
-
6.7 小结 163
第 7 章高级实践 164
-
7.1 使用 mydocker 创建一个可访问的 nginx 容器 164
-
7.1.1 获取 nginx tar 包 164
-
7.1.2 构建自己的 nginx 镜像 165
-
7.1.3 运行 mynginx 容器 167
-
7.2 使用 mydocker 创建一个?sk + redis 的计数器 169
-
7.2.1 创建 redis 容器 169
-
7.2.2 制作?sk 镜像 173
-
7.2.3 创建 my?sk 容器 176
-
7.3runC 177
-
7.3.1 简介 177
-
7.3.2OCI 标准包(bundle) 177
-
7.3.3con?.json 178
-
7.3.4mounts 178
-
7.3.5process 179
-
7.3.6user 179
-
7.3.7hostname 180
-
7.3.8platform 180
-
7.3.9 钩子(Hook) 181
-
7.4runC 创建容器流程 182
-
7.5Docker containerd 项目介绍 186
-
7.5.1 架构 187
-
7.5.2 特性和路线图 188
-
7.5.3containerd 和 Docker 之间的关系 188
-
7.5.4containerd、OCI 和 runC 之间的关系 188
-
7.5.5containerd 和容器编排系统的关系 189
-
7.6Kubernetes CRI 容器引擎 189
-
7.6.1 什么是 CRI 189
-
7.6.2 为什么需要 CRI 193
-
7.6.3 为什么 CRI 是接口且是基于容器的而不是基于 Pod 的 193
-
7.6.4 如何使用 CRI 193
-
7.6.5CRI 的目标 194
-
7.6.6 已知的问题 194
-
7.7 小结 195