From 4e84715725107499dd90f76150edb429cd9909f8 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 1 Sep 2019 20:05:43 +0800 Subject: [PATCH 001/201] Fixed error --- .travis/docker-entrypoint.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis/docker-entrypoint.sh b/.travis/docker-entrypoint.sh index fe7b61d74..21d66fc9a 100755 --- a/.travis/docker-entrypoint.sh +++ b/.travis/docker-entrypoint.sh @@ -13,9 +13,11 @@ cp -a . /srv/gitbook cd /srv/gitbook main(){ - if [ "$1" = build ];then gitbook build && cp -a _book $srcDir && echo $START && date "+%F %T" && exit 0; fi - exec gitbook serve - exit 0 + if [ "$1" = build ];then + gitbook build && cp -a _book $srcDir && echo $START && date "+%F %T" && exit 0 + else + exec gitbook serve + fi } main $1 $2 $3 From 96aa9b99debf5161acf04bfdc02dcfdc3f05f6be Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 5 Sep 2019 12:59:25 +0800 Subject: [PATCH 002/201] deploy pages to docker-practice/zh-cn Signed-off-by: Kang HuaiShuai --- .travis.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e9d033e..e98d6bbb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ after_success: - cd _book - git init -- git remote add origin "$REPO" +- git remote add origin "$DEPLOY_REPO" - git add . - COMMIT=`date "+%F %T"` - git commit -m "Travis CI Site updated $COMMIT" @@ -41,9 +41,8 @@ after_success: env: global: - - DEPLOY_BRANCH: pages - # - DEPLOY_BRANCH: legacy-pages - - REPO: git@github.com:yeasy/docker_practice.git + - DEPLOY_BRANCH: master + - DEPLOY_REPO: git@github.com:docker-practice/zh-cn.git addons: ssh_known_hosts: @@ -52,5 +51,3 @@ addons: branches: only: - master - - dev - # - docker-legacy From dd060d026a55193c32b3cc0e161c06dffae67006 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 5 Sep 2019 13:40:53 +0800 Subject: [PATCH 003/201] add docker-practice.com Signed-off-by: Kang HuaiShuai --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3185e3035..e4622086f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ | 语言 | 构建状态 | - | | :------------- | :------------- | :--- | -| [zh-hans](https://github.com/yeasy/docker_practice) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/) | +| [zh-hans](https://github.com/yeasy/docker_practice) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh-cn) | | [us-en](https://github.com/yeasy/docker_practice/tree/english) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=english)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/us_en) | | [zh-hant](https://github.com/yeasy/docker_practice/tree/zh-Hant) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=zh-hant)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh_hant) | @@ -16,7 +16,7 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -* 在线阅读:[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us_en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F) +* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/zh-cn),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us_en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) * [英文翻译](https://github.com/yeasy/docker_practice/issues/363) From 49ef715e99ae57b78245e87c32908e1e87345740 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 14:06:04 +0800 Subject: [PATCH 004/201] [install] Update settings Signed-off-by: Kang HuaiShuai --- SUMMARY.md | 2 +- .../_images/install-win-docker-app-search.png | Bin 454686 -> 12146 bytes install/mac.md | 2 +- install/mirror.md | 22 ++++++++++++++++-- install/windows.md | 2 +- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 322669b75..64897ab19 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,7 +17,7 @@ * [CentOS](install/centos.md) * [Raspberry Pi](install/raspberry-pi.md) * [macOS](install/mac.md) - * [Windows PC](install/windows.md) + * [Windows 10](install/windows.md) * [镜像加速器](install/mirror.md) * [使用镜像](image/README.md) * [获取镜像](image/pull.md) diff --git a/install/_images/install-win-docker-app-search.png b/install/_images/install-win-docker-app-search.png index 02d8afaa7b5f035f011b27536bc899d89aed4e99..42361f6110ea592aea41042732fc5281194e9b6d 100644 GIT binary patch literal 12146 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 literal 454686 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 z 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 z

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

gX~FA~EQUKcK&d`IaTMDP}ci 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⪚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%0A-vOgC^y3) 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

)ItYOgJ~kbj)3$49lhO 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 z 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 diff --git a/install/mac.md b/install/mac.md index 44a571b6a..52513e9fc 100644 --- a/install/mac.md +++ b/install/mac.md @@ -2,7 +2,7 @@ ### 系统要求 -[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS El Capitan 10.11。 +[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Sierra 10.12。 ### 安装 diff --git a/install/mirror.md b/install/mirror.md index 25ee0f65a..57ee1a3ec 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -38,11 +38,29 @@ $ sudo systemctl restart docker ### Windows 10 -对于使用 Windows 10 的系统,在系统右下角托盘 Docker 图标内右键菜单选择 `Settings`,打开配置窗口后左侧导航菜单选择 `Daemon`。在 `Registry mirrors` 一栏中填写加速器地址 `https://dockerhub.azk8s.cn`,之后点击 `Apply` 保存后 Docker 就会重启并应用配置的镜像地址了。 +对于使用 Windows 10 的系统,在系统右下角托盘 Docker 图标内右键菜单选择 `Settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。 + +```json +{ + "registry-mirrors": [ + "https://dockerhub.azk8s.cn", + "https://reg-mirror.qiniu.com" + ] +} +``` ### macOS -对于使用 macOS 的用户,在任务栏点击 Docker Desktop 应用图标 -> Perferences... -> Daemon -> Registry mirrors。在列表中填写加速器地址 `https://dockerhub.azk8s.cn`。修改完成之后,点击 `Apply & Restart` 按钮,Docker 就会重启并应用配置的镜像地址了。 +对于使用 macOS 的用户,在任务栏点击 Docker Desktop 应用图标 -> `Perferences`,在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件。修改完成之后,点击 `Apply & Restart` 按钮,Docker 就会重启并应用配置的镜像地址了。 + +```json +{ + "registry-mirrors": [ + "https://dockerhub.azk8s.cn", + "https://reg-mirror.qiniu.com" + ] +} +``` ### 检查加速器是否生效 diff --git a/install/windows.md b/install/windows.md index 2caa7601c..c7e387694 100644 --- a/install/windows.md +++ b/install/windows.md @@ -1,4 +1,4 @@ -## Windows 10 PC 安装 Docker Desktop CE +## Windows 10 安装 Docker Desktop CE ### 系统要求 From 1aef2b77347857868f13e204ac4659642ac9e621 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 14:08:30 +0800 Subject: [PATCH 005/201] [cases] Fixed typo Signed-off-by: Kang HuaiShuai --- cases/ci/actions/README.md | 4 ++-- cases/{ => ci/drone}/.image/drone-build.png | Bin cases/ci/drone/README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename cases/{ => ci/drone}/.image/drone-build.png (100%) diff --git a/cases/ci/actions/README.md b/cases/ci/actions/README.md index 42ad77f19..ce36b1d72 100644 --- a/cases/ci/actions/README.md +++ b/cases/ci/actions/README.md @@ -1,8 +1,8 @@ # GitHub Actions -GitGub Actions 是 GitHub 推出的一款 CI/CD 工具。 +GitHub [Actions](https://github.com/features/actions) 是 GitHub 推出的一款 CI/CD 工具。 -我们可以在每个 job 的 step 中使用 Docker 执行构建步骤。 +我们可以在每个 `job` 的 `step` 中使用 Docker 执行构建步骤。 ```yaml on: push diff --git a/cases/.image/drone-build.png b/cases/ci/drone/.image/drone-build.png similarity index 100% rename from cases/.image/drone-build.png rename to cases/ci/drone/.image/drone-build.png diff --git a/cases/ci/drone/README.md b/cases/ci/drone/README.md index daa8de1e0..994eb114c 100644 --- a/cases/ci/drone/README.md +++ b/cases/ci/drone/README.md @@ -86,7 +86,7 @@ $ git push origin master 打开我们部署好的 `Drone` 网站或者 Drone Cloud,即可看到构建结果。 -![](../.image/drone-build.png) +![](.image/drone-build.png) 当然我们也可以把构建结果上传到 GitHub,Docker Registry,云服务商提供的对象存储,或者生产环境中。 @@ -95,5 +95,5 @@ $ git push origin master ## 参考链接 * [Drone Github](https://github.com/drone/drone) -* [Drone 文档](http://docs.drone.io/) +* [Drone 文档](https://docs.drone.io/) * [Drone 示例](https://github.com/docker-practice/drone-demo) From 4873267f31e62a71a3c2b02c529f8ee206f01e95 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 14:28:50 +0800 Subject: [PATCH 006/201] Update format Signed-off-by: Kang HuaiShuai --- cases/os/README.md | 4 ++-- cases/os/alpine.md | 10 +++++----- cases/os/busybox.md | 14 +++++++------- cases/os/centos.md | 10 +++++----- cases/os/debian.md | 10 +++++----- cases/os/summary.md | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/cases/os/README.md b/cases/os/README.md index 09b654576..2c2d839b4 100644 --- a/cases/os/README.md +++ b/cases/os/README.md @@ -1,9 +1,9 @@ # 操作系统 -目前常用的 Linux 发行版主要包括 Debian/Ubuntu 系列和 CentOS/Fedora 系列。 +目前常用的 Linux 发行版主要包括 `Debian/Ubuntu` 系列和 `CentOS/Fedora` 系列。 前者以自带软件包版本较新而出名;后者则宣称运行更稳定一些。选择哪个操作系统取决于读者的具体需求。 使用 Docker,读者只需要一个命令就能快速获取一个 Linux 发行版镜像,这是以往包括各种虚拟化技术都难以实现的。这些镜像一般都很精简,但是可以支持完整 Linux 系统的大部分功能。 -本章将介绍如何使用 Docker 安装和使用 Busybox、Alphine、Debian/Ubuntu、CentOS/Fedora 等操作系统。 +本章将介绍如何使用 Docker 安装和使用 `Busybox`、`Alphine`、`Debian/Ubuntu`、`CentOS/Fedora` 等操作系统。 diff --git a/cases/os/alpine.md b/cases/os/alpine.md index 58cd84225..842644984 100644 --- a/cases/os/alpine.md +++ b/cases/os/alpine.md @@ -33,15 +33,15 @@ $ docker run alpine echo '123' ### 迁移至 `Alpine` 基础镜像 -目前,大部分 Docker 官方镜像都已经支持 Alpine 作为基础镜像,可以很容易进行迁移。 +目前,大部分 Docker 官方镜像都已经支持 `Alpine` 作为基础镜像,可以很容易进行迁移。 例如: -* ubuntu/debian -> alpine -* python:2.7 -> python:2.7-alpine -* ruby:2.3 -> ruby:2.3-alpine +* `ubuntu/debian` -> `alpine` +* `python:3` -> `python:3-alpine` +* `ruby:2.6` -> `ruby:2.6-alpine` -另外,如果使用 `Alpine` 镜像替换 `Ubuntu` 基础镜像,安装软件包时需要用 apk 包管理器替换 apt 工具,如 +另外,如果使用 `Alpine` 镜像替换 `Ubuntu` 基础镜像,安装软件包时需要用 `apk` 包管理器替换 `apt` 工具,如 ```bash $ apk add --no-cache diff --git a/cases/os/busybox.md b/cases/os/busybox.md index 188e33157..e18b0b4a0 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -4,13 +4,13 @@ ![Busybox - Linux 瑞士军刀](_images/busybox-logo.png) -BusyBox 是一个集成了一百多个最常用 Linux 命令和工具(如 cat、echo、grep、mount、telnet 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证,被誉为“Linux 系统的瑞士军刀”。 +`BusyBox` 是一个集成了一百多个最常用 Linux 命令和工具(如 `cat`、`echo`、`grep`、`mount`、`telnet` 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证,被誉为“Linux 系统的瑞士军刀”。 -BusyBox 可运行于多款 POSIX 环境的操作系统中,如 Linux(包括 Android)、Hurd、FreeBSD 等。 +`BusyBox` 可运行于多款 POSIX 环境的操作系统中,如 `Linux`(包括 `Android`)、`Hurd`、`FreeBSD` 等。 ### 获取官方镜像 -在 Docker Hub 中搜索 busybox 相关的镜像。 +在 Docker Hub 中搜索 `busybox` 相关的镜像。 ```bash $ docker search busybox @@ -24,7 +24,7 @@ azukiapp/busybox This image is meant to be used as the base... ... ``` -读者可以看到最受欢迎的镜像同时带有 OFFICIAL 标记,说明它是官方镜像。用户使用 docker pull 指令下载镜像 `busybox:latest`: +读者可以看到最受欢迎的镜像同时带有 `OFFICIAL` 标记,说明它是官方镜像。用户使用 `docker pull` 指令下载 `busybox:latest` 镜像: ```bash $ docker pull busybox:latest @@ -36,7 +36,7 @@ df7546f9f060: Pull complete Status: Downloaded newer image for busybox:latest ``` -下载后,可以看到 busybox 镜像只有2.433 MB: +下载后,可以看到 `busybox` 镜像只有 2.433 MB: ```bash $ docker image ls @@ -46,7 +46,7 @@ busybox latest e72ac664f4f0 6 weeks ago ### 运行 busybox -启动一个 busybox 容器,并在容器中执行 grep 命令。 +启动一个 `busybox` 容器,并在容器中执行 `grep` 命令。 ```bash $ docker run -it busybox @@ -103,7 +103,7 @@ proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime) tmpfs on /proc/kcore type tmpfs (rw,nosuid,mode=755) ``` -busybox 镜像虽然小巧,但包括了大量常见的 Linux 命令,读者可以用它快速熟悉 Linux 命令。 +`busybox` 镜像虽然小巧,但包括了大量常见的 Linux 命令,读者可以用它快速熟悉 Linux 命令。 ### 相关资源 diff --git a/cases/os/centos.md b/cases/os/centos.md index 287a4b543..463607532 100644 --- a/cases/os/centos.md +++ b/cases/os/centos.md @@ -2,11 +2,11 @@ ### CentOS 系统简介 -CentOS 和 Fedora 都是基于 Redhat 的常见 Linux 分支。CentOS 是目前企业级服务器的常用操作系统;Fedora 则主要面向个人桌面用户。 +`CentOS` 和 `Fedora` 都是基于 `Redhat` 的常见 Linux 分支。`CentOS` 是目前企业级服务器的常用操作系统;`Fedora` 则主要面向个人桌面用户。 ![CentOS 操作系统](_images/centos-logo.png) -CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 Red Hat Enterprise Linux 源代码编译而成。由于 CentOS 与 Redhat Linux 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 CentOS 来替代商业版 Red Hat Enterprise Linux。CentOS 自身不包含闭源软件。 +CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 Red Hat Enterprise Linux 源代码编译而成。由于 CentOS 与 Redhat Linux 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 `CentOS` 来替代商业版 Red Hat Enterprise Linux。CentOS 自身不包含闭源软件。 #### 使用 CentOS 官方镜像 @@ -19,7 +19,7 @@ centos The official... 2543 [OK] jdeathe/centos-ssh 27 [OK] ``` -使用 docker run 直接运行最新的 CentOS 镜像,并登录 bash。 +使用 docker run 直接运行最新的 CentOS 镜像,并登录 `bash`。 ```bash $ docker run -it centos bash @@ -36,7 +36,7 @@ CentOS Linux release 7.2.1511 (Core) ![Fedora 操作系统](_images/fedora-logo.png) -Fedora 由 Fedora Project 社区开发,红帽公司赞助的 Linux 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。Fedora 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 Red Hat 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 Red Hat Enterprise Linux中。 +`Fedora` 由 Fedora Project 社区开发,红帽公司赞助的 Linux 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。`Fedora` 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 Red Hat 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 Red Hat Enterprise Linux 中。 #### 使用 Fedora 官方镜像 @@ -51,7 +51,7 @@ gluster/gluster-fedora Official GlusterFS image [ Fedora 21 + Glu... 3 startx/fedora Simple container used for all startx based... 2 [OK] ``` -使用 docker run 命令直接运行 Fedora 官方镜像,并登录 bash。 +使用 `docker run` 命令直接运行 `Fedora` 官方镜像,并登录 `bash`。 ```bash $ docker run -it fedora bash diff --git a/cases/os/debian.md b/cases/os/debian.md index 3cdaa168a..b27bb7dc9 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -1,11 +1,11 @@ ## Debian/Ubuntu -Debian 和 Ubuntu 都是目前较为流行的 Debian 系的服务器操作系统,十分适合研发场景。Docker Hub 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 +`Debian` 和 `Ubuntu` 都是目前较为流行的 Debian 系的服务器操作系统,十分适合研发场景。Docker Hub 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 ### Debian 系统简介 ![Debian 操作系统](_images/debian-logo.png) -Debian 是由 GPL 和其他自由软件许可协议授权的自由软件组成的操作系统,由Debian 计划(Debian Project)组织维护。Debian 计划是一个独立的、分散的组织,由 3000 人志愿者组成,接受世界多个非盈利组织的资金支持,Software in the Public Interest 提供支持并持有商标作为保护机构。Debian 以其坚守 Unix 和自由软件的精神,以及其给予用户的众多选择而闻名。现时 Debian 包括了超过 25,000 个软件包并支持 12 个计算机系统结构。 +`Debian` 是由 `GPL` 和其他自由软件许可协议授权的自由软件组成的操作系统,由 Debian 计划(Debian Project)组织维护。Debian 计划是一个独立的、分散的组织,由 3000 人志愿者组成,接受世界多个非盈利组织的资金支持,Software in the Public Interest 提供支持并持有商标作为保护机构。Debian 以其坚守 Unix 和自由软件的精神,以及其给予用户的众多选择而闻名。现时 Debian 包括了超过 25,000 个软件包并支持 12 个计算机系统结构。 Debian 作为一个大的系统组织框架,其下有多种不同操作系统核心的分支计划,主要为采用 Linux 核心的 Debian GNU/Linux 系统,其他还有采用 GNU Hurd 核心的 Debian GNU/Hurd 系统、采用 FreeBSD 核心的 Debian GNU/kFreeBSD 系统,以及采用 NetBSD 核心的 Debian GNU/NetBSD 系统。甚至还有利用 Debian 的系统架构和工具,采用 OpenSolaris 核心构建而成的 Nexenta OS 系统。在这些 Debian 系统中,以采用 Linux 核心的 Debian GNU/Linux 最为著名。 @@ -63,9 +63,9 @@ tutum/ubuntu Ubuntu image with SSH access. For the root. 根据搜索出来的结果,读者可以自行选择下载镜像并使用。 -下面以 ubuntu 18.04 为例,演示如何使用该镜像安装一些常用软件。 +下面以 `ubuntu:18.04` 为例,演示如何使用该镜像安装一些常用软件。 -首先使用 `-ti` 参数启动容器,登录 bash,查看 ubuntu 的发行版本号。 +首先使用 `-ti` 参数启动容器,登录 `bash`,查看 `ubuntu` 的发行版本号。 ```bash $ docker run -ti ubuntu:18.04 /bin/bash @@ -94,7 +94,7 @@ Reading state information... Done E: Unable to locate package curl ``` -这并非系统不支持 `apt-get` 命令。Docker 镜像在制作时为了精简清除了 apt 仓库信息,因此需要先执行 `apt-get update` 命令来更新仓库信息。更新信息后即可成功通过 apt-get 命令来安装软件。 +这并非系统不支持 `apt-get` 命令。Docker 镜像在制作时为了精简清除了 `apt` 仓库信息,因此需要先执行 `apt-get update` 命令来更新仓库信息。更新信息后即可成功通过 `apt-get` 命令来安装软件。 ```bash root@7d93de07bf76:/# apt-get update diff --git a/cases/os/summary.md b/cases/os/summary.md index 0817e80be..88136dce0 100644 --- a/cases/os/summary.md +++ b/cases/os/summary.md @@ -6,6 +6,6 @@ 读者可以根据具体情况来选择。一般来说: -* 官方镜像体积都比较小,只带有一些基本的组件。 精简的系统有利于安全、稳定和高效的运行,也适合进行定制化。 +* 官方镜像体积都比较小,只带有一些基本的组件。 精简的系统有利于安全、稳定和高效的运行,也适合进行个性化定制。 * 出于安全考虑,几乎所有官方制作的镜像都没有安装 SSH 服务,无法通过用户名和密码直接登录到容器中。 From 803b93c1fc2e166bff8d907e4ff9acef7215ed2f Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 14:48:54 +0800 Subject: [PATCH 007/201] Update format Signed-off-by: Kang HuaiShuai --- README.md | 2 +- advanced_network/example.md | 2 +- cases/ci/travis/README.md | 2 +- coreos/README.md | 6 +++--- swarm_mode/create.md | 2 +- swarm_mode/deploy.md | 2 +- underly/namespace.md | 10 +++++----- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e4622086f..002356db3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/zh-cn),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us_en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F) +* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/zh-cn),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us_en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F), [新版 GitBook](https://gitbook.docker-practice.com/) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) * [英文翻译](https://github.com/yeasy/docker_practice/issues/363) diff --git a/advanced_network/example.md b/advanced_network/example.md index 2bad70204..23ac7af13 100644 --- a/advanced_network/example.md +++ b/advanced_network/example.md @@ -5,4 +5,4 @@ Jérôme Petazzoni 编写了一个叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接。 ### playground -Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的服务器。 +Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 `HTTP` `SMTP` `POP` `IMAP` `Telnet` `SSH` `FTP` 的服务器。 diff --git a/cases/ci/travis/README.md b/cases/ci/travis/README.md index 5d6fbaa62..b845309ec 100644 --- a/cases/ci/travis/README.md +++ b/cases/ci/travis/README.md @@ -44,4 +44,4 @@ after_success: ### 查看结果 -将项目推送到 GitHub, 登录 [Travis CI](https://travis-ci.com/) 查看构建详情。 +将项目推送到 GitHub,登录 [Travis CI](https://travis-ci.com/) 查看构建详情。 diff --git a/coreos/README.md b/coreos/README.md index 90d240f8a..dbde5c5ba 100644 --- a/coreos/README.md +++ b/coreos/README.md @@ -1,7 +1,7 @@ # CoreOS -CoreOS 的设计是为你提供能够像谷歌一样的大型互联网公司一样的基础设施管理能力来动态扩展和管理的计算能力。 +`CoreOS` 的设计是为你提供能够像谷歌一样的大型互联网公司一样的基础设施管理能力来动态扩展和管理的计算能力。 -CoreOS 的安装文件和运行依赖非常小,它提供了精简的 Linux 系统。它使用 Linux 容器在更高的抽象层来管理你的服务,而不是通过常规的 YUM 和 APT 来安装包。 +`CoreOS` 的安装文件和运行依赖非常小,它提供了精简的 Linux 系统。它使用 Linux 容器在更高的抽象层来管理你的服务,而不是通过常规的包管理工具 `yum` 或 `apt` 来安装包。 -同时,CoreOS 几乎可以运行在任何平台:`VirtualBox`, `Amazon EC2`, `QEMU/KVM`, `VMware` 和 `OpenStack` 等 。 +同时,`CoreOS` 几乎可以运行在任何平台:`VirtualBox` `Amazon EC2` `QEMU/KVM` `VMware` `Bare Metal` 和 `OpenStack` 等 。 diff --git a/swarm_mode/create.md b/swarm_mode/create.md index 4e35b6174..a64fb5c57 100644 --- a/swarm_mode/create.md +++ b/swarm_mode/create.md @@ -61,7 +61,7 @@ docker@worker1:~$ docker swarm join \ This node joined a swarm as a worker. ``` ->注意:一些细心的读者可能通过 `docker-machine create --help` 查看到 `--swarm*` 等一系列参数。该参数是用于旧的 `Docker Swarm`,与本章所讲的 `Swarm mode` 没有关系。 +>注意:一些细心的读者可能通过 `docker-machine create --help` 查看到 `--swarm*` 等一系列参数。该参数是用于旧的 `Docker Swarm`,与本章所讲的 `Swarm mode` 没有关系。 ### 查看集群 diff --git a/swarm_mode/deploy.md b/swarm_mode/deploy.md index 9d46c3720..91a84ffd2 100644 --- a/swarm_mode/deploy.md +++ b/swarm_mode/deploy.md @@ -10,7 +10,7 @@ $ docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13.7-alpine ``` -现在我们使用浏览器,输入任意节点 IP ,即可看到 nginx 默认页面。 +现在我们使用浏览器,输入任意节点 IP ,即可看到 nginx 默认页面。 ### 查看服务 diff --git a/underly/namespace.md b/underly/namespace.md index 35cf38653..b4226aff4 100644 --- a/underly/namespace.md +++ b/underly/namespace.md @@ -2,21 +2,21 @@ 命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。 ### pid 命名空间 -不同用户的进程就是通过 pid 命名空间隔离开的,且不同命名空间中可以有相同 pid。所有的 LXC 进程在 Docker 中的父进程为Docker进程,每个 LXC 进程具有不同的命名空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。 +不同用户的进程就是通过 pid 命名空间隔离开的,且不同命名空间中可以有相同 pid。所有的 LXC 进程在 Docker 中的父进程为 Docker 进程,每个 LXC 进程具有不同的命名空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。 ### net 命名空间 -有了 pid 命名空间, 每个命名空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 命名空间实现的, 每个 net 命名空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。Docker 默认采用 veth 的方式,将容器中的虚拟网卡同 host 上的一 个Docker 网桥 docker0 连接在一起。 +有了 pid 命名空间,每个命名空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 命名空间实现的, 每个 net 命名空间有独立的 网络设备,IP 地址,路由表,/proc/net 目录。这样每个容器的网络就能隔离开来。Docker 默认采用 veth 的方式,将容器中的虚拟网卡同 host 上的一 个Docker 网桥 docker0 连接在一起。 ### ipc 命名空间 -容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存等。然而同 VM 不同的是,容器的进程间交互实际上还是 host 上具有相同 pid 命名空间中的进程间交互,因此需要在 IPC 资源申请时加入命名空间信息,每个 IPC 资源有一个唯一的 32 位 id。 +容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存等。然而同 VM 不同的是,容器的进程间交互实际上还是 host 上具有相同 pid 命名空间中的进程间交互,因此需要在 IPC 资源申请时加入命名空间信息,每个 IPC 资源有一个唯一的 32 位 id。 ### mnt 命名空间 类似 chroot,将一个进程放到一个特定的目录执行。mnt 命名空间允许不同命名空间的进程看到的文件结构不同,这样每个命名空间 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个命名空间中的容器在 /proc/mounts 的信息只包含所在命名空间的 mount point。 ### uts 命名空间 -UTS("UNIX Time-sharing System") 命名空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。 +UTS("UNIX Time-sharing System") 命名空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。 ### user 命名空间 -每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。 +每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。 *注:更多关于 Linux 上命名空间的信息,请阅读 [这篇文章](https://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/)。 From 21a811d265524300fda2411d9daadf83bddf9517 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 15:05:06 +0800 Subject: [PATCH 008/201] [install] Fixed error Signed-off-by: Kang HuaiShuai --- install/README.md | 4 ++-- install/mirror.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install/README.md b/install/README.md index 915f7f0d8..eb6180d80 100644 --- a/install/README.md +++ b/install/README.md @@ -2,6 +2,6 @@ Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 -Docker CE 分为 **stable**, **test**, 和 **nightly** 三个更新频道。每六个月发布一个 **stable** 版本 (18.09, 19.03, 19.09...)。 +Docker CE 分为 `stable` `test` 和 `nightly` 三个更新频道。每六个月发布一个 `stable` 版本 (`18.09`, `19.03`, `19.09`...)。 -官方网站上有各种环境下的 [安装指南](https://docs.docker.com/engine/installation/),这里主要介绍 Docker CE 在 Linux 、Windows 10 (PC) 和 macOS 上的安装。 +官方网站上有各种环境下的 [安装指南](https://docs.docker.com/install/),这里主要介绍 Docker CE 在 `Linux` 、`Windows 10` 和 `macOS` 上的安装。 diff --git a/install/mirror.md b/install/mirror.md index 57ee1a3ec..3b7e25e44 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -10,7 +10,7 @@ > 国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考官方文档。 -我们以 Azure 中国镜像 `https://dockerhub.azk8s.cn` 为例进行介绍。 +本节我们以 Azure 中国镜像 `https://dockerhub.azk8s.cn` 为例进行介绍。 ### Ubuntu 16.04+、Debian 8+、CentOS 7 @@ -38,7 +38,7 @@ $ sudo systemctl restart docker ### Windows 10 -对于使用 Windows 10 的系统,在系统右下角托盘 Docker 图标内右键菜单选择 `Settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。 +对于使用 `Windows 10` 的用户,在任务栏托盘 Docker 图标内右键菜单选择 `Settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。 ```json { From f17f29bf4174fff3e81c3ca587f84281bf60ff0c Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 15:29:02 +0800 Subject: [PATCH 009/201] Update format Signed-off-by: Kang HuaiShuai --- cases/os/alpine.md | 2 +- cases/os/busybox.md | 8 ++++---- cases/os/centos.md | 10 +++++----- cases/os/debian.md | 26 +++++++++++++------------- cases/os/summary.md | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cases/os/alpine.md b/cases/os/alpine.md index 842644984..89398ab71 100644 --- a/cases/os/alpine.md +++ b/cases/os/alpine.md @@ -8,7 +8,7 @@ `Alpine` 由非商业组织维护的,支持广泛场景的 `Linux`发行版,它特别为资深/重度`Linux`用户而优化,关注安全,性能和资源效能。`Alpine` 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。 -`Alpine` Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 `Docker` 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 `docker-alpine` 项目。 +`Alpine` Docker 镜像也继承了 `Alpine Linux` 发行版的这些优势。相比于其他 `Docker` 镜像,它的容量非常小,仅仅只有 **5 MB** 左右(对比 `Ubuntu` 系列镜像接近 `200 MB`),且拥有非常友好的包管理机制。官方镜像来自 `docker-alpine` 项目。 目前 Docker 官方已开始推荐使用 `Alpine` 替代之前的 `Ubuntu` 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。 diff --git a/cases/os/busybox.md b/cases/os/busybox.md index e18b0b4a0..16bd26cb3 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -6,11 +6,11 @@ `BusyBox` 是一个集成了一百多个最常用 Linux 命令和工具(如 `cat`、`echo`、`grep`、`mount`、`telnet` 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证,被誉为“Linux 系统的瑞士军刀”。 -`BusyBox` 可运行于多款 POSIX 环境的操作系统中,如 `Linux`(包括 `Android`)、`Hurd`、`FreeBSD` 等。 +`BusyBox` 可运行于多款 `POSIX` 环境的操作系统中,如 `Linux`(包括 `Android`)、`Hurd`、`FreeBSD` 等。 ### 获取官方镜像 -在 Docker Hub 中搜索 `busybox` 相关的镜像。 +在 `Docker Hub` 中搜索 `busybox` 相关的镜像。 ```bash $ docker search busybox @@ -36,7 +36,7 @@ df7546f9f060: Pull complete Status: Downloaded newer image for busybox:latest ``` -下载后,可以看到 `busybox` 镜像只有 2.433 MB: +下载后,可以看到 `busybox` 镜像只有 **2.433 MB**: ```bash $ docker image ls @@ -103,7 +103,7 @@ proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime) tmpfs on /proc/kcore type tmpfs (rw,nosuid,mode=755) ``` -`busybox` 镜像虽然小巧,但包括了大量常见的 Linux 命令,读者可以用它快速熟悉 Linux 命令。 +`busybox` 镜像虽然小巧,但包括了大量常见的 `Linux` 命令,读者可以用它快速熟悉 `Linux` 命令。 ### 相关资源 diff --git a/cases/os/centos.md b/cases/os/centos.md index 463607532..10ed74467 100644 --- a/cases/os/centos.md +++ b/cases/os/centos.md @@ -6,11 +6,11 @@ ![CentOS 操作系统](_images/centos-logo.png) -CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 Red Hat Enterprise Linux 源代码编译而成。由于 CentOS 与 Redhat Linux 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 `CentOS` 来替代商业版 Red Hat Enterprise Linux。CentOS 自身不包含闭源软件。 +CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 `Red Hat Enterprise Linux` 源代码编译而成。由于 `CentOS` 与 `Redhat Linux` 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 `CentOS` 来替代商业版 `Red Hat Enterprise Linux`。`CentOS` 自身不包含闭源软件。 #### 使用 CentOS 官方镜像 -首先使用 `docker search` 命令来搜索标星至少为 25 的 CentOS 相关镜像。 +首先使用 `docker search` 命令来搜索标星至少为 `25` 的 `CentOS` 相关镜像。 ```bash $ docker search -f stars=25 centos @@ -19,7 +19,7 @@ centos The official... 2543 [OK] jdeathe/centos-ssh 27 [OK] ``` -使用 docker run 直接运行最新的 CentOS 镜像,并登录 `bash`。 +使用 `docker run` 直接运行最新的 `CentOS` 镜像,并登录 `bash`。 ```bash $ docker run -it centos bash @@ -36,11 +36,11 @@ CentOS Linux release 7.2.1511 (Core) ![Fedora 操作系统](_images/fedora-logo.png) -`Fedora` 由 Fedora Project 社区开发,红帽公司赞助的 Linux 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。`Fedora` 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 Red Hat 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 Red Hat Enterprise Linux 中。 +`Fedora` 由 `Fedora Project` 社区开发,红帽公司赞助的 `Linux` 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。`Fedora` 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 `Red Hat` 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 `Red Hat Enterprise Linux` 中。 #### 使用 Fedora 官方镜像 -首先使用 `docker search` 命令来搜索标星至少为 2 的 Fedora 相关镜像,结果如下。 +首先使用 `docker search` 命令来搜索标星至少为 `2` 的 `Fedora` 相关镜像,结果如下。 ```bash $ docker search -f stars=2 fedora diff --git a/cases/os/debian.md b/cases/os/debian.md index b27bb7dc9..ce975dde8 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -1,19 +1,19 @@ ## Debian/Ubuntu -`Debian` 和 `Ubuntu` 都是目前较为流行的 Debian 系的服务器操作系统,十分适合研发场景。Docker Hub 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 +`Debian` 和 `Ubuntu` 都是目前较为流行的 **Debian 系** 的服务器操作系统,十分适合研发场景。`Docker Hub` 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 ### Debian 系统简介 ![Debian 操作系统](_images/debian-logo.png) -`Debian` 是由 `GPL` 和其他自由软件许可协议授权的自由软件组成的操作系统,由 Debian 计划(Debian Project)组织维护。Debian 计划是一个独立的、分散的组织,由 3000 人志愿者组成,接受世界多个非盈利组织的资金支持,Software in the Public Interest 提供支持并持有商标作为保护机构。Debian 以其坚守 Unix 和自由软件的精神,以及其给予用户的众多选择而闻名。现时 Debian 包括了超过 25,000 个软件包并支持 12 个计算机系统结构。 +`Debian` 是由 `GPL` 和其他自由软件许可协议授权的自由软件组成的操作系统,由 **Debian 计划(Debian Project)** 组织维护。**Debian 计划** 是一个独立的、分散的组织,由 `3000` 人志愿者组成,接受世界多个非盈利组织的资金支持,`Software in the Public Interest` 提供支持并持有商标作为保护机构。`Debian` 以其坚守 `Unix` 和自由软件的精神,以及其给予用户的众多选择而闻名。现时 `Debian` 包括了超过 `25,000` 个软件包并支持 `12` 个计算机系统结构。 -Debian 作为一个大的系统组织框架,其下有多种不同操作系统核心的分支计划,主要为采用 Linux 核心的 Debian GNU/Linux 系统,其他还有采用 GNU Hurd 核心的 Debian GNU/Hurd 系统、采用 FreeBSD 核心的 Debian GNU/kFreeBSD 系统,以及采用 NetBSD 核心的 Debian GNU/NetBSD 系统。甚至还有利用 Debian 的系统架构和工具,采用 OpenSolaris 核心构建而成的 Nexenta OS 系统。在这些 Debian 系统中,以采用 Linux 核心的 Debian GNU/Linux 最为著名。 +`Debian` 作为一个大的系统组织框架,其下有多种不同操作系统核心的分支计划,主要为采用 `Linux` 核心的 `Debian GNU/Linux` 系统,其他还有采用 `GNU Hurd` 核心的 `Debian GNU/Hurd` 系统、采用 `FreeBSD` 核心的 `Debian GNU/kFreeBSD` 系统,以及采用 `NetBSD` 核心的 `Debian GNU/NetBSD` 系统。甚至还有利用 `Debian` 的系统架构和工具,采用 `OpenSolaris` 核心构建而成的 `Nexenta OS` 系统。在这些 `Debian` 系统中,以采用 `Linux` 核心的 `Debian GNU/Linux` 最为著名。 -众多的 Linux 发行版,例如 Ubuntu、Knoppix 和 Linspire 及 Xandros 等,都基于 Debian GNU/Linux。 +众多的 `Linux` 发行版,例如 `Ubuntu`、`Knoppix` 和 `Linspire` 及 `Xandros` 等,都基于 `Debian GNU/Linux`。 #### 使用 Debian 官方镜像 -读者可以使用 docker search 搜索 Docker Hub,查找 Debian 镜像: +读者可以使用 `docker search` 查找 `Debian` 镜像: ```bash $ docker search debian @@ -24,9 +24,9 @@ armbuild/debian port of debian 8 [OK] ... ``` -官方提供了大家熟知的 debian 镜像以及面向科研领域的 neurodebian 镜像。 +官方提供了大家熟知的 `debian` 镜像以及面向科研领域的 `neurodebian` 镜像。 -可以使用 docker run 直接运行 Debian 镜像。 +可以使用 `docker run` 直接运行 `Debian` 镜像。 ```bash $ docker run -it debian bash @@ -34,17 +34,17 @@ root@668e178d8d69:/# cat /etc/issue Debian GNU/Linux 8 ``` -Debian 镜像很适合作为基础镜像,构建自定义镜像。 +`Debian` 镜像很适合作为基础镜像,构建自定义镜像。 ### Ubuntu 系统简介 ![Ubuntu 操作系统](_images/ubuntu-logo.jpg) -Ubuntu 是一个以桌面应用为主的GNU/Linux操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词(官方译名“友帮拓”,另有“吾帮托”、“乌班图”、“有奔头”或“乌斑兔”等译名)。Ubuntu 意思是“人性”以及“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。 Ubuntu 基于 Debian 发行版和 GNOME/Unity 桌面环境,与 Debian 的不同在于它每 6 个月会发布一个新版本,每 2 年推出一个长期支持(Long Term Support,LTS)版本,一般支持 3 年时间。 +`Ubuntu` 是一个以桌面应用为主的 `GNU/Linux` 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词(官方译名“友帮拓”,另有“吾帮托”、“乌班图”、“有奔头”或“乌斑兔”等译名)。`Ubuntu` 意思是“人性”以及“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。 `Ubuntu` 基于 `Debian` 发行版和 `GNOME/Unity` 桌面环境,与 `Debian` 的不同在于它每 6 个月会发布一个新版本,每 2 年推出一个长期支持 **(Long Term Support,LTS)** 版本,一般支持 3 年时间。 #### 使用 Ubuntu 官方镜像 -Ubuntu 相关的镜像有很多,这里使用 `--filter=stars=10` 参数,只搜索那些被收藏 10 次以上的镜像。 +`Ubuntu` 相关的镜像有很多,这里使用 `--filter=stars=10` 参数,只搜索那些被收藏 `10` 次以上的镜像。 ```bash $ docker search --filter=stars=10 ubuntu @@ -106,7 +106,7 @@ Get:1 http://archive.ubuntu.com trusty Release.gpg [933 B] ... ``` -首先,安装 curl 工具。 +首先,安装 `curl` 工具。 ```bash root@7d93de07bf76:/# apt-get install curl @@ -125,7 +125,7 @@ root@7d93de07bf76:/# curl curl: try 'curl --help' or 'curl --manual' for more information ``` -接下来,再安装 apache 服务。 +接下来,再安装 `apache` 服务。 ```bash root@7d93de07bf76:/# apt-get install -y apache2 @@ -138,7 +138,7 @@ The following extra packages will be installed: ... ``` -启动这个 apache 服务,然后使用 curl 来测试本地访问。 +启动这个 `apache` 服务,然后使用 `curl` 来测试本地访问。 ```bash root@7d93de07bf76:/# service apache2 start diff --git a/cases/os/summary.md b/cases/os/summary.md index 88136dce0..48afe0436 100644 --- a/cases/os/summary.md +++ b/cases/os/summary.md @@ -2,7 +2,7 @@ 本章讲解了典型操作系统镜像的下载和使用。 -除了官方的镜像外,在 Docker Hub 上还有许多第三方组织或个人上传的 Docker 镜像。 +除了官方的镜像外,在 `Docker Hub` 上还有许多第三方组织或个人上传的 Docker 镜像。 读者可以根据具体情况来选择。一般来说: From f260e3ba88551b7540b9e7a14160a6565ea5bd07 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 16:50:32 +0800 Subject: [PATCH 010/201] Add wechat group Signed-off-by: Kang HuaiShuai --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 002356db3..26f81731b 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,13 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 * QQ 群 IX (已满):571502246 * QQ 群 X (可加):145983035 ->如果有问题,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。 +>如果有容器相关的疑问,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。 + +

+ +

+ +

微信扫码 加入群聊~

## 进阶学习 From 224fbe9fedb1960be84806dd1019c2c22bf65828 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 20 Sep 2019 16:51:04 +0800 Subject: [PATCH 011/201] Fixed outdated content Signed-off-by: Kang HuaiShuai --- SUMMARY.md | 2 +- appendix/repo/nodejs.md | 4 ++-- cases/ci/README.md | 6 +++--- cases/ci/drone/README.md | 2 +- cases/ci/drone/{.image => _images}/drone-build.png | Bin 5 files changed, 7 insertions(+), 7 deletions(-) rename cases/ci/drone/{.image => _images}/drone-build.png (100%) diff --git a/SUMMARY.md b/SUMMARY.md index 64897ab19..b2a8b868e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -156,11 +156,11 @@ * [CentOS](appendix/repo/centos.md) * [Nginx](appendix/repo/nginx.md) * [PHP](appendix/repo/php.md) + * [Node.js](appendix/repo/nodejs.md) * [MySQL](appendix/repo/mysql.md) * [WordPress](appendix/repo/wordpress.md) * [MongoDB](appendix/repo/mongodb.md) * [Redis](appendix/repo/redis.md) - * [Node.js](appendix/repo/nodejs.md) * [附录三:Docker 命令查询](appendix/command/README.md) * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) diff --git a/appendix/repo/nodejs.md b/appendix/repo/nodejs.md index 10b24b10d..38503a9d3 100644 --- a/appendix/repo/nodejs.md +++ b/appendix/repo/nodejs.md @@ -11,7 +11,7 @@ 在项目中创建一个 Dockerfile。 ```bash -FROM node:9 +FROM node:12 # replace this with your application's default port EXPOSE 8888 ``` @@ -31,7 +31,7 @@ $ docker run -it --rm \ # -v "$(pwd)":/usr/src/myapp \ --mount type=bind,src=`$(pwd)`,target=/usr/src/myapp \ -w /usr/src/myapp \ - node:9-alpine \ + node:12-alpine \ node your-daemon-or-script.js ``` diff --git a/cases/ci/README.md b/cases/ci/README.md index 40910184d..e304f68ec 100644 --- a/cases/ci/README.md +++ b/cases/ci/README.md @@ -1,7 +1,7 @@ # CI/CD -持续集成(Continuous integration)是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 +**持续集成(Continuous integration)** 是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 -持续部署(continuous deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。 +**持续部署(continuous deployment)** 是通过自动化的构建、测试和部署循环来快速交付高质量的产品。 -与 `Jenkins` 不同的是,基于 Docker 的 CI/CD 每一步都运行在 Docker 镜像中,所以理论上支持所有的编程语言。 +与 `Jenkins` 不同的是,基于 Docker 的 CI/CD 每一步都运行在 Docker 容器中,所以理论上支持所有的编程语言。 diff --git a/cases/ci/drone/README.md b/cases/ci/drone/README.md index 994eb114c..69271c39a 100644 --- a/cases/ci/drone/README.md +++ b/cases/ci/drone/README.md @@ -86,7 +86,7 @@ $ git push origin master 打开我们部署好的 `Drone` 网站或者 Drone Cloud,即可看到构建结果。 -![](.image/drone-build.png) +![](_images/drone-build.png) 当然我们也可以把构建结果上传到 GitHub,Docker Registry,云服务商提供的对象存储,或者生产环境中。 diff --git a/cases/ci/drone/.image/drone-build.png b/cases/ci/drone/_images/drone-build.png similarity index 100% rename from cases/ci/drone/.image/drone-build.png rename to cases/ci/drone/_images/drone-build.png From 38e810a407a8b2dc808ed87ee6d6a520fc5c55be Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 25 Sep 2019 10:30:12 +0800 Subject: [PATCH 012/201] [install] Fixed script install, default channel is stable Signed-off-by: Kang HuaiShuai --- install/centos.md | 5 +++-- install/debian.md | 5 +++-- install/fedora.md | 5 +++-- install/raspberry-pi.md | 5 +++-- install/ubuntu.md | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/install/centos.md b/install/centos.md index 8c986a700..d0d2ec3d0 100644 --- a/install/centos.md +++ b/install/centos.md @@ -74,14 +74,15 @@ $ sudo yum install docker-ce ### 使用脚本自动安装 -在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装: +在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: ```bash $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun +# $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的 Edge 版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 ### 启动 Docker CE diff --git a/install/debian.md b/install/debian.md index fa7f7fa5e..3d38b1f28 100644 --- a/install/debian.md +++ b/install/debian.md @@ -78,14 +78,15 @@ $ sudo apt-get install docker-ce ### 使用脚本自动安装 -在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装: +在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: ```bash $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun +# $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的 Edge 版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 ### 启动 Docker CE diff --git a/install/fedora.md b/install/fedora.md index 0f235e99c..dfd4d4f8a 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -92,14 +92,15 @@ $ sudo dnf -y install docker-ce-18.06.1.ce ### 使用脚本自动安装 -在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装: +在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: ```bash $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun +# $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 最新版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 最新稳定(stable)版本安装在系统中。 ### 启动 Docker CE diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 4a15a035e..5d04de4df 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -70,14 +70,15 @@ $ sudo apt-get install docker-ce ### 使用脚本自动安装 -在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspbian 系统上可以使用这套脚本安装: +在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspbian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: ```bash $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun +# $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的 Edge 版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 ### 启动 Docker CE diff --git a/install/ubuntu.md b/install/ubuntu.md index ad6e20060..9cd599d35 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -81,14 +81,15 @@ $ sudo apt-get install docker-ce ### 使用脚本自动安装 -在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装: +在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: ```bash $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun +# $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的 Edge 版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 ### 启动 Docker CE From b11cac80fb9e910457dea4fc0316eb138ab06ebf Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 25 Sep 2019 10:49:40 +0800 Subject: [PATCH 013/201] [Registry Mirror] Update mirror Signed-off-by: Kang HuaiShuai --- machine/usage.md | 4 ++-- repository/registry.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/machine/usage.md b/machine/usage.md index 3330fafd9..f9b90d416 100644 --- a/machine/usage.md +++ b/machine/usage.md @@ -16,7 +16,7 @@ $ docker-machine create -d virtualbox test `--engine-opt dns=114.114.114.114` 配置 Docker 的默认 DNS -`--engine-registry-mirror https://registry.docker-cn.com` 配置 Docker 的仓库镜像 +`--engine-registry-mirror https://dockerhub.azk8s.cn` 配置 Docker 的仓库镜像 `--virtualbox-memory 2048` 配置主机内存 @@ -37,7 +37,7 @@ $ docker-machine create \ -d xhyve \ # --xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso \ --engine-opt dns=114.114.114.114 \ - --engine-registry-mirror https://registry.docker-cn.com \ + --engine-registry-mirror https://dockerhub.azk8s.cn \ --xhyve-memory-size 2048 \ --xhyve-rawdisk \ --xhyve-cpu-count 2 \ diff --git a/repository/registry.md b/repository/registry.md index 9b11e1caa..bacc3a150 100644 --- a/repository/registry.md +++ b/repository/registry.md @@ -104,7 +104,7 @@ REPOSITORY TAG IMAGE ID CREAT ```json { "registry-mirror": [ - "https://registry.docker-cn.com" + "https://dockerhub.azk8s.cn" ], "insecure-registries": [ "192.168.199.100:5000" @@ -116,4 +116,4 @@ REPOSITORY TAG IMAGE ID CREAT ### 其他 -对于 Docker Desktop for Windows 、 Docker Desktop for Mac 在设置中编辑 `daemon.json` 增加和上边一样的字符串即可。 +对于 Docker Desktop for Windows 、 Docker Desktop for Mac 在设置中的 `Docker Engine` 中进行编辑 ,增加和上边一样的字符串即可。 From 3923858f00702efa2ccd1e93b96ecba9f40f5991 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 25 Sep 2019 11:00:57 +0800 Subject: [PATCH 014/201] Update format Signed-off-by: Kang HuaiShuai --- introduction/README.md | 4 ++-- introduction/what.md | 10 +++++----- introduction/why.md | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/introduction/README.md b/introduction/README.md index 55f5dac92..2907907a5 100644 --- a/introduction/README.md +++ b/introduction/README.md @@ -1,7 +1,7 @@ # 简介 -本章将带领你进入 Docker 的世界。 +本章将带领你进入 **Docker** 的世界。 -什么是 Docker? +什么是 **Docker**? 用它会带来什么样的好处? diff --git a/introduction/what.md b/introduction/what.md index 84060c501..dd568dd5f 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -1,10 +1,10 @@ ## 什么是 Docker -Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://www.opencontainers.org/)。 +**Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,它是基于 `dotCloud` 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。`Docker` 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://www.opencontainers.org/)。 -Docker 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 2 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,[dotCloud 公司决定改名为 Docker](https://blog.docker.com/2013/10/dotcloud-is-becoming-docker-inc/)。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。 +**Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 4 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://blog.docker.com/2013/10/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 -Docker 使用 Google 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 Linux 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [AUFS](https://en.wikipedia.org/wiki/Aufs) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 +**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [AUFS](https://en.wikipedia.org/wiki/Aufs) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 ![Docker 架构](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/media/docker-on-linux.png) @@ -12,9 +12,9 @@ Docker 使用 Google 公司推出的 [Go 语言](https://golang.org/) 进行开 > `containerd` 是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。 -Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。 +**Docker** 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 `Docker` 技术比虚拟机技术更为轻便、快捷。 -下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。 +下面的图片比较了 **Docker** 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。 ![传统虚拟化](_images/virtualization.png) diff --git a/introduction/why.md b/introduction/why.md index 0f7ae0823..d083044f1 100644 --- a/introduction/why.md +++ b/introduction/why.md @@ -1,34 +1,34 @@ ## 为什么要使用 Docker? -作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。 +作为一种新兴的虚拟化方式,`Docker` 跟传统的虚拟化方式相比具有众多的优势。 ### 更高效的利用系统资源 -由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。 +由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,`Docker` 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。 ### 更快速的启动时间 -传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。 +传统的虚拟机技术启动应用服务往往需要数分钟,而 `Docker` 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。 ### 一致的运行环境 -开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 *「这段代码在我机器上没问题啊」* 这类问题。 +开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 `Docker` 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 *「这段代码在我机器上没问题啊」* 这类问题。 ### 持续交付和部署 对开发和运维([DevOps](https://zh.wikipedia.org/wiki/DevOps))人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。 -使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 [Dockerfile](../image/dockerfile/) 来进行镜像构建,并结合 [持续集成(Continuous Integration)](https://en.wikipedia.org/wiki/Continuous_integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 [持续部署(Continuous Delivery/Deployment)](https://en.wikipedia.org/wiki/Continuous_delivery) 系统进行自动部署。 +使用 `Docker` 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 [Dockerfile](../image/dockerfile/) 来进行镜像构建,并结合 [持续集成(Continuous Integration)](https://en.wikipedia.org/wiki/Continuous_integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 [持续部署(Continuous Delivery/Deployment)](https://en.wikipedia.org/wiki/Continuous_delivery) 系统进行自动部署。 -而且使用 `Dockerfile` 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。 +而且使用 [`Dockerfile`](../image/build.md) 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。 ### 更轻松的迁移 -由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。 +由于 `Docker` 确保了执行环境的一致性,使得应用的迁移更加容易。`Docker` 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。 ### 更轻松的维护和扩展 -Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 [官方镜像](https://hub.docker.com/search/?type=image&image_filter=official),既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。 +`Docker` 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,`Docker` 团队同各个开源项目团队一起维护了一大批高质量的 [官方镜像](https://hub.docker.com/search/?type=image&image_filter=official),既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。 ### 对比传统虚拟机总结 From 008f01592b02ca86e6591a99cd03ace50c7f7a74 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 25 Sep 2019 11:04:01 +0800 Subject: [PATCH 015/201] Update docker hub Signed-off-by: Kang HuaiShuai --- repository/dockerhub.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 2284b9cbd..7ed35aafb 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -1,6 +1,6 @@ ## Docker Hub -目前 Docker 官方维护了一个公共仓库 [Docker Hub](https://hub.docker.com/),其中已经包括了数量超过 15,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。 +目前 Docker 官方维护了一个公共仓库 [Docker Hub](https://hub.docker.com/),其中已经包括了数量超过 [2,650,000](https://hub.docker.com/search/?type=image) 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。 ### 注册 From a3647ec3a3f65f4062a0b407fae83d33ca15d679 Mon Sep 17 00:00:00 2001 From: uscwifi <42139780+uscwifi@users.noreply.github.com> Date: Sat, 5 Oct 2019 23:18:48 +0800 Subject: [PATCH 016/201] Update centos.md --- appendix/repo/centos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appendix/repo/centos.md b/appendix/repo/centos.md index 96b7d7192..3ef727ff0 100644 --- a/appendix/repo/centos.md +++ b/appendix/repo/centos.md @@ -4,7 +4,7 @@ [CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致。 -该仓库位于 `https://hub.docker.com/_/centos` ,提供了 CentOS 从 5 ~ 7 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/centos` ,提供了 CentOS 从 5 ~ 8 各个版本的镜像。 ### 使用方法 From c788212aad0502dd36659d254296aa3758460b20 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 29 Oct 2019 14:31:45 +0800 Subject: [PATCH 017/201] Use vuepress build book Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 14 ++ .gitignore | 1 + .vuepress/config.js | 352 +++++++++++++++++++++++++++++ CHANGELOG.md | 3 +- CONTRIBUTING.md | 2 +- SUMMARY.md | 4 +- appendix/best_practices.md | 28 +-- appendix/faq/README.md | 11 +- basic_concept/container.md | 2 +- basic_concept/image.md | 4 +- basic_concept/repository.md | 6 +- cases/ci/travis/README.md | 2 +- compose/django.md | 2 +- compose/rails.md | 4 +- compose/usage.md | 2 +- image/build.md | 12 +- image/buildkit.md | 2 +- image/buildx.md | 148 ++++++++++++ image/buildx_multi-arch-images.md | 78 +++++++ image/commit.md | 4 +- image/demo/multi-arch/Dockerfile | 5 + image/dockerfile/add.md | 4 +- image/dockerfile/cmd.md | 8 +- image/dockerfile/copy.md | 6 +- image/dockerfile/entrypoint.md | 6 +- image/dockerfile/env.md | 2 +- image/dockerfile/healthcheck.md | 2 +- image/dockerfile/onbuild.md | 10 +- image/dockerfile/user.md | 4 +- image/dockerfile/volume.md | 2 +- image/manifest.md | 4 +- image/multistage-builds/README.md | 12 +- image/multistage-builds/laravel.md | 10 +- introduction/what.md | 2 +- introduction/why.md | 16 +- 35 files changed, 690 insertions(+), 84 deletions(-) create mode 100644 .vuepress/config.js create mode 100644 image/buildx.md create mode 100644 image/buildx_multi-arch-images.md create mode 100644 image/demo/multi-arch/Dockerfile diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2a9b40867..24b1f2e83 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,3 +16,17 @@ jobs: uses: docker://yeasy/docker_practice with: args: build + - name: vuepress + run: | + npx vuepress build + - name: Upload Vuepress dist + uses: docker://pcit/pages + env: + PCIT_EMAIL: khs1994@khs1994.com + PCIT_GIT_TOKEN: ${{ secrets.PCIT_GIT_TOKEN }} + PCIT_GIT_URL: github.com/docker-practice/vuepress + PCIT_KEEP_HISTORY: "1" + PCIT_LOCAL_DIR: .vuepress/dist + PCIT_MESSAGE: Sync from yeasy/docker-practice@${{github.sha}} by PCIT + PCIT_TARGET_BRANCH: master + PCIT_USERNAME: khs1994 diff --git a/.gitignore b/.gitignore index e9372eb0f..5bd7cae1d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ _book/ *.edx .DS_Store node_modules/ +.vuepress/dist diff --git a/.vuepress/config.js b/.vuepress/config.js new file mode 100644 index 000000000..094378553 --- /dev/null +++ b/.vuepress/config.js @@ -0,0 +1,352 @@ +module.exports = { + title: 'Docker 从入门到实践', + base: '/', + themeConfig: { + docsRepo: 'yeasy/docker_practice', + docsDir: '/', + editLinks: true, + nav: [{ + text: '安装 Docker', + link: '/install/', + }, + { + text: 'Docker 入门', + link: '/' + }, + { + text: 'Docker 实战', + link: '/cases/os/' + }, + { + text: 'CI/CD', + link: '/cases/ci/' + }, + { + text: 'Docker 仓库', + link: '/repository/' + }, + { + text: '底层实现', + link: '/underly/', + }, + { + text: 'Compose', + link: '/compose/', + }, + { + text: 'Kubernetes', + link: '/kubernetes/', + }, + { + text: 'GitHub', + link: 'https://github.com/yeasy/docker_practice' + }, + // { + // text: '捐赠', + // link: '' + // }, + { + text: '腾讯云容器服务', + link: 'https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' + }, + // { + // text: '语言', + // items: [{ + // text: 'English', + // link: '' + // }] + // } + ], + sidebar: { + '/kubernetes/': [ + 'intro', + 'quickstart', + 'concepts', + 'kubectl', + 'design', + ], + '/compose/': [ + 'introduction', + 'install', + 'usage', + 'commands', + 'compose_file', + 'django', + 'rails', + 'wordpress', + ], + '/install/': [ + '/install/', + 'ubuntu', + 'debian', + 'fedora', + 'centos', + 'raspberry-pi', + 'mac', + 'windows', + 'mirror', + ], + '/underly/': [ + '/underly/', + 'arch', + 'namespace', + 'cgroups', + 'ufs', + 'container_format', + 'network', + ], + '/repository/': [ + '/repository/', + 'dockerhub', + 'registry', + 'registry_auth', + 'nexus3_registry', + ], + '/cases/os/': [ + { + title: "操作系统", + collapsable:false, + children: [ + '/cases/os/', + 'busybox', + 'alpine', + 'debian', + 'centos', + 'summary', + ], + }, + ], + '/cases/ci/': [ + '/cases/ci/', + '/cases/ci/actions/', + { + title: "Drone", + collapsable: false, + children: [ + 'drone/', + 'drone/install' + ] + }, + 'travis/' + ], + '/': [ + '/', + '/CHANGELOG', + '/CONTRIBUTING', + { + title: "Docker 简介", + collapsable: false, + children: [ + '/introduction/', + '/introduction/what', + '/introduction/why', + ] + },{ + title: "基本概念", + collapsable: false, + children: [ + '/basic_concept/', + '/basic_concept/image', + '/basic_concept/container', + '/basic_concept/repository' + ] + }, + { + title: "使用镜像", + collapsable: false, + children: [ + '/image/', + '/image/pull', + '/image/list', + '/image/rm', + '/image/commit', + '/image/build', + '/image/other.md', + '/image/internal.md', + ] + }, + { + title: 'Dockerfile', + collapsable: false, + children: [ + "/image/dockerfile/", + '/image/dockerfile/copy', + '/image/dockerfile/add', + '/image/dockerfile/cmd', + '/image/dockerfile/entrypoint', + '/image/dockerfile/env', + '/image/dockerfile/arg', + '/image/dockerfile/volume', + '/image/dockerfile/expose', + '/image/dockerfile/workdir', + '/image/dockerfile/user', + '/image/dockerfile/healthcheck', + '/image/dockerfile/onbuild', + '/image/dockerfile/references', + '/image/multistage-builds/', + '/image/multistage-builds/laravel', + '/image/manifest', + '/image/buildx_multi-arch-images', + '/image/buildkit', + '/image/buildx', + ] + },{ + title: "操作容器", + collapsable: false, + children: [ + 'container/', + 'container/run', + 'container/daemon', + 'container/stop', + 'container/attach_exec', + 'container/import_export', + 'container/rm', + ], + }, + { + title: "数据管理", + collapsable:false, + children: [ + 'data_management/', + 'data_management/volume', + 'data_management/bind-mounts', + ], + },{ + title: "使用网络", + collapsable:false, + children: [ + 'network/', + 'network/port_mapping', + 'network/linking', + 'network/dns', + ], + }, + { + title: "高级网络配置", + collapsable:false, + children: [ + 'advanced_network/', + 'advanced_network/quick_guide', + 'advanced_network/access_control', + 'advanced_network/port_mapping', + 'advanced_network/bridge', + 'advanced_network/example', + 'advanced_network/config_file', + 'advanced_network/ptp', + ], + }, + { + title: "Swarm mode", + collapsable:false, + children: [ + 'swarm_mode/', + 'swarm_mode/overview', + 'swarm_mode/create', + 'swarm_mode/deploy', + 'swarm_mode/stack', + 'swarm_mode/secret', + 'swarm_mode/config', + 'swarm_mode/rolling_update', + ], + }, + { + title: "安全", + collapsable: false, + children: [ + 'security/', + 'security/kernel_ns', + 'security/control_group', + 'security/daemon_sec', + 'security/kernel_capability', + 'security/other_feature', + 'security/summary', + ], + }, + { + title: "Etcd", + collapsable:false, + children: [ + 'etcd/', + 'etcd/intro', + 'etcd/install', + 'etcd/cluster', + 'etcd/etcdctl', + ], + }, + { + title: "Fedora CoreOS", + collapsable: false, + children: [ + 'coreos/', + 'coreos/intro', + 'coreos/intro_tools', + ], + }, + { + title: "容器与云计算", + collapsable:false, + children: [ + 'cloud/', + 'cloud/intro', + 'cloud/aws', + 'cloud/tencentCloud', + 'cloud/alicloud', + 'cloud/summary', + ], + }, + { + title: "Docker 开源项目", + collapsable:false, + children:[ + 'opensource/', + 'opensource/linuxkit', + ], + }, + { + title: "附录", + collapsable:false, + children: [ + 'appendix/', + 'appendix/faq/', + 'appendix/repo/', + 'appendix/repo/ubuntu', + 'appendix/repo/centos', + 'appendix/repo/nginx', + 'appendix/repo/php', + 'appendix/repo/nodejs', + 'appendix/repo/mysql', + 'appendix/repo/wordpress', + 'appendix/repo/mongodb', + 'appendix/repo/redis', + 'appendix/command/', + 'appendix/best_practices', + 'appendix/debug', + 'appendix/resources' + ], + }, + { + title: "Docker Machine", + collapsable: false, + children: [ + 'machine/', + 'machine/install', + 'machine/usage', + ], + }, + { + title: 'Mesos', + collapsable: false, + children: [ + '/mesos/intro', + '/mesos/installation', + '/mesos/architecture', + '/mesos/configuration', + '/mesos/monitor', + '/mesos/framework', + '/mesos/summary', + ] + }, + ], + }, + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 055b45edc..dd7d2e578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ -## 主要修订记录 +# 修订记录 * 1.1.0 2019-12-31 * 全面支持 v19.x 新版本 * 增加 `BuildKit` + * 增加 `docker buildx` 命令使用说明 * 增加 `docker manifest` 命令使用说明 * 移除 `Ubuntu 14.04` `Debian 8` `Debian 7` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a2460660..65162c145 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`。 diff --git a/SUMMARY.md b/SUMMARY.md index b2a8b868e..3496d9b26 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -42,7 +42,9 @@ * [Dockerfile 多阶段构建](image/multistage-builds/README.md) * [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md) * [构建多种系统架构支持的 Docker 镜像](image/manifest.md) - * [使用 BuildKit 构建镜像](image/buildkit.md) + * [使用 buildx 构建多种系统架构支持的 Docker 镜像](image/buildx_multi-arch-images.md) + * [Docker v18.09 版本使用 BuildKit 构建镜像](image/buildkit.md) + * [Docker v19.03 版本使用 BuildKit 构建镜像](image/buildx.md) * [其它制作镜像的方式](image/other.md) * [实现原理](image/internal.md) * [操作容器](container/README.md) diff --git a/appendix/best_practices.md b/appendix/best_practices.md index 1aa165fe7..e93f8e2ec 100644 --- a/appendix/best_practices.md +++ b/appendix/best_practices.md @@ -36,7 +36,7 @@ 下面是来自 `buildpack-deps` 镜像的例子: -```dockerfile +```docker RUN apt-get update && apt-get install -y \ bzr \ cvs \ @@ -72,7 +72,7 @@ RUN apt-get update && apt-get install -y \ >注意:如果你的字符串中包含空格,必须将字符串放入引号中或者对空格使用转义。如果字符串内容本身就包含引号,必须对引号使用转义。 -```dockerfile +```docker # Set one or more individual labels LABEL com.example.version="0.0.1-beta" @@ -85,7 +85,7 @@ LABEL com.example.version.is-production="" 一个镜像可以包含多个标签,但建议将多个标签放入到一个 `LABEL` 指令中。 -```dockerfile +```docker # Set multiple labels at once, using line-continuation characters to break long lines LABEL vendor=ACME\ Incorporated \ com.example.is-beta= \ @@ -108,7 +108,7 @@ LABEL vendor=ACME\ Incorporated \ 永远将 `RUN apt-get update` 和 `apt-get install` 组合成一条 `RUN` 声明,例如: -```dockerfile +```docker RUN apt-get update && apt-get install -y \ package-bar \ package-baz \ @@ -117,7 +117,7 @@ RUN apt-get update && apt-get install -y \ 将 `apt-get update` 放在一条单独的 `RUN` 声明中会导致缓存问题以及后续的 `apt-get install` 失败。比如,假设你有一个 `Dockerfile` 文件: -```dockerfile +```docker FROM ubuntu:18.04 RUN apt-get update @@ -127,7 +127,7 @@ RUN apt-get install -y curl 构建镜像后,所有的层都在 Docker 的缓存中。假设你后来又修改了其中的 `apt-get install` 添加了一个包: -```dockerfile +```docker FROM ubuntu:18.04 RUN apt-get update @@ -139,7 +139,7 @@ Docker 发现修改后的 `RUN apt-get update` 指令和之前的完全一样。 使用 `RUN apt-get update && apt-get install -y` 可以确保你的 Dockerfiles 每次安装的都是包的最新的版本,而且这个过程不需要进一步的编码或额外干预。这项技术叫作 `cache busting`。你也可以显示指定一个包的版本号来达到 `cache-busting`,这就是所谓的固定版本,例如: -```dockerfile +```docker RUN apt-get update && apt-get install -y \ package-bar \ package-baz \ @@ -150,7 +150,7 @@ RUN apt-get update && apt-get install -y \ 下面是一个 `RUN` 指令的示例模板,展示了所有关于 `apt-get` 的建议。 -```dockerfile +```docker RUN apt-get update && apt-get install -y \ aufs-tools \ automake \ @@ -193,7 +193,7 @@ RUN apt-get update && apt-get install -y \ 最后,`ENV` 也能用于设置常见的版本号,比如下面的示例: -```dockerfile +```docker ENV PG_MAJOR 9.3 ENV PG_VERSION 9.3.4 @@ -211,7 +211,7 @@ ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH 如果你的 `Dockerfile` 有多个步骤需要使用上下文中不同的文件。单独 `COPY` 每个文件,而不是一次性的 `COPY` 所有文件,这将保证每个步骤的构建缓存只在特定的文件变化时失效。例如: -```dockerfile +```docker COPY requirements.txt /tmp/ RUN pip install --requirement /tmp/requirements.txt @@ -223,7 +223,7 @@ COPY . /tmp/ 为了让镜像尽量小,最好不要使用 `ADD` 指令从远程 URL 获取包,而是使用 `curl` 和 `wget`。这样你可以在文件提取完之后删掉不再需要的文件来避免在镜像中额外添加一层。比如尽量避免下面的用法: -```dockerfile +```docker ADD http://example.com/big.tar.xz /usr/src/things/ RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things @@ -233,7 +233,7 @@ RUN make -C /usr/src/things all 而是应该使用下面这种方法: -```dockerfile +```docker RUN mkdir -p /usr/src/things \ && curl -SL http://example.com/big.tar.xz \ | tar -xJC /usr/src/things \ @@ -250,7 +250,7 @@ RUN mkdir -p /usr/src/things \ 例如,下面的示例镜像提供了命令行工具 `s3cmd`: -```dockerfile +```docker ENTRYPOINT ["s3cmd"] CMD ["--help"] @@ -295,7 +295,7 @@ exec "$@" 该辅助脚本被拷贝到容器,并在容器启动时通过 `ENTRYPOINT` 执行: -```dockerfile +```docker COPY ./docker-entrypoint.sh / ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/appendix/faq/README.md b/appendix/faq/README.md index cd91454af..5870c85bd 100644 --- a/appendix/faq/README.md +++ b/appendix/faq/README.md @@ -52,11 +52,18 @@ ### 如何获取某个容器的 PID 信息? -答:可以使用 `docker inspect --format '{{ .State.Pid }}' ` 命令。 +答:可以使用 + +```bash +docker inspect --format '{{ .State.Pid }}' +``` ### 如何获取某个容器的 IP 地址? -答:可以使用 `docker inspect --format '{{ .NetworkSettings.IPAddress }}' ` 命令 +答:可以使用 +```bash +docker inspect --format '{{ .NetworkSettings.IPAddress }}' +``` ### 如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变? diff --git a/basic_concept/container.md b/basic_concept/container.md index aafb4093d..cd1dd441b 100644 --- a/basic_concept/container.md +++ b/basic_concept/container.md @@ -1,4 +1,4 @@ -## Docker 容器 +# Docker 容器 镜像(`Image`)和容器(`Container`)的关系,就像是面向对象程序设计中的 `类` 和 `实例` 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 diff --git a/basic_concept/image.md b/basic_concept/image.md index 6e4443e7f..5718a1556 100644 --- a/basic_concept/image.md +++ b/basic_concept/image.md @@ -1,10 +1,10 @@ -## Docker 镜像 +# Docker 镜像 我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 `root` 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 `root` 文件系统。比如官方镜像 `ubuntu:18.04` 就包含了完整的一套 Ubuntu 18.04 最小系统的 `root` 文件系统。 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 -### 分层存储 +## 分层存储 因为镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。 diff --git a/basic_concept/repository.md b/basic_concept/repository.md index c1dae8242..f7255873d 100644 --- a/basic_concept/repository.md +++ b/basic_concept/repository.md @@ -1,4 +1,4 @@ -## Docker Registry +# Docker Registry 镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,[Docker Registry](../repository/registry.md) 就是这样的服务。 @@ -10,7 +10,7 @@ 仓库名经常以 *两段式路径* 形式出现,比如 `jwilder/nginx-proxy`,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。 -### Docker Registry 公开服务 +## Docker Registry 公开服务 Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 @@ -20,7 +20,7 @@ Docker Registry 公开服务是开放给用户使用、允许用户管理镜像 国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [时速云镜像仓库](https://hub.tenxcloud.com/)、[网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com) 等。 -### 私有 Docker Registry +## 私有 Docker Registry 除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 [Docker Registry](https://hub.docker.com/_/registry/) 镜像,可以直接使用做为私有 Registry 服务。在 [私有仓库](../repository/registry.md) 一节中,会有进一步的搭建私有 Registry 服务的讲解。 diff --git a/cases/ci/travis/README.md b/cases/ci/travis/README.md index b845309ec..d3337da6d 100644 --- a/cases/ci/travis/README.md +++ b/cases/ci/travis/README.md @@ -10,7 +10,7 @@ 在项目根目录新建一个 `Dockerfile` 文件。 -```dockerfile +```docker FROM alpine RUN echo "Hello World" diff --git a/compose/django.md b/compose/django.md index ce8fd7c41..c0f9f455c 100644 --- a/compose/django.md +++ b/compose/django.md @@ -8,7 +8,7 @@ 第一步,因为应用将要运行在一个满足所有环境依赖的 Docker 容器里面,那么我们可以通过编辑 `Dockerfile` 文件来指定 Docker 容器要安装内容。内容如下: -```dockerfile +```docker FROM python:3 ENV PYTHONUNBUFFERED 1 RUN mkdir /code diff --git a/compose/rails.md b/compose/rails.md index 96b2bb8f5..66db4a5c3 100644 --- a/compose/rails.md +++ b/compose/rails.md @@ -8,7 +8,7 @@ 首先,因为应用将要运行在一个满足所有环境依赖的 Docker 容器里面,那么我们可以通过编辑 `Dockerfile` 文件来指定 Docker 容器要安装内容。内容如下: -```dockerfile +```docker FROM ruby RUN apt-get update -qq && apt-get install -y build-essential libpq-dev RUN mkdir /myapp @@ -117,5 +117,3 @@ $ docker-compose run web rake db:create ``` 这个 web 应用已经开始在你的 docker 守护进程里面监听着 3000 端口了。 - -![](../_images/docker-compose-rails-screenshot.png) diff --git a/compose/usage.md b/compose/usage.md index 7f3d8b515..39cef0c6b 100644 --- a/compose/usage.md +++ b/compose/usage.md @@ -40,7 +40,7 @@ if __name__ == "__main__": 编写 `Dockerfile` 文件,内容为 -```dockerfile +```docker FROM python:3.6-alpine ADD . /code WORKDIR /code diff --git a/image/build.md b/image/build.md index ed2ca60e0..135207ddb 100644 --- a/image/build.md +++ b/image/build.md @@ -16,7 +16,7 @@ $ touch Dockerfile 其内容为: -```dockerfile +```docker FROM nginx RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html ``` @@ -33,7 +33,7 @@ RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html 除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 `scratch`。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。 -```dockerfile +```docker FROM scratch ... ``` @@ -48,7 +48,7 @@ FROM scratch * *shell* 格式:`RUN <命令>`,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 `RUN` 指令就是这种格式。 -```Dockerfile +```docker RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html ``` @@ -56,7 +56,7 @@ RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html 既然 `RUN` 就像 Shell 脚本一样可以执行命令,那么我们是否就可以像 Shell 脚本一样把每个命令对应一个 RUN 呢?比如这样: -```dockerfile +```docker FROM debian:stretch RUN apt-get update @@ -77,7 +77,7 @@ RUN make -C /usr/src/redis install 上面的 `Dockerfile` 正确的写法应该是这样: -```dockerfile +```docker FROM debian:stretch RUN buildDeps='gcc libc6-dev make wget' \ @@ -142,7 +142,7 @@ docker build [选项] <上下文路径/URL/-> 如果在 `Dockerfile` 中这么写: -```Dockerfile +```docker COPY ./package.json /app/ ``` diff --git a/image/buildkit.md b/image/buildkit.md index cf82aa636..7dc176f43 100644 --- a/image/buildkit.md +++ b/image/buildkit.md @@ -6,7 +6,7 @@ **注意:docker-compose build 命令暂时不支持 BuildKit** -下面介绍如何在 Docker CE 18.09+ 版本中使用 `BuildKit` 提供的 `Dockerfile` 新指令来更快、更安全的构建 Docker 镜像。 +下面介绍如何在 Docker CE 18.09 版本中使用 `BuildKit` 提供的 `Dockerfile` 新指令来更快、更安全的构建 Docker 镜像。 ### 启用 `BuildKit` diff --git a/image/buildx.md b/image/buildx.md new file mode 100644 index 000000000..a6ef6c796 --- /dev/null +++ b/image/buildx.md @@ -0,0 +1,148 @@ +## 使用 `Buildx` 构建镜像 + +**BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。 + +**注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(Docker Hub 自动构建、腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)** + +下面介绍如何在 Docker CE 19.03+ 版本中使用 `BuildKit` 提供的 `Dockerfile` 新指令来更快、更安全的构建 Docker 镜像。 + +### `Dockerfile` 新增指令详解 + +启用 `BuildKit` 之后,我们可以使用下面几个新的指令来加快镜像构建。为了使用 `BuildKit` 我们 **必须** 使用新的 `$ docker buildx build` 命令来构建 Docker 镜像。 + +#### `RUN --mount=type=cache` + +目前,几乎所有的程序都会使用依赖管理工具,例如 `Go` 中的 `go mod`、`Node.js` 中的 `npm` 等等,当我们构建一个镜像时,往往会重复的从互联网中获取依赖包,难以缓存,大大降低了镜像的构建效率。 + +例如一个前端工程需要用到 `npm`: + +```docker +FROM node:alpine as builder + +WORKDIR /app + +COPY package.json /app/ + +RUN npm i --registry=https://registry.npm.taobao.org \ + && rm -rf ~/.npm + +COPY src /app/src + +RUN npm run build + +FROM nginx:alpine + +COPY --from=builder /app/dist /app/dist +``` + +使用多阶段构建,构建的镜像中只包含了目标文件夹 `dist`,但仍然存在一些问题,当 `package.json` 文件变动时,`RUN npm i && rm -rf ~/.npm` 这一层会重新执行,变更多次后,生成了大量的中间层镜像。 + +为解决这个问题,进一步的我们可以设想一个类似 **数据卷** 的功能,在镜像构建时把 `node_modules` 文件夹挂载上去,在构建完成后,这个 `node_modules` 文件夹会自动卸载,实际的镜像中并不包含 `node_modules` 这个文件夹,这样我们就省去了每次获取依赖的时间,大大增加了镜像构建效率,同时也避免了生成了大量的中间层镜像。 + +`BuildKit` 提供了 `RUN --mount=type=cache` 指令,可以实现上边的设想。 + +```docker +FROM node:alpine as builder + +WORKDIR /app + +COPY package.json /app/ + +RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ + --mount=type=cache,target=/root/.npm,id=npm_cache \ + npm i --registry=https://registry.npm.taobao.org + +COPY src /app/src + +RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ +# --mount=type=cache,target=/app/dist,id=my_app_dist,sharing=locked \ + npm run build + +FROM nginx:alpine + +# COPY --from=builder /app/dist /app/dist + +# 为了更直观的说明 from 和 source 指令,这里使用 RUN 指令 +RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \ + # --mount=type=cache,target/tmp/dist,from=my_app_dist,sharing=locked \ + mkdir -p /app/dist && cp -r /tmp/dist/* /app/dist +``` + +第一个 `RUN` 指令执行后,`id` 为 `my_app_npm_module` 的缓存文件夹挂载到了 `/app/node_modules` 文件夹中。多次执行也不会产生多个中间层镜像。 + +第二个 `RUN` 指令执行时需要用到 `node_modules` 文件夹,`node_modules` 已经挂载,命令也可以正确执行。 + +第三个 `RUN` 指令将上一阶段产生的文件复制到指定位置,`from` 指明缓存的来源,这里 `builder` 表示缓存来源于构建的第一阶段,`source` 指明缓存来源的文件夹。 + +上面的 `Dockerfile` 中 `--mount=type=cache,...` 中指令作用如下: + +|Option |Description| +|---------------------|-----------| +|`id` | `id` 设置一个标志,以便区分缓存。| +|`target` (必填项) | 缓存的挂载目标文件夹。| +|`ro`,`readonly` | 只读,缓存文件夹不能被写入。 | +|`sharing` | 有 `shared` `private` `locked` 值可供选择。`sharing` 设置当一个缓存被多次使用时的表现,由于 `BuildKit` 支持并行构建,当多个步骤使用同一缓存时(同一 `id`)会发生冲突。`shared` 表示多个步骤可以同时读写,`private` 表示当多个步骤使用同一缓存时,每个步骤使用不同的缓存,`locked` 表示当一个步骤完成释放缓存后,后一个步骤才能继续使用该缓存。| +|`from` | 缓存来源(构建阶段),不填写时为空文件夹。| +|`source` | 来源的文件夹路径。| + +#### `RUN --mount=type=bind` + +该指令可以将一个镜像(或上一构建阶段)的文件挂载到指定位置。 + +```docker +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` 文件系统挂载到指定位置。 + +```docker +RUN --mount=type=tmpfs,target=/temp \ + mount | grep /temp +``` + +#### `RUN --mount=type=secret` + +该指令可以将一个文件挂载到指定位置。 + +```docker +RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \ + cat /root/.aws/credentials +``` + +```bash +$ docker buildx build -t test --secret id=aws,src=$HOME/.aws/credentials . +``` + +#### `RUN --mount=type=ssh` + +该指令可以挂载 `ssh` 密钥。 + +```docker +FROM alpine +RUN apk add --no-cache openssh-client +RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts +RUN --mount=type=ssh ssh git@gitlab.com | tee /hello +``` + +```bash +$ eval $(ssh-agent) +$ ssh-add ~/.ssh/id_rsa +(Input your passphrase here) + +$ docker buildx build -t test --ssh default=$SSH_AUTH_SOCK . +``` + +### 清理构建缓存 + +执行以下命令清理构建缓存 + +```bash +$ docker builder prune +``` + +### 官方文档 + +* https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md diff --git a/image/buildx_multi-arch-images.md b/image/buildx_multi-arch-images.md new file mode 100644 index 000000000..62ead2bd5 --- /dev/null +++ b/image/buildx_multi-arch-images.md @@ -0,0 +1,78 @@ +# 使用 buildx 构建多种系统架构支持的 Docker 镜像 + +在之前的版本中构建多种系统架构支持的 Docker 镜像,要想使用统一的名字必须使用 [`$ docker manifest`](manifest.md) 命令。 + +在 Docker 19.03+ 版本中可以使用 `$ docker buildx build` 命令使用 `BuildKit` 构建镜像。 + +该命令支持 `--platform` 参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。 + +## 设置环境变量 + +`buildx` 命令属于实验特性,必须设置环境变量以使用该命令。 + +Linux/macOS + +```bash +$ export DOCKER_CLI_EXPERIMENTAL=enabled +``` + +Windows + +```bash +$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled +``` + +## 新建 `builder` 实例 + +Docker for Linux 不支持构建 `arm` 架构镜像,我们可以运行一个新的容器让其支持该特性,Docker 桌面版无需进行此项设置。 + +```bash +$ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3 +``` + +由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。 + +```bash +$ docker buildx create --name mybuilder + +$ docker buildx use mybuilder +``` + +## 构建镜像 + +新建 Dockerfile 文件。 + +```docker +FROM --platform=$TARGETPLATFORM alpine + +RUN uname -a > /os.txt + +CMD cat /os.txt +``` + +使用 `$ docker buildx build` 命令构建镜像,注意将 `myusername` 替换为自己的 Docker Hub 用户名。 + +`--push` 参数表示将构建好的镜像推送到 Docker 仓库。 + +```bash +$ docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t myusername/hello . --push + +# 查看镜像信息 +$ docker buildx imagetools inspect myusername/hello +``` + +在不同架构运行该镜像,可以得到该架构的信息。 + +```bash +# arm +$ docker run -it --rm myusername/hello +Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 armv7l Linux + +# arm64 +$ docker run -it --rm myusername/hello +Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 aarch64 Linux + +# amd64 +$ docker run -it --rm myusername/hello +Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 Linux +``` diff --git a/image/commit.md b/image/commit.md index 37664cb68..6f921e546 100644 --- a/image/commit.md +++ b/image/commit.md @@ -21,7 +21,7 @@ $ docker run --name webserver -d -p 80:80 nginx 直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。 - +![](_images/images-mac-example-nginx.png) 现在,假设我们非常不喜欢这个欢迎页面,我们希望改成欢迎 Docker 的文字,我们可以使用 `docker exec` 命令进入容器,修改其内容。 @@ -38,7 +38,7 @@ exit 现在我们再刷新浏览器的话,会发现内容被改变了。 - +![](_images/images-create-nginx-docker.png) 我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 `docker diff` 命令看到具体的改动。 diff --git a/image/demo/multi-arch/Dockerfile b/image/demo/multi-arch/Dockerfile new file mode 100644 index 000000000..9fbaba74e --- /dev/null +++ b/image/demo/multi-arch/Dockerfile @@ -0,0 +1,5 @@ +FROM --platform=$TARGETPLATFORM alpine + +RUN uname -a > /os.txt + +CMD cat /os.txt diff --git a/image/dockerfile/add.md b/image/dockerfile/add.md index 3c3a2dcf7..5d9f18f25 100644 --- a/image/dockerfile/add.md +++ b/image/dockerfile/add.md @@ -8,7 +8,7 @@ 在某些情况下,这个自动解压缩的功能非常有用,比如官方镜像 `ubuntu` 中: -```Dockerfile +```docker FROM scratch ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz / ... @@ -24,7 +24,7 @@ ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz / 在使用该指令的时候还可以加上 `--chown=:` 选项来改变文件的所属用户及所属组。 -```Dockerfile +```docker ADD --chown=55:mygroup files* /mydir/ ADD --chown=bin files* /mydir/ ADD --chown=1 files* /mydir/ diff --git a/image/dockerfile/cmd.md b/image/dockerfile/cmd.md index d21c61184..9877c00e5 100644 --- a/image/dockerfile/cmd.md +++ b/image/dockerfile/cmd.md @@ -14,13 +14,13 @@ 如果使用 `shell` 格式的话,实际的命令会被包装为 `sh -c` 的参数的形式进行执行。比如: -```Dockerfile +```docker CMD echo $HOME ``` 在实际执行中,会将其变更为: -```Dockerfile +```docker CMD [ "sh", "-c", "echo $HOME" ] ``` @@ -32,7 +32,7 @@ Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是 一些初学者将 `CMD` 写为: -```Dockerfile +```docker CMD service nginx start ``` @@ -44,6 +44,6 @@ CMD service nginx start 正确的做法是直接执行 `nginx` 可执行文件,并且要求以前台形式运行。比如: -```Dockerfile +```docker CMD ["nginx", "-g", "daemon off;"] ``` diff --git a/image/dockerfile/copy.md b/image/dockerfile/copy.md index 53914a46a..d12b446c8 100644 --- a/image/dockerfile/copy.md +++ b/image/dockerfile/copy.md @@ -9,13 +9,13 @@ `COPY` 指令将从构建上下文目录中 `<源路径>` 的文件/目录复制到新的一层的镜像内的 `<目标路径>` 位置。比如: -```Dockerfile +```docker COPY package.json /usr/src/app/ ``` `<源路径>` 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 [`filepath.Match`](https://golang.org/pkg/path/filepath/#Match) 规则,如: -```Dockerfile +```docker COPY hom* /mydir/ COPY hom?.txt /mydir/ ``` @@ -26,7 +26,7 @@ COPY hom?.txt /mydir/ 在使用该指令的时候还可以加上 `--chown=:` 选项来改变文件的所属用户及所属组。 -```Dockerfile +```docker COPY --chown=55:mygroup files* /mydir/ COPY --chown=bin files* /mydir/ COPY --chown=1 files* /mydir/ diff --git a/image/dockerfile/entrypoint.md b/image/dockerfile/entrypoint.md index 07e79e034..25090dd46 100644 --- a/image/dockerfile/entrypoint.md +++ b/image/dockerfile/entrypoint.md @@ -16,7 +16,7 @@ 假设我们需要一个得知自己当前公网 IP 的镜像,那么可以先用 `CMD` 来实现: -```Dockerfile +```docker FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ @@ -48,7 +48,7 @@ $ docker run myip curl -s https://ip.cn -i 这显然不是很好的解决方案,而使用 `ENTRYPOINT` 就可以解决这个问题。现在我们重新用 `ENTRYPOINT` 来实现这个镜像: -```Dockerfile +```docker FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ @@ -91,7 +91,7 @@ Connection: keep-alive 这些准备工作是和容器 `CMD` 无关的,无论 `CMD` 为什么,都需要事先进行一个预处理的工作。这种情况下,可以写一个脚本,然后放入 `ENTRYPOINT` 中去执行,而这个脚本会将接到的参数(也就是 ``)作为命令,在脚本最后执行。比如官方镜像 `redis` 中就是这么做的: -```Dockerfile +```docker FROM alpine:3.4 ... RUN addgroup -S redis && adduser -S -G redis redis diff --git a/image/dockerfile/env.md b/image/dockerfile/env.md index 58108bdfb..f55d567d8 100644 --- a/image/dockerfile/env.md +++ b/image/dockerfile/env.md @@ -16,7 +16,7 @@ ENV VERSION=1.0 DEBUG=on \ 定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。比如在官方 `node` 镜像 `Dockerfile` 中,就有类似这样的代码: -```Dockerfile +```docker ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ diff --git a/image/dockerfile/healthcheck.md b/image/dockerfile/healthcheck.md index 7daa2e3d9..78a83a6db 100644 --- a/image/dockerfile/healthcheck.md +++ b/image/dockerfile/healthcheck.md @@ -25,7 +25,7 @@ 假设我们有个镜像是个最简单的 Web 服务,我们希望增加健康检查来判断其 Web 服务是否在正常工作,我们可以用 `curl` 来帮助判断,其 `Dockerfile` 的 `HEALTHCHECK` 可以这么写: -```Dockerfile +```docker FROM nginx RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* HEALTHCHECK --interval=5s --timeout=3s \ diff --git a/image/dockerfile/onbuild.md b/image/dockerfile/onbuild.md index 0c2e02257..dbe1384a0 100644 --- a/image/dockerfile/onbuild.md +++ b/image/dockerfile/onbuild.md @@ -8,7 +8,7 @@ 假设我们要制作 Node.js 所写的应用的镜像。我们都知道 Node.js 使用 `npm` 进行包管理,所有依赖、配置、启动信息等会放到 `package.json` 文件里。在拿到程序代码后,需要先进行 `npm install` 才可以获得所有需要的依赖。然后就可以通过 `npm start` 来启动应用。因此,一般来说会这样写 `Dockerfile`: -```Dockerfile +```docker FROM node:slim RUN mkdir /app WORKDIR /app @@ -24,7 +24,7 @@ CMD [ "npm", "start" ] 那么我们可不可以做一个基础镜像,然后各个项目使用这个基础镜像呢?这样基础镜像更新,各个项目不用同步 `Dockerfile` 的变化,重新构建后就继承了基础镜像的更新?好吧,可以,让我们看看这样的结果。那么上面的这个 `Dockerfile` 就会变为: -```Dockerfile +```docker FROM node:slim RUN mkdir /app WORKDIR /app @@ -33,7 +33,7 @@ CMD [ "npm", "start" ] 这里我们把项目相关的构建指令拿出来,放到子项目里去。假设这个基础镜像的名字为 `my-node` 的话,各个项目内的自己的 `Dockerfile` 就变为: -```Dockerfile +```docker FROM my-node COPY ./package.json /app RUN [ "npm", "install" ] @@ -46,7 +46,7 @@ COPY . /app/ `ONBUILD` 可以解决这个问题。让我们用 `ONBUILD` 重新写一下基础镜像的 `Dockerfile`: -```Dockerfile +```docker FROM node:slim RUN mkdir /app WORKDIR /app @@ -58,7 +58,7 @@ CMD [ "npm", "start" ] 这次我们回到原始的 `Dockerfile`,但是这次将项目相关的指令加上 `ONBUILD`,这样在构建基础镜像的时候,这三行并不会被执行。然后各个项目的 `Dockerfile` 就变成了简单地: -```Dockerfile +```docker FROM my-node ``` diff --git a/image/dockerfile/user.md b/image/dockerfile/user.md index 68af82200..260b439b1 100644 --- a/image/dockerfile/user.md +++ b/image/dockerfile/user.md @@ -6,7 +6,7 @@ 当然,和 `WORKDIR` 一样,`USER` 只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。 -```Dockerfile +```docker RUN groupadd -r redis && useradd -r -g redis redis USER redis RUN [ "redis-server" ] @@ -14,7 +14,7 @@ RUN [ "redis-server" ] 如果以 `root` 执行的脚本,在执行期间希望改变身份,比如希望以某个已经建立好的用户来运行某个服务进程,不要使用 `su` 或者 `sudo`,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 [`gosu`](https://github.com/tianon/gosu)。 -```Dockerfile +```docker # 建立 redis 用户,并使用 gosu 换另一个用户执行命令 RUN groupadd -r redis && useradd -r -g redis redis # 下载 gosu diff --git a/image/dockerfile/volume.md b/image/dockerfile/volume.md index 59dca9c4d..d27172f6a 100644 --- a/image/dockerfile/volume.md +++ b/image/dockerfile/volume.md @@ -7,7 +7,7 @@ 之前我们说过,容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,后面的章节我们会进一步介绍 Docker 卷的概念。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 `Dockerfile` 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。 -```Dockerfile +```docker VOLUME /data ``` diff --git a/image/manifest.md b/image/manifest.md index 0c98c7860..e77eb40c3 100644 --- a/image/manifest.md +++ b/image/manifest.md @@ -2,11 +2,11 @@ 我们知道使用镜像创建一个容器,该镜像必须与 Docker 宿主机系统架构一致,例如 `Linux x86_64` 架构的系统中只能使用 `Linux x86_64` 的镜像创建容器。 -> macOS 除外,其使用了 [binfmt_misc](https://docs.docker.com/docker-for-mac/multi-arch/) 提供了多种架构支持,在 macOS 系统上 (x86_64) 可以运行 arm 等其他架构的镜像。 +> Windows、macOS 除外,其使用了 [binfmt_misc](https://docs.docker.com/docker-for-mac/multi-arch/) 提供了多种架构支持,在 Windows、macOS 系统上 (x86_64) 可以运行 arm 等其他架构的镜像。 例如我们在 `Linux x86_64` 中构建一个 `username/test` 镜像。 -```Dockerfile +```docker FROM alpine CMD echo 1 diff --git a/image/multistage-builds/README.md b/image/multistage-builds/README.md index 59c37071e..97a61610f 100644 --- a/image/multistage-builds/README.md +++ b/image/multistage-builds/README.md @@ -26,7 +26,7 @@ func main(){ 编写 `Dockerfile.one` 文件 -```dockerfile +```docker FROM golang:1.9-alpine RUN apk --no-cache add git ca-certificates @@ -56,7 +56,7 @@ $ docker build -t go/helloworld:1 -f Dockerfile.one . 例如,编写 `Dockerfile.build` 文件 -```dockerfile +```docker FROM golang:1.9-alpine RUN apk --no-cache add git @@ -71,7 +71,7 @@ RUN go get -d -v github.com/go-sql-driver/mysql \ 编写 `Dockerfile.copy` 文件 -```dockerfile +```docker FROM alpine:latest RUN apk --no-cache add ca-certificates @@ -125,7 +125,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB 例如,编写 `Dockerfile` 文件 -```dockerfile +```docker FROM golang:1.9-alpine as builder RUN apk --no-cache add git @@ -172,7 +172,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB 我们可以使用 `as` 来为某一阶段命名,例如 -```dockerfile +```docker FROM golang:1.9-alpine as builder ``` @@ -186,6 +186,6 @@ $ docker build --target builder -t username/imagename:tag . 上面例子中我们使用 `COPY --from=0 /go/src/github.com/go/helloworld/app .` 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。 -```dockerfile +```docker $ COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf ``` diff --git a/image/multistage-builds/laravel.md b/image/multistage-builds/laravel.md index e8c8f10ac..5d7a44b10 100644 --- a/image/multistage-builds/laravel.md +++ b/image/multistage-builds/laravel.md @@ -50,7 +50,7 @@ server { 第一阶段进行前端构建。 -```dockerfile +```docker FROM node:alpine as frontend COPY package.json /app/ @@ -69,7 +69,7 @@ RUN cd /app \ 第二阶段安装 Composer 依赖。 -```dockerfile +```docker FROM composer as composer COPY database/ /app/database/ @@ -89,7 +89,7 @@ RUN cd /app \ 第三阶段对以上阶段生成的文件进行整合。 -```dockerfile +```docker FROM php:7.2-fpm-alpine as laravel ARG LARAVEL_PATH=/app/laravel @@ -113,7 +113,7 @@ RUN cd ${LARAVEL_PATH} \ ### 最后一个阶段构建 NGINX 镜像 -```dockerfile +```docker FROM nginx:alpine as nginx ARG LARAVEL_PATH=/app/laravel @@ -164,7 +164,7 @@ $ docker run -it --rm --network=laravel -p 8080:80 my/nginx 完整的 `Dockerfile` 文件如下。 -```dockerfile +```docker FROM node:alpine as frontend COPY package.json /app/ diff --git a/introduction/what.md b/introduction/what.md index dd568dd5f..1351afeaf 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -1,4 +1,4 @@ -## 什么是 Docker +# 什么是 Docker **Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,它是基于 `dotCloud` 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。`Docker` 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://www.opencontainers.org/)。 diff --git a/introduction/why.md b/introduction/why.md index d083044f1..df6ce2c11 100644 --- a/introduction/why.md +++ b/introduction/why.md @@ -1,20 +1,20 @@ -## 为什么要使用 Docker? +# 为什么要使用 Docker? 作为一种新兴的虚拟化方式,`Docker` 跟传统的虚拟化方式相比具有众多的优势。 -### 更高效的利用系统资源 +## 更高效的利用系统资源 由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,`Docker` 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。 -### 更快速的启动时间 +## 更快速的启动时间 传统的虚拟机技术启动应用服务往往需要数分钟,而 `Docker` 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。 -### 一致的运行环境 +## 一致的运行环境 开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 `Docker` 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 *「这段代码在我机器上没问题啊」* 这类问题。 -### 持续交付和部署 +## 持续交付和部署 对开发和运维([DevOps](https://zh.wikipedia.org/wiki/DevOps))人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。 @@ -22,15 +22,15 @@ 而且使用 [`Dockerfile`](../image/build.md) 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。 -### 更轻松的迁移 +## 更轻松的迁移 由于 `Docker` 确保了执行环境的一致性,使得应用的迁移更加容易。`Docker` 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。 -### 更轻松的维护和扩展 +## 更轻松的维护和扩展 `Docker` 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,`Docker` 团队同各个开源项目团队一起维护了一大批高质量的 [官方镜像](https://hub.docker.com/search/?type=image&image_filter=official),既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。 -### 对比传统虚拟机总结 +## 对比传统虚拟机总结 | 特性 | 容器 | 虚拟机 | | :-------- | :-------- | :---------- | From fadf84bb69465a0a11b5cc33a7b2d4e701173d5d Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 5 Nov 2019 19:26:45 +0800 Subject: [PATCH 018/201] Archive docker-machine mesos docker-swarm, close #425 Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 7 +++++++ SUMMARY.md | 27 ++++++++++++++------------- archive/README.md | 3 +++ 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 archive/README.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 094378553..fbdc4a69f 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -324,6 +324,13 @@ module.exports = { 'appendix/resources' ], }, + { + title: "归档", + collapsable: false, + children: [ + 'archive/', + ], + }, { title: "Docker Machine", collapsable: false, diff --git a/SUMMARY.md b/SUMMARY.md index 3496d9b26..f3bd82b85 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -75,7 +75,7 @@ * [工具和示例](advanced_network/example.md) * [编辑网络配置文件](advanced_network/config_file.md) * [实例:创建一个点到点连接](advanced_network/ptp.md) -* [Docker 三剑客之 Compose 项目](compose/README.md) +* [Docker Compose](compose/README.md) * [简介](compose/introduction.md) * [安装与卸载](compose/install.md) * [使用](compose/usage.md) @@ -84,10 +84,6 @@ * [实战 Django](compose/django.md) * [实战 Rails](compose/rails.md) * [实战 WordPress](compose/wordpress.md) -* [Docker 三剑客之 Machine 项目](machine/README.md) - * [安装](machine/install.md) - * [使用](machine/usage.md) -* [Docker 三剑客之 Docker Swarm](swarm/README.md) * [Swarm mode](swarm_mode/README.md) * [基本概念](swarm_mode/overview.md) * [创建 Swarm 集群](swarm_mode/create.md) @@ -124,14 +120,6 @@ * [基本概念](kubernetes/concepts.md) * [kubectl 使用](kubernetes/kubectl.md) * [架构设计](kubernetes/design.md) -* [Mesos - 优秀的集群资源调度平台](mesos/README.md) - * [Mesos 简介](mesos/intro.md) - * [安装与使用](mesos/installation.md) - * [原理与架构](mesos/architecture.md) - * [Mesos 配置项解析](mesos/configuration.md) - * [日志与监控](mesos/monitor.md) - * [常见应用框架](mesos/framework.md) - * [本章小结](mesos/summary.md) * [容器与云计算](cloud/README.md) * [简介](cloud/intro.md) * [亚马逊云](cloud/aws.md) @@ -167,3 +155,16 @@ * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) +* [归档](archive/README.md) + * [Mesos - 优秀的集群资源调度平台](mesos/README.md) + * [Mesos 简介](mesos/intro.md) + * [安装与使用](mesos/installation.md) + * [原理与架构](mesos/architecture.md) + * [Mesos 配置项解析](mesos/configuration.md) + * [日志与监控](mesos/monitor.md) + * [常见应用框架](mesos/framework.md) + * [本章小结](mesos/summary.md) + * [Docker Machine](machine/README.md) + * [安装](machine/install.md) + * [使用](machine/usage.md) + * [Docker Swarm](swarm/README.md) diff --git a/archive/README.md b/archive/README.md new file mode 100644 index 000000000..042dde31c --- /dev/null +++ b/archive/README.md @@ -0,0 +1,3 @@ +# 归档项目 + +以下项目不被官方支持或内容陈旧,将在下一版本中删除。 From eb274b16f6d933235d27178b6872dac49add3664 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 5 Nov 2019 21:50:05 +0800 Subject: [PATCH 019/201] Add Docker Buildx Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 2 +- .vuepress/config.js | 15 +- SUMMARY.md | 7 +- buildx/README.md | 5 + {image => buildx}/buildkit.md | 48 ++---- buildx/buildx.md | 33 ++++ .../multi-arch-images.md | 26 +-- image/buildx.md | 148 ------------------ 8 files changed, 69 insertions(+), 215 deletions(-) create mode 100644 buildx/README.md rename {image => buildx}/buildkit.md (85%) create mode 100644 buildx/buildx.md rename image/buildx_multi-arch-images.md => buildx/multi-arch-images.md (78%) delete mode 100644 image/buildx.md diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 24b1f2e83..62c10c980 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,6 +27,6 @@ jobs: PCIT_GIT_URL: github.com/docker-practice/vuepress PCIT_KEEP_HISTORY: "1" PCIT_LOCAL_DIR: .vuepress/dist - PCIT_MESSAGE: Sync from yeasy/docker-practice@${{github.sha}} by PCIT + PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master PCIT_USERNAME: khs1994 diff --git a/.vuepress/config.js b/.vuepress/config.js index fbdc4a69f..18948e3c3 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -3,7 +3,7 @@ module.exports = { base: '/', themeConfig: { docsRepo: 'yeasy/docker_practice', - docsDir: '/', + docsDir: '/vuepress', editLinks: true, nav: [{ text: '安装 Docker', @@ -186,9 +186,6 @@ module.exports = { '/image/multistage-builds/', '/image/multistage-builds/laravel', '/image/manifest', - '/image/buildx_multi-arch-images', - '/image/buildkit', - '/image/buildx', ] },{ title: "操作容器", @@ -262,6 +259,16 @@ module.exports = { 'security/summary', ], }, + { + title: "Docker Buildx", + collapsable: false, + children: [ + "buildx/", + "buildx/buildkit", + "buildx/buildx", + "buildx/multi-arch-images", + ], + }, { title: "Etcd", collapsable:false, diff --git a/SUMMARY.md b/SUMMARY.md index f3bd82b85..4dc717700 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -42,9 +42,6 @@ * [Dockerfile 多阶段构建](image/multistage-builds/README.md) * [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md) * [构建多种系统架构支持的 Docker 镜像](image/manifest.md) - * [使用 buildx 构建多种系统架构支持的 Docker 镜像](image/buildx_multi-arch-images.md) - * [Docker v18.09 版本使用 BuildKit 构建镜像](image/buildkit.md) - * [Docker v19.03 版本使用 BuildKit 构建镜像](image/buildx.md) * [其它制作镜像的方式](image/other.md) * [实现原理](image/internal.md) * [操作容器](container/README.md) @@ -75,6 +72,10 @@ * [工具和示例](advanced_network/example.md) * [编辑网络配置文件](advanced_network/config_file.md) * [实例:创建一个点到点连接](advanced_network/ptp.md) +* [Docker Buildx](buildx/README.md) + * [BuildKit](buildx/buildkit.md) + * [使用 buildx 构建镜像](buildx/buildx.md) + * [使用 buildx 构建多种系统架构支持的 Docker 镜像](buildx/multi-arch-images.md) * [Docker Compose](compose/README.md) * [简介](compose/introduction.md) * [安装与卸载](compose/install.md) diff --git a/buildx/README.md b/buildx/README.md new file mode 100644 index 000000000..1408b3bc8 --- /dev/null +++ b/buildx/README.md @@ -0,0 +1,5 @@ +# Docker Buildx + +Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。 + +> 该功能仅适用于 Docker v19.03+ 版本 diff --git a/image/buildkit.md b/buildx/buildkit.md similarity index 85% rename from image/buildkit.md rename to buildx/buildkit.md index 7dc176f43..f1b7e9f1d 100644 --- a/image/buildkit.md +++ b/buildx/buildkit.md @@ -1,4 +1,4 @@ -## 使用 `BuildKit` 构建镜像 +# 使用 `BuildKit` 构建镜像 **BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。 @@ -6,31 +6,11 @@ **注意:docker-compose build 命令暂时不支持 BuildKit** -下面介绍如何在 Docker CE 18.09 版本中使用 `BuildKit` 提供的 `Dockerfile` 新指令来更快、更安全的构建 Docker 镜像。 +## `Dockerfile` 新增指令详解 -### 启用 `BuildKit` +启用 `BuildKit` 之后,我们可以使用下面几个新的 `Dockerfile` 指令来加快镜像构建。 -启用 `BuildKit` 必须先设置 **环境变量**。 - -Linux、macOS 执行如下命令: - -```bash -$ export DOCKER_BUILDKIT=1 -``` - -Windows 执行如下命令: - -```powershell -$ set $env:DOCKER_BUILDKIT=1 -``` - -> 以上是设置环境变量的临时方法,若使环境变量永久生效请读者自行设置。 - -### `Dockerfile` 新增指令详解 - -启用 `BuildKit` 之后,我们可以使用下面几个新的指令来加快镜像构建。 - -#### `RUN --mount=type=cache` +### `RUN --mount=type=cache` 目前,几乎所有的程序都会使用依赖管理工具,例如 `Go` 中的 `go mod`、`Node.js` 中的 `npm` 等等,当我们构建一个镜像时,往往会重复的从互联网中获取依赖包,难以缓存,大大降低了镜像的构建效率。 @@ -112,7 +92,7 @@ RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \ |`from` | 缓存来源(构建阶段),不填写时为空文件夹。| |`source` | 来源的文件夹路径。| -#### `RUN --mount=type=bind` +### `RUN --mount=type=bind` 该指令可以将一个镜像(或上一构建阶段)的文件挂载到指定位置。 @@ -122,7 +102,7 @@ RUN --mount=type=bind,from=php:alpine,source=/usr/local/bin/docker-php-entrypoin cat /docker-php-entrypoint ``` -#### `RUN --mount=type=tmpfs` +### `RUN --mount=type=tmpfs` 该指令可以将一个 `tmpfs` 文件系统挂载到指定位置。 @@ -132,9 +112,9 @@ RUN --mount=type=tmpfs,target=/temp \ mount | grep /temp ``` -#### `RUN --mount=type=secret` +### `RUN --mount=type=secret` -该指令可以将一个文件挂载到指定位置。 +该指令可以将一个文件(例如密钥)挂载到指定位置。 ```docker # syntax = docker/dockerfile:experimental @@ -146,7 +126,7 @@ RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \ $ docker build -t test --secret id=aws,src=$HOME/.aws/credentials . ``` -#### `RUN --mount=type=ssh` +### `RUN --mount=type=ssh` 该指令可以挂载 `ssh` 密钥。 @@ -165,14 +145,6 @@ $ ssh-add ~/.ssh/id_rsa $ docker build -t test --ssh default=$SSH_AUTH_SOCK . ``` -### 清理构建缓存 - -执行以下命令清理构建缓存 - -```bash -$ docker builder prune -``` - -### 官方文档 +## 官方文档 * https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md diff --git a/buildx/buildx.md b/buildx/buildx.md new file mode 100644 index 000000000..6dc2c9985 --- /dev/null +++ b/buildx/buildx.md @@ -0,0 +1,33 @@ +# 使用 Buildx 构建镜像 + +## 启用 Buildx + +`buildx` 命令属于实验特性,必须设置环境变量以使用该命令。 + +Linux/macOS + +```bash +$ export DOCKER_CLI_EXPERIMENTAL=enabled +``` + +Windows + +```bash +$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled +``` + +## 使用 + +你可以直接使用 `docker buildx build` 命令构建镜像。 + +```bash +$ docker buildx build . +[+] Building 8.4s (23/32) + => ... +``` + +Buildx 使用 [BuildKit 引擎](buildkit.md) 进行构建,支持许多新的功能,具体参考 [Buildkit](buildkit.md) 一节。 + +## 官方文档 + +* https://docs.docker.com/engine/reference/commandline/buildx/ diff --git a/image/buildx_multi-arch-images.md b/buildx/multi-arch-images.md similarity index 78% rename from image/buildx_multi-arch-images.md rename to buildx/multi-arch-images.md index 62ead2bd5..d423dfc8b 100644 --- a/image/buildx_multi-arch-images.md +++ b/buildx/multi-arch-images.md @@ -1,26 +1,8 @@ # 使用 buildx 构建多种系统架构支持的 Docker 镜像 -在之前的版本中构建多种系统架构支持的 Docker 镜像,要想使用统一的名字必须使用 [`$ docker manifest`](manifest.md) 命令。 +在之前的版本中构建多种系统架构支持的 Docker 镜像,要想使用统一的名字必须使用 [`$ docker manifest`](../image/manifest.md) 命令。 -在 Docker 19.03+ 版本中可以使用 `$ docker buildx build` 命令使用 `BuildKit` 构建镜像。 - -该命令支持 `--platform` 参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。 - -## 设置环境变量 - -`buildx` 命令属于实验特性,必须设置环境变量以使用该命令。 - -Linux/macOS - -```bash -$ export DOCKER_CLI_EXPERIMENTAL=enabled -``` - -Windows - -```bash -$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled -``` +在 Docker 19.03+ 版本中可以使用 `$ docker buildx build` 命令使用 `BuildKit` 构建镜像。该命令支持 `--platform` 参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。 ## 新建 `builder` 实例 @@ -33,7 +15,9 @@ $ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd44 由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。 ```bash -$ docker buildx create --name mybuilder +# $ docker buildx create --name mybuilder + +$ docker buildx create --name=mybuilder --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master $ docker buildx use mybuilder ``` diff --git a/image/buildx.md b/image/buildx.md deleted file mode 100644 index a6ef6c796..000000000 --- a/image/buildx.md +++ /dev/null @@ -1,148 +0,0 @@ -## 使用 `Buildx` 构建镜像 - -**BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。 - -**注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(Docker Hub 自动构建、腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)** - -下面介绍如何在 Docker CE 19.03+ 版本中使用 `BuildKit` 提供的 `Dockerfile` 新指令来更快、更安全的构建 Docker 镜像。 - -### `Dockerfile` 新增指令详解 - -启用 `BuildKit` 之后,我们可以使用下面几个新的指令来加快镜像构建。为了使用 `BuildKit` 我们 **必须** 使用新的 `$ docker buildx build` 命令来构建 Docker 镜像。 - -#### `RUN --mount=type=cache` - -目前,几乎所有的程序都会使用依赖管理工具,例如 `Go` 中的 `go mod`、`Node.js` 中的 `npm` 等等,当我们构建一个镜像时,往往会重复的从互联网中获取依赖包,难以缓存,大大降低了镜像的构建效率。 - -例如一个前端工程需要用到 `npm`: - -```docker -FROM node:alpine as builder - -WORKDIR /app - -COPY package.json /app/ - -RUN npm i --registry=https://registry.npm.taobao.org \ - && rm -rf ~/.npm - -COPY src /app/src - -RUN npm run build - -FROM nginx:alpine - -COPY --from=builder /app/dist /app/dist -``` - -使用多阶段构建,构建的镜像中只包含了目标文件夹 `dist`,但仍然存在一些问题,当 `package.json` 文件变动时,`RUN npm i && rm -rf ~/.npm` 这一层会重新执行,变更多次后,生成了大量的中间层镜像。 - -为解决这个问题,进一步的我们可以设想一个类似 **数据卷** 的功能,在镜像构建时把 `node_modules` 文件夹挂载上去,在构建完成后,这个 `node_modules` 文件夹会自动卸载,实际的镜像中并不包含 `node_modules` 这个文件夹,这样我们就省去了每次获取依赖的时间,大大增加了镜像构建效率,同时也避免了生成了大量的中间层镜像。 - -`BuildKit` 提供了 `RUN --mount=type=cache` 指令,可以实现上边的设想。 - -```docker -FROM node:alpine as builder - -WORKDIR /app - -COPY package.json /app/ - -RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ - --mount=type=cache,target=/root/.npm,id=npm_cache \ - npm i --registry=https://registry.npm.taobao.org - -COPY src /app/src - -RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ -# --mount=type=cache,target=/app/dist,id=my_app_dist,sharing=locked \ - npm run build - -FROM nginx:alpine - -# COPY --from=builder /app/dist /app/dist - -# 为了更直观的说明 from 和 source 指令,这里使用 RUN 指令 -RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \ - # --mount=type=cache,target/tmp/dist,from=my_app_dist,sharing=locked \ - mkdir -p /app/dist && cp -r /tmp/dist/* /app/dist -``` - -第一个 `RUN` 指令执行后,`id` 为 `my_app_npm_module` 的缓存文件夹挂载到了 `/app/node_modules` 文件夹中。多次执行也不会产生多个中间层镜像。 - -第二个 `RUN` 指令执行时需要用到 `node_modules` 文件夹,`node_modules` 已经挂载,命令也可以正确执行。 - -第三个 `RUN` 指令将上一阶段产生的文件复制到指定位置,`from` 指明缓存的来源,这里 `builder` 表示缓存来源于构建的第一阶段,`source` 指明缓存来源的文件夹。 - -上面的 `Dockerfile` 中 `--mount=type=cache,...` 中指令作用如下: - -|Option |Description| -|---------------------|-----------| -|`id` | `id` 设置一个标志,以便区分缓存。| -|`target` (必填项) | 缓存的挂载目标文件夹。| -|`ro`,`readonly` | 只读,缓存文件夹不能被写入。 | -|`sharing` | 有 `shared` `private` `locked` 值可供选择。`sharing` 设置当一个缓存被多次使用时的表现,由于 `BuildKit` 支持并行构建,当多个步骤使用同一缓存时(同一 `id`)会发生冲突。`shared` 表示多个步骤可以同时读写,`private` 表示当多个步骤使用同一缓存时,每个步骤使用不同的缓存,`locked` 表示当一个步骤完成释放缓存后,后一个步骤才能继续使用该缓存。| -|`from` | 缓存来源(构建阶段),不填写时为空文件夹。| -|`source` | 来源的文件夹路径。| - -#### `RUN --mount=type=bind` - -该指令可以将一个镜像(或上一构建阶段)的文件挂载到指定位置。 - -```docker -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` 文件系统挂载到指定位置。 - -```docker -RUN --mount=type=tmpfs,target=/temp \ - mount | grep /temp -``` - -#### `RUN --mount=type=secret` - -该指令可以将一个文件挂载到指定位置。 - -```docker -RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \ - cat /root/.aws/credentials -``` - -```bash -$ docker buildx build -t test --secret id=aws,src=$HOME/.aws/credentials . -``` - -#### `RUN --mount=type=ssh` - -该指令可以挂载 `ssh` 密钥。 - -```docker -FROM alpine -RUN apk add --no-cache openssh-client -RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts -RUN --mount=type=ssh ssh git@gitlab.com | tee /hello -``` - -```bash -$ eval $(ssh-agent) -$ ssh-add ~/.ssh/id_rsa -(Input your passphrase here) - -$ docker buildx build -t test --ssh default=$SSH_AUTH_SOCK . -``` - -### 清理构建缓存 - -执行以下命令清理构建缓存 - -```bash -$ docker builder prune -``` - -### 官方文档 - -* https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md From f44a3ee402a6935fee789977e989d4691030ccfc Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 5 Nov 2019 22:19:50 +0800 Subject: [PATCH 020/201] Add ide with docker Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 1 + .vuepress/config.js | 8 ++++++++ IDE/README.md | 3 +++ IDE/vsCode.md | 5 +++++ SUMMARY.md | 2 ++ 5 files changed, 19 insertions(+) create mode 100644 IDE/README.md create mode 100644 IDE/vsCode.md diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 62c10c980..4a2625c21 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,6 +18,7 @@ jobs: args: build - name: vuepress run: | + rm -rf _book npx vuepress build - name: Upload Vuepress dist uses: docker://pcit/pages diff --git a/.vuepress/config.js b/.vuepress/config.js index 18948e3c3..f9e96cc70 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -115,6 +115,14 @@ module.exports = { 'summary', ], }, + { + title: "在 IDE 中使用 Docker", + collapsable: false, + children: [ + '/ide/', + '/ide/vscode', + ], + }, ], '/cases/ci/': [ '/cases/ci/', diff --git a/IDE/README.md b/IDE/README.md new file mode 100644 index 000000000..a0bb743e3 --- /dev/null +++ b/IDE/README.md @@ -0,0 +1,3 @@ +# 在 IDE 中使用 Docker + +使用 IDE 进行开发,往往要求本地安装好工具链。一些 IDE 支持 Docker 容器中的工具链,这样充分利用了 Docker 的优点,而无需在本地安装。 diff --git a/IDE/vsCode.md b/IDE/vsCode.md new file mode 100644 index 000000000..762077619 --- /dev/null +++ b/IDE/vsCode.md @@ -0,0 +1,5 @@ +# VS Code 中使用 Docker + +## 将 Docker 容器作为远程开发环境 + +无需本地安装开发工具,直接将 Docker 容器作为开发环境,具体参考 [官方文档](https://code.visualstudio.com/docs/remote/containers)。 diff --git a/SUMMARY.md b/SUMMARY.md index 4dc717700..6057f12fc 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -138,6 +138,8 @@ * [Drone](cases/ci/drone/README.md) * [部署 Drone](cases/ci/drone/install.md) * [Travis CI](cases/ci/travis/README.md) +* [在 IDE 中使用 Docker](IDE/README.md) + * [VS Code](IDE/vsCode.md) * [Docker 开源项目](opensource/README.md) * [LinuxKit](opensource/linuxkit.md) * [附录](appendix/README.md) From 3ba7560b4d304b4ee74a773ec40fb492a2b7f8ee Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 5 Nov 2019 23:28:01 +0800 Subject: [PATCH 021/201] Add experimental Signed-off-by: Kang HuaiShuai --- SUMMARY.md | 1 + install/experimental.md | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 install/experimental.md diff --git a/SUMMARY.md b/SUMMARY.md index 6057f12fc..f3b2d3ae7 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -19,6 +19,7 @@ * [macOS](install/mac.md) * [Windows 10](install/windows.md) * [镜像加速器](install/mirror.md) + * [开启实验特性](install/experimental.md) * [使用镜像](image/README.md) * [获取镜像](image/pull.md) * [列出镜像](image/list.md) diff --git a/install/experimental.md b/install/experimental.md new file mode 100644 index 000000000..f4f6895e2 --- /dev/null +++ b/install/experimental.md @@ -0,0 +1,37 @@ +# 开启实验特性 + +一些 docker 命令或功能仅当 **实验特性** 开启时才能使用,请按照以下方法进行设置。 + +## 开启 Docker CLI 的实验特性 + +编辑 `~/.docker/config.json` 文件,新增如下条目 + +```json +{ + "experimental": "enabled" +} +``` + +或者通过设置环境变量的方式: + +**Linux/macOS** + +```bash +$ export DOCKER_CLI_EXPERIMENTAL=enabled +``` + +**Windows** + +```powershell +$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled +``` + +## 开启 Dockerd 的实验特性 + +编辑 `/etc/docker/daemon.json`,新增如下条目 + +```json +{ + "experimental": true +} +``` From 709c77adcbb46cf75a8b316495de30c5db4ca521 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 5 Nov 2019 23:35:43 +0800 Subject: [PATCH 022/201] Update title style Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 121 +++++++++++++++++----------------- archive/README.md | 4 ++ buildx/buildx.md | 14 +--- cases/ci/travis/README.md | 6 +- cases/os/alpine.md | 10 +-- cases/os/busybox.md | 10 +-- cases/os/debian.md | 12 ++-- cloud/alicloud.md | 2 +- cloud/aws.md | 2 +- cloud/intro.md | 4 +- cloud/summary.md | 2 +- cloud/tencentCloud.md | 2 +- compose/commands.md | 56 ++++++++-------- compose/compose_file.md | 72 ++++++++++---------- compose/django.md | 2 +- compose/install.md | 10 +-- compose/introduction.md | 2 +- compose/rails.md | 2 +- compose/usage.md | 14 ++-- compose/wordpress.md | 8 +-- image/manifest.md | 16 +---- install/centos.md | 26 ++++---- install/debian.md | 24 +++---- install/fedora.md | 24 +++---- install/mac.md | 16 ++--- install/mirror.md | 12 ++-- install/raspberry-pi.md | 18 ++--- install/ubuntu.md | 24 +++---- install/windows.md | 12 ++-- repository/dockerhub.md | 12 ++-- repository/nexus3_registry.md | 12 ++-- repository/registry.md | 14 ++-- repository/registry_auth.md | 18 ++--- underly/arch.md | 2 +- underly/cgroups.md | 2 +- underly/container_format.md | 2 +- underly/namespace.md | 14 ++-- underly/network.md | 8 +-- underly/ufs.md | 2 +- 39 files changed, 297 insertions(+), 316 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index f9e96cc70..af5b2815f 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -37,6 +37,10 @@ module.exports = { text: 'Kubernetes', link: '/kubernetes/', }, + { + text: "云计算", + link: "/cloud/", + }, { text: 'GitHub', link: 'https://github.com/yeasy/docker_practice' @@ -58,6 +62,13 @@ module.exports = { // } ], sidebar: { + '/cloud/': [ + 'intro', + 'aws', + 'tencentCloud', + 'alicloud', + 'summary', + ], '/kubernetes/': [ 'intro', 'quickstart', @@ -76,7 +87,6 @@ module.exports = { 'wordpress', ], '/install/': [ - '/install/', 'ubuntu', 'debian', 'fedora', @@ -85,9 +95,9 @@ module.exports = { 'mac', 'windows', 'mirror', + 'experimental', ], '/underly/': [ - '/underly/', 'arch', 'namespace', 'cgroups', @@ -96,7 +106,6 @@ module.exports = { 'network', ], '/repository/': [ - '/repository/', 'dockerhub', 'registry', 'registry_auth', @@ -107,7 +116,6 @@ module.exports = { title: "操作系统", collapsable:false, children: [ - '/cases/os/', 'busybox', 'alpine', 'debian', @@ -119,14 +127,13 @@ module.exports = { title: "在 IDE 中使用 Docker", collapsable: false, children: [ - '/ide/', - '/ide/vscode', + '/IDE/', + '/IDE/vsCode', ], }, ], '/cases/ci/': [ - '/cases/ci/', - '/cases/ci/actions/', + 'actions/', { title: "Drone", collapsable: false, @@ -145,55 +152,55 @@ module.exports = { title: "Docker 简介", collapsable: false, children: [ - '/introduction/', - '/introduction/what', - '/introduction/why', + 'introduction/', + 'introduction/what', + 'introduction/why', ] },{ title: "基本概念", collapsable: false, children: [ - '/basic_concept/', - '/basic_concept/image', - '/basic_concept/container', - '/basic_concept/repository' + 'basic_concept/', + 'basic_concept/image', + 'basic_concept/container', + 'basic_concept/repository' ] }, { title: "使用镜像", collapsable: false, children: [ - '/image/', - '/image/pull', - '/image/list', - '/image/rm', - '/image/commit', - '/image/build', - '/image/other.md', - '/image/internal.md', + 'image/', + 'image/pull', + 'image/list', + 'image/rm', + 'image/commit', + 'image/build', + 'image/other.md', + 'image/internal.md', ] }, { title: 'Dockerfile', collapsable: false, children: [ - "/image/dockerfile/", - '/image/dockerfile/copy', - '/image/dockerfile/add', - '/image/dockerfile/cmd', - '/image/dockerfile/entrypoint', - '/image/dockerfile/env', - '/image/dockerfile/arg', - '/image/dockerfile/volume', - '/image/dockerfile/expose', - '/image/dockerfile/workdir', - '/image/dockerfile/user', - '/image/dockerfile/healthcheck', - '/image/dockerfile/onbuild', - '/image/dockerfile/references', - '/image/multistage-builds/', - '/image/multistage-builds/laravel', - '/image/manifest', + "image/dockerfile/", + 'image/dockerfile/copy', + 'image/dockerfile/add', + 'image/dockerfile/cmd', + 'image/dockerfile/entrypoint', + 'image/dockerfile/env', + 'image/dockerfile/arg', + 'image/dockerfile/volume', + 'image/dockerfile/expose', + 'image/dockerfile/workdir', + 'image/dockerfile/user', + 'image/dockerfile/healthcheck', + 'image/dockerfile/onbuild', + 'image/dockerfile/references', + 'image/multistage-builds/', + 'image/multistage-builds/laravel', + 'image/manifest', ] },{ title: "操作容器", @@ -297,18 +304,6 @@ module.exports = { 'coreos/intro_tools', ], }, - { - title: "容器与云计算", - collapsable:false, - children: [ - 'cloud/', - 'cloud/intro', - 'cloud/aws', - 'cloud/tencentCloud', - 'cloud/alicloud', - 'cloud/summary', - ], - }, { title: "Docker 开源项目", collapsable:false, @@ -359,15 +354,23 @@ module.exports = { title: 'Mesos', collapsable: false, children: [ - '/mesos/intro', - '/mesos/installation', - '/mesos/architecture', - '/mesos/configuration', - '/mesos/monitor', - '/mesos/framework', - '/mesos/summary', + 'mesos/', + 'mesos/intro', + 'mesos/installation', + 'mesos/architecture', + 'mesos/configuration', + 'mesos/monitor', + 'mesos/framework', + 'mesos/summary', ] }, + { + title: 'Docker Swarm', + collapsable: false, + children: [ + "swarm/" + ] + } ], }, } diff --git a/archive/README.md b/archive/README.md index 042dde31c..5f748758a 100644 --- a/archive/README.md +++ b/archive/README.md @@ -1,3 +1,7 @@ # 归档项目 以下项目不被官方支持或内容陈旧,将在下一版本中删除。 + +* Docker Machine +* Mesos +* Docker Swarm diff --git a/buildx/buildx.md b/buildx/buildx.md index 6dc2c9985..02c7ca5fc 100644 --- a/buildx/buildx.md +++ b/buildx/buildx.md @@ -2,19 +2,7 @@ ## 启用 Buildx -`buildx` 命令属于实验特性,必须设置环境变量以使用该命令。 - -Linux/macOS - -```bash -$ export DOCKER_CLI_EXPERIMENTAL=enabled -``` - -Windows - -```bash -$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled -``` +`buildx` 命令属于实验特性,参考 [开启实验特性](../install/experimental.md) 一节。 ## 使用 diff --git a/cases/ci/travis/README.md b/cases/ci/travis/README.md index d3337da6d..792a5cee1 100644 --- a/cases/ci/travis/README.md +++ b/cases/ci/travis/README.md @@ -1,10 +1,10 @@ -## 在 Travis CI 中使用 Docker +# 在 Travis CI 中使用 Docker 当代码提交到 GitHub 时,[Travis CI](https://travis-ci.com/) 会根据项目根目录 `.travis.yml` 文件设置的指令,执行一系列操作。 本小节介绍如何在 Travis CI 中使用 Docker 进行持续集成/持续部署(CI/CD)。这里以当代码提交到 GitHub 时自动构建 Docker 镜像并推送到 Docker Hub 为例进行介绍。 -### 准备 +## 准备 首先登录 https://travis-ci.com/account/repositories 选择 GitHub 仓库,按照指引安装 GitHub App 来启用 GitHub 仓库构建。 @@ -42,6 +42,6 @@ after_success: > 请提前在 Travis CI 仓库设置页面配置 `DOCKER_PASSWORD` `DOCKER_USERNAME` 变量 -### 查看结果 +## 查看结果 将项目推送到 GitHub,登录 [Travis CI](https://travis-ci.com/) 查看构建详情。 diff --git a/cases/os/alpine.md b/cases/os/alpine.md index 89398ab71..7c10df046 100644 --- a/cases/os/alpine.md +++ b/cases/os/alpine.md @@ -1,6 +1,6 @@ -## Alpine +# Alpine -### 简介 +## 简介 ![Apline Linux 操作系统](_images/alpinelinux-logo.png) @@ -22,7 +22,7 @@ ubuntu latest b39b81afc8ca 188.3 MB centos latest 8efe422e6104 210 MB ``` -### 获取并使用官方镜像 +## 获取并使用官方镜像 由于镜像很小,下载时间往往很短,读者可以直接使用 `docker run` 指令直接运行一个 `Alpine` 容器,并指定运行的 Linux 指令,例如: @@ -31,7 +31,7 @@ $ docker run alpine echo '123' 123 ``` -### 迁移至 `Alpine` 基础镜像 +## 迁移至 `Alpine` 基础镜像 目前,大部分 Docker 官方镜像都已经支持 `Alpine` 作为基础镜像,可以很容易进行迁移。 @@ -54,7 +54,7 @@ $ echo "http://dl-4.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositorie $ apk --update add --no-cache ``` -### 相关资源 +## 相关资源 * `Alpine` 官网:https://www.alpinelinux.org/ * `Alpine` 官方仓库:https://github.com/alpinelinux diff --git a/cases/os/busybox.md b/cases/os/busybox.md index 16bd26cb3..1eb471a97 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -1,6 +1,6 @@ -## Busybox +# Busybox -### 简介 +## 简介 ![Busybox - Linux 瑞士军刀](_images/busybox-logo.png) @@ -8,7 +8,7 @@ `BusyBox` 可运行于多款 `POSIX` 环境的操作系统中,如 `Linux`(包括 `Android`)、`Hurd`、`FreeBSD` 等。 -### 获取官方镜像 +## 获取官方镜像 在 `Docker Hub` 中搜索 `busybox` 相关的镜像。 @@ -44,7 +44,7 @@ REPOSITORY TAG IMAGE ID CREATED busybox latest e72ac664f4f0 6 weeks ago 2.433 MB ``` -### 运行 busybox +## 运行 busybox 启动一个 `busybox` 容器,并在容器中执行 `grep` 命令。 @@ -105,7 +105,7 @@ tmpfs on /proc/kcore type tmpfs (rw,nosuid,mode=755) `busybox` 镜像虽然小巧,但包括了大量常见的 `Linux` 命令,读者可以用它快速熟悉 `Linux` 命令。 -### 相关资源 +## 相关资源 * `Busybox` 官网:https://busybox.net/ * `Busybox` 官方仓库:https://git.busybox.net/busybox/ diff --git a/cases/os/debian.md b/cases/os/debian.md index ce975dde8..6e8724197 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -1,7 +1,7 @@ -## Debian/Ubuntu +# Debian/Ubuntu `Debian` 和 `Ubuntu` 都是目前较为流行的 **Debian 系** 的服务器操作系统,十分适合研发场景。`Docker Hub` 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 -### Debian 系统简介 +## Debian 系统简介 ![Debian 操作系统](_images/debian-logo.png) @@ -11,7 +11,7 @@ 众多的 `Linux` 发行版,例如 `Ubuntu`、`Knoppix` 和 `Linspire` 及 `Xandros` 等,都基于 `Debian GNU/Linux`。 -#### 使用 Debian 官方镜像 +### 使用 Debian 官方镜像 读者可以使用 `docker search` 查找 `Debian` 镜像: @@ -36,13 +36,13 @@ Debian GNU/Linux 8 `Debian` 镜像很适合作为基础镜像,构建自定义镜像。 -### Ubuntu 系统简介 +## Ubuntu 系统简介 ![Ubuntu 操作系统](_images/ubuntu-logo.jpg) `Ubuntu` 是一个以桌面应用为主的 `GNU/Linux` 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词(官方译名“友帮拓”,另有“吾帮托”、“乌班图”、“有奔头”或“乌斑兔”等译名)。`Ubuntu` 意思是“人性”以及“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。 `Ubuntu` 基于 `Debian` 发行版和 `GNOME/Unity` 桌面环境,与 `Debian` 的不同在于它每 6 个月会发布一个新版本,每 2 年推出一个长期支持 **(Long Term Support,LTS)** 版本,一般支持 3 年时间。 -#### 使用 Ubuntu 官方镜像 +### 使用 Ubuntu 官方镜像 `Ubuntu` 相关的镜像有很多,这里使用 `--filter=stars=10` 参数,只搜索那些被收藏 `10` 次以上的镜像。 @@ -162,7 +162,7 @@ root@7d93de07bf76:/# curl 127.0.0.1 配合使用 `-p` 参数对外映射服务端口,可以允许容器外来访问该服务。 -### 相关资源 +## 相关资源 * `Debian` 官网:https://www.debian.org/ * `Neuro Debian` 官网:http://neuro.debian.net/ diff --git a/cloud/alicloud.md b/cloud/alicloud.md index cf48a9508..b8e59572b 100644 --- a/cloud/alicloud.md +++ b/cloud/alicloud.md @@ -1,4 +1,4 @@ -## 阿里云 +# 阿里云 ![阿里云](_images/aliyun-logo.png) diff --git a/cloud/aws.md b/cloud/aws.md index b73b87ad9..aea35a170 100644 --- a/cloud/aws.md +++ b/cloud/aws.md @@ -1,4 +1,4 @@ -## 亚马逊云 +# 亚马逊云 ![AWS](_images/aws-logo.jpg) diff --git a/cloud/intro.md b/cloud/intro.md index b91187802..ceffdf19a 100644 --- a/cloud/intro.md +++ b/cloud/intro.md @@ -1,7 +1,7 @@ -## 简介 +# 简介 目前与容器相关的云计算主要分为两种类型。 一种是传统的 IaaS 服务商提供对容器相关的服务,包括镜像下载、容器托管等。 -另一种是直接基于容器技术对外提供容器云服务,所谓 Container as a Service(CaaS)。 \ No newline at end of file +另一种是直接基于容器技术对外提供容器云服务,所谓 Container as a Service(CaaS)。 diff --git a/cloud/summary.md b/cloud/summary.md index fd3c1fb83..118332439 100644 --- a/cloud/summary.md +++ b/cloud/summary.md @@ -1,4 +1,4 @@ -## 本章小结 +# 本章小结 本章介绍了公有云服务对 Docker 的积极支持,以及新出现的容器云平台。 diff --git a/cloud/tencentCloud.md b/cloud/tencentCloud.md index 38933eac1..4af43eea4 100644 --- a/cloud/tencentCloud.md +++ b/cloud/tencentCloud.md @@ -1,4 +1,4 @@ -## 腾讯云 +# 腾讯云 ![腾讯云](_images/qcloud-logo.jpg) diff --git a/compose/commands.md b/compose/commands.md index 23d9c8196..dda0b834f 100644 --- a/compose/commands.md +++ b/compose/commands.md @@ -1,6 +1,6 @@ -## Compose 命令说明 +# Compose 命令说明 -### 命令对象与格式 +## 命令对象与格式 对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。 @@ -12,7 +12,7 @@ docker-compose [-f=...] [options] [COMMAND] [ARGS...] ``` -### 命令选项 +## 命令选项 * `-f, --file FILE` 指定使用的 Compose 模板文件,默认为 `docker-compose.yml`,可以多次指定。 @@ -26,9 +26,9 @@ docker-compose [-f=...] [options] [COMMAND] [ARGS...] * `-v, --version` 打印版本并退出。 -### 命令使用说明 +## 命令使用说明 -#### `build` +### `build` 格式为 `docker-compose build [options] [SERVICE...]`。 @@ -46,27 +46,27 @@ docker-compose [-f=...] [options] [COMMAND] [ARGS...] * `--pull` 始终尝试通过 pull 来获取更新版本的镜像。 -#### `config` +### `config` 验证 Compose 文件格式是否正确,若正确则显示配置,若格式错误显示错误原因。 -#### `down` +### `down` 此命令将会停止 `up` 命令所启动的容器,并移除网络 -#### `exec` +### `exec` 进入指定的容器。 -#### `help` +### `help` 获得一个命令的帮助。 -#### `images` +### `images` 列出 Compose 文件中包含的镜像。 -#### `kill` +### `kill` 格式为 `docker-compose kill [options] [SERVICE...]`。 @@ -78,7 +78,7 @@ docker-compose [-f=...] [options] [COMMAND] [ARGS...] $ docker-compose kill -s SIGINT ``` -#### `logs` +### `logs` 格式为 `docker-compose logs [options] [SERVICE...]`。 @@ -86,13 +86,13 @@ $ docker-compose kill -s SIGINT 该命令在调试问题的时候十分有用。 -#### `pause` +### `pause` 格式为 `docker-compose pause [SERVICE...]`。 暂停一个服务容器。 -#### `port` +### `port` 格式为 `docker-compose port [options] SERVICE PRIVATE_PORT`。 @@ -104,7 +104,7 @@ $ docker-compose kill -s SIGINT * `--index=index` 如果同一服务存在多个容器,指定命令对象容器的序号(默认为 1)。 -#### `ps` +### `ps` 格式为 `docker-compose ps [options] [SERVICE...]`。 @@ -114,7 +114,7 @@ $ docker-compose kill -s SIGINT * `-q` 只打印容器的 ID 信息。 -#### `pull` +### `pull` 格式为 `docker-compose pull [options] [SERVICE...]`。 @@ -124,11 +124,11 @@ $ docker-compose kill -s SIGINT * `--ignore-pull-failures` 忽略拉取镜像过程中的错误。 -#### `push` +### `push` 推送服务依赖的镜像到 Docker 镜像仓库。 -#### `restart` +### `restart` 格式为 `docker-compose restart [options] [SERVICE...]`。 @@ -138,7 +138,7 @@ $ docker-compose kill -s SIGINT * `-t, --timeout TIMEOUT` 指定重启前停止容器的超时(默认为 10 秒)。 -#### `rm` +### `rm` 格式为 `docker-compose rm [options] [SERVICE...]`。 @@ -150,7 +150,7 @@ $ docker-compose kill -s SIGINT * `-v` 删除容器所挂载的数据卷。 -#### `run` +### `run` 格式为 `docker-compose run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]`。 在指定服务上执行一个命令。 @@ -203,7 +203,7 @@ $ docker-compose run --no-deps web python manage.py shell * `-T` 不分配伪 tty,意味着依赖 tty 的指令将无法运行。 -#### `scale` +### `scale` 格式为 `docker-compose scale [options] [SERVICE=NUM...]`。 @@ -223,13 +223,13 @@ $ docker-compose scale web=3 db=2 * `-t, --timeout TIMEOUT` 停止容器时候的超时(默认为 10 秒)。 -#### `start` +### `start` 格式为 `docker-compose start [SERVICE...]`。 启动已经存在的服务容器。 -#### `stop` +### `stop` 格式为 `docker-compose stop [options] [SERVICE...]`。 @@ -239,17 +239,17 @@ $ docker-compose scale web=3 db=2 * `-t, --timeout TIMEOUT` 停止容器时候的超时(默认为 10 秒)。 -#### `top` +### `top` 查看各个服务容器内运行的进程。 -#### `unpause` +### `unpause` 格式为 `docker-compose unpause [SERVICE...]`。 恢复处于暂停状态中的服务。 -#### `up` +### `up` 格式为 `docker-compose up [options] [SERVICE...]`。 @@ -283,12 +283,12 @@ $ docker-compose scale web=3 db=2 * `-t, --timeout TIMEOUT` 停止容器时候的超时(默认为 10 秒)。 -#### `version` +### `version` 格式为 `docker-compose version`。 打印版本信息。 -### 参考资料 +## 参考资料 * [官方文档](https://docs.docker.com/compose/reference/overview/) diff --git a/compose/compose_file.md b/compose/compose_file.md index d41ea4152..f99fb16b3 100644 --- a/compose/compose_file.md +++ b/compose/compose_file.md @@ -1,4 +1,4 @@ -## Compose 模板文件 +# Compose 模板文件 模板文件是使用 `Compose` 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 `docker run` 相关参数的含义都是类似的。 @@ -22,7 +22,7 @@ services: 下面分别介绍各个指令的用法。 -### `build` +## `build` 指定 `Dockerfile` 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 `Compose` 将会利用它自动构建这个镜像,然后使用这个镜像。 @@ -62,7 +62,7 @@ build: - corp/web_app:3.14 ``` -### `cap_add, cap_drop` +## `cap_add, cap_drop` 指定容器的内核能力(capacity)分配。 @@ -80,7 +80,7 @@ cap_drop: - NET_ADMIN ``` -### `command` +## `command` 覆盖容器启动后默认执行的命令。 @@ -88,11 +88,11 @@ cap_drop: command: echo "hello world" ``` -### `configs` +## `configs` 仅用于 `Swarm mode`,详细内容请查看 [`Swarm mode`](../swarm_mode/) 一节。 -### `cgroup_parent` +## `cgroup_parent` 指定父 `cgroup` 组,意味着将继承该组的资源限制。 @@ -102,7 +102,7 @@ command: echo "hello world" cgroup_parent: cgroups_1 ``` -### `container_name` +## `container_name` 指定容器名称。默认将会使用 `项目名称_服务名称_序号` 这样的格式。 @@ -112,11 +112,11 @@ container_name: docker-web-container >注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。 -### `deploy` +## `deploy` 仅用于 `Swarm mode`,详细内容请查看 [`Swarm mode`](../swarm_mode/) 一节 -### `devices` +## `devices` 指定设备映射关系。 @@ -125,7 +125,7 @@ devices: - "/dev/ttyUSB1:/dev/ttyUSB0" ``` -### `depends_on` +## `depends_on` 解决容器的依赖、启动先后的问题。以下例子中会先启动 `redis` `db` 再启动 `web` @@ -148,7 +148,7 @@ services: >注意:`web` 服务不会等待 `redis` `db` 「完全启动」之后才启动。 -### `dns` +## `dns` 自定义 `DNS` 服务器。可以是一个值,也可以是一个列表。 @@ -160,7 +160,7 @@ dns: - 114.114.114.114 ``` -### `dns_search` +## `dns_search` 配置 `DNS` 搜索域。可以是一个值,也可以是一个列表。 @@ -172,7 +172,7 @@ dns_search: - domain2.example.com ``` -### `tmpfs` +## `tmpfs` 挂载一个 tmpfs 文件系统到容器。 @@ -183,7 +183,7 @@ tmpfs: - /tmp ``` -### `env_file` +## `env_file` 从文件中获取环境变量,可以为单独的文件路径或列表。 @@ -207,7 +207,7 @@ env_file: PROG_ENV=development ``` -### `environment` +## `environment` 设置环境变量。你可以使用数组或字典两种格式。 @@ -229,7 +229,7 @@ environment: y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF ``` -### `expose` +## `expose` 暴露端口,但不映射到宿主机,只被连接的服务访问。 @@ -241,7 +241,7 @@ expose: - "8000" ``` -### `external_links` +## `external_links` >注意:不建议使用该指令。 @@ -254,7 +254,7 @@ external_links: - project_db_1:postgresql ``` -### `extra_hosts` +## `extra_hosts` 类似 Docker 中的 `--add-host` 参数,指定额外的 host 名称映射信息。 @@ -271,7 +271,7 @@ extra_hosts: 52.1.157.61 dockerhub ``` -### `healthcheck` +## `healthcheck` 通过命令检查容器是否健康运行。 @@ -283,7 +283,7 @@ healthcheck: retries: 3 ``` -### `image` +## `image` 指定为镜像名称或镜像 ID。如果镜像在本地不存在,`Compose` 将会尝试拉取这个镜像。 @@ -293,7 +293,7 @@ image: orchardup/postgresql image: a4bc65fd ``` -### `labels` +## `labels` 为容器添加 Docker 元数据(metadata)信息。例如可以为容器添加辅助说明信息。 @@ -304,11 +304,11 @@ labels: com.startupteam.release: "rc3 for v1.0" ``` -### `links` +## `links` >注意:不推荐使用该指令。 -### `logging` +## `logging` 配置日志选项。 @@ -335,7 +335,7 @@ options: max-file: "10" ``` -### `network_mode` +## `network_mode` 设置网络模式。使用和 `docker run` 的 `--network` 参数一样的值。 @@ -347,7 +347,7 @@ network_mode: "service:[service name]" network_mode: "container:[container name/id]" ``` -### `networks` +## `networks` 配置容器连接的网络。 @@ -365,7 +365,7 @@ networks: other-network: ``` -### `pid` +## `pid` 跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程 ID 来相互访问和操作。 @@ -373,7 +373,7 @@ networks: pid: "host" ``` -### `ports` +## `ports` 暴露端口信息。 @@ -389,7 +389,7 @@ ports: *注意:当使用 `HOST:CONTAINER` 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 `YAML` 会自动解析 `xx:yy` 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。* -### `secrets` +## `secrets` 存储敏感数据,例如 `mysql` 服务密码。 @@ -412,7 +412,7 @@ secrets: external: true ``` -### `security_opt` +## `security_opt` 指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。例如配置标签的用户名和角色名。 @@ -422,7 +422,7 @@ security_opt: - label:role:ROLE ``` -### `stop_signal` +## `stop_signal` 设置另一个信号来停止容器。在默认情况下使用的是 SIGTERM 停止容器。 @@ -430,7 +430,7 @@ security_opt: stop_signal: SIGUSR1 ``` -### `sysctls` +## `sysctls` 配置容器内核参数。 @@ -444,7 +444,7 @@ sysctls: - net.ipv4.tcp_syncookies=0 ``` -### `ulimits` +## `ulimits` 指定容器的 ulimits 限制值。 @@ -458,7 +458,7 @@ sysctls: hard: 40000 ``` -### `volumes` +## `volumes` 数据卷所挂载路径设置。可以设置为宿主机路径(`HOST:CONTAINER`)或者数据卷名称(`VOLUME:CONTAINER`),并且可以设置访问模式 (`HOST:CONTAINER:ro`)。 @@ -486,7 +486,7 @@ volumes: mysql_data: ``` -### 其它指令 +## 其它指令 此外,还有包括 `domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir` 等指令,基本跟 `docker run` 中对应参数的功能一致。 @@ -546,7 +546,7 @@ stdin_open: true tty: true ``` -### 读取变量 +## 读取变量 Compose 模板文件支持动态读取主机的系统环境变量和当前目录下的 `.env` 文件中的变量。 @@ -573,6 +573,6 @@ MONGO_VERSION=3.6 执行 `docker-compose up` 则会启动一个 `mongo:3.6` 镜像的容器。 -### 参考资料 +## 参考资料 * [官方文档](https://docs.docker.com/compose/compose-file/) diff --git a/compose/django.md b/compose/django.md index c0f9f455c..2b5219769 100644 --- a/compose/django.md +++ b/compose/django.md @@ -1,4 +1,4 @@ -## 使用 Django +# 使用 Django > 本小节内容适合 `Python` 开发人员阅读。 diff --git a/compose/install.md b/compose/install.md index 4a7ba479f..b9625e93d 100644 --- a/compose/install.md +++ b/compose/install.md @@ -1,4 +1,4 @@ -## 安装与卸载 +# 安装与卸载 `Compose` 支持 Linux、macOS、Windows 10 三大平台。 @@ -14,7 +14,7 @@ docker-compose version 1.24.1, build 4667896b Linux 系统请使用以下介绍的方法安装。 -### 二进制包 +## 二进制包 在 Linux 上的也安装十分简单,从 [官方 GitHub Release](https://github.com/docker/compose/releases) 处直接下载编译好的二进制文件即可。 @@ -26,7 +26,7 @@ $ sudo curl -L https://github.com/docker/compose/releases/download/1.24.1/docker $ sudo chmod +x /usr/local/bin/docker-compose ``` -### PIP 安装 +## PIP 安装 *注:* `x86_64` 架构的 Linux 建议按照上边的方法下载二进制包进行安装,如果您计算机的架构是 `ARM` (例如,树莓派),再使用 `pip` 安装。 @@ -47,13 +47,13 @@ Collecting docker-compose Successfully installed docker-compose cached-property requests texttable websocket-client docker-py dockerpty six enum34 backports.ssl-match-hostname ipaddress ``` -### bash 补全命令 +## bash 补全命令 ```bash $ curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose ``` -### 卸载 +## 卸载 如果是二进制包方式安装的,删除二进制文件即可。 diff --git a/compose/introduction.md b/compose/introduction.md index cde4affba..677761430 100644 --- a/compose/introduction.md +++ b/compose/introduction.md @@ -1,4 +1,4 @@ -## Compose 简介 +# Compose 简介 `Compose` 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 `OpenStack` 中的 `Heat` 十分类似。 diff --git a/compose/rails.md b/compose/rails.md index 66db4a5c3..5222848f1 100644 --- a/compose/rails.md +++ b/compose/rails.md @@ -1,4 +1,4 @@ -## 使用 Rails +# 使用 Rails > 本小节内容适合 `Ruby` 开发人员阅读。 diff --git a/compose/usage.md b/compose/usage.md index 39cef0c6b..ec0479b0e 100644 --- a/compose/usage.md +++ b/compose/usage.md @@ -1,6 +1,6 @@ -## 使用 +# 使用 -### 术语 +## 术语 首先介绍几个术语。 @@ -10,13 +10,13 @@ 可见,一个项目可以由多个服务(容器)关联而成,`Compose` 面向项目进行管理。 -### 场景 +## 场景 最常见的项目是 web 网站,该项目应该包含 web 应用和缓存。 下面我们用 `Python` 来建立一个能够记录页面访问次数的 web 网站。 -#### web 应用 +### web 应用 新建文件夹,在该目录中编写 `app.py` 文件 @@ -36,7 +36,7 @@ if __name__ == "__main__": app.run(host="0.0.0.0", debug=True) ``` -#### Dockerfile +### Dockerfile 编写 `Dockerfile` 文件,内容为 @@ -48,7 +48,7 @@ RUN pip install redis flask CMD ["python", "app.py"] ``` -#### docker-compose.yml +### docker-compose.yml 编写 `docker-compose.yml` 文件,这个是 Compose 使用的主模板文件。 @@ -65,7 +65,7 @@ services: image: "redis:alpine" ``` -#### 运行 compose 项目 +### 运行 compose 项目 ```bash $ docker-compose up diff --git a/compose/wordpress.md b/compose/wordpress.md index 7188bb35b..170e54df7 100644 --- a/compose/wordpress.md +++ b/compose/wordpress.md @@ -1,14 +1,14 @@ -## 使用 WordPress +# 使用 WordPress > 本小节内容适合 `PHP` 开发人员阅读。 `Compose` 可以很便捷的让 `Wordpress` 运行在一个独立的环境中。 -### 创建空文件夹 +## 创建空文件夹 假设新建一个名为 `wordpress` 的文件夹,然后进入这个文件夹。 -### 创建 `docker-compose.yml` 文件 +## 创建 `docker-compose.yml` 文件 [`docker-compose.yml`](https://github.com/yeasy/docker_practice/blob/master/compose/demo/wordpress/docker-compose.yml) 文件将开启一个 `wordpress` 服务和一个独立的 `MySQL` 实例: @@ -46,6 +46,6 @@ volumes: db_data: ``` -### 构建并运行项目 +## 构建并运行项目 运行 `docker-compose up -d` Compose 就会拉取镜像再创建我们所需要的镜像,然后启动 `wordpress` 和数据库容器。 接着浏览器访问 `127.0.0.1:8000` 端口就能看到 `WordPress` 安装界面了。 diff --git a/image/manifest.md b/image/manifest.md index e77eb40c3..3783303c7 100644 --- a/image/manifest.md +++ b/image/manifest.md @@ -34,21 +34,7 @@ $ docker run -it --rm username/test 我们可以使用 `$ docker manifest inspect golang:alpine` 查看这个 `manifest` 列表的结构。 -由于该命令属于实验特性,必须设置如下 **环境变量** 之后才能使用: - -```bash -# Linux、macOS - -$ export DOCKER_CLI_EXPERIMENTAL=enabled - -# Windows - -$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled -``` - -> 以上是设置环境变量的临时方法,若使环境变量永久生效请读者自行设置。 - -设置之后,执行结果如下 +> 该命令属于实验特性,请参考 [开启实验特性](../install/experimental) 一节。 ```bash $ docker manifest inspect golang:alpine diff --git a/install/centos.md b/install/centos.md index d0d2ec3d0..c368cae3c 100644 --- a/install/centos.md +++ b/install/centos.md @@ -1,14 +1,14 @@ -## CentOS 安装 Docker CE +# CentOS 安装 Docker CE >警告:切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker. -### 准备工作 +## 准备工作 -#### 系统要求 +### 系统要求 Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 `overlay2` 存储层驱动)无法使用,并且部分功能可能不太稳定。 -#### 卸载旧版本 +### 卸载旧版本 旧版本的 Docker 称为 `docker` 或者 `docker-engine`,使用以下命令卸载旧版本: @@ -25,7 +25,7 @@ $ sudo yum remove docker \ docker-engine ``` -### 使用 yum 安装 +## 使用 yum 安装 执行以下命令安装依赖包: @@ -63,7 +63,7 @@ $ sudo yum-config-manager --enable docker-ce-test $ sudo yum-config-manager --enable docker-ce-nightly ``` -#### 安装 Docker CE +### 安装 Docker CE 更新 `yum` 软件源缓存,并安装 `docker-ce`。 @@ -72,7 +72,7 @@ $ sudo yum makecache fast $ sudo yum install docker-ce ``` -### 使用脚本自动安装 +## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -84,14 +84,14 @@ $ sudo sh get-docker.sh --mirror Aliyun 执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 -### 启动 Docker CE +## 启动 Docker CE ```bash $ sudo systemctl enable docker $ sudo systemctl start docker ``` -### 建立 docker 用户组 +## 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 @@ -109,7 +109,7 @@ $ sudo usermod -aG docker $USER 退出当前终端并重新登录,进行如下测试。 -### 测试 Docker 是否安装正确 +## 测试 Docker 是否安装正确 ```bash $ docker run hello-world @@ -144,11 +144,11 @@ For more examples and ideas, visit: 若能正常输出以上信息,则说明安装成功。 -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 -### 添加内核参数 +## 添加内核参数 如果在 CentOS 使用 Docker CE 看到下面的这些警告信息: @@ -172,6 +172,6 @@ EOF $ sudo sysctl -p ``` -### 参考文档 +## 参考文档 * [Docker 官方 CentOS 安装文档](https://docs.docker.com/install/linux/docker-ce/centos/)。 diff --git a/install/debian.md b/install/debian.md index 3d38b1f28..28c88a8a6 100644 --- a/install/debian.md +++ b/install/debian.md @@ -1,17 +1,17 @@ -## Debian 安装 Docker CE +# Debian 安装 Docker CE >警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. -### 准备工作 +## 准备工作 -#### 系统要求 +### 系统要求 Docker CE 支持以下版本的 [Debian](https://www.debian.org/intro/about) 操作系统: * Buster 10 * Stretch 9 -#### 卸载旧版本 +### 卸载旧版本 旧版本的 Docker 称为 `docker` 或者 `docker-engine`,使用以下命令卸载旧版本: @@ -21,7 +21,7 @@ $ sudo apt-get remove docker \ docker.io ``` -### 使用 APT 安装 +## 使用 APT 安装 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。 @@ -66,7 +66,7 @@ $ sudo add-apt-repository \ >以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。 -#### 安装 Docker CE +### 安装 Docker CE 更新 apt 软件包缓存,并安装 `docker-ce`。 @@ -76,7 +76,7 @@ $ sudo apt-get update $ sudo apt-get install docker-ce ``` -### 使用脚本自动安装 +## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -88,14 +88,14 @@ $ sudo sh get-docker.sh --mirror Aliyun 执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 -### 启动 Docker CE +## 启动 Docker CE ```bash $ sudo systemctl enable docker $ sudo systemctl start docker ``` -### 建立 docker 用户组 +## 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 @@ -113,7 +113,7 @@ $ sudo usermod -aG docker $USER 退出当前终端并重新登录,进行如下测试。 -### 测试 Docker 是否安装正确 +## 测试 Docker 是否安装正确 ```bash $ docker run hello-world @@ -148,10 +148,10 @@ For more examples and ideas, visit: 若能正常输出以上信息,则说明安装成功。 -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 -### 参考文档 +## 参考文档 * [Docker 官方 Debian 安装文档](https://docs.docker.com/install/linux/docker-ce/debian/) diff --git a/install/fedora.md b/install/fedora.md index dfd4d4f8a..05d0081fa 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -1,10 +1,10 @@ -## Fedora 安装 Docker CE +# Fedora 安装 Docker CE >警告:切勿在没有配置 Docker dnf 源的情况下直接使用 dnf 命令安装 Docker. -### 准备工作 +## 准备工作 -#### 系统要求 +### 系统要求 Docker CE 支持以下版本的 [Fedora](https://fedoraproject.org/) 操作系统: @@ -12,7 +12,7 @@ Docker CE 支持以下版本的 [Fedora](https://fedoraproject.org/) 操作系 * 29 * 30 -#### 卸载旧版本 +### 卸载旧版本 旧版本的 Docker 称为 `docker` 或者 `docker-engine`,使用以下命令卸载旧版本: @@ -29,7 +29,7 @@ $ sudo dnf remove docker \ docker-engine ``` -### 使用 dnf 安装 +## 使用 dnf 安装 执行以下命令安装依赖包: @@ -71,7 +71,7 @@ $ sudo dnf config-manager --set-enabled docker-ce-nightly $ sudo dnf config-manager --set-disabled docker-ce-test ``` -#### 安装 Docker CE +### 安装 Docker CE 更新 `dnf` 软件源缓存,并安装 `docker-ce`。 @@ -90,7 +90,7 @@ docker-ce.x86_64 18.06.1.ce-3.fc28 docker-ce-stable $ sudo dnf -y install docker-ce-18.06.1.ce ``` -### 使用脚本自动安装 +## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -102,14 +102,14 @@ $ sudo sh get-docker.sh --mirror Aliyun 执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 最新稳定(stable)版本安装在系统中。 -### 启动 Docker CE +## 启动 Docker CE ```bash $ sudo systemctl enable docker $ sudo systemctl start docker ``` -### 建立 docker 用户组 +## 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 @@ -127,7 +127,7 @@ $ sudo usermod -aG docker $USER 退出当前终端并重新登录,进行如下测试。 -### 测试 Docker 是否安装正确 +## 测试 Docker 是否安装正确 ```bash $ docker run hello-world @@ -162,10 +162,10 @@ For more examples and ideas, visit: 若能正常输出以上信息,则说明安装成功。 -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 -### 参考文档 +## 参考文档 * [Docker 官方 Fedora 安装文档](https://docs.docker.com/install/linux/docker-ce/fedora)。 diff --git a/install/mac.md b/install/mac.md index 52513e9fc..80a385dfe 100644 --- a/install/mac.md +++ b/install/mac.md @@ -1,12 +1,12 @@ -## macOS 安装 Docker Desktop CE +# macOS 安装 Docker Desktop CE -### 系统要求 +## 系统要求 [Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Sierra 10.12。 -### 安装 +## 安装 -#### 使用 Homebrew 安装 +### 使用 Homebrew 安装 [Homebrew](https://brew.sh/) 的 [Cask](https://caskroom.github.io/) 已经支持 Docker Desktop for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装: @@ -14,7 +14,7 @@ $ brew cask install docker ``` -#### 手动下载安装 +### 手动下载安装 如果需要手动下载,请点击以下链接下载 [Stable](https://download.docker.com/mac/stable/Docker.dmg) 或 [Edge](https://download.docker.com/mac/edge/Docker.dmg) 版本的 Docker Desktop for Mac。 @@ -22,7 +22,7 @@ $ brew cask install docker ![](_images/install-mac-dmg.png) -### 运行 +## 运行 从应用中找到 Docker 图标并点击运行。 @@ -68,10 +68,10 @@ $ docker stop webserver $ docker rm webserver ``` -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 -### 参考链接 +## 参考链接 * [官方文档](https://docs.docker.com/docker-for-mac/install/) diff --git a/install/mirror.md b/install/mirror.md index 3b7e25e44..b999b0505 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -1,4 +1,4 @@ -## 镜像加速器 +# 镜像加速器 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如: @@ -12,7 +12,7 @@ 本节我们以 Azure 中国镜像 `https://dockerhub.azk8s.cn` 为例进行介绍。 -### Ubuntu 16.04+、Debian 8+、CentOS 7 +## Ubuntu 16.04+、Debian 8+、CentOS 7 对于使用 [systemd](https://www.freedesktop.org/wiki/Software/systemd/) 的系统,请在 `/etc/docker/daemon.json` 中写入如下内容(如果文件不存在请新建该文件) @@ -36,7 +36,7 @@ $ sudo systemctl restart docker >注意:如果您之前查看旧教程,修改了 `docker.service` 文件内容,请去掉您添加的内容(`--registry-mirror=https://dockerhub.azk8s.cn`)。 -### Windows 10 +## Windows 10 对于使用 `Windows 10` 的用户,在任务栏托盘 Docker 图标内右键菜单选择 `Settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。 @@ -49,7 +49,7 @@ $ sudo systemctl restart docker } ``` -### macOS +## macOS 对于使用 macOS 的用户,在任务栏点击 Docker Desktop 应用图标 -> `Perferences`,在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件。修改完成之后,点击 `Apply & Restart` 按钮,Docker 就会重启并应用配置的镜像地址了。 @@ -62,7 +62,7 @@ $ sudo systemctl restart docker } ``` -### 检查加速器是否生效 +## 检查加速器是否生效 执行 `$ docker info`,如果从结果中看到了如下内容,说明配置成功。 @@ -71,7 +71,7 @@ Registry Mirrors: https://dockerhub.azk8s.cn/ ``` -### gcr.io 镜像 +## gcr.io 镜像 国内无法直接获取 `gcr.io/*` 镜像,我们可以将 `gcr.io//:` 替换为 `gcr.azk8s.cn//:` ,例如 diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 5d04de4df..36d48c895 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -1,8 +1,8 @@ -## 树莓派卡片电脑安装 Docker CE +# 树莓派卡片电脑安装 Docker CE >警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. -### 系统要求 +## 系统要求 Docker CE 不仅支持 `x86_64` 架构的计算机,同时也支持 `ARM` 架构的计算机,本小节内容以树莓派单片电脑为例讲解 `ARM` 架构安装 Docker CE。 @@ -12,7 +12,7 @@ Docker CE 支持以下版本的 [Raspbian](https://www.raspberrypi.org/downloads *注:* `Raspbian` 是树莓派的开发与维护机构 [树莓派基金会](http://www.raspberrypi.org/) 推荐用于树莓派的首选系统,其基于 `Debian`。 -### 使用 APT 安装 +## 使用 APT 安装 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。 @@ -58,7 +58,7 @@ $ sudo add-apt-repository \ >以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。 -#### 安装 Docker CE +### 安装 Docker CE 更新 apt 软件包缓存,并安装 `docker-ce`。 @@ -68,7 +68,7 @@ $ sudo apt-get update $ sudo apt-get install docker-ce ``` -### 使用脚本自动安装 +## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspbian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -80,14 +80,14 @@ $ sudo sh get-docker.sh --mirror Aliyun 执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 -### 启动 Docker CE +## 启动 Docker CE ```bash $ sudo systemctl enable docker $ sudo systemctl start docker ``` -### 建立 docker 用户组 +## 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 @@ -105,7 +105,7 @@ $ sudo usermod -aG docker $USER 退出当前终端并重新登录,进行如下测试。 -### 测试 Docker 是否安装正确 +## 测试 Docker 是否安装正确 ```bash $ docker run arm32v7/hello-world @@ -142,6 +142,6 @@ For more examples and ideas, visit: *注意:* ARM 平台不能使用 `x86` 镜像,查看 Raspbian 可使用镜像请访问 [arm32v7](https://hub.docker.com/u/arm32v7/)。 -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 diff --git a/install/ubuntu.md b/install/ubuntu.md index 9cd599d35..2c5516500 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -1,10 +1,10 @@ -## Ubuntu 安装 Docker CE +# Ubuntu 安装 Docker CE >警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. -### 准备工作 +## 准备工作 -#### 系统要求 +### 系统要求 Docker CE 支持以下版本的 [Ubuntu](https://www.ubuntu.com/server) 操作系统: @@ -15,7 +15,7 @@ Docker CE 支持以下版本的 [Ubuntu](https://www.ubuntu.com/server) 操作 Docker CE 可以安装在 64 位的 x86 平台或 ARM 平台上。Ubuntu 发行版中,LTS(Long-Term-Support)长期支持版本,会获得 5 年的升级维护支持,这样的版本会更稳定,因此在生产环境中推荐使用 LTS 版本。 -#### 卸载旧版本 +### 卸载旧版本 旧版本的 Docker 称为 `docker` 或者 `docker-engine`,使用以下命令卸载旧版本: @@ -25,7 +25,7 @@ $ sudo apt-get remove docker \ docker.io ``` -### 使用 APT 安装 +## 使用 APT 安装 由于 `apt` 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。 @@ -69,7 +69,7 @@ $ sudo add-apt-repository \ >以上命令会添加稳定版本的 Docker CE APT 镜像源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。 -#### 安装 Docker CE +### 安装 Docker CE 更新 apt 软件包缓存,并安装 `docker-ce`: @@ -79,7 +79,7 @@ $ sudo apt-get update $ sudo apt-get install docker-ce ``` -### 使用脚本自动安装 +## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: @@ -91,14 +91,14 @@ $ sudo sh get-docker.sh --mirror Aliyun 执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 -### 启动 Docker CE +## 启动 Docker CE ```bash $ sudo systemctl enable docker $ sudo systemctl start docker ``` -### 建立 docker 用户组 +## 建立 docker 用户组 默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。 @@ -116,7 +116,7 @@ $ sudo usermod -aG docker $USER 退出当前终端并重新登录,进行如下测试。 -### 测试 Docker 是否安装正确 +## 测试 Docker 是否安装正确 ```bash $ docker run hello-world @@ -151,10 +151,10 @@ For more examples and ideas, visit: 若能正常输出以上信息,则说明安装成功。 -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 -### 参考文档 +## 参考文档 * [Docker 官方 Ubuntu 安装文档](https://docs.docker.com/install/linux/docker-ce/ubuntu/) diff --git a/install/windows.md b/install/windows.md index c7e387694..0286c28df 100644 --- a/install/windows.md +++ b/install/windows.md @@ -1,16 +1,16 @@ -## Windows 10 安装 Docker Desktop CE +# Windows 10 安装 Docker Desktop CE -### 系统要求 +## 系统要求 [Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V。 -### 安装 +## 安装 点击以下链接下载 [Stable](https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe) 或 [Edge](https://download.docker.com/win/edge/Docker%20Desktop%20Installer.exe) 版本的 Docker Desktop for Windows。 下载好之后双击 `Docker Desktop Installer.exe` 开始安装。 -### 运行 +## 运行 在 Windows 搜索栏输入 Docker 点击 Docker for Windows 开始运行。 @@ -24,10 +24,10 @@ Docker CE 启动之后会在 Windows 任务栏出现鲸鱼图标。 ![](_images/install-win-success-popup-cloud.png) -### 镜像加速 +## 镜像加速 如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](mirror.md)。 -### 参考链接 +## 参考链接 * [官方文档](https://docs.docker.com/docker-for-windows/install/) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 7ed35aafb..1ea7bdddc 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -1,18 +1,18 @@ -## Docker Hub +# Docker Hub 目前 Docker 官方维护了一个公共仓库 [Docker Hub](https://hub.docker.com/),其中已经包括了数量超过 [2,650,000](https://hub.docker.com/search/?type=image) 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。 -### 注册 +## 注册 你可以在 https://hub.docker.com 免费注册一个 Docker 账号。 -### 登录 +## 登录 可以通过执行 `docker login` 命令交互式的输入用户名及密码来完成在命令行界面登录 Docker Hub。 你可以通过 `docker logout` 退出登录。 -### 拉取镜像 +## 拉取镜像 你可以通过 `docker search` 命令来查找官方仓库中的镜像,并利用 `docker pull` 命令来将它下载到本地。 @@ -49,7 +49,7 @@ Pulling repository centos 7064731afe90: Download complete ``` -### 推送镜像 +## 推送镜像 用户也可以在登录后通过 `docker push` 命令来将自己的镜像推送到 Docker Hub。 @@ -72,7 +72,7 @@ NAME DESCRIPTION STARS username/ubuntu ``` -### 自动构建 +## 自动构建 自动构建(Automated Builds)功能对于需要经常升级镜像内程序来说,十分方便。 diff --git a/repository/nexus3_registry.md b/repository/nexus3_registry.md index 45a6ae669..479e64478 100644 --- a/repository/nexus3_registry.md +++ b/repository/nexus3_registry.md @@ -1,8 +1,8 @@ -## Nexus3.x 的私有仓库 +# Nexus3.x 的私有仓库 使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/download-oss-sonatype/) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 -### 启动 Nexus 容器 +## 启动 Nexus 容器 ```bash $ docker run -d --name nexus3 --restart=always \ @@ -15,7 +15,7 @@ $ docker run -d --name nexus3 --restart=always \ 第一次启动 Nexus 的默认帐号是 `admin` 密码是 `admin123` 登录以后点击页面上方的齿轮按钮进行设置。 -### 创建仓库 +## 创建仓库 创建一个私有仓库的方法: `Repository->Repositories` 点击右边菜单 `Create repository` 选择 `docker (hosted)` @@ -26,7 +26,7 @@ $ docker run -d --name nexus3 --restart=always \ 其它的仓库创建方法请各位自己摸索,还可以创建一个 docker (proxy) 类型的仓库链接到 DockerHub 上。再创建一个 docker (group) 类型的仓库把刚才的 hosted 与 proxy 添加在一起。主机在访问的时候默认下载私有仓库中的镜像,如果没有将链接到 DockerHub 中下载并缓存到 Nexus 中。 -### 添加访问权限 +## 添加访问权限 菜单 `Security->Realms` 把 Docker Bearer Token Realm 移到右边的框中保存。 @@ -34,7 +34,7 @@ $ docker run -d --name nexus3 --restart=always \ 添加用户:菜单 `Security->Users`->`Create local user` 在 `Roles` 选项中选中刚才创建的规则移动到右边的窗口保存。 -### NGINX 加密代理 +## NGINX 加密代理 证书的生成请参见 [`私有仓库高级配置`](registry_auth.md) 里面证书生成一节。 @@ -89,7 +89,7 @@ server { } ``` -### Docker 主机访问镜像仓库 +## Docker 主机访问镜像仓库 如果不启用 SSL 加密可以通过前面章节的方法添加信任地址到 Docker 的配置文件中然后重启 Docker diff --git a/repository/registry.md b/repository/registry.md index bacc3a150..433262ab0 100644 --- a/repository/registry.md +++ b/repository/registry.md @@ -1,4 +1,4 @@ -## 私有仓库 +# 私有仓库 有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。 @@ -6,9 +6,9 @@ [`docker-registry`](https://docs.docker.com/registry/) 是官方提供的工具,可以用于构建私有的镜像仓库。本文内容基于 [`docker-registry`](https://github.com/docker/distribution) v2.x 版本。 -### 安装运行 docker-registry +## 安装运行 docker-registry -#### 容器运行 +### 容器运行 你可以通过获取官方 `registry` 镜像来运行。 @@ -25,7 +25,7 @@ $ docker run -d \ registry ``` -### 在私有仓库上传、搜索、下载镜像 +## 在私有仓库上传、搜索、下载镜像 创建好私有仓库之后,就可以使用 `docker tag` 来标记一个镜像,然后推送它到仓库。例如私有仓库地址为 `127.0.0.1:5000`。 @@ -91,13 +91,13 @@ REPOSITORY TAG IMAGE ID CREAT 127.0.0.1:5000/ubuntu:latest latest ba5877dc9bec 6 weeks ago 192.7 MB ``` -### 注意事项 +## 注意事项 如果你不想使用 `127.0.0.1:5000` 作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。你就得把例如 `192.168.199.100:5000` 这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。 这是因为 Docker 默认不允许非 `HTTPS` 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制,或者查看下一节配置能够通过 `HTTPS` 访问的私有仓库。 -#### Ubuntu 16.04+, Debian 8+, centos 7 +### Ubuntu 16.04+, Debian 8+, centos 7 对于使用 `systemd` 的系统,请在 `/etc/docker/daemon.json` 中写入如下内容(如果文件不存在请新建该文件) @@ -114,6 +114,6 @@ REPOSITORY TAG IMAGE ID CREAT >注意:该文件必须符合 `json` 规范,否则 Docker 将不能启动。 -### 其他 +## 其他 对于 Docker Desktop for Windows 、 Docker Desktop for Mac 在设置中的 `Docker Engine` 中进行编辑 ,增加和上边一样的字符串即可。 diff --git a/repository/registry_auth.md b/repository/registry_auth.md index 9b5054400..68fda836a 100644 --- a/repository/registry_auth.md +++ b/repository/registry_auth.md @@ -1,10 +1,10 @@ -## 私有仓库高级配置 +# 私有仓库高级配置 上一节我们搭建了一个具有基础功能的私有仓库,本小节我们来使用 `Docker Compose` 搭建一个拥有权限认证、TLS 的私有仓库。 新建一个文件夹,以下步骤均在该文件夹中进行。 -### 准备站点证书 +## 准备站点证书 如果你拥有一个域名,国内各大云服务商均提供免费的站点证书。你也可以使用 `openssl` 自行签发证书。 @@ -82,7 +82,7 @@ $ openssl x509 -req -days 750 -in "site.csr" -sha256 \ 新建 `ssl` 文件夹并将 `docker.domain.com.key` `docker.domain.com.crt` `root-ca.crt` 这三个文件移入,删除其他文件。 -### 配置私有仓库 +## 配置私有仓库 私有仓库默认的配置文件位于 `/etc/docker/registry/config.yml`,我们先在本地编辑 `config.yml`,之后挂载到容器中。 @@ -124,7 +124,7 @@ health: threshold: 3 ``` -### 生成 http 认证文件 +## 生成 http 认证文件 ```bash $ mkdir auth @@ -137,7 +137,7 @@ $ docker run --rm \ > 将上面的 `username` `password` 替换为你自己的用户名和密码。 -### 编辑 `docker-compose.yml` +## 编辑 `docker-compose.yml` ```yaml version: '3' @@ -155,7 +155,7 @@ volumes: registry-data: ``` -### 修改 hosts +## 修改 hosts 编辑 `/etc/hosts` @@ -163,7 +163,7 @@ volumes: 127.0.0.1 docker.domain.com ``` -### 启动 +## 启动 ```bash $ docker-compose up -d @@ -171,7 +171,7 @@ $ docker-compose up -d 这样我们就搭建好了一个具有权限认证、TLS 的私有仓库,接下来我们测试其功能是否正常。 -### 测试私有仓库功能 +## 测试私有仓库功能 由于自行签发的 CA 根证书不被系统信任,所以我们需要将 CA 根证书 `ssl/root-ca.crt` 移入 `/etc/docker/certs.d/docker.domain.com` 文件夹中。 @@ -213,6 +213,6 @@ no basic auth credentials 发现会提示没有登录,不能将镜像推送到私有仓库中。 -### 注意事项 +## 注意事项 如果你本机占用了 `443` 端口,你可以配置 [Nginx 代理](https://docs.docker.com/registry/recipes/nginx/),这里不再赘述。 diff --git a/underly/arch.md b/underly/arch.md index 508ce5da9..b4366dfc9 100644 --- a/underly/arch.md +++ b/underly/arch.md @@ -1,4 +1,4 @@ -## 基本架构 +# 基本架构 Docker 采用了 `C/S` 架构,包括客户端和服务端。Docker 守护进程 (`Daemon`)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。 diff --git a/underly/cgroups.md b/underly/cgroups.md index 6ccd703d9..e7d5fd8f7 100644 --- a/underly/cgroups.md +++ b/underly/cgroups.md @@ -1,4 +1,4 @@ -## 控制组 +# 控制组 控制组([cgroups](https://en.wikipedia.org/wiki/Cgroups))是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。 diff --git a/underly/container_format.md b/underly/container_format.md index d634e30e6..94944a8fc 100644 --- a/underly/container_format.md +++ b/underly/container_format.md @@ -1,4 +1,4 @@ -## 容器格式 +# 容器格式 最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://containerd.tools/)。 diff --git a/underly/namespace.md b/underly/namespace.md index b4226aff4..ec66db213 100644 --- a/underly/namespace.md +++ b/underly/namespace.md @@ -1,22 +1,22 @@ -## 命名空间 +# 命名空间 命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。 -### pid 命名空间 +## pid 命名空间 不同用户的进程就是通过 pid 命名空间隔离开的,且不同命名空间中可以有相同 pid。所有的 LXC 进程在 Docker 中的父进程为 Docker 进程,每个 LXC 进程具有不同的命名空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。 -### net 命名空间 +## net 命名空间 有了 pid 命名空间,每个命名空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 命名空间实现的, 每个 net 命名空间有独立的 网络设备,IP 地址,路由表,/proc/net 目录。这样每个容器的网络就能隔离开来。Docker 默认采用 veth 的方式,将容器中的虚拟网卡同 host 上的一 个Docker 网桥 docker0 连接在一起。 -### ipc 命名空间 +## ipc 命名空间 容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存等。然而同 VM 不同的是,容器的进程间交互实际上还是 host 上具有相同 pid 命名空间中的进程间交互,因此需要在 IPC 资源申请时加入命名空间信息,每个 IPC 资源有一个唯一的 32 位 id。 -### mnt 命名空间 +## mnt 命名空间 类似 chroot,将一个进程放到一个特定的目录执行。mnt 命名空间允许不同命名空间的进程看到的文件结构不同,这样每个命名空间 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个命名空间中的容器在 /proc/mounts 的信息只包含所在命名空间的 mount point。 -### uts 命名空间 +## uts 命名空间 UTS("UNIX Time-sharing System") 命名空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。 -### user 命名空间 +## user 命名空间 每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。 *注:更多关于 Linux 上命名空间的信息,请阅读 [这篇文章](https://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/)。 diff --git a/underly/network.md b/underly/network.md index 4a0c20097..cec496c93 100644 --- a/underly/network.md +++ b/underly/network.md @@ -1,8 +1,8 @@ -## Docker 网络实现 +# Docker 网络实现 Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 veth pair)。建议先熟悉了解这两部分的基本概念再阅读本章。 -### 基本原理 +## 基本原理 首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。 Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 @@ -10,7 +10,7 @@ Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据 Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 `veth pair`)。 -### 创建网络参数 +## 创建网络参数 Docker 创建一个容器的时候,会执行如下操作: * 创建一对虚拟接口,分别放到本地主机和新容器中; * 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9; @@ -25,7 +25,7 @@ Docker 创建一个容器的时候,会执行如下操作: * `--net=container:NAME_or_ID` 让 Docker 将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过 `lo` 环回接口通信。 * `--net=none` 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。 -### 网络配置细节 +## 网络配置细节 用户使用 `--net=none` 后,可以自行配置网络,让容器达到跟平常一样具有访问网络的权限。通过这个过程,可以了解 Docker 配置网络的细节。 首先,启动一个 `/bin/bash` 容器,指定 `--net=none` 参数。 diff --git a/underly/ufs.md b/underly/ufs.md index d9251a21e..78d0bd586 100644 --- a/underly/ufs.md +++ b/underly/ufs.md @@ -1,4 +1,4 @@ -## 联合文件系统 +# 联合文件系统 联合文件系统([UnionFS](https://en.wikipedia.org/wiki/UnionFS))是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。 From 6f96aaf5a6c2adf95356be3375d07fb8afe6c316 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 6 Nov 2019 10:44:57 +0800 Subject: [PATCH 023/201] [CI] Fixed actions Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4a2625c21..99c253e68 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,10 +18,11 @@ jobs: args: build - name: vuepress run: | - rm -rf _book + sudo rm -rf _book npx vuepress build - name: Upload Vuepress dist uses: docker://pcit/pages + if: github.repository == 'docker-practice/docker_practice' env: PCIT_EMAIL: khs1994@khs1994.com PCIT_GIT_TOKEN: ${{ secrets.PCIT_GIT_TOKEN }} From 61492ff11a37146d5de53bc3f362c234308dbf99 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 6 Nov 2019 13:16:09 +0800 Subject: [PATCH 024/201] [vuepress] push dist to coding.net Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 99c253e68..4cfaecefe 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,6 +20,7 @@ jobs: run: | sudo rm -rf _book npx vuepress build + echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME - name: Upload Vuepress dist uses: docker://pcit/pages if: github.repository == 'docker-practice/docker_practice' @@ -32,3 +33,15 @@ jobs: PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master PCIT_USERNAME: khs1994 + - name: Upload Vuepress dist to coding.net + uses: docker://pcit/pages + if: github.repository == 'docker-practice/docker_practice' + env: + PCIT_EMAIL: khs1994@khs1994.com + PCIT_GIT_TOKEN: ${{ secrets.CODING_GIT_TOKEN }} + PCIT_GIT_URL: git.dev.tencent.com/khs1994/docker_practice + PCIT_KEEP_HISTORY: "1" + PCIT_LOCAL_DIR: .vuepress/dist + PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT + PCIT_TARGET_BRANCH: master + PCIT_USERNAME: khs1994 From 99e470eb2ae2cbcfdb2837c86968348a5b48fd76 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 6 Nov 2019 14:22:02 +0800 Subject: [PATCH 025/201] Update link Signed-off-by: Kang HuaiShuai --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 26f81731b..afdcbad16 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # Docker — 从入门到实践 -[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v18.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS) +[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS) **v1.1.0** | 语言 | 构建状态 | - | | :------------- | :------------- | :--- | | [zh-hans](https://github.com/yeasy/docker_practice) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh-cn) | -| [us-en](https://github.com/yeasy/docker_practice/tree/english) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=english)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/us_en) | -| [zh-hant](https://github.com/yeasy/docker_practice/tree/zh-Hant) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=zh-hant)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh_hant) | +| [us-en](https://github.com/yeasy/docker_practice/tree/english) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=english)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/us-en) | +| [zh-hant](https://github.com/yeasy/docker_practice/tree/zh-Hant) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=zh-hant)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh-hant) | [Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松! @@ -16,7 +16,7 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/zh-cn),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us_en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F), [新版 GitBook](https://gitbook.docker-practice.com/) +* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/zh-cn),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us-en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F), [新版 GitBook](https://gitbook.docker-practice.com/) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) * [英文翻译](https://github.com/yeasy/docker_practice/issues/363) From 5cb92f63cfd77f2164039cf0804c53d50ce6752d Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 6 Nov 2019 14:53:09 +0800 Subject: [PATCH 026/201] Update title style Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 23 +++++++------------ advanced_network/access_control.md | 10 ++++----- advanced_network/bridge.md | 2 +- advanced_network/config_file.md | 2 +- advanced_network/docker0.md | 2 +- advanced_network/example.md | 6 ++--- advanced_network/port_mapping.md | 6 ++--- advanced_network/ptp.md | 2 +- advanced_network/quick_guide.md | 2 +- appendix/repo/centos.md | 8 +++---- appendix/repo/mongodb.md | 8 +++---- appendix/repo/mysql.md | 8 +++---- appendix/repo/nginx.md | 8 +++---- appendix/repo/nodejs.md | 8 +++---- appendix/repo/php.md | 8 +++---- appendix/repo/redis.md | 8 +++---- appendix/repo/ubuntu.md | 8 +++---- appendix/repo/wordpress.md | 8 +++---- cases/os/centos.md | 12 +++++----- container/attach_exec.md | 8 +++---- container/daemon.md | 2 +- container/import_export.md | 6 ++--- container/rm.md | 4 ++-- container/run.md | 6 ++--- container/stop.md | 2 +- data_management/bind-mounts.md | 8 +++---- data_management/volume.md | 10 ++++----- etcd/cluster.md | 2 +- etcd/etcdctl-v2.md | 36 +++++++++++++++--------------- etcd/etcdctl.md | 16 ++++++------- etcd/install.md | 8 +++---- etcd/intro.md | 2 +- image/build.md | 20 ++++++++--------- image/commit.md | 5 ++--- image/dockerfile/README.md | 2 +- image/internal.md | 2 +- image/list.md | 12 +++++----- image/manifest.md | 16 ++++++------- image/multistage-builds/README.md | 14 ++++++------ image/multistage-builds/laravel.md | 20 ++++++++--------- image/other.md | 8 +++---- image/pull.md | 4 ++-- image/rm.md | 10 ++++----- network/dns.md | 2 +- network/linking.md | 8 +++---- network/port_mapping.md | 10 ++++----- opensource/linuxkit.md | 10 ++++----- security/control_group.md | 2 +- security/daemon_sec.md | 2 +- security/kernel_capability.md | 2 +- security/kernel_ns.md | 2 +- security/other_feature.md | 2 +- security/summary.md | 2 +- swarm_mode/config.md | 8 +++---- swarm_mode/create.md | 8 +++---- swarm_mode/deploy.md | 10 ++++----- swarm_mode/overview.md | 6 ++--- swarm_mode/rolling_update.md | 4 ++-- swarm_mode/secret.md | 8 +++---- swarm_mode/stack.md | 8 +++---- 60 files changed, 224 insertions(+), 232 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index af5b2815f..ce4a00027 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -312,12 +312,11 @@ module.exports = { 'opensource/linuxkit', ], }, + 'appendix/faq/', { - title: "附录", - collapsable:false, + title: "热门镜像介绍", + collapsable: false, children: [ - 'appendix/', - 'appendix/faq/', 'appendix/repo/', 'appendix/repo/ubuntu', 'appendix/repo/centos', @@ -328,19 +327,13 @@ module.exports = { 'appendix/repo/wordpress', 'appendix/repo/mongodb', 'appendix/repo/redis', - 'appendix/command/', - 'appendix/best_practices', - 'appendix/debug', - 'appendix/resources' - ], - }, - { - title: "归档", - collapsable: false, - children: [ - 'archive/', ], }, + 'appendix/command/', + 'appendix/best_practices', + 'appendix/debug', + 'appendix/resources', + 'archive/', { title: "Docker Machine", collapsable: false, diff --git a/advanced_network/access_control.md b/advanced_network/access_control.md index e9fff7102..c382b5d7b 100644 --- a/advanced_network/access_control.md +++ b/advanced_network/access_control.md @@ -1,7 +1,7 @@ -## 容器访问控制 +# 容器访问控制 容器的访问控制,主要通过 Linux 上的 `iptables` 防火墙来进行管理和实现。`iptables` 是 Linux 上默认的防火墙软件,在大部分发行版中都自带。 -### 容器访问外部网络 +## 容器访问外部网络 容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。 ```bash @@ -14,17 +14,17 @@ $sysctl -w net.ipv4.ip_forward=1 ``` 如果在启动 Docker 服务的时候设定 `--ip-forward=true`, Docker 就会自动设定系统的 `ip_forward` 参数为 1。 -### 容器之间访问 +## 容器之间访问 容器之间相互访问,需要两方面的支持。 * 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 `docker0` 网桥上。 * 本地系统的防火墙软件 -- `iptables` 是否允许通过。 -#### 访问所有端口 +### 访问所有端口 当启动 Docker 服务(即 dockerd)的时候,默认会添加一条转发策略到本地主机 iptables 的 FORWARD 链上。策略为通过(`ACCEPT`)还是禁止(`DROP`)取决于配置`--icc=true`(缺省值)还是 `--icc=false`。当然,如果手动指定 `--iptables=false` 则不会添加 `iptables` 规则。 可见,默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在 `/etc/docker/daemon.json` 文件中配置 `{"icc": false}` 来禁止它。 -#### 访问指定端口 +### 访问指定端口 在通过 `-icc=false` 关闭网络访问后,还可以通过 `--link=CONTAINER_NAME:ALIAS` 选项来访问容器的开放端口。 例如,在启动 Docker 服务时,可以同时使用 `icc=false --iptables=true` 参数来关闭允许相互的网络访问,并让 Docker 可以修改系统中的 `iptables` 规则。 diff --git a/advanced_network/bridge.md b/advanced_network/bridge.md index 31e24b16e..0ce6a5298 100644 --- a/advanced_network/bridge.md +++ b/advanced_network/bridge.md @@ -1,4 +1,4 @@ -## 自定义网桥 +# 自定义网桥 除了默认的 `docker0` 网桥,用户也可以指定网桥来连接各个容器。 diff --git a/advanced_network/config_file.md b/advanced_network/config_file.md index 43733b821..b084c79ad 100644 --- a/advanced_network/config_file.md +++ b/advanced_network/config_file.md @@ -1,4 +1,4 @@ -## 编辑网络配置文件 +# 编辑网络配置文件 Docker 1.2.0 开始支持在运行中的容器里编辑 `/etc/hosts`, `/etc/hostname` 和 `/etc/resolv.conf` 文件。 diff --git a/advanced_network/docker0.md b/advanced_network/docker0.md index 99e578580..c21ce8b70 100644 --- a/advanced_network/docker0.md +++ b/advanced_network/docker0.md @@ -1,4 +1,4 @@ -## 配置 docker0 网桥 +# 配置 docker0 网桥 Docker 服务默认会创建一个 `docker0` 网桥(其上有一个 `docker0` 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。 diff --git a/advanced_network/example.md b/advanced_network/example.md index 23ac7af13..f7ca843b1 100644 --- a/advanced_network/example.md +++ b/advanced_network/example.md @@ -1,8 +1,8 @@ -## 工具和示例 +# 工具和示例 在介绍自定义网络拓扑之前,你可能会对一些外部工具和例子感兴趣: -### pipework +## pipework Jérôme Petazzoni 编写了一个叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接。 -### playground +## playground Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 `HTTP` `SMTP` `POP` `IMAP` `Telnet` `SSH` `FTP` 的服务器。 diff --git a/advanced_network/port_mapping.md b/advanced_network/port_mapping.md index 8625e3a57..dc6f92d30 100644 --- a/advanced_network/port_mapping.md +++ b/advanced_network/port_mapping.md @@ -1,8 +1,8 @@ -## 映射容器端口到宿主主机的实现 +# 映射容器端口到宿主主机的实现 默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。 -### 容器访问外部实现 +## 容器访问外部实现 容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址。这是使用 `iptables` 的源地址伪装操作实现的。 @@ -19,7 +19,7 @@ MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16 其中,上述规则将所有源地址在 `172.17.0.0/16` 网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 的好处是它能动态从网卡获取地址。 -### 外部访问容器实现 +## 外部访问容器实现 容器允许外部访问,可以在 `docker run` 时候通过 `-p` 或 `-P` 参数来启用。 diff --git a/advanced_network/ptp.md b/advanced_network/ptp.md index 438f6f116..738a75171 100644 --- a/advanced_network/ptp.md +++ b/advanced_network/ptp.md @@ -1,4 +1,4 @@ -## 示例:创建一个点到点连接 +# 示例:创建一个点到点连接 默认情况下,Docker 会将所有容器连接到由 `docker0` 提供的虚拟子网中。 用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。 diff --git a/advanced_network/quick_guide.md b/advanced_network/quick_guide.md index e32641816..455a81814 100644 --- a/advanced_network/quick_guide.md +++ b/advanced_network/quick_guide.md @@ -1,4 +1,4 @@ -## 快速配置指南 +# 快速配置指南 下面是一个跟 Docker 网络相关的命令列表。 diff --git a/appendix/repo/centos.md b/appendix/repo/centos.md index 3ef727ff0..5ebaf20f6 100644 --- a/appendix/repo/centos.md +++ b/appendix/repo/centos.md @@ -1,12 +1,12 @@ -## [CentOS](https://hub.docker.com/_/centos) +# [CentOS](https://hub.docker.com/_/centos) -### 基本信息 +## 基本信息 [CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致。 该仓库位于 `https://hub.docker.com/_/centos` ,提供了 CentOS 从 5 ~ 8 各个版本的镜像。 -### 使用方法 +## 使用方法 默认会启动一个最小化的 CentOS 环境。 @@ -15,6 +15,6 @@ $ docker run --name centos -it centos bash bash-4.2# ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/centos 查看。 diff --git a/appendix/repo/mongodb.md b/appendix/repo/mongodb.md index fc7025a67..129e90869 100644 --- a/appendix/repo/mongodb.md +++ b/appendix/repo/mongodb.md @@ -1,12 +1,12 @@ -## [MongoDB](https://hub.docker.com/_/mongo/) +# [MongoDB](https://hub.docker.com/_/mongo/) -### 基本信息 +## 基本信息 [MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是开源的 NoSQL 数据库实现。 该仓库位于 `https://hub.docker.com/_/mongo/` ,提供了 MongoDB 2.x ~ 4.x 各个版本的镜像。 -### 使用方法 +## 使用方法 默认会在 `27017` 端口启动数据库。 @@ -29,6 +29,6 @@ $ docker run -it --rm \ sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test"' ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/mongo 查看。 diff --git a/appendix/repo/mysql.md b/appendix/repo/mysql.md index eef26d5a9..1a38c9dfc 100644 --- a/appendix/repo/mysql.md +++ b/appendix/repo/mysql.md @@ -1,12 +1,12 @@ -## [MySQL](https://hub.docker.com/_/mysql/) +# [MySQL](https://hub.docker.com/_/mysql/) -### 基本信息 +## 基本信息 [MySQL](https://en.wikipedia.org/wiki/MySQL) 是开源的关系数据库实现。 该仓库位于 `https://hub.docker.com/_/mysql/` ,提供了 MySQL 5.5 ~ 8.x 各个版本的镜像。 -### 使用方法 +## 使用方法 默认会在 `3306` 端口启动数据库。 @@ -29,6 +29,6 @@ $ docker run -it --rm \ sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"' ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/mysql 查看 diff --git a/appendix/repo/nginx.md b/appendix/repo/nginx.md index b649a31ee..36b11c0e5 100644 --- a/appendix/repo/nginx.md +++ b/appendix/repo/nginx.md @@ -1,12 +1,12 @@ -## [Nginx](https://hub.docker.com/_/nginx/) +# [Nginx](https://hub.docker.com/_/nginx/) -### 基本信息 +## 基本信息 [Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。 该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.17.x 各个版本的镜像。 -### 使用方法 +## 使用方法 下面的命令将作为一个静态页面服务器启动。 @@ -43,6 +43,6 @@ $ docker run -d \ nginx ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/nginx 查看。 diff --git a/appendix/repo/nodejs.md b/appendix/repo/nodejs.md index 38503a9d3..ffe426743 100644 --- a/appendix/repo/nodejs.md +++ b/appendix/repo/nodejs.md @@ -1,12 +1,12 @@ -## [Node.js](https://hub.docker.com/_/node/) +# [Node.js](https://hub.docker.com/_/node/) -### 基本信息 +## 基本信息 [Node.js](https://en.wikipedia.org/wiki/Node.js) 是基于 JavaScript 的可扩展服务端和网络软件开发平台。 该仓库位于 `https://hub.docker.com/_/node/` ,提供了 Node.js 0.10 ~ 12.x 各个版本的镜像。 -### 使用方法 +## 使用方法 在项目中创建一个 Dockerfile。 @@ -35,6 +35,6 @@ $ docker run -it --rm \ node your-daemon-or-script.js ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/node 查看。 diff --git a/appendix/repo/php.md b/appendix/repo/php.md index cf62af628..7edbb85be 100644 --- a/appendix/repo/php.md +++ b/appendix/repo/php.md @@ -1,12 +1,12 @@ -## [PHP](https://hub.docker.com/_/php/) +# [PHP](https://hub.docker.com/_/php/) -### 基本信息 +## 基本信息 [PHP](https://en.wikipedia.org/wiki/php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。 该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 7.x 各个版本的镜像。 -### 使用方法 +## 使用方法 下面的命令将运行一个已有的 PHP 脚本。 @@ -14,6 +14,6 @@ $ docker run -it --rm -v "$PWD":/app -w /app php:alpine php your-script.php ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/php 查看。 diff --git a/appendix/repo/redis.md b/appendix/repo/redis.md index 92eb53f7d..9f06dedea 100644 --- a/appendix/repo/redis.md +++ b/appendix/repo/redis.md @@ -1,12 +1,12 @@ -## [Redis](https://hub.docker.com/_/redis/) +# [Redis](https://hub.docker.com/_/redis/) -### 基本信息 +## 基本信息 [Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。 该仓库位于 `https://hub.docker.com/_/redis/` ,提供了 Redis 3.x ~ 5.x 各个版本的镜像。 -### 使用方法 +## 使用方法 默认会在 `6379` 端口启动数据库。 @@ -37,6 +37,6 @@ $ docker run -it --rm \ sh -c 'exec redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT"' ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/redis 查看。 diff --git a/appendix/repo/ubuntu.md b/appendix/repo/ubuntu.md index 20aea1d6a..c904d991c 100644 --- a/appendix/repo/ubuntu.md +++ b/appendix/repo/ubuntu.md @@ -1,12 +1,12 @@ -## [Ubuntu](https://hub.docker.com/_/ubuntu/) +# [Ubuntu](https://hub.docker.com/_/ubuntu/) -### 基本信息 +## 基本信息 [Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。 该仓库位于 `https://hub.docker.com/_/ubuntu/` ,提供了 Ubuntu 从 12.04 ~ 19.04 各个版本的镜像。 -### 使用方法 +## 使用方法 默认会启动一个最小化的 Ubuntu 环境。 @@ -15,6 +15,6 @@ $ docker run --name some-ubuntu -it ubuntu:18.04 root@523c70904d54:/# ``` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/ubuntu 查看。 diff --git a/appendix/repo/wordpress.md b/appendix/repo/wordpress.md index b6cace123..2e571c491 100644 --- a/appendix/repo/wordpress.md +++ b/appendix/repo/wordpress.md @@ -1,12 +1,12 @@ -## [WordPress](https://hub.docker.com/_/wordpress/) +# [WordPress](https://hub.docker.com/_/wordpress/) -### 基本信息 +## 基本信息 [WordPress](https://en.wikipedia.org/wiki/WordPress) 是开源的 Blog 和内容管理系统框架,它基于 PHP 和 MySQL。 该仓库位于 `https://hub.docker.com/_/wordpress/` ,提供了 WordPress 4.x ~ 5.x 版本的镜像。 -### 使用方法 +## 使用方法 启动容器需要 MySQL 的支持,默认端口为 `80`。 @@ -20,6 +20,6 @@ $ docker run --name some-wordpress --link some-mysql:mysql -d wordpress * `WORDPRESS_DB_PASSWORD` 缺省为连接 mysql 容器的环境变量 `MYSQL_ROOT_PASSWORD` 的值 * `WORDPRESS_DB_NAME` 缺省为 `wordpress` -### Dockerfile +## Dockerfile 请到 https://github.com/docker-library/docs/tree/master/wordpress 查看。 diff --git a/cases/os/centos.md b/cases/os/centos.md index 10ed74467..b331e0486 100644 --- a/cases/os/centos.md +++ b/cases/os/centos.md @@ -1,6 +1,6 @@ -## CentOS/Fedora +# CentOS/Fedora -### CentOS 系统简介 +## CentOS 系统简介 `CentOS` 和 `Fedora` 都是基于 `Redhat` 的常见 Linux 分支。`CentOS` 是目前企业级服务器的常用操作系统;`Fedora` 则主要面向个人桌面用户。 @@ -8,7 +8,7 @@ CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 `Red Hat Enterprise Linux` 源代码编译而成。由于 `CentOS` 与 `Redhat Linux` 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 `CentOS` 来替代商业版 `Red Hat Enterprise Linux`。`CentOS` 自身不包含闭源软件。 -#### 使用 CentOS 官方镜像 +### 使用 CentOS 官方镜像 首先使用 `docker search` 命令来搜索标星至少为 `25` 的 `CentOS` 相关镜像。 @@ -32,13 +32,13 @@ Status: Downloaded newer image for centos:latest CentOS Linux release 7.2.1511 (Core) ``` -### Fedora 系统简介 +## Fedora 系统简介 ![Fedora 操作系统](_images/fedora-logo.png) `Fedora` 由 `Fedora Project` 社区开发,红帽公司赞助的 `Linux` 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。`Fedora` 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 `Red Hat` 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 `Red Hat Enterprise Linux` 中。 -#### 使用 Fedora 官方镜像 +### 使用 Fedora 官方镜像 首先使用 `docker search` 命令来搜索标星至少为 `2` 的 `Fedora` 相关镜像,结果如下。 @@ -64,7 +64,7 @@ Status: Downloaded newer image for fedora:latest Fedora release 24 (Twenty Four) ``` -### 相关资源 +## 相关资源 * `Fedora` 官网:https://getfedora.org/ * `Fedora` 官方仓库:https://github.com/fedora-infra diff --git a/container/attach_exec.md b/container/attach_exec.md index 0feb1342a..3c342cdce 100644 --- a/container/attach_exec.md +++ b/container/attach_exec.md @@ -1,10 +1,10 @@ -## 进入容器 +# 进入容器 在使用 `-d` 参数时,容器启动后会进入后台。 某些时候需要进入容器进行操作,包括使用 `docker attach` 命令或 `docker exec` 命令,推荐大家使用 `docker exec` 命令,原因会在下面说明。 -### `attach` 命令 +## `attach` 命令 下面示例如何使用 `docker attach` 命令。 @@ -22,9 +22,9 @@ root@243c32535da7:/# *注意:* 如果从这个 stdin 中 exit,会导致容器的停止。 -### `exec` 命令 +## `exec` 命令 -#### -i -t 参数 +### -i -t 参数 `docker exec` 后边可以跟多个参数,这里主要说明 `-i` `-t` 参数。 diff --git a/container/daemon.md b/container/daemon.md index 5175c3557..37840aff2 100644 --- a/container/daemon.md +++ b/container/daemon.md @@ -1,4 +1,4 @@ -## 后台运行 +# 后台运行 更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 `-d` 参数来实现。 diff --git a/container/import_export.md b/container/import_export.md index c2a76a29e..7f88763fd 100644 --- a/container/import_export.md +++ b/container/import_export.md @@ -1,6 +1,6 @@ -## 导出和导入容器 +# 导出和导入容器 -### 导出容器 +## 导出容器 如果要导出本地某个容器,可以使用 `docker export` 命令。 ```bash @@ -12,7 +12,7 @@ $ docker export 7691a814370e > ubuntu.tar 这样将导出容器快照到本地文件。 -### 导入容器快照 +## 导入容器快照 可以使用 `docker import` 从容器快照文件中再导入为镜像,例如 diff --git a/container/rm.md b/container/rm.md index 4de8504b9..5fce0fe17 100644 --- a/container/rm.md +++ b/container/rm.md @@ -1,4 +1,4 @@ -## 删除容器 +# 删除容器 可以使用 `docker container rm` 来删除一个处于终止状态的容器。例如 @@ -9,7 +9,7 @@ trusting_newton 如果要删除一个运行中的容器,可以添加 `-f` 参数。Docker 会发送 `SIGKILL` 信号给容器。 -## 清理所有处于终止状态的容器 +# 清理所有处于终止状态的容器 用 `docker container ls -a` 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。 diff --git a/container/run.md b/container/run.md index 9dfd596ca..a58697e5f 100644 --- a/container/run.md +++ b/container/run.md @@ -1,10 +1,10 @@ -## 启动容器 +# 启动容器 启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(`stopped`)的容器重新启动。 因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。 -### 新建并启动 +## 新建并启动 所需要的命令主要为 `docker run`。 @@ -45,7 +45,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr * 执行用户指定的应用程序 * 执行完毕后容器被终止 -### 启动已终止容器 +## 启动已终止容器 可以利用 `docker container start` 命令,直接将一个已经终止的容器启动运行。 diff --git a/container/stop.md b/container/stop.md index 31853a5d9..77dd73269 100644 --- a/container/stop.md +++ b/container/stop.md @@ -1,4 +1,4 @@ -## 终止容器 +# 终止容器 可以使用 `docker container stop` 来终止一个运行中的容器。 diff --git a/data_management/bind-mounts.md b/data_management/bind-mounts.md index 6d0bef720..8c9ac30c6 100644 --- a/data_management/bind-mounts.md +++ b/data_management/bind-mounts.md @@ -1,6 +1,6 @@ -## 挂载主机目录 +# 挂载主机目录 -### 挂载一个主机目录作为数据卷 +## 挂载一个主机目录作为数据卷 使用 `--mount` 标记可以指定挂载一个本地主机的目录到容器中去。 @@ -33,7 +33,7 @@ $ docker run -d -P \ touch: new.txt: Read-only file system ``` -### 查看数据卷的具体信息 +## 查看数据卷的具体信息 在主机里使用以下命令可以查看 `web` 容器的信息 @@ -56,7 +56,7 @@ $ docker inspect web ], ``` -### 挂载一个本地主机文件作为数据卷 +## 挂载一个本地主机文件作为数据卷 `--mount` 标记也可以从主机挂载单个文件到容器中 diff --git a/data_management/volume.md b/data_management/volume.md index b96b624c5..5fc3193cf 100644 --- a/data_management/volume.md +++ b/data_management/volume.md @@ -1,4 +1,4 @@ -## 数据卷 +# 数据卷 `数据卷` 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性: @@ -12,7 +12,7 @@ >注意:`数据卷` 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 `数据卷`。 -### 创建一个数据卷 +## 创建一个数据卷 ```bash $ docker volume create my-vol @@ -42,7 +42,7 @@ $ docker volume inspect my-vol ] ``` -### 启动一个挂载数据卷的容器 +## 启动一个挂载数据卷的容器 在用 `docker run` 命令的时候,使用 `--mount` 标记来将 `数据卷` 挂载到容器里。在一次 `docker run` 中可以挂载多个 `数据卷`。 @@ -57,7 +57,7 @@ $ docker run -d -P \ python app.py ``` -### 查看数据卷的具体信息 +## 查看数据卷的具体信息 在主机里使用以下命令可以查看 `web` 容器的信息 @@ -82,7 +82,7 @@ $ docker inspect web ], ``` -### 删除数据卷 +## 删除数据卷 ```bash $ docker volume rm my-vol diff --git a/etcd/cluster.md b/etcd/cluster.md index dc39d33ae..305e78e4a 100644 --- a/etcd/cluster.md +++ b/etcd/cluster.md @@ -1,4 +1,4 @@ -## etcd 集群 +# etcd 集群 下面我们使用 [Docker Compose](../compose/) 模拟启动一个 3 节点的 `etcd` 集群。 diff --git a/etcd/etcdctl-v2.md b/etcd/etcdctl-v2.md index 6e66a9ff8..d37e4ce75 100644 --- a/etcd/etcdctl-v2.md +++ b/etcd/etcdctl-v2.md @@ -1,4 +1,4 @@ -## 使用 etcdctl v2 +# 使用 etcdctl v2 `etcdctl` 是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟 `etcd` 服务打交道,而无需基于 `HTTP API` 方式。这在某些情况下将很方便,例如用户对服务进行测试或者手动修改数据库内容。我们也推荐在刚接触 `etcd` 时通过 `etcdctl` 命令来熟悉相关的操作,这些操作跟 `HTTP API` 实际上是对应的。 @@ -46,14 +46,14 @@ GLOBAL OPTIONS: --version, -v print the version ``` -### 数据库操作 +## 数据库操作 数据库操作围绕对键值和目录的 CRUD (符合 REST 风格的一套操作:Create)完整生命周期的管理。 etcd 在键的组织上采用了层次化的空间结构(类似于文件系统中目录的概念),用户指定的键可以为单独的名字,如 `testkey`,此时实际上放在根目录 `/` 下面,也可以为指定目录结构,如 `cluster1/node2/testkey`,则将创建相应的目录结构。 *注:CRUD 即 Create, Read, Update, Delete,是符合 REST 风格的一套 API 操作。* -#### set +### set 指定某个键的值。例如 ```bash $ etcdctl set /testdir/testkey "Hello world" @@ -66,7 +66,7 @@ Hello world --swap-with-index '0' 若该键现在的索引值是指定索引,则进行设置操作 ``` -#### get +### get 获取指定键的值。例如 ```bash $ etcdctl set testkey hello @@ -87,7 +87,7 @@ Error: 100: Key not found (/testkey2) [1] --consistent 将请求发给主节点,保证获取内容的一致性 ``` -#### update +### update 当键存在时,更新值内容。例如 ```bash $ etcdctl set testkey hello @@ -107,7 +107,7 @@ Error: 100: Key not found (/testkey2) [1] --ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时 ``` -#### rm +### rm 删除某个键值。例如 ```bash $ etcdctl rm testkey @@ -127,7 +127,7 @@ Error: 100: Key not found (/testkey2) [8] --with-index '0' 检查现有的 index 是否匹配 ``` -#### mk +### mk 如果给定的键不存在,则创建一个新的键值。例如 ```bash $ etcdctl mk /testdir/testkey "Hello world" @@ -146,7 +146,7 @@ Error: 105: Key already exists (/testkey) [2] --ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时 ``` -#### mkdir +### mkdir 如果给定的键目录不存在,则创建一个新的键目录。例如 ```bash $ etcdctl mkdir testdir @@ -162,7 +162,7 @@ Error: 105: Key already exists (/testdir) [7] --ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时 ``` -#### setdir +### setdir 创建一个键目录,无论存在与否。 @@ -171,14 +171,14 @@ Error: 105: Key already exists (/testdir) [7] --ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时 ``` -#### updatedir +### updatedir 更新一个已经存在的目录。 支持的选项为 ```bash --ttl '0' 超时时间(单位为秒),不配置(默认为 0)则永不超时 ``` -#### rmdir +### rmdir 删除一个空目录,或者键值对。 若目录不空,会报错 @@ -189,7 +189,7 @@ $ etcdctl rmdir /dir Error: 108: Directory not empty (/dir) [13] ``` -#### ls +### ls 列出目录(默认为根目录)下的键或者子目录,默认不显示子目录中内容。 例如 @@ -212,9 +212,9 @@ $ ./etcdctl ls dir -p 对于输出为目录,在最后添加 `/` 进行区分 ``` -### 非数据库操作 +## 非数据库操作 -#### backup +### backup 备份 etcd 的数据。 支持的选项包括 @@ -222,7 +222,7 @@ $ ./etcdctl ls dir --data-dir etcd 的数据目录 --backup-dir 备份到指定路径 ``` -#### watch +### watch 监测一个键值的变化,一旦键值发生更新,就会输出最新的值并退出。 例如,用户更新 testkey 键值为 Hello world。 @@ -237,7 +237,7 @@ Hello world --after-index '0' 在指定 index 之前一直监测 --recursive 返回所有的键值和子键值 ``` -#### exec-watch +### exec-watch 监测一个键值的变化,一旦键值发生更新,就执行给定命令。 例如,用户更新 testkey 键值。 @@ -258,7 +258,7 @@ README.md --recursive 返回所有的键值和子键值 ``` -#### member +### member 通过 list、add、remove 命令列出、添加、删除 etcd 实例到 etcd 集群中。 @@ -269,7 +269,7 @@ $ etcdctl member list ce2a822cea30bfca: name=default peerURLs=http://localhost:2380,http://localhost:7001 clientURLs=http://localhost:2379,http://localhost:4001 ``` -### 命令选项 +## 命令选项 * `--debug` 输出 cURL 命令,显示执行命令的时候发起的请求 * `--no-sync` 发出请求之前不同步集群信息 * `--output, -o 'simple'` 输出内容的格式 (`simple` 为原始信息,`json` 为进行json格式解码,易读性好一些) diff --git a/etcd/etcdctl.md b/etcd/etcdctl.md index e9d398a74..29c0f0d9f 100644 --- a/etcd/etcdctl.md +++ b/etcd/etcdctl.md @@ -1,4 +1,4 @@ -## 使用 etcdctl +# 使用 etcdctl `etcdctl` 是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟 `etcd` 服务打交道,而无需基于 `HTTP API` 方式。这在某些情况下将很方便,例如用户对服务进行测试或者手动修改数据库内容。我们也推荐在刚接触 `etcd` 时通过 `etcdctl` 命令来熟悉相关的操作,这些操作跟 `HTTP API` 实际上是对应的。 @@ -81,7 +81,7 @@ OPTIONS: -w, --write-out="simple" set the output format (fields, json, protobuf, simple, table) ``` -### 数据库操作 +## 数据库操作 数据库操作围绕对键值和目录的 CRUD (符合 REST 风格的一套操作:Create)完整生命周期的管理。 @@ -89,14 +89,14 @@ etcd 在键的组织上采用了层次化的空间结构(类似于文件系统 >注:CRUD 即 Create, Read, Update, Delete,是符合 REST 风格的一套 API 操作。 -#### put +### put ```bash $ etcdctl put /testdir/testkey "Hello world" OK ``` -#### get +### get 获取指定键的值。例如 @@ -114,7 +114,7 @@ hello `--consistent` 将请求发给主节点,保证获取内容的一致性 -#### del +### del 删除某个键值。例如 @@ -123,9 +123,9 @@ $ etcdctl del testkey 1 ``` -### 非数据库操作 +## 非数据库操作 -#### watch +### watch 监测一个键值的变化,一旦键值发生更新,就会输出最新的值。 @@ -138,7 +138,7 @@ testkey 2 ``` -#### member +### member 通过 `list`、`add`、`update`、`remove` 命令列出、添加、更新、删除 etcd 实例到 etcd 集群中。 diff --git a/etcd/install.md b/etcd/install.md index 472865d48..d188f5efe 100644 --- a/etcd/install.md +++ b/etcd/install.md @@ -1,10 +1,10 @@ -## 安装 +# 安装 `etcd` 基于 `Go` 语言实现,因此,用户可以从 [项目主页](https://github.com/etcd-io/etcd) 下载源代码自行编译,也可以下载编译好的二进制文件,甚至直接使用制作好的 `Docker` 镜像文件来体验。 >注意:本章节内容基于 etcd `3.4.x` 版本 -### 二进制文件方式下载 +## 二进制文件方式下载 编译好的二进制文件都在 [github.com/etcd-io/etcd/releases](https://github.com/etcd-io/etcd/releases/) 页面,用户可以选择需要的版本,或通过下载工具下载。 @@ -56,7 +56,7 @@ hello world 说明 etcd 服务已经成功启动了。 -### Docker 镜像方式运行 +## Docker 镜像方式运行 镜像名称为 `quay.io/coreos/etcd`,可以通过下面的命令启动 `etcd` 服务监听到 `2379` 和 `2380` 端口。 @@ -84,7 +84,7 @@ quay.io/coreos/etcd:v3.4.0 \ 打开新的终端按照上一步的方法测试 `etcd` 是否成功启动。 -### macOS 中运行 +## macOS 中运行 ```bash $ brew install etcd diff --git a/etcd/intro.md b/etcd/intro.md index 186209192..19f98b17c 100644 --- a/etcd/intro.md +++ b/etcd/intro.md @@ -1,4 +1,4 @@ -## 什么是 etcd +# 什么是 etcd ![](_images/etcd_logo.png) diff --git a/image/build.md b/image/build.md index 135207ddb..6fde477d6 100644 --- a/image/build.md +++ b/image/build.md @@ -1,4 +1,4 @@ -## 使用 Dockerfile 定制镜像 +# 使用 Dockerfile 定制镜像 从刚才的 `docker commit` 的学习中,我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。 @@ -23,7 +23,7 @@ RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html 这个 Dockerfile 很简单,一共就两行。涉及到了两条指令,`FROM` 和 `RUN`。 -### FROM 指定基础镜像 +## FROM 指定基础镜像 所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 `nginx` 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 `FROM` 就是指定 **基础镜像**,因此一个 `Dockerfile` 中 `FROM` 是必备的指令,并且必须是第一条指令。 @@ -42,7 +42,7 @@ FROM scratch 不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,比如 [`swarm`](https://hub.docker.com/_/swarm/)、[`etcd`](https://quay.io/repository/coreos/etcd)。对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 `FROM scratch` 会让镜像体积更加小巧。使用 [Go 语言](https://golang.org/) 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。 -### RUN 执行命令 +## RUN 执行命令 `RUN` 指令是用来执行命令行命令的。由于命令行的强大能力,`RUN` 指令在定制镜像时是最常用的指令之一。其格式有两种: @@ -102,7 +102,7 @@ RUN buildDeps='gcc libc6-dev make wget' \ 很多人初学 Docker 制作出了很臃肿的镜像的原因之一,就是忘记了每一层构建的最后一定要清理掉无关文件。 -### 构建镜像 +## 构建镜像 好了,让我们再回到之前定制的 nginx 镜像的 Dockerfile 来。现在我们明白了这个 Dockerfile 的内容,那么让我们来构建这个镜像吧。 @@ -130,7 +130,7 @@ docker build [选项] <上下文路径/URL/-> 在这里我们指定了最终镜像的名称 `-t nginx:v3`,构建成功后,我们可以像之前运行 `nginx:v2` 那样来运行这个镜像,其结果会和 `nginx:v2` 一样。 -### 镜像构建上下文(Context) +## 镜像构建上下文(Context) 如果注意,会看到 `docker build` 命令最后有一个 `.`。`.` 表示当前目录,而 `Dockerfile` 就在当前目录,因此不少初学者以为这个路径是在指定 `Dockerfile` 所在路径,这么理解其实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定 **上下文路径**。那么什么是上下文呢? @@ -170,9 +170,9 @@ Sending build context to Docker daemon 2.048 kB 当然,一般大家习惯性的会使用默认的文件名 `Dockerfile`,以及会将其置于镜像构建上下文目录中。 -### 其它 `docker build` 的用法 +## 其它 `docker build` 的用法 -#### 直接用 Git repo 进行构建 +### 直接用 Git repo 进行构建 或许你已经注意到了,`docker build` 还支持从 URL 构建,比如可以直接从 Git repo 中构建: @@ -189,7 +189,7 @@ aed15891ba52: Already exists 这行命令指定了构建所需的 Git repo,并且指定默认的 `master` 分支,构建目录为 `/11.1/`,然后 Docker 就会自己去 `git clone` 这个项目、切换到指定分支、并进入到指定目录后开始构建。 -#### 用给定的 tar 压缩包构建 +### 用给定的 tar 压缩包构建 ```bash $ docker build http://server/context.tar.gz @@ -197,7 +197,7 @@ $ docker build http://server/context.tar.gz 如果所给出的 URL 不是个 Git repo,而是个 `tar` 压缩包,那么 Docker 引擎会下载这个包,并自动解压缩,以其作为上下文,开始构建。 -#### 从标准输入中读取 Dockerfile 进行构建 +### 从标准输入中读取 Dockerfile 进行构建 ```bash docker build - < Dockerfile @@ -211,7 +211,7 @@ cat Dockerfile | docker build - 如果标准输入传入的是文本文件,则将其视为 `Dockerfile`,并开始构建。这种形式由于直接从标准输入中读取 Dockerfile 的内容,它没有上下文,因此不可以像其他方法那样可以将本地文件 `COPY` 进镜像之类的事情。 -#### 从标准输入中读取上下文压缩包进行构建 +### 从标准输入中读取上下文压缩包进行构建 ```bash $ docker build - < context.tar.gz diff --git a/image/commit.md b/image/commit.md index 6f921e546..01ca00256 100644 --- a/image/commit.md +++ b/image/commit.md @@ -1,8 +1,7 @@ +# 利用 commit 理解镜像构成 >注意:如果您是初学者,您可以暂时跳过后面的内容,直接学习 [容器](../container) 一节。 -## 利用 commit 理解镜像构成 - 注意: `docker commit` 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用 `docker commit` 定制镜像,定制镜像应该使用 `Dockerfile` 来完成。如果你想要定制镜像请查看下一小节。 镜像是容器的基础,每次执行 `docker run` 的时候都会指定哪个镜像作为容器运行的基础。在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像。直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜像。接下来的几节就将讲解如何定制镜像。 @@ -120,7 +119,7 @@ docker run --name web2 -d -p 81:80 nginx:v2 至此,我们第一次完成了定制镜像,使用的是 `docker commit` 命令,手动操作给旧的镜像添加了新的一层,形成新的镜像,对镜像多层存储应该有了更直观的感觉。 -### 慎用 `docker commit` +## 慎用 `docker commit` 使用 `docker commit` 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。 diff --git a/image/dockerfile/README.md b/image/dockerfile/README.md index fa4d01f98..15f5d4fc5 100644 --- a/image/dockerfile/README.md +++ b/image/dockerfile/README.md @@ -1,3 +1,3 @@ -## Dockerfile 指令详解 +# Dockerfile 指令详解 我们已经介绍了 `FROM`,`RUN`,还提及了 `COPY`, `ADD`,其实 `Dockerfile` 功能很强大,它提供了十多个指令。下面我们继续讲解其他的指令。 diff --git a/image/internal.md b/image/internal.md index 8cb7ccf95..f22123b66 100644 --- a/image/internal.md +++ b/image/internal.md @@ -1,4 +1,4 @@ -## 镜像的实现原理 +# 镜像的实现原理 Docker 镜像是怎么实现增量的修改和维护的? diff --git a/image/list.md b/image/list.md index d3f60b22f..107c36d1b 100644 --- a/image/list.md +++ b/image/list.md @@ -1,4 +1,4 @@ -## 列出镜像 +# 列出镜像 要想列出已经下载下来的镜像,可以使用 `docker image ls` 命令。 @@ -17,7 +17,7 @@ ubuntu latest f753707788c5 4 weeks ago 其中仓库名、标签在之前的基础概念章节已经介绍过了。**镜像 ID** 则是镜像的唯一标识,一个镜像可以对应多个 **标签**。因此,在上面的例子中,我们可以看到 `ubuntu:18.04` 和 `ubuntu:latest` 拥有相同的 ID,因为它们对应的是同一个镜像。 -### 镜像体积 +## 镜像体积 如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,`ubuntu:18.04` 镜像大小,在这里是 `127 MB`,但是在 [Docker Hub](https://hub.docker.com/r/library/ubuntu/tags/) 显示的却是 `50 MB`。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 `docker image ls` 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。 @@ -35,7 +35,7 @@ Local Volumes 9 0 652.2MB Build Cache 0B 0B ``` -### 虚悬镜像 +## 虚悬镜像 上面的镜像列表中,还可以看到一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为 ``。: @@ -57,7 +57,7 @@ REPOSITORY TAG IMAGE ID CREATED $ docker image prune ``` -### 中间层镜像 +## 中间层镜像 为了加速镜像构建、重复利用资源,Docker 会利用 **中间层镜像**。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。默认的 `docker image ls` 列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加 `-a` 参数。 @@ -67,7 +67,7 @@ $ docker image ls -a 这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。这些无标签镜像不应该删除,否则会导致上层镜像因为依赖丢失而出错。实际上,这些镜像也没必要删除,因为之前说过,相同的层只会存一遍,而这些镜像是别的镜像的依赖,因此并不会因为它们被列出来而多存了一份,无论如何你也会需要它们。只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除。 -### 列出部分镜像 +## 列出部分镜像 不加任何参数的情况下,`docker image ls` 会列出所有顶层镜像,但是有时候我们只希望列出部分镜像。`docker image ls` 有好几个参数可以帮助做到这个事情。 @@ -106,7 +106,7 @@ $ docker image ls -f label=com.example.version=0.1 ... ``` -### 以特定格式显示 +## 以特定格式显示 默认情况下,`docker image ls` 会输出一个完整的表格,但是我们并非所有时候都会需要这些内容。比如,刚才删除虚悬镜像的时候,我们需要利用 `docker image ls` 把所有的虚悬镜像的 ID 列出来,然后才可以交给 `docker image rm` 命令作为参数来删除指定的这些镜像,这个时候就用到了 `-q` 参数。 diff --git a/image/manifest.md b/image/manifest.md index 3783303c7..78dd12851 100644 --- a/image/manifest.md +++ b/image/manifest.md @@ -1,4 +1,4 @@ -## 构建多种系统架构支持的 Docker 镜像 -- docker manifest 命令详解 +# 构建多种系统架构支持的 Docker 镜像 -- docker manifest 命令详解 我们知道使用镜像创建一个容器,该镜像必须与 Docker 宿主机系统架构一致,例如 `Linux x86_64` 架构的系统中只能使用 `Linux x86_64` 的镜像创建容器。 @@ -109,11 +109,11 @@ $ docker manifest inspect golang:alpine 下面介绍如何使用 `$ docker manifest` 命令创建并推送 `manifest` 列表到 Docker Hub。 -### 构建镜像 +## 构建镜像 首先在 `Linux x86_64` 构建 `username/x8664-test` 镜像。并在 `Linux arm64v8` 中构建 `username/arm64v8-test` 镜像,构建好之后推送到 Docker Hub。 -### 创建 `manifest` 列表 +## 创建 `manifest` 列表 ```bash # $ docker manifest create MANIFEST_LIST MANIFEST [MANIFEST...] @@ -124,7 +124,7 @@ $ docker manifest create username/test \ 当要修改一个 `manifest` 列表时,可以加入 `-a,--amend` 参数。 -### 设置 `manifest` 列表 +## 设置 `manifest` 列表 ```bash # $ docker manifest annotate [OPTIONS] MANIFEST_LIST MANIFEST @@ -139,13 +139,13 @@ $ docker manifest annotate username/test \ 这样就配置好了 `manifest` 列表。 -### 查看 `manifest` 列表 +## 查看 `manifest` 列表 ```bash $ docker manifest inspect username/test ``` -### 推送 `manifest` 列表 +## 推送 `manifest` 列表 最后我们可以将其推送到 Docker Hub。 @@ -153,11 +153,11 @@ $ docker manifest inspect username/test $ docker manifest push username/test ``` -### 测试 +## 测试 我们在 `Linux x86_64` `Linux arm64v8` 中分别执行 `$ docker run -it --rm username/test` 命令,发现可以正确的执行。 -### 官方博客 +## 官方博客 详细了解 `manifest` 可以阅读官方博客。 diff --git a/image/multistage-builds/README.md b/image/multistage-builds/README.md index 97a61610f..f924cd2d7 100644 --- a/image/multistage-builds/README.md +++ b/image/multistage-builds/README.md @@ -1,10 +1,10 @@ -## 多阶段构建 +# 多阶段构建 -### 之前的做法 +## 之前的做法 在 Docker 17.05 版本之前,我们构建 Docker 镜像时,通常会采用两种方式: -#### 全部放入一个 Dockerfile +### 全部放入一个 Dockerfile 一种方式是将所有的构建过程编包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题: @@ -50,7 +50,7 @@ CMD ["./app"] $ docker build -t go/helloworld:1 -f Dockerfile.one . ``` -#### 分散到多个 Dockerfile +### 分散到多个 Dockerfile 另一种方式,就是我们事先在一个 `Dockerfile` 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 `Dockerfile` 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。 @@ -119,7 +119,7 @@ go/helloworld 2 f7cf3465432c 22 seconds ago 6.47MB go/helloworld 1 f55d3e16affc 2 minutes ago 295MB ``` -### 使用多阶段构建 +## 使用多阶段构建 为解决以上问题,Docker v17.05 开始支持多阶段构建 (`multistage builds`)。使用多阶段构建我们就可以很容易解决前面提到的问题,并且只需要编写一个 `Dockerfile`: @@ -168,7 +168,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB 很明显使用多阶段构建的镜像体积小,同时也完美解决了上边提到的问题。 -#### 只构建某一阶段的镜像 +### 只构建某一阶段的镜像 我们可以使用 `as` 来为某一阶段命名,例如 @@ -182,7 +182,7 @@ FROM golang:1.9-alpine as builder $ docker build --target builder -t username/imagename:tag . ``` -#### 构建时从其他镜像复制文件 +### 构建时从其他镜像复制文件 上面例子中我们使用 `COPY --from=0 /go/src/github.com/go/helloworld/app .` 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。 diff --git a/image/multistage-builds/laravel.md b/image/multistage-builds/laravel.md index 5d7a44b10..da14fdb01 100644 --- a/image/multistage-builds/laravel.md +++ b/image/multistage-builds/laravel.md @@ -1,8 +1,8 @@ -## 实战多阶段构建 Laravel 镜像 +# 实战多阶段构建 Laravel 镜像 > 本节适用于 PHP 开发者阅读。 -### 准备 +## 准备 新建一个 `Laravel` 项目或在已有的 `Laravel` 项目根目录下新建 `Dockerfile` `.dockerignore` `laravel.conf` 文件。 @@ -46,7 +46,7 @@ server { } ``` -### 前端构建 +## 前端构建 第一阶段进行前端构建。 @@ -65,7 +65,7 @@ RUN cd /app \ && npm run production ``` -### 安装 Composer 依赖 +## 安装 Composer 依赖 第二阶段安装 Composer 依赖。 @@ -85,7 +85,7 @@ RUN cd /app \ --prefer-dist ``` -### 整合以上阶段所生成的文件 +## 整合以上阶段所生成的文件 第三阶段对以上阶段生成的文件进行整合。 @@ -111,7 +111,7 @@ RUN cd ${LARAVEL_PATH} \ && chmod -R 777 storage ``` -### 最后一个阶段构建 NGINX 镜像 +## 最后一个阶段构建 NGINX 镜像 ```docker FROM nginx:alpine as nginx @@ -122,7 +122,7 @@ COPY laravel.conf /etc/nginx/conf.d/ COPY --from=laravel ${LARAVEL_PATH}/public ${LARAVEL_PATH}/public ``` -### 构建 Laravel 及 Nginx 镜像 +## 构建 Laravel 及 Nginx 镜像 使用 `docker build` 命令构建镜像。 @@ -132,7 +132,7 @@ $ docker build -t my/laravel --target=laravel . $ docker build -t my/nginx --target=nginx . ``` -### 启动容器并测试 +## 启动容器并测试 新建 Docker 网络 @@ -156,11 +156,11 @@ $ docker run -it --rm --network=laravel -p 8080:80 my/nginx > 也许 Laravel 项目依赖其他外部服务,例如 redis、MySQL,请自行启动这些服务之后再进行测试,本小节不再赘述。 -### 生产环境优化 +## 生产环境优化 本小节内容为了方便测试,将配置文件直接放到了镜像中,实际在使用时 **建议** 将配置文件作为 `config` 或 `secret` 挂载到容器中,请读者自行学习 `Swarm mode` 或 `Kubernetes` 的相关内容。 -### 附录 +## 附录 完整的 `Dockerfile` 文件如下。 diff --git a/image/other.md b/image/other.md index 8a9414795..4d4dd1383 100644 --- a/image/other.md +++ b/image/other.md @@ -1,8 +1,8 @@ -## 其它制作镜像的方式 +# 其它制作镜像的方式 除了标准的使用 `Dockerfile` 生成镜像的方法外,由于各种特殊需求和历史原因,还提供了一些其它方法用以生成镜像。 -### 从 rootfs 压缩包导入 +## 从 rootfs 压缩包导入 格式:`docker import [选项] <文件>||- [<仓库名>[:<标签>]]` @@ -37,11 +37,11 @@ IMAGE CREATED CREATED BY SIZE f477a6e18e98 About a minute ago 214.9 MB Imported from http://download.openvz.org/template/precreated/ubuntu-16.04-x86_64.tar.gz ``` -### `docker save` 和 `docker load` +## `docker save` 和 `docker load` Docker 还提供了 `docker save` 和 `docker load` 命令,用以将镜像保存为一个文件,然后传输到另一个位置上,再加载进来。这是在没有 Docker Registry 时的做法,现在已经不推荐,镜像迁移应该直接使用 Docker Registry,无论是直接使用 Docker Hub 还是使用内网私有 Registry 都可以。 -#### 保存镜像 +### 保存镜像 使用 `docker save` 命令可以将镜像保存为归档文件。 diff --git a/image/pull.md b/image/pull.md index 7733f70b6..51c47c90e 100644 --- a/image/pull.md +++ b/image/pull.md @@ -1,4 +1,4 @@ -## 获取镜像 +# 获取镜像 之前提到过,[Docker Hub](https://hub.docker.com/explore/) 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像。 @@ -35,7 +35,7 @@ Status: Downloaded newer image for ubuntu:18.04 *如果从 Docker Hub 下载镜像非常缓慢,可以参照 [镜像加速器](/install/mirror.md) 一节配置加速器。* -### 运行 +## 运行 有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 `ubuntu:18.04` 为例,如果我们打算启动里面的 `bash` 并且进行交互式操作的话,可以执行下面的命令。 diff --git a/image/rm.md b/image/rm.md index d0870be49..07b0f19e4 100644 --- a/image/rm.md +++ b/image/rm.md @@ -1,4 +1,4 @@ -## 删除本地镜像 +# 删除本地镜像 如果要删除本地的镜像,可以使用 `docker image rm` 命令,其格式为: @@ -6,7 +6,7 @@ $ docker image rm [选项] <镜像1> [<镜像2> ...] ``` -### 用 ID、镜像名、摘要删除镜像 +## 用 ID、镜像名、摘要删除镜像 其中,`<镜像>` 可以是 `镜像短 ID`、`镜像长 ID`、`镜像名` 或者 `镜像摘要`。 @@ -58,7 +58,7 @@ $ docker image rm node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235 Untagged: node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b164422be228 ``` -### Untagged 和 Deleted +## Untagged 和 Deleted 如果观察上面这几个命令的运行输出信息的话,你会注意到删除行为分为两类,一类是 `Untagged`,另一类是 `Deleted`。我们之前介绍过,镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。 @@ -68,7 +68,7 @@ Untagged: node@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b16442 除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。之前讲过,容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。 -### 用 docker image ls 命令来配合 +## 用 docker image ls 命令来配合 像其它可以承接多个实体的命令一样,可以使用 `docker image ls -q` 来配合使用 `docker image rm`,这样可以成批的删除希望删除的镜像。我们在“镜像列表”章节介绍过很多过滤镜像列表的方式都可以拿过来使用。 @@ -86,7 +86,7 @@ $ docker image rm $(docker image ls -q -f before=mongo:3.2) 充分利用你的想象力和 Linux 命令行的强大,你可以完成很多非常赞的功能。 -### CentOS/RHEL 的用户需要注意的事项 +## CentOS/RHEL 的用户需要注意的事项 > 以下内容仅适用于 Docker CE 18.09 以下版本,在 Docker CE 18.09 版本中默认使用的是 `overlay2` 驱动。 diff --git a/network/dns.md b/network/dns.md index a84f90ea1..f13bbb7c8 100644 --- a/network/dns.md +++ b/network/dns.md @@ -1,4 +1,4 @@ -## 配置 DNS +# 配置 DNS 如何自定义配置容器的主机名和 DNS 呢?秘诀就是 Docker 利用虚拟文件来挂载容器的 3 个相关配置文件。 diff --git a/network/linking.md b/network/linking.md index a4319a537..e24ebd9bd 100644 --- a/network/linking.md +++ b/network/linking.md @@ -1,10 +1,10 @@ -## 容器互联 +# 容器互联 如果你之前有 `Docker` 使用经验,你可能已经习惯了使用 `--link` 参数来使容器互联。 随着 Docker 网络的完善,强烈建议大家将容器加入自定义的 Docker 网络来连接多个容器,而不是使用 `--link` 参数。 -### 新建网络 +## 新建网络 下面先创建一个新的 Docker 网络。 @@ -14,7 +14,7 @@ $ docker network create -d bridge my-net `-d` 参数指定 Docker 网络类型,有 `bridge` `overlay`。其中 `overlay` 网络类型用于 [Swarm mode](../swarm_mode/),在本小节中你可以忽略它。 -### 连接容器 +## 连接容器 运行一个容器并连接到新建的 `my-net` 网络 @@ -62,6 +62,6 @@ PING busybox1 (172.19.0.2): 56 data bytes 这样,`busybox1` 容器和 `busybox2` 容器建立了互联关系。 -### Docker Compose +## Docker Compose 如果你有多个容器之间需要互相连接,推荐使用 [Docker Compose](../compose)。 diff --git a/network/port_mapping.md b/network/port_mapping.md index 59b0690cc..ef42475a3 100644 --- a/network/port_mapping.md +++ b/network/port_mapping.md @@ -1,4 +1,4 @@ -## 外部访问容器 +# 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 `-P` 或 `-p` 参数来指定端口映射。 @@ -25,7 +25,7 @@ $ docker logs -f nostalgic_morse `-p` 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 `ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。 -### 映射所有接口地址 +## 映射所有接口地址 使用 `hostPort:containerPort` 格式本地的 5000 端口映射到容器的 5000 端口,可以执行 @@ -35,7 +35,7 @@ $ docker run -d -p 5000:5000 training/webapp python app.py 此时默认会绑定本地所有接口上的所有地址。 -### 映射到指定地址的指定端口 +## 映射到指定地址的指定端口 可以使用 `ip:hostPort:containerPort` 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1 @@ -43,7 +43,7 @@ $ docker run -d -p 5000:5000 training/webapp python app.py $ docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py ``` -### 映射到指定地址的任意端口 +## 映射到指定地址的任意端口 使用 `ip::containerPort` 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。 @@ -57,7 +57,7 @@ $ docker run -d -p 127.0.0.1::5000 training/webapp python app.py $ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py ``` -### 查看映射端口配置 +## 查看映射端口配置 使用 `docker port` 来查看当前映射的端口配置,也可以查看到绑定的地址 diff --git a/opensource/linuxkit.md b/opensource/linuxkit.md index a4513c0e6..ee491ebd7 100644 --- a/opensource/linuxkit.md +++ b/opensource/linuxkit.md @@ -1,10 +1,10 @@ -## LinuxKit +# LinuxKit `LinuxKit` 这个工具可以将多个 Docker 镜像组成一个最小化、可自由定制的 Linux 系统,最后的生成的系统只有几十 M 大小,可以很方便的在云端进行部署。 下面我们在 macOS 上通过实例,来编译并运行一个全部由 Docker 镜像组成的包含 nginx 服务的 Linux 系统。 -### 安装 Linuxkit +## 安装 Linuxkit ```bash $ brew tap linuxkit/linuxkit @@ -12,7 +12,7 @@ $ brew tap linuxkit/linuxkit $ brew install --HEAD linuxkit ``` -### 克隆源代码 +## 克隆源代码 ```bash $ git clone -b master --depth=1 https://github.com/linuxkit/linuxkit.git @@ -20,7 +20,7 @@ $ git clone -b master --depth=1 https://github.com/linuxkit/linuxkit.git $ cd linuxkit ``` -### 编译 Linux 系统 +## 编译 Linux 系统 LinuxKit 通过 `yaml` 文件配置。 @@ -40,7 +40,7 @@ LinuxKit 通过 `yaml` 文件配置。 $ linuxkit build linuxkit.yml ``` -### 启动 Linux 系统 +## 启动 Linux 系统 编译成功后,接下来启动这个 Linux 系统。 diff --git a/security/control_group.md b/security/control_group.md index 0940a3073..cd2bd39ed 100644 --- a/security/control_group.md +++ b/security/control_group.md @@ -1,4 +1,4 @@ -## 控制组 +# 控制组 控制组是 Linux 容器机制的另外一个关键组件,负责实现资源的审计和限制。 它提供了很多有用的特性;以及确保各个容器可以公平地分享主机的内存、CPU、磁盘 IO 等资源;当然,更重要的是,控制组确保了当容器内的资源使用产生压力时不会连累主机系统。 diff --git a/security/daemon_sec.md b/security/daemon_sec.md index c1b4057d6..7389ffba8 100644 --- a/security/daemon_sec.md +++ b/security/daemon_sec.md @@ -1,4 +1,4 @@ -## Docker服务端的防护 +# Docker服务端的防护 运行一个容器或应用程序的核心是通过 Docker 服务端。Docker 服务的运行目前需要 root 权限,因此其安全性十分关键。 首先,确保只有可信的用户才可以访问 Docker 服务。Docker 允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限,这就容易让容器突破资源限制。例如,恶意用户启动容器的时候将主机的根目录`/`映射到容器的 `/host` 目录中,那么容器理论上就可以对主机的文件系统进行任意修改了。这听起来很疯狂?但是事实上几乎所有虚拟化系统都允许类似的资源共享,而没法禁止用户共享主机根文件系统到虚拟机系统。 diff --git a/security/kernel_capability.md b/security/kernel_capability.md index bbe3a5236..4ebc9eabf 100644 --- a/security/kernel_capability.md +++ b/security/kernel_capability.md @@ -1,4 +1,4 @@ -## 内核能力机制 +# 内核能力机制 能力机制(Capability)是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制。 Linux 内核自 2.2 版本起就支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。 diff --git a/security/kernel_ns.md b/security/kernel_ns.md index 1ce607c37..18e070b1a 100644 --- a/security/kernel_ns.md +++ b/security/kernel_ns.md @@ -1,4 +1,4 @@ -## 内核命名空间 +# 内核命名空间 Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。当用 `docker run` 启动一个容器时,在后台 Docker 为容器创建了一个独立的命名空间和控制组集合。 命名空间提供了最基础也是最直接的隔离,在容器中运行的进程不会被运行在主机上的进程和其它容器发现和作用。 diff --git a/security/other_feature.md b/security/other_feature.md index 5b70b5fb1..3a288c9f2 100644 --- a/security/other_feature.md +++ b/security/other_feature.md @@ -1,4 +1,4 @@ -## 其它安全特性 +# 其它安全特性 除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等。 Docker 当前默认只启用了能力机制。用户可以采用多种方案来加强 Docker 主机的安全,例如: diff --git a/security/summary.md b/security/summary.md index 0b2b52890..90d144b8f 100644 --- a/security/summary.md +++ b/security/summary.md @@ -1,4 +1,4 @@ -## 总结 +# 总结 总体来看,Docker 容器还是十分安全的,特别是在容器内不使用 root 权限来运行进程的话。 另外,用户可以使用现有工具,比如 Apparmor, SELinux, GRSEC 来增强安全性;甚至自己在内核中实现更复杂的安全机制。 diff --git a/swarm_mode/config.md b/swarm_mode/config.md index 484e94349..a18e5a1cf 100644 --- a/swarm_mode/config.md +++ b/swarm_mode/config.md @@ -1,4 +1,4 @@ -## 在 Swarm 集群中管理配置数据 +# 在 Swarm 集群中管理配置数据 在动态的、大规模的分布式集群上,管理和分发配置文件也是很重要的工作。传统的配置文件分发方式(如配置文件放入镜像中,设置环境变量,volume 动态挂载等)都降低了镜像的通用性。 @@ -8,7 +8,7 @@ 这里我们以在 Swarm 集群中部署 `redis` 服务为例。 -### 创建 config +## 创建 config 新建 `redis.conf` 文件 @@ -24,7 +24,7 @@ port 6380 $ docker config create redis.conf redis.conf ``` -### 查看 config +## 查看 config 使用 `docker config ls` 命令来查看 `config` @@ -35,7 +35,7 @@ ID NAME CREATED UPDATED yod8fx8iiqtoo84jgwadp86yk redis.conf 4 seconds ago 4 seconds ago ``` -### 创建 redis 服务 +## 创建 redis 服务 ```bash $ docker service create \ diff --git a/swarm_mode/create.md b/swarm_mode/create.md index a64fb5c57..91391242a 100644 --- a/swarm_mode/create.md +++ b/swarm_mode/create.md @@ -1,8 +1,8 @@ -## 创建 Swarm 集群 +# 创建 Swarm 集群 阅读 [基本概念](overview.md) 一节我们知道 `Swarm` 集群由 **管理节点** 和 **工作节点** 组成。本节我们来创建一个包含一个管理节点和两个工作节点的最小 `Swarm` 集群。 -### 初始化集群 +## 初始化集群 在 [`Docker Machine`](../machine) 一节中我们了解到 `Docker Machine` 可以在数秒内创建一个虚拟的 Docker 主机,下面我们使用它来创建三个 Docker 主机,并加入到集群中。 @@ -33,7 +33,7 @@ To add a manager to this swarm, run 'docker swarm join-token manager' and follow > 执行 `docker swarm init` 命令的节点自动成为管理节点。 -### 增加工作节点 +## 增加工作节点 上一步我们初始化了一个 `Swarm` 集群,拥有了一个管理节点,下面我们继续创建两个 Docker 主机作为工作节点,并加入到集群中。 @@ -63,7 +63,7 @@ This node joined a swarm as a worker. >注意:一些细心的读者可能通过 `docker-machine create --help` 查看到 `--swarm*` 等一系列参数。该参数是用于旧的 `Docker Swarm`,与本章所讲的 `Swarm mode` 没有关系。 -### 查看集群 +## 查看集群 经过上边的两步,我们已经拥有了一个最小的 `Swarm` 集群,包含一个管理节点和两个工作节点。 diff --git a/swarm_mode/deploy.md b/swarm_mode/deploy.md index 91a84ffd2..2c22679cc 100644 --- a/swarm_mode/deploy.md +++ b/swarm_mode/deploy.md @@ -1,8 +1,8 @@ -## 部署服务 +# 部署服务 我们使用 `docker service` 命令来管理 `Swarm` 集群中的服务,该命令只能在管理节点运行。 -### 新建服务 +## 新建服务 现在我们在上一节创建的 `Swarm` 集群中运行一个名为 `nginx` 服务。 @@ -12,7 +12,7 @@ $ docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13.7-alpine 现在我们使用浏览器,输入任意节点 IP ,即可看到 nginx 默认页面。 -### 查看服务 +## 查看服务 使用 `docker service ls` 来查看当前 `Swarm` 集群运行的服务。 @@ -44,7 +44,7 @@ nginx.1.pjfzd39buzlt@swarm2 | 10.255.0.2 - - [25/Nov/2017:02:10:27 +0000] "GE nginx.1.pjfzd39buzlt@swarm2 | 2017/11/25 02:10:27 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.255.0.2, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.99.101" ``` -### 服务伸缩 +## 服务伸缩 我们可以使用 `docker service scale` 对一个服务运行的容器数量进行伸缩。 @@ -60,7 +60,7 @@ $ docker service scale nginx=5 $ docker service scale nginx=2 ``` -### 删除服务 +## 删除服务 使用 `docker service rm` 来从 `Swarm` 集群移除某个服务。 diff --git a/swarm_mode/overview.md b/swarm_mode/overview.md index d3f5264a6..cd853afe3 100644 --- a/swarm_mode/overview.md +++ b/swarm_mode/overview.md @@ -1,10 +1,10 @@ -## 基本概念 +# 基本概念 `Swarm` 是使用 [`SwarmKit`](https://github.com/docker/swarmkit/) 构建的 Docker 引擎内置(原生)的集群管理和编排工具。 使用 `Swarm` 集群之前需要了解以下几个概念。 -### 节点 +## 节点 运行 Docker 的主机可以主动初始化一个 `Swarm` 集群或者加入一个已存在的 `Swarm` 集群,这样这个运行 Docker 的主机就成为一个 `Swarm` 集群的节点 (`node`) 。 @@ -18,7 +18,7 @@ ![](https://docs.docker.com/engine/swarm/images/swarm-diagram.png) -### 服务和任务 +## 服务和任务 任务 (`Task`)是 `Swarm` 中的最小的调度单位,目前来说就是一个单一的容器。 diff --git a/swarm_mode/rolling_update.md b/swarm_mode/rolling_update.md index 767be2064..560b0ae5f 100644 --- a/swarm_mode/rolling_update.md +++ b/swarm_mode/rolling_update.md @@ -1,4 +1,4 @@ -## SWarm mode 与滚动升级 +# SWarm mode 与滚动升级 在 [部署服务](deploy.md) 一节中我们使用 `nginx:1.13.7-alpine` 镜像部署了一个名为 `nginx` 的服务。 @@ -24,7 +24,7 @@ $ docker service update \ 更多选项可以通过 `docker service update -h` 命令查看。 -### 服务回退 +## 服务回退 现在假设我们发现 `nginx` 服务的镜像升级到 `nginx:1.13.12-alpine` 出现了一些问题,我们可以使用命令一键回退。 diff --git a/swarm_mode/secret.md b/swarm_mode/secret.md index 4d8476568..28981d5f2 100644 --- a/swarm_mode/secret.md +++ b/swarm_mode/secret.md @@ -1,4 +1,4 @@ -## 在 Swarm 集群中管理敏感数据 +# 在 Swarm 集群中管理敏感数据 在动态的、大规模的分布式集群上,管理和分发 `密码`、`证书` 等敏感信息是极其重要的工作。传统的密钥分发方式(如密钥放入镜像中,设置环境变量,volume 动态挂载等)都存在着潜在的巨大的安全风险。 @@ -10,7 +10,7 @@ Docker 目前已经提供了 `secrets` 管理功能,用户可以在 Swarm 集 这里我们以在 Swarm 集群中部署 `mysql` 和 `wordpress` 服务为例。 -### 创建 secret +## 创建 secret 我们使用 `docker secret create` 命令以管道符的形式创建 `secret` @@ -20,7 +20,7 @@ $ openssl rand -base64 20 | docker secret create mysql_password - $ openssl rand -base64 20 | docker secret create mysql_root_password - ``` -### 查看 secret +## 查看 secret 使用 `docker secret ls` 命令来查看 `secret` @@ -32,7 +32,7 @@ l1vinzevzhj4goakjap5ya409 mysql_password 41 seconds ago 41 seconds yvsczlx9votfw3l0nz5rlidig mysql_root_password 12 seconds ago 12 seconds ago ``` -### 创建 MySQL 服务 +## 创建 MySQL 服务 创建服务相关命令已经在前边章节进行了介绍,这里直接列出命令。 diff --git a/swarm_mode/stack.md b/swarm_mode/stack.md index 66561f47e..a7d1ebd04 100644 --- a/swarm_mode/stack.md +++ b/swarm_mode/stack.md @@ -1,4 +1,4 @@ -## 在 Swarm 集群中使用 compose 文件 +# 在 Swarm 集群中使用 compose 文件 正如之前使用 `docker-compose.yml` 来一次配置、启动多个容器,在 `Swarm` 集群中也可以使用 `compose` 文件 (`docker-compose.yml`) 来配置、启动多个服务。 @@ -60,7 +60,7 @@ networks: 在 `Swarm` 集群中使用 `docker-compose.yml` 我们用 `docker stack` 命令,下面我们对该命令进行详细讲解。 -### 部署服务 +## 部署服务 部署服务使用 `docker stack deploy`,其中 `-c` 参数指定 compose 文件名。 @@ -74,7 +74,7 @@ $ docker stack deploy -c docker-compose.yml wordpress 在浏览器新的标签页输入 `任一节点IP` 即可看到 `WordPress` 安装界面,安装完成之后,输入 `任一节点IP` 即可看到 `WordPress` 页面。 -### 查看服务 +## 查看服务 ```bash $ docker stack ls @@ -82,7 +82,7 @@ NAME SERVICES wordpress 3 ``` -### 移除服务 +## 移除服务 要移除服务,使用 `docker stack down` From c836c65a78c67ae3dc76a11949f259c49206c722 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 14 Nov 2019 09:21:31 +0800 Subject: [PATCH 027/201] Update command Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 10 ++- SUMMARY.md | 2 + appendix/command/README.md | 118 +----------------------------------- appendix/command/docker.md | 70 +++++++++++++++++++++ appendix/command/dockerd.md | 58 ++++++++++++++++++ 5 files changed, 140 insertions(+), 118 deletions(-) create mode 100644 appendix/command/docker.md create mode 100644 appendix/command/dockerd.md diff --git a/.vuepress/config.js b/.vuepress/config.js index ce4a00027..b20b65199 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -329,7 +329,15 @@ module.exports = { 'appendix/repo/redis', ], }, - 'appendix/command/', + { + title: "Docker 命令", + collapsable: false, + children: [ + 'appendix/command/', + 'appendix/command/docker', + 'appendix/command/dockerd', + ] + }, 'appendix/best_practices', 'appendix/debug', 'appendix/resources', diff --git a/SUMMARY.md b/SUMMARY.md index f3b2d3ae7..0ca744407 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -156,6 +156,8 @@ * [MongoDB](appendix/repo/mongodb.md) * [Redis](appendix/repo/redis.md) * [附录三:Docker 命令查询](appendix/command/README.md) + * [客户端命令 (docker)](appendix/command/docker.md) + * [服务端命令 (dockerd)](appendix/command/dockerd.md) * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) diff --git a/appendix/command/README.md b/appendix/command/README.md index bb7ec866b..5bea7319c 100644 --- a/appendix/command/README.md +++ b/appendix/command/README.md @@ -10,120 +10,4 @@ Docker 命令有两大类,客户端命令和服务端命令。前者是主要 可以通过 `man docker` 或 `docker help` 来查看这些命令。 -## 客户端命令选项 - -* `--config=""`:指定客户端配置文件,默认为 `~/.docker`; -* `-D=true|false`:是否使用 debug 模式。默认不开启; -* `-H, --host=[]`:指定命令对应 Docker 守护进程的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`; -* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别; -* `--tls=true|false`:是否对 Docker 守护进程启用 TLS 安全机制,默认为否; -* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径; -* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径; -* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径; -* `--tlsverify=true|false`:启用 TLS 校验,默认为否。 - -## dockerd 命令选项 - -* `--api-cors-header=""`:CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 "*"; -* `--authorization-plugin=""`:载入认证的插件; -* `-b=""`:将容器挂载到一个已存在的网桥上。指定为 `none` 时则禁用容器的网络,与 `--bip` 选项互斥; -* `--bip=""`:让动态创建的 `docker0` 网桥采用给定的 CIDR 地址; 与 `-b` 选项互斥; -* `--cgroup-parent=""`:指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`; -* `--cluster-store=""`:构成集群(如 `Swarm`)时,集群键值数据库服务地址; -* `--cluster-advertise=""`:构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`; -* `--cluster-store-opt=""`:构成集群时,键值数据库的配置选项; -* `--config-file="/etc/docker/daemon.json"`:daemon 配置文件路径; -* `--containerd=""`:containerd 文件的路径; -* `-D, --debug=true|false`:是否使用 Debug 模式。缺省为 false; -* `--default-gateway=""`:容器的 IPv4 网关地址,必须在网桥的子网段内; -* `--default-gateway-v6=""`:容器的 IPv6 网关地址; -* `--default-ulimit=[]`:默认的 ulimit 值; -* `--disable-legacy-registry=true|false`:是否允许访问旧版本的镜像仓库服务器; -* `--dns=""`:指定容器使用的 DNS 服务器地址; -* `--dns-opt=""`:DNS 选项; -* `--dns-search=[]`:DNS 搜索域; -* `--exec-opt=[]`:运行时的执行选项; -* `--exec-root=""`:容器执行状态文件的根路径,默认为 `/var/run/docker`; -* `--fixed-cidr=""`:限定分配 IPv4 地址范围; -* `--fixed-cidr-v6=""`:限定分配 IPv6 地址范围; -* `-G, --group=""`:分配给 unix 套接字的组,默认为 `docker`; -* `-g, --graph=""`:Docker 运行时的根路径,默认为 `/var/lib/docker`; -* `-H, --host=[]`:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`; -* `--icc=true|false`:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。 -* `--insecure-registry=[]`:允许访问给定的非安全仓库服务; -* `--ip=""`:绑定容器端口时候的默认 IP 地址。缺省为 `0.0.0.0`; -* `--ip-forward=true|false`:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改; -* `--ip-masq=true|false`:是否进行地址伪装,用于容器访问外部网络,默认开启; -* `--iptables=true|false`:是否允许 Docker 添加 iptables 规则。缺省为 true; -* `--ipv6=true|false`:是否启用 IPv6 支持,默认关闭; -* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别; -* `--label="[]"`:添加指定的键值对标注; -* `--log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none"`:指定日志后端驱动,默认为 `json-file`; -* `--log-opt=[]`:日志后端的选项; -* `--mtu=VALUE`:指定容器网络的 `mtu`; -* `-p=""`:指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`; -* `--raw-logs`:输出原始,未加色彩的日志信息; -* `--registry-mirror=://`:指定 `docker pull` 时使用的注册服务器镜像地址; -* `-s, --storage-driver=""`:指定使用给定的存储后端; -* `--selinux-enabled=true|false`:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动; -* `--storage-opt=[]`:驱动后端选项; -* `--tls=true|false`:是否对 Docker daemon 启用 TLS 安全机制,默认为否; -* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径; -* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径; -* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径; -* `--tlsverify=true|false`:启用 TLS 校验,默认为否; -* `--userland-proxy=true|false`:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true; -* `--userns-remap=default|uid:gid|user:group|user|uid`:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。 - -## 客户端命令 - -可以通过 `docker COMMAND --help` 来查看这些命令的具体用法。 - -* `attach`:依附到一个正在运行的容器中; -* `build`:从一个 Dockerfile 创建一个镜像; -* `commit`:从一个容器的修改中创建一个新的镜像; -* `cp`:在容器和本地宿主系统之间复制文件中; -* `create`:创建一个新容器,但并不运行它; -* `diff`:检查一个容器内文件系统的修改,包括修改和增加; -* `events`:从服务端获取实时的事件; -* `exec`:在运行的容器内执行命令; -* `export`:导出容器内容为一个 `tar` 包; -* `history`:显示一个镜像的历史信息; -* `images`:列出存在的镜像; -* `import`:导入一个文件(典型为 `tar` 包)路径或目录来创建一个本地镜像; -* `info`:显示一些相关的系统信息; -* `inspect`:显示一个容器的具体配置信息; -* `kill`:关闭一个运行中的容器 (包括进程和所有相关资源); -* `load`:从一个 tar 包中加载一个镜像; -* `login`:注册或登录到一个 Docker 的仓库服务器; -* `logout`:从 Docker 的仓库服务器登出; -* `logs`:获取容器的 log 信息; -* `network`:管理 Docker 的网络,包括查看、创建、删除、挂载、卸载等; -* `node`:管理 swarm 集群中的节点,包括查看、更新、删除、提升/取消管理节点等; -* `pause`:暂停一个容器中的所有进程; -* `port`:查找一个 nat 到一个私有网口的公共口; -* `ps`:列出主机上的容器; -* `pull`:从一个Docker的仓库服务器下拉一个镜像或仓库; -* `push`:将一个镜像或者仓库推送到一个 Docker 的注册服务器; -* `rename`:重命名一个容器; -* `restart`:重启一个运行中的容器; -* `rm`:删除给定的若干个容器; -* `rmi`:删除给定的若干个镜像; -* `run`:创建一个新容器,并在其中运行给定命令; -* `save`:保存一个镜像为 tar 包文件; -* `search`:在 Docker index 中搜索一个镜像; -* `service`:管理 Docker 所启动的应用服务,包括创建、更新、删除等; -* `start`:启动一个容器; -* `stats`:输出(一个或多个)容器的资源使用统计信息; -* `stop`:终止一个运行中的容器; -* `swarm`:管理 Docker swarm 集群,包括创建、加入、退出、更新等; -* `tag`:为一个镜像打标签; -* `top`:查看一个容器中的正在运行的进程信息; -* `unpause`:将一个容器内所有的进程从暂停状态中恢复; -* `update`:更新指定的若干容器的配置信息; -* `version`:输出 Docker 的版本信息; -* `volume`:管理 Docker volume,包括查看、创建、删除等; -* `wait`:阻塞直到一个容器终止,然后输出它的退出符。 - -## 一张图总结 Docker 的命令 -![Docker 命令总结](../_images/cmd_logic.png) +接下来的小节对这两个命令进行介绍。 diff --git a/appendix/command/docker.md b/appendix/command/docker.md new file mode 100644 index 000000000..6c2463a63 --- /dev/null +++ b/appendix/command/docker.md @@ -0,0 +1,70 @@ +# 客户端命令(docker) + +## 客户端命令选项 + +* `--config=""`:指定客户端配置文件,默认为 `~/.docker`; +* `-D=true|false`:是否使用 debug 模式。默认不开启; +* `-H, --host=[]`:指定命令对应 Docker 守护进程的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`; +* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别; +* `--tls=true|false`:是否对 Docker 守护进程启用 TLS 安全机制,默认为否; +* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径; +* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径; +* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径; +* `--tlsverify=true|false`:启用 TLS 校验,默认为否。 + +## 客户端命令 + +可以通过 `docker COMMAND --help` 来查看这些命令的具体用法。 + +* `attach`:依附到一个正在运行的容器中; +* `build`:从一个 Dockerfile 创建一个镜像; +* `commit`:从一个容器的修改中创建一个新的镜像; +* `cp`:在容器和本地宿主系统之间复制文件中; +* `create`:创建一个新容器,但并不运行它; +* `diff`:检查一个容器内文件系统的修改,包括修改和增加; +* `events`:从服务端获取实时的事件; +* `exec`:在运行的容器内执行命令; +* `export`:导出容器内容为一个 `tar` 包; +* `history`:显示一个镜像的历史信息; +* `images`:列出存在的镜像; +* `import`:导入一个文件(典型为 `tar` 包)路径或目录来创建一个本地镜像; +* `info`:显示一些相关的系统信息; +* `inspect`:显示一个容器的具体配置信息; +* `kill`:关闭一个运行中的容器 (包括进程和所有相关资源); +* `load`:从一个 tar 包中加载一个镜像; +* `login`:注册或登录到一个 Docker 的仓库服务器; +* `logout`:从 Docker 的仓库服务器登出; +* `logs`:获取容器的 log 信息; +* `network`:管理 Docker 的网络,包括查看、创建、删除、挂载、卸载等; +* `node`:管理 swarm 集群中的节点,包括查看、更新、删除、提升/取消管理节点等; +* `pause`:暂停一个容器中的所有进程; +* `port`:查找一个 nat 到一个私有网口的公共口; +* `ps`:列出主机上的容器; +* `pull`:从一个Docker的仓库服务器下拉一个镜像或仓库; +* `push`:将一个镜像或者仓库推送到一个 Docker 的注册服务器; +* `rename`:重命名一个容器; +* `restart`:重启一个运行中的容器; +* `rm`:删除给定的若干个容器; +* `rmi`:删除给定的若干个镜像; +* `run`:创建一个新容器,并在其中运行给定命令; +* `save`:保存一个镜像为 tar 包文件; +* `search`:在 Docker index 中搜索一个镜像; +* `service`:管理 Docker 所启动的应用服务,包括创建、更新、删除等; +* `start`:启动一个容器; +* `stats`:输出(一个或多个)容器的资源使用统计信息; +* `stop`:终止一个运行中的容器; +* `swarm`:管理 Docker swarm 集群,包括创建、加入、退出、更新等; +* `tag`:为一个镜像打标签; +* `top`:查看一个容器中的正在运行的进程信息; +* `unpause`:将一个容器内所有的进程从暂停状态中恢复; +* `update`:更新指定的若干容器的配置信息; +* `version`:输出 Docker 的版本信息; +* `volume`:管理 Docker volume,包括查看、创建、删除等; +* `wait`:阻塞直到一个容器终止,然后输出它的退出符。 + +## 一张图总结 Docker 的命令 +![Docker 命令总结](../_images/cmd_logic.png) + +## 参考 + +* [官方文档](https://docs.docker.com/engine/reference/commandline/cli/) diff --git a/appendix/command/dockerd.md b/appendix/command/dockerd.md new file mode 100644 index 000000000..7b30c7989 --- /dev/null +++ b/appendix/command/dockerd.md @@ -0,0 +1,58 @@ +# 服务端命令(dockerd) + +## dockerd 命令选项 + +* `--api-cors-header=""`:CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 "*"; +* `--authorization-plugin=""`:载入认证的插件; +* `-b=""`:将容器挂载到一个已存在的网桥上。指定为 `none` 时则禁用容器的网络,与 `--bip` 选项互斥; +* `--bip=""`:让动态创建的 `docker0` 网桥采用给定的 CIDR 地址; 与 `-b` 选项互斥; +* `--cgroup-parent=""`:指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`; +* `--cluster-store=""`:构成集群(如 `Swarm`)时,集群键值数据库服务地址; +* `--cluster-advertise=""`:构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`; +* `--cluster-store-opt=""`:构成集群时,键值数据库的配置选项; +* `--config-file="/etc/docker/daemon.json"`:daemon 配置文件路径; +* `--containerd=""`:containerd 文件的路径; +* `-D, --debug=true|false`:是否使用 Debug 模式。缺省为 false; +* `--default-gateway=""`:容器的 IPv4 网关地址,必须在网桥的子网段内; +* `--default-gateway-v6=""`:容器的 IPv6 网关地址; +* `--default-ulimit=[]`:默认的 ulimit 值; +* `--disable-legacy-registry=true|false`:是否允许访问旧版本的镜像仓库服务器; +* `--dns=""`:指定容器使用的 DNS 服务器地址; +* `--dns-opt=""`:DNS 选项; +* `--dns-search=[]`:DNS 搜索域; +* `--exec-opt=[]`:运行时的执行选项; +* `--exec-root=""`:容器执行状态文件的根路径,默认为 `/var/run/docker`; +* `--fixed-cidr=""`:限定分配 IPv4 地址范围; +* `--fixed-cidr-v6=""`:限定分配 IPv6 地址范围; +* `-G, --group=""`:分配给 unix 套接字的组,默认为 `docker`; +* `-g, --graph=""`:Docker 运行时的根路径,默认为 `/var/lib/docker`; +* `-H, --host=[]`:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`; +* `--icc=true|false`:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。 +* `--insecure-registry=[]`:允许访问给定的非安全仓库服务; +* `--ip=""`:绑定容器端口时候的默认 IP 地址。缺省为 `0.0.0.0`; +* `--ip-forward=true|false`:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改; +* `--ip-masq=true|false`:是否进行地址伪装,用于容器访问外部网络,默认开启; +* `--iptables=true|false`:是否允许 Docker 添加 iptables 规则。缺省为 true; +* `--ipv6=true|false`:是否启用 IPv6 支持,默认关闭; +* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别; +* `--label="[]"`:添加指定的键值对标注; +* `--log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none"`:指定日志后端驱动,默认为 `json-file`; +* `--log-opt=[]`:日志后端的选项; +* `--mtu=VALUE`:指定容器网络的 `mtu`; +* `-p=""`:指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`; +* `--raw-logs`:输出原始,未加色彩的日志信息; +* `--registry-mirror=://`:指定 `docker pull` 时使用的注册服务器镜像地址; +* `-s, --storage-driver=""`:指定使用给定的存储后端; +* `--selinux-enabled=true|false`:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动; +* `--storage-opt=[]`:驱动后端选项; +* `--tls=true|false`:是否对 Docker daemon 启用 TLS 安全机制,默认为否; +* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径; +* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径; +* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径; +* `--tlsverify=true|false`:启用 TLS 校验,默认为否; +* `--userland-proxy=true|false`:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true; +* `--userns-remap=default|uid:gid|user:group|user|uid`:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。 + +## 参考 + +* [官方文档](https://docs.docker.com/engine/reference/commandline/dockerd/) From e1961d62eb33f56188300299ebc53f034f97a6d4 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 14 Nov 2019 09:22:06 +0800 Subject: [PATCH 028/201] Fixed 404 link Signed-off-by: Kang HuaiShuai --- underly/container_format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/underly/container_format.md b/underly/container_format.md index 94944a8fc..983992538 100644 --- a/underly/container_format.md +++ b/underly/container_format.md @@ -1,5 +1,5 @@ # 容器格式 -最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://containerd.tools/)。 +最初,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)。 对更多容器格式的支持,还在进一步的发展中。 From fde5496bb838823b6a62b3db86101ca02f80b29a Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 15 Nov 2019 11:01:25 +0800 Subject: [PATCH 029/201] Update kubernetes Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 17 +++++++++++++++-- SUMMARY.md | 7 ++++--- kubernetes/{kubectl.md => kubectl/README.md} | 1 + kubernetes/setup/README.md | 9 +++++++++ kubernetes/{quickstart.md => setup/docker.md} | 4 ++-- kubernetes/setup/k3s.md | 0 kubernetes/setup/kind.md | 0 underly/ufs.md | 2 +- 8 files changed, 32 insertions(+), 8 deletions(-) rename kubernetes/{kubectl.md => kubectl/README.md} (99%) create mode 100644 kubernetes/setup/README.md rename kubernetes/{quickstart.md => setup/docker.md} (94%) create mode 100644 kubernetes/setup/k3s.md create mode 100644 kubernetes/setup/kind.md diff --git a/.vuepress/config.js b/.vuepress/config.js index b20b65199..287ce3397 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -71,10 +71,23 @@ module.exports = { ], '/kubernetes/': [ 'intro', - 'quickstart', 'concepts', - 'kubectl', 'design', + { + title: "部署 Kubernetes", + collapsable: false, + children: [ + "setup/", + "setup/docker", + ] + }, + { + title: "Kubernetes 命令行 kubectl", + collapsable:false, + children: [ + 'kubectl/' + ] + } ], '/compose/': [ 'introduction', diff --git a/SUMMARY.md b/SUMMARY.md index 0ca744407..5229ed586 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -116,12 +116,13 @@ * [CoreOS 项目](coreos/README.md) * [简介](coreos/intro.md) * [工具](coreos/intro_tools.md) -* [Kubernetes 项目](kubernetes/README.md) +* [Kubernetes - 开源容器编排引擎](kubernetes/README.md) * [简介](kubernetes/intro.md) - * [快速上手](kubernetes/quickstart.md) * [基本概念](kubernetes/concepts.md) - * [kubectl 使用](kubernetes/kubectl.md) * [架构设计](kubernetes/design.md) +* [部署 Kubernetes](kubernetes/setup/README.md) + * [使用 Docker 容器部署](kubernetes/setup/docker.md) +* [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) * [容器与云计算](cloud/README.md) * [简介](cloud/intro.md) * [亚马逊云](cloud/aws.md) diff --git a/kubernetes/kubectl.md b/kubernetes/kubectl/README.md similarity index 99% rename from kubernetes/kubectl.md rename to kubernetes/kubectl/README.md index 5fd34079e..19e16a9ff 100644 --- a/kubernetes/kubectl.md +++ b/kubernetes/kubectl/README.md @@ -1,4 +1,5 @@ # kubectl 使用 + [kubectl](https://github.com/kubernetes/kubernetes) 是 Kubernetes 自带的客户端,可以用它来直接操作 Kubernetes。 使用格式有两种: diff --git a/kubernetes/setup/README.md b/kubernetes/setup/README.md new file mode 100644 index 000000000..1cb311e25 --- /dev/null +++ b/kubernetes/setup/README.md @@ -0,0 +1,9 @@ +# 部署 Kubernetes + +目前,Kubernetes 支持在多种环境下使用,包括本地主机(Fedora)、云服务(Google GAE、AWS 等)。 + +你可以使用以下几种方式部署 Kubernetes: + +* Docker 容器 + +接下来的小节会对以上几种方式进行详细介绍。 diff --git a/kubernetes/quickstart.md b/kubernetes/setup/docker.md similarity index 94% rename from kubernetes/quickstart.md rename to kubernetes/setup/docker.md index a68f2fd44..6f27a7570 100644 --- a/kubernetes/quickstart.md +++ b/kubernetes/setup/docker.md @@ -1,6 +1,6 @@ -# 快速上手 +# 使用 Docker 容器部署 Kubernetes -目前,Kubernetes 支持在多种环境下的安装,包括本地主机(Fedora)、云服务(Google GAE、AWS 等)。然而最快速体验 Kubernetes 的方式显然是本地通过 Docker 的方式来启动相关进程。 +最快速体验 Kubernetes 的方式就是在本地通过 Docker 的方式来启动相关进程。 下图展示了在单节点使用 Docker 快速部署一套 Kubernetes 的拓扑。 diff --git a/kubernetes/setup/k3s.md b/kubernetes/setup/k3s.md new file mode 100644 index 000000000..e69de29bb diff --git a/kubernetes/setup/kind.md b/kubernetes/setup/kind.md new file mode 100644 index 000000000..e69de29bb diff --git a/underly/ufs.md b/underly/ufs.md index 78d0bd586..cbc4f87a5 100644 --- a/underly/ufs.md +++ b/underly/ufs.md @@ -19,4 +19,4 @@ Docker 目前支持的联合文件系统包括 `OverlayFS`, `AUFS`, `Btrfs`, `VF |Docker CE on CentOS | `overlay2` | |Docker CE on Fedora | `overlay2` | -在可能的情况下,推荐使用 `overlay2` 存储驱动,`overlay2` 是目前 Docker 默认的存储驱动,以前则是 `aufs`。你可以通过配置来使用以上提到的其他类型的存储驱动。 +在可能的情况下,[推荐](https://docs.docker.com/storage/storagedriver/select-storage-driver/) 使用 `overlay2` 存储驱动,`overlay2` 是目前 Docker 默认的存储驱动,以前则是 `aufs`。你可以通过配置来使用以上提到的其他类型的存储驱动。 From e02f015a23486441ebbe9d7275b1cf80841054b3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 18 Nov 2019 22:32:44 +0800 Subject: [PATCH 030/201] Fixed #430 --- image/dockerfile/env.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/dockerfile/env.md b/image/dockerfile/env.md index f55d567d8..f3d4430cb 100644 --- a/image/dockerfile/env.md +++ b/image/dockerfile/env.md @@ -30,6 +30,6 @@ RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux- 在这里先定义了环境变量 `NODE_VERSION`,其后的 `RUN` 这层里,多次使用 `$NODE_VERSION` 来进行操作定制。可以看到,将来升级镜像构建版本的时候,只需要更新 `7.2.0` 即可,`Dockerfile` 构建维护变得更轻松了。 -下列指令可以支持环境变量展开: `ADD`、`COPY`、`ENV`、`EXPOSE`、`LABEL`、`USER`、`WORKDIR`、`VOLUME`、`STOPSIGNAL`、`ONBUILD`。 +下列指令可以支持环境变量展开: `ADD`、`COPY`、`ENV`、`EXPOSE`、`FROM`、`LABEL`、`USER`、`WORKDIR`、`VOLUME`、`STOPSIGNAL`、`ONBUILD`、`RUN`。 可以从这个指令列表里感觉到,环境变量可以使用的地方很多,很强大。通过环境变量,我们可以让一份 `Dockerfile` 制作更多的镜像,只需使用不同的环境变量即可。 From c574178a02eccc40919e352a3bcb2e3781defd15 Mon Sep 17 00:00:00 2001 From: loopever Date: Tue, 26 Nov 2019 18:56:12 +0800 Subject: [PATCH 031/201] =?UTF-8?q?Fix=20issue=20#431:=20AUFS=E5=85=A8?= =?UTF-8?q?=E7=A7=B0=E4=BF=AE=E6=94=B9=E4=B8=BAWikipedia=E7=9A=84=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- underly/ufs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/underly/ufs.md b/underly/ufs.md index cbc4f87a5..9b3ed1237 100644 --- a/underly/ufs.md +++ b/underly/ufs.md @@ -6,7 +6,7 @@ 另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。 -Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 `AUFS` 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 `AUFS` 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。 +Docker 中使用的 AUFS(Advanced Multi-Layered Unification Filesystem)就是一种联合文件系统。 `AUFS` 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 `AUFS` 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。 Docker 目前支持的联合文件系统包括 `OverlayFS`, `AUFS`, `Btrfs`, `VFS`, `ZFS` 和 `Device Mapper`。 From 83619ad6e307537ef0d9ca3bec2a887ebd35e18e Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Fri, 29 Nov 2019 23:16:18 +0800 Subject: [PATCH 032/201] [Public] coding.net domain is *.mirror.docker-practice.com Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 3 +++ .vuepress/config.js | 2 +- SUMMARY.md | 4 ++-- install/experimental.md | 6 +++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4cfaecefe..96f5b8331 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -33,6 +33,9 @@ jobs: PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master PCIT_USERNAME: khs1994 + - name: Set coding.net CNAME + run: | + echo "vuepress.mirror.docker-practice.com" > .vuepress/dist/CNAME - name: Upload Vuepress dist to coding.net uses: docker://pcit/pages if: github.repository == 'docker-practice/docker_practice' diff --git a/.vuepress/config.js b/.vuepress/config.js index 287ce3397..233b875ac 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -3,7 +3,7 @@ module.exports = { base: '/', themeConfig: { docsRepo: 'yeasy/docker_practice', - docsDir: '/vuepress', + docsDir: '/', editLinks: true, nav: [{ text: '安装 Docker', diff --git a/SUMMARY.md b/SUMMARY.md index 5229ed586..b9e83ba4c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -129,13 +129,13 @@ * [腾讯云](cloud/tencentCloud.md) * [阿里云](cloud/alicloud.md) * [小结](cloud/summary.md) -* [实战案例-操作系统](cases/os/README.md) +* [实战案例 - 操作系统](cases/os/README.md) * [Busybox](cases/os/busybox.md) * [Alpine](cases/os/alpine.md) * [Debian Ubuntu](cases/os/debian.md) * [CentOS Fedora](cases/os/centos.md) * [本章小结](cases/os/summary.md) -* [实战案例-CI/CD](cases/ci/README.md) +* [实战案例 - CI/CD](cases/ci/README.md) * [GitHub Actions](cases/ci/actions/README.md) * [Drone](cases/ci/drone/README.md) * [部署 Drone](cases/ci/drone/install.md) diff --git a/install/experimental.md b/install/experimental.md index f4f6895e2..037ea40d3 100644 --- a/install/experimental.md +++ b/install/experimental.md @@ -23,7 +23,11 @@ $ export DOCKER_CLI_EXPERIMENTAL=enabled **Windows** ```powershell -$ set $env:DOCKER_CLI_EXPERIMENTAL=enabled +# 临时生效 +$ set $env:DOCKER_CLI_EXPERIMENTAL="enabled" + +# 永久生效 +$ [environment]::SetEnvironmentvariable("DOCKER_CLI_EXPERIMENTAL","enabled","User") ``` ## 开启 Dockerd 的实验特性 From a85ae7da1e1cb46b7afaee9001df749538a3a4f8 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sun, 1 Dec 2019 10:12:14 +0800 Subject: [PATCH 033/201] Fixed buildx --- buildx/multi-arch-images.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/buildx/multi-arch-images.md b/buildx/multi-arch-images.md index d423dfc8b..4a6a2c02e 100644 --- a/buildx/multi-arch-images.md +++ b/buildx/multi-arch-images.md @@ -15,9 +15,7 @@ $ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd44 由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。 ```bash -# $ docker buildx create --name mybuilder - -$ docker buildx create --name=mybuilder --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master +$ docker buildx create --name mybuilder --driver docker-container $ docker buildx use mybuilder ``` From 0ac24829e1f0673f9202c2fa39ea1481e8ba5b8c Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Mon, 9 Dec 2019 12:21:52 +0800 Subject: [PATCH 034/201] Add enable kubernetes on docker-sektop,close #262 Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 1 + SUMMARY.md | 1 + kubernetes/setup/docker-desktop.md | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 kubernetes/setup/docker-desktop.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 233b875ac..79320dfce 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -79,6 +79,7 @@ module.exports = { children: [ "setup/", "setup/docker", + "setup/docker-desktop", ] }, { diff --git a/SUMMARY.md b/SUMMARY.md index b9e83ba4c..6aa8439dd 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -122,6 +122,7 @@ * [架构设计](kubernetes/design.md) * [部署 Kubernetes](kubernetes/setup/README.md) * [使用 Docker 容器部署](kubernetes/setup/docker.md) + * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) * [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) * [容器与云计算](cloud/README.md) * [简介](cloud/intro.md) diff --git a/kubernetes/setup/docker-desktop.md b/kubernetes/setup/docker-desktop.md new file mode 100644 index 000000000..20040087c --- /dev/null +++ b/kubernetes/setup/docker-desktop.md @@ -0,0 +1,23 @@ +# Docker Desktop 启用 Kubernetes + +使用 Docker Desktop 可以很方便的启用 Kubernetes,由于国内获取不到 `k8s.gcr.io` 镜像,我们必须首先解决这一问题。 + +## 获取 `k8s.gcr.io` 镜像 + +我们可以先从国内镜像 `gcr.azk8s.cn` 拉取镜像,再通过 `$ docker tag` 命令重新将镜像标记为 `k8s.gcr.io` 镜像。 + +开源项目 [AliyunContainerService/k8s-for-docker-desktop](https://github.com/AliyunContainerService/k8s-for-docker-desktop) 使用 `powershell` 或 `shell` 脚本简化了以上步骤,建议读者使用该开源项目获取 `k8s.gcr.io` 镜像。 + +## 启用 Kubernetes + +在 Docker Desktop 设置页面,点击 `Kubernetes`,选择 `Enable Kubernetes`,稍等片刻,看到左下方 `Kubernetes` 变为 `running`,Kubernetes 启动成功。 + +![](https://github.com/AliyunContainerService/k8s-for-docker-desktop/raw/master/images/k8s.png) + +## 测试 + +```bash +$ kubectl version +``` + +如果正常输出信息,则证明 Kubernetes 成功启动。 From a601a83c0e5ed278dd61107d0c62e097ee7aedfb Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Mon, 9 Dec 2019 13:40:10 +0800 Subject: [PATCH 035/201] Update vuepress Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 4 +- .gitignore | 3 + .vuepress/config.js | 199 +++++++++++++++++++++---------------- kubernetes/setup/docker.md | 2 +- package.json | 28 ++++++ 5 files changed, 150 insertions(+), 86 deletions(-) create mode 100644 package.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 96f5b8331..dab00ad02 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,7 +19,9 @@ jobs: - name: vuepress run: | sudo rm -rf _book - npx vuepress build + npm i vuepress --save-dev + npm i + npm run vuepress:build echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME - name: Upload Vuepress dist uses: docker://pcit/pages diff --git a/.gitignore b/.gitignore index 5bd7cae1d..4d197531a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,8 @@ _book/ *.swp *.edx .DS_Store + node_modules/ +package-lock.json + .vuepress/dist diff --git a/.vuepress/config.js b/.vuepress/config.js index 79320dfce..9edef45f9 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -1,58 +1,89 @@ module.exports = { title: 'Docker 从入门到实践', base: '/', + head: [['script', {}, ` + var _hmt = _hmt || []; + (function() { + var hm = document.createElement("script"); + hm.src = "//hm.baidu.com/hm.js?81a3490c9cd141dbcf6d00bc18b6edae"; + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(hm, s); + })(); +`], + [ + 'script', {}, ` + (function(){ + var bp = document.createElement('script'); + var curProtocol = window.location.protocol.split(':')[0]; + if (curProtocol === 'https') { + bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; + } + else { + bp.src = 'http://push.zhanzhang.baidu.com/push.js'; + } + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(bp, s); +})(); + ` + ] + ], + plugins: { + sitemap: { + hostname: 'https://vuepress.mirror.docker-practice.com' + }, + }, themeConfig: { docsRepo: 'yeasy/docker_practice', docsDir: '/', editLinks: true, nav: [{ - text: '安装 Docker', - link: '/install/', - }, - { - text: 'Docker 入门', - link: '/' - }, - { - text: 'Docker 实战', - link: '/cases/os/' - }, - { - text: 'CI/CD', - link: '/cases/ci/' - }, - { - text: 'Docker 仓库', - link: '/repository/' - }, - { - text: '底层实现', - link: '/underly/', - }, - { - text: 'Compose', - link: '/compose/', - }, - { - text: 'Kubernetes', - link: '/kubernetes/', - }, - { - text: "云计算", - link: "/cloud/", - }, - { - text: 'GitHub', - link: 'https://github.com/yeasy/docker_practice' - }, - // { - // text: '捐赠', - // link: '' - // }, - { - text: '腾讯云容器服务', - link: 'https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' - }, + text: '安装 Docker', + link: '/install/', + }, + { + text: 'Docker 入门', + link: '/' + }, + { + text: 'Docker 实战', + link: '/cases/os/' + }, + { + text: 'CI/CD', + link: '/cases/ci/' + }, + { + text: 'Docker 仓库', + link: '/repository/' + }, + { + text: '底层实现', + link: '/underly/', + }, + { + text: 'Compose', + link: '/compose/', + }, + { + text: 'Kubernetes', + link: '/kubernetes/', + }, + { + text: "云计算", + link: "/cloud/", + }, + { + text: 'GitHub', + link: 'https://github.com/yeasy/docker_practice' + }, + // { + // text: '捐赠', + // link: '' + // }, + { + text: '腾讯云容器服务', + link: 'https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' + }, // { // text: '语言', // items: [{ @@ -84,7 +115,7 @@ module.exports = { }, { title: "Kubernetes 命令行 kubectl", - collapsable:false, + collapsable: false, children: [ 'kubectl/' ] @@ -101,23 +132,23 @@ module.exports = { 'wordpress', ], '/install/': [ - 'ubuntu', - 'debian', - 'fedora', - 'centos', - 'raspberry-pi', - 'mac', - 'windows', - 'mirror', - 'experimental', + 'ubuntu', + 'debian', + 'fedora', + 'centos', + 'raspberry-pi', + 'mac', + 'windows', + 'mirror', + 'experimental', ], '/underly/': [ - 'arch', - 'namespace', - 'cgroups', - 'ufs', - 'container_format', - 'network', + 'arch', + 'namespace', + 'cgroups', + 'ufs', + 'container_format', + 'network', ], '/repository/': [ 'dockerhub', @@ -128,7 +159,7 @@ module.exports = { '/cases/os/': [ { title: "操作系统", - collapsable:false, + collapsable: false, children: [ 'busybox', 'alpine', @@ -162,7 +193,7 @@ module.exports = { '/', '/CHANGELOG', '/CONTRIBUTING', - { + { title: "Docker 简介", collapsable: false, children: [ @@ -170,7 +201,7 @@ module.exports = { 'introduction/what', 'introduction/why', ] - },{ + }, { title: "基本概念", collapsable: false, children: [ @@ -216,7 +247,7 @@ module.exports = { 'image/multistage-builds/laravel', 'image/manifest', ] - },{ + }, { title: "操作容器", collapsable: false, children: [ @@ -231,25 +262,25 @@ module.exports = { }, { title: "数据管理", - collapsable:false, + collapsable: false, children: [ 'data_management/', 'data_management/volume', 'data_management/bind-mounts', ], - },{ - title: "使用网络", - collapsable:false, - children: [ - 'network/', - 'network/port_mapping', - 'network/linking', - 'network/dns', - ], + }, { + title: "使用网络", + collapsable: false, + children: [ + 'network/', + 'network/port_mapping', + 'network/linking', + 'network/dns', + ], }, { title: "高级网络配置", - collapsable:false, + collapsable: false, children: [ 'advanced_network/', 'advanced_network/quick_guide', @@ -263,7 +294,7 @@ module.exports = { }, { title: "Swarm mode", - collapsable:false, + collapsable: false, children: [ 'swarm_mode/', 'swarm_mode/overview', @@ -300,7 +331,7 @@ module.exports = { }, { title: "Etcd", - collapsable:false, + collapsable: false, children: [ 'etcd/', 'etcd/intro', @@ -320,10 +351,10 @@ module.exports = { }, { title: "Docker 开源项目", - collapsable:false, - children:[ - 'opensource/', - 'opensource/linuxkit', + collapsable: false, + children: [ + 'opensource/', + 'opensource/linuxkit', ], }, 'appendix/faq/', diff --git a/kubernetes/setup/docker.md b/kubernetes/setup/docker.md index 6f27a7570..fede4556e 100644 --- a/kubernetes/setup/docker.md +++ b/kubernetes/setup/docker.md @@ -8,7 +8,7 @@ Kubernetes 依赖 Etcd 服务来维护所有主节点的状态。 -## 启动 Etcd 服务。 +## 启动 Etcd 服务 ```bash docker run --net=host -d gcr.io/google_containers/etcd:2.0.9 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data diff --git a/package.json b/package.json new file mode 100644 index 000000000..66a88fc12 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "docker_practice", + "version": "1.0.0", + "description": "docker_practice", + "main": "index.js", + "dependencies": {}, + "devDependencies": { + "chalk": "^3.0.0", + "commander": "^4.0.1", + "esm": "^3.2.25", + "vuepress-plugin-container": "^2.1.2", + "vuepress-plugin-sitemap": "^2.3.1" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "vuepress:build": "npx vuepress build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/yeasy/docker_practice.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/yeasy/docker_practice/issues" + }, + "homepage": "https://github.com/yeasy/docker_practice#readme" +} From f940d22950dc401378c2d8e3b41d4e0c16db4cac Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Mon, 9 Dec 2019 14:28:18 +0800 Subject: [PATCH 036/201] Add CODEOWNERS * https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners Signed-off-by: Kang HuaiShuai --- .github/CODEOWNERS | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..fb7faa903 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,40 @@ +* @yeasy @khs1994 +/.github/* @khs1994 +/.travis/* @khs1994 +/.vuepress/* @khs1994 +/advanced_network/* @yeasy @khs1994 +/appendix/* @yeasy @khs1994 +/archive/* @khs1994 +/basic_concept/* @yeasy @khs1994 +/buildx/* @khs1994 +/cases/* @yeasy @khs1994 +/cloud/* @khs1994 +/compose/* @yeasy @khs1994 +/container/* @yeasy @khs1994 +/coreos/* @khs1994 +/data_management/* @khs1994 +/etcd/* @khs1994 +/IDE/* @khs1994 +/image/* @yeasy @khs1994 +/install/* @khs1994 +/introduction/* @yeasy @khs1994 +/kubernetes/* @yeasy @khs1994 +/network/* @yeasy @khs1994 +/opensource/* @khs1994 +/repository/* @khs1994 +/security/* @yeasy @khs1994 +/underly/* @yeasy @khs1994 +/.drone.yml @khs1994 +/.editorconfig/ @khs1994 +/.gitattributes @khs1994 +/.gitignore @khs1994 +/.travis.yml @khs1994 +/_config.yml @yeasy @khs1994 +/book.json @yeasy @khs1994 +/CHANGELOG.md @yeasy @khs1994 +/CONTRIBUTING.md @yeasy @khs1994 +/docker-compose.yml @khs1994 +/manifest @khs1994 +/package.json @khs1994 +/README.md @yeasy @khs1994 +/SUMMARY.md @yeasy @khs1994 From fbfab11293fe976cc09257742f5b20c4a7a3cdd8 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Mon, 9 Dec 2019 15:05:06 +0800 Subject: [PATCH 037/201] Update registry mirror Signed-off-by: Kang HuaiShuai --- install/mirror.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/install/mirror.md b/install/mirror.md index b999b0505..8cfb8fba2 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -4,9 +4,9 @@ * [Azure 中国镜像 `https://dockerhub.azk8s.cn`](https://github.com/Azure/container-service-for-azure-china/blob/master/aks/README.md#22-container-registry-proxy) * [阿里云加速器(需登录账号获取)](https://cr.console.aliyun.com/cn-hangzhou/mirrors) -* [七牛云加速器 `https://reg-mirror.qiniu.com`](https://kirk-enterprise.github.io/hub-docs/#/user-guide/mirror) +* [网易云加速器 `https://hub-mirror.c.163.com`](https://www.163yun.com/help/documents/56918246390157312) -> 由于镜像服务可能出现宕机,建议同时配置多个镜像。 +> 由于镜像服务可能出现宕机,建议同时配置多个镜像。各个镜像站测试结果请到 [docker-practice/docker-registry-cn-mirror-test](https://github.com/docker-practice/docker-registry-cn-mirror-test/actions) 查看。 > 国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考官方文档。 @@ -20,7 +20,7 @@ { "registry-mirrors": [ "https://dockerhub.azk8s.cn", - "https://reg-mirror.qiniu.com" + "https://hub-mirror.c.163.com" ] } ``` @@ -44,7 +44,7 @@ $ sudo systemctl restart docker { "registry-mirrors": [ "https://dockerhub.azk8s.cn", - "https://reg-mirror.qiniu.com" + "https://hub-mirror.c.163.com" ] } ``` @@ -57,7 +57,7 @@ $ sudo systemctl restart docker { "registry-mirrors": [ "https://dockerhub.azk8s.cn", - "https://reg-mirror.qiniu.com" + "https://hub-mirror.c.163.com" ] } ``` From 3ba77a747084c30e2a113dabb6abd25b30b1bdc5 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Mon, 9 Dec 2019 20:46:21 +0800 Subject: [PATCH 038/201] Drone agent use drone/drone-runner-docker:1 Signed-off-by: Kang HuaiShuai --- README.md | 3 +-- cases/ci/drone/docker-compose.yml | 2 +- cases/ci/drone/install.md | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index afdcbad16..649514f26 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,9 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md),[GitBook 国内镜像](https://docker_practice.gitee.io/zh-cn),[GitBook 英文版国内镜像](https://docker_practice.gitee.io/us-en),[国内镜像](https://github.com/yeasy/docker_practice/wiki/%E9%A1%B9%E7%9B%AE%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F), [新版 GitBook](https://gitbook.docker-practice.com/) +* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) -* [英文翻译](https://github.com/yeasy/docker_practice/issues/363) Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初学者使用最新稳定版本的 Docker 进行学习实践。欢迎 [参与项目维护](CONTRIBUTING.md)。 diff --git a/cases/ci/drone/docker-compose.yml b/cases/ci/drone/docker-compose.yml index d183b208a..8ef416bad 100644 --- a/cases/ci/drone/docker-compose.yml +++ b/cases/ci/drone/docker-compose.yml @@ -21,7 +21,7 @@ services: - DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET} drone-agent: - image: drone/agent:1 + image: drone/drone-runner-docker:1 restart: always depends_on: - drone-server diff --git a/cases/ci/drone/install.md b/cases/ci/drone/install.md index 18d3b7941..3d94ee5c1 100644 --- a/cases/ci/drone/install.md +++ b/cases/ci/drone/install.md @@ -48,7 +48,7 @@ services: - DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET} drone-agent: - image: drone/agent:1 + image: drone/drone-runner-docker:1 restart: always depends_on: - drone-server From 2092debcc038eed0edfbb9b4dc3b4b5524ff3851 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Mon, 9 Dec 2019 21:00:18 +0800 Subject: [PATCH 039/201] [Cloud] Remove docker cloud Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 2 +- SUMMARY.md | 2 +- cloud/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 9edef45f9..d6c2bd8cf 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -95,9 +95,9 @@ module.exports = { sidebar: { '/cloud/': [ 'intro', - 'aws', 'tencentCloud', 'alicloud', + 'aws', 'summary', ], '/kubernetes/': [ diff --git a/SUMMARY.md b/SUMMARY.md index 6aa8439dd..54fb47232 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -126,9 +126,9 @@ * [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) * [容器与云计算](cloud/README.md) * [简介](cloud/intro.md) - * [亚马逊云](cloud/aws.md) * [腾讯云](cloud/tencentCloud.md) * [阿里云](cloud/alicloud.md) + * [亚马逊云](cloud/aws.md) * [小结](cloud/summary.md) * [实战案例 - 操作系统](cases/os/README.md) * [Busybox](cases/os/busybox.md) diff --git a/cloud/README.md b/cloud/README.md index 2fa6e02d1..44e994c22 100644 --- a/cloud/README.md +++ b/cloud/README.md @@ -2,4 +2,4 @@ Docker 目前已经得到了众多公有云平台的支持,并成为除虚拟机之外的核心云业务。 -除了 AWS、Google、Azure、Docker 官方云服务等,国内的各大公有云厂商,基本上都同时支持了虚拟机服务和容器服务,甚至还专门推出了容器云业务。 \ No newline at end of file +除了 AWS、Google、Azure 等,国内的各大公有云厂商,基本上都同时支持了虚拟机服务和基于 Kubernetes 的容器云业务。有的还推出了 [容器实例服务](https://cloud.tencent.com/act/cps/redirect?redirect=10230&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上快捷、灵活的部署 Docker 容器。 From 59317624bba0c719d6137a5b530c6dea73643c90 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 22 Dec 2019 10:34:52 +0800 Subject: [PATCH 040/201] Update link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 649514f26..30be2bf8b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -* 在线阅读:[docker-practice.com](https://docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) +* 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) From bbfe14e0afc02bffc210eabc1f263014bc875db7 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 26 Dec 2019 11:54:45 +0800 Subject: [PATCH 041/201] Update docker commit, Fixed #437 --- image/commit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/commit.md b/image/commit.md index 01ca00256..205da616b 100644 --- a/image/commit.md +++ b/image/commit.md @@ -125,6 +125,6 @@ docker run --name web2 -d -p 81:80 nginx:v2 首先,如果仔细观察之前的 `docker diff webserver` 的结果,你会发现除了真正想要修改的 `/usr/share/nginx/html/index.html` 文件外,由于命令的执行,还有很多文件被改动或添加了。这还仅仅是最简单的操作,如果是安装软件包、编译构建,那会有大量的无关内容被添加进来,如果不小心清理,将会导致镜像极为臃肿。 -此外,使用 `docker commit` 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 **黑箱镜像**,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具体在操作的。虽然 `docker diff` 或许可以告诉得到一些线索,但是远远不到可以确保生成一致镜像的地步。这种黑箱镜像的维护工作是非常痛苦的。 +此外,使用 `docker commit` 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 **黑箱镜像**,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具体的操作。这种黑箱镜像的维护工作是非常痛苦的。 而且,回顾之前提及的镜像所使用的分层存储的概念,除当前层外,之前的每一层都是不会发生改变的,换句话说,任何修改的结果仅仅是在当前层进行标记、添加、修改,而不会改动上一层。如果使用 `docker commit` 制作镜像,以及后期修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使根本无法访问到。这会让镜像更加臃肿。 From 0dcc67da1c53aad3b8effacfb4f27d7ddc677196 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 31 Dec 2019 20:26:22 +0800 Subject: [PATCH 042/201] Add kubeadm, close #438 Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 4 +- .vuepress/config.js | 3 +- CHANGELOG.md | 2 + SUMMARY.md | 3 +- kubernetes/setup/README.md | 4 +- kubernetes/setup/docker.md | 91 ------------------ kubernetes/setup/kubeadm.md | 183 ++++++++++++++++++++++++++++++++++++ kubernetes/setup/systemd.md | 3 + 8 files changed, 197 insertions(+), 96 deletions(-) delete mode 100644 kubernetes/setup/docker.md create mode 100644 kubernetes/setup/kubeadm.md create mode 100644 kubernetes/setup/systemd.md diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dab00ad02..9c2d25da2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -30,7 +30,7 @@ jobs: PCIT_EMAIL: khs1994@khs1994.com PCIT_GIT_TOKEN: ${{ secrets.PCIT_GIT_TOKEN }} PCIT_GIT_URL: github.com/docker-practice/vuepress - PCIT_KEEP_HISTORY: "1" + PCIT_KEEP_HISTORY: "true" PCIT_LOCAL_DIR: .vuepress/dist PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master @@ -45,7 +45,7 @@ jobs: PCIT_EMAIL: khs1994@khs1994.com PCIT_GIT_TOKEN: ${{ secrets.CODING_GIT_TOKEN }} PCIT_GIT_URL: git.dev.tencent.com/khs1994/docker_practice - PCIT_KEEP_HISTORY: "1" + PCIT_KEEP_HISTORY: "true" PCIT_LOCAL_DIR: .vuepress/dist PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master diff --git a/.vuepress/config.js b/.vuepress/config.js index d6c2bd8cf..625705b01 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -109,8 +109,9 @@ module.exports = { collapsable: false, children: [ "setup/", - "setup/docker", + "setup/kubeadm", "setup/docker-desktop", + "setup/systemd", ] }, { diff --git a/CHANGELOG.md b/CHANGELOG.md index dd7d2e578..2e04a3d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # 修订记录 +* 1.2.0 2020-12-31 + * 1.1.0 2019-12-31 * 全面支持 v19.x 新版本 * 增加 `BuildKit` diff --git a/SUMMARY.md b/SUMMARY.md index 54fb47232..07697d109 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -121,8 +121,9 @@ * [基本概念](kubernetes/concepts.md) * [架构设计](kubernetes/design.md) * [部署 Kubernetes](kubernetes/setup/README.md) - * [使用 Docker 容器部署](kubernetes/setup/docker.md) + * [使用 kubeadm 部署 kubernetes](kubernetes/setup/kubeadm.md) * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) + * [一步步部署 kubernetes 集群](kubernetes/setup/systemd.md) * [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) * [容器与云计算](cloud/README.md) * [简介](cloud/intro.md) diff --git a/kubernetes/setup/README.md b/kubernetes/setup/README.md index 1cb311e25..f6bc2ff90 100644 --- a/kubernetes/setup/README.md +++ b/kubernetes/setup/README.md @@ -4,6 +4,8 @@ 你可以使用以下几种方式部署 Kubernetes: -* Docker 容器 +* kubeadm +* docker-desktop +* k3s 接下来的小节会对以上几种方式进行详细介绍。 diff --git a/kubernetes/setup/docker.md b/kubernetes/setup/docker.md deleted file mode 100644 index fede4556e..000000000 --- a/kubernetes/setup/docker.md +++ /dev/null @@ -1,91 +0,0 @@ -# 使用 Docker 容器部署 Kubernetes - -最快速体验 Kubernetes 的方式就是在本地通过 Docker 的方式来启动相关进程。 - -下图展示了在单节点使用 Docker 快速部署一套 Kubernetes 的拓扑。 - -![在 Docker 中启动 Kubernetes](_images/k8s-singlenode-docker.png) - -Kubernetes 依赖 Etcd 服务来维护所有主节点的状态。 - -## 启动 Etcd 服务 - -```bash -docker run --net=host -d gcr.io/google_containers/etcd:2.0.9 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data -``` - -## 启动主节点 - -启动 kubelet。 - -```bash -docker run --net=host -d -v /var/run/docker.sock:/var/run/docker.sock gcr.io/google_containers/hyperkube:v0.17.0 /hyperkube kubelet --api_servers=http://localhost:8080 --v=2 --address=0.0.0.0 --enable_server --hostname_override=127.0.0.1 --config=/etc/kubernetes/manifests -``` - -## 启动服务代理 - -```bash -docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v0.17.0 /hyperkube proxy --master=http://127.0.0.1:8080 --v=2 -``` - -## 测试状态 - -在本地访问 `8080` 端口,可以获取到如下的结果: - -```bash -$ curl 127.0.0.1:8080 -{ - "paths": [ - "/api", - "/api/v1beta1", - "/api/v1beta2", - "/api/v1beta3", - "/healthz", - "/healthz/ping", - "/logs/", - "/metrics", - "/static/", - "/swagger-ui/", - "/swaggerapi/", - "/validate", - "/version" - ] -} -``` - -## 查看服务 - -所有服务启动后,查看本地实际运行的 Docker 容器,有如下几个。 - -```bash -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -ee054db2516c gcr.io/google_containers/hyperkube:v0.17.0 "/hyperkube schedule 2 days ago Up 1 days k8s_scheduler.509f29c9_k8s-master-127.0.0.1_default_9941e5170b4365bd4aa91f122ba0c061_e97037f5 -3b0f28de07a2 gcr.io/google_containers/hyperkube:v0.17.0 "/hyperkube apiserve 2 days ago Up 1 days k8s_apiserver.245e44fa_k8s-master-127.0.0.1_default_9941e5170b4365bd4aa91f122ba0c061_6ab5c23d -2eaa44ecdd8e gcr.io/google_containers/hyperkube:v0.17.0 "/hyperkube controll 2 days ago Up 1 days k8s_controller-manager.33f83d43_k8s-master-127.0.0.1_default_9941e5170b4365bd4aa91f122ba0c061_1a60106f -30aa7163cbef gcr.io/google_containers/hyperkube:v0.17.0 "/hyperkube proxy -- 2 days ago Up 1 days jolly_davinci -a2f282976d91 gcr.io/google_containers/pause:0.8.0 "/pause" 2 days ago Up 2 days k8s_POD.e4cc795_k8s-master-127.0.0.1_default_9941e5170b4365bd4aa91f122ba0c061_e8085b1f -c060c52acc36 gcr.io/google_containers/hyperkube:v0.17.0 "/hyperkube kubelet 2 days ago Up 1 days serene_nobel -cc3cd263c581 gcr.io/google_containers/etcd:2.0.9 "/usr/local/bin/etcd 2 days ago Up 1 days happy_turing -``` - -这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 - -### 主节点服务 - -* `apiserver` 是整个系统的对外接口,提供 RESTful 方式供客户端和其它组件调用; - -* `scheduler` 负责对资源进行调度,分配某个 pod 到某个节点上; - -* `controller-manager` 负责管理控制器,包括 endpoint-controller(刷新服务和 pod 的关联信息)和 replication-controller(维护某个 pod 的复制为配置的数值)。 - -### 工作节点服务 - -* `kubelet` 是工作节点执行操作的 agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报 pod 运行状态等; - -* `proxy` 为 pod 上的服务提供访问的代理。 - -### 其它服务 - -* Etcd 是所有状态的存储数据库; - -* `gcr.io/google_containers/pause:0.8.0` 是 Kubernetes 启动后自动 pull 下来的测试镜像。 diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md new file mode 100644 index 000000000..f999b0daa --- /dev/null +++ b/kubernetes/setup/kubeadm.md @@ -0,0 +1,183 @@ +# 使用 kubeadm 部署 kubernetes + +`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `kubernetes` 集群的最佳实践。 + +## 安装 Docker + +参考 [安装 Docker](../../install) 一节安装 Docker。 + +## 安装 **kubelet** **kubeadm** **kubectl** + +### Ubuntu/Debian + +```bash +$ apt-get update && apt-get install -y apt-transport-https +$ curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - + +$ cat < 执行可能出现错误,例如缺少依赖包,根据提示安装即可。 + +执行成功会输出 + +```bash +... +[addons] Applied essential addon: CoreDNS +I1116 12:35:13.270407 86677 request.go:538] Throttling request took 181.409184ms, request: POST:https://192.168.199.100:6443/api/v1/namespaces/kube-system/serviceaccounts +I1116 12:35:13.470292 86677 request.go:538] Throttling request took 186.088112ms, request: POST:https://192.168.199.100:6443/api/v1/namespaces/kube-system/configmaps +[addons] Applied essential addon: kube-proxy + +Your Kubernetes control-plane has initialized successfully! + +To start using your cluster, you need to run the following as a regular user: + + mkdir -p $HOME/.kube + sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config + sudo chown $(id -u):$(id -g) $HOME/.kube/config + +You should now deploy a pod network to the cluster. +Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: + https://kubernetes.io/docs/concepts/cluster-administration/addons/ + +Then you can join any number of worker nodes by running the following on each as root: + +kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ + --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe +``` + +### node 工作节点 + +在 **另一主机** 重复 **部署** 小节以前的步骤,安装配置好 kubelet。根据提示,加入到集群。 + +```bash +$ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ + --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe +``` + +## 查看服务 + +所有服务启动后,查看本地实际运行的 Docker 容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 + +### 主节点服务 + +* `apiserver` 是整个系统的对外接口,提供 RESTful 方式供客户端和其它组件调用; + +* `scheduler` 负责对资源进行调度,分配某个 pod 到某个节点上; + +* `controller-manager` 负责管理控制器,包括 endpoint-controller(刷新服务和 pod 的关联信息)和 replication-controller(维护某个 pod 的复制为配置的数值)。 + +### 工作节点服务 + +* `proxy` 为 pod 上的服务提供访问的代理。 + +### 其它服务 + +* Etcd 是所有状态的存储数据库; + +## 使用 + +将 `/etc/kubernetes/admin.conf` 复制到 `~/.kube/config` + +执行 `$ kubectl get all -A` 查看启动的服务。 + +由于未部署 CNI 插件,CoreDNS 未正常启动。如何使用 Kubernetes,请参考后续章节。 + +## 部署 CNI + +这里以 `flannel` 为例进行介绍。 + +### flannel + +检查 podCIDR 设置 + +```bash +$ kubectl get node -o yaml | grep CIDR + +# 输出 + podCIDR: 10.244.0.0/24 + podCIDRs: +``` + +```bash +$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml +``` + +## master 节点默认不能运行 pod + +如果用 `kubeadm` 部署一个单节点集群,默认情况下无法使用,请执行以下命令解除限制 + +```bash +$ kubectl taint nodes --all node-role.kubernetes.io/master- + +# 恢复默认值 +# $ kubectl taint nodes NODE_NAME node-role.kubernetes.io/master=true:NoSchedule +``` diff --git a/kubernetes/setup/systemd.md b/kubernetes/setup/systemd.md new file mode 100644 index 000000000..a3ae99f3b --- /dev/null +++ b/kubernetes/setup/systemd.md @@ -0,0 +1,3 @@ +# 一步步部署 kubernetes 集群 + +可以参考 [opsnull/follow-me-install-kubernetes-cluster](https://github.com/opsnull/follow-me-install-kubernetes-cluster) 项目一步步部署 kubernetes 集群。 From 9f0b2c725f01deee81d44cc1b27816e4d237465e Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 31 Dec 2019 20:48:52 +0800 Subject: [PATCH 043/201] Add podman Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 1 + SUMMARY.md | 1 + podman/README.md | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 podman/README.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 625705b01..781afbf37 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -358,6 +358,7 @@ module.exports = { 'opensource/linuxkit', ], }, + 'podman/', 'appendix/faq/', { title: "热门镜像介绍", diff --git a/SUMMARY.md b/SUMMARY.md index 07697d109..d3288afb8 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -146,6 +146,7 @@ * [VS Code](IDE/vsCode.md) * [Docker 开源项目](opensource/README.md) * [LinuxKit](opensource/linuxkit.md) +* [podman -- 下一代 Linux 容器工具](podman/README.md) * [附录](appendix/README.md) * [附录一:常见问题总结](appendix/faq/README.md) * [附录二:热门镜像介绍](appendix/repo/README.md) diff --git a/podman/README.md b/podman/README.md new file mode 100644 index 000000000..b24215200 --- /dev/null +++ b/podman/README.md @@ -0,0 +1,23 @@ +# podman + +[`podman`](https://github.com/containers/libpod) 是一个无守护程序与 docker 命令兼容的下一代 Linux 容器工具。 + +## 安装 + +```bash +$ sudo yum -y install podman +``` + +## 使用 + +`podman` 与 docker 命令完全兼容,只需将 `docker` 替换为 `podman` 即可,例如运行一个容器: + +```bash +# $ docker run -d -p 80:80 nginx:alpine + +$ podman run -d -p 80:80 nginx:alpine +``` + +## 参考 + +* https://developers.redhat.com/blog/2019/02/21/podman-and-buildah-for-docker-users/ From 386b1e4cf69352e060fb2522a40111a32e49f3b0 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 31 Dec 2019 21:10:06 +0800 Subject: [PATCH 044/201] Replace dead link Signed-off-by: Kang HuaiShuai --- repository/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/README.md b/repository/README.md index d705fa9bb..52df443a6 100644 --- a/repository/README.md +++ b/repository/README.md @@ -2,6 +2,6 @@ 仓库(`Repository`)是集中存放镜像的地方。 -一个容易混淆的概念是注册服务器(`Registry`)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 `dl.dockerpool.com/ubuntu` 来说,`dl.dockerpool.com` 是注册服务器地址,`ubuntu` 是仓库名。 +一个容易混淆的概念是注册服务器(`Registry`)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 `docker.io/ubuntu` 来说,`docker.io` 是注册服务器地址,`ubuntu` 是仓库名。 大部分时候,并不需要严格区分这两者的概念。 From e77c9ecbab15d5b90483c843f5c5aabeface1047 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 9 Jan 2020 16:57:38 +0800 Subject: [PATCH 045/201] [Kubernetes] Add dashboard Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 1 + SUMMARY.md | 5 ++-- kubernetes/setup/dashboard.md | 45 +++++++++++++++++++++++++++++++++++ kubernetes/setup/kubeadm.md | 4 ++++ manifest | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 kubernetes/setup/dashboard.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 781afbf37..c9e50b53a 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -112,6 +112,7 @@ module.exports = { "setup/kubeadm", "setup/docker-desktop", "setup/systemd", + "setup/dashboard", ] }, { diff --git a/SUMMARY.md b/SUMMARY.md index d3288afb8..6f323ebde 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -124,6 +124,7 @@ * [使用 kubeadm 部署 kubernetes](kubernetes/setup/kubeadm.md) * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) * [一步步部署 kubernetes 集群](kubernetes/setup/systemd.md) + * [部署 Dashboard](kubernetes/setup/dashboard.md) * [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) * [容器与云计算](cloud/README.md) * [简介](cloud/intro.md) @@ -160,8 +161,8 @@ * [MongoDB](appendix/repo/mongodb.md) * [Redis](appendix/repo/redis.md) * [附录三:Docker 命令查询](appendix/command/README.md) - * [客户端命令 (docker)](appendix/command/docker.md) - * [服务端命令 (dockerd)](appendix/command/dockerd.md) + * [客户端命令 -- docker](appendix/command/docker.md) + * [服务端命令 -- dockerd](appendix/command/dockerd.md) * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) diff --git a/kubernetes/setup/dashboard.md b/kubernetes/setup/dashboard.md new file mode 100644 index 000000000..e7275d820 --- /dev/null +++ b/kubernetes/setup/dashboard.md @@ -0,0 +1,45 @@ +# Kubernetes Dashboard + +[Kubernetes Dashboard](https://github.com/kubernetes/dashboard) 是基于网页的 Kubernetes 用户界面。 + +![](https://d33wubrfki0l68.cloudfront.net/349824f68836152722dab89465835e604719caea/6e0b7/images/docs/ui-dashboard.png) + +## 部署 + +执行以下命令即可部署 Dashboard: + +```bash +kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml +``` + +## 访问 + +通过命令行代理访问,执行以下命令: + +```bash +$ kubectl proxy +``` + +到 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ 即可访问。 + +## 登录 + +目前,Dashboard 仅支持使用 Bearer 令牌登录。下面教大家如何创建该令牌: + +```bash +$ kubectl create sa dashboard-admin -n kube-system + +$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin + +$ ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}') + +$ DASHBOARD_LOGIN_TOKEN=$(kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}') + +echo ${DASHBOARD_LOGIN_TOKEN} +``` + +将结果粘贴到登录页面,即可登录。 + +## 参考文档 + +* [官方文档](https://kubernetes.io/zh/docs/tasks/access-application-cluster/web-ui-dashboard/) diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md index f999b0daa..e764c74ae 100644 --- a/kubernetes/setup/kubeadm.md +++ b/kubernetes/setup/kubeadm.md @@ -181,3 +181,7 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master- # 恢复默认值 # $ kubectl taint nodes NODE_NAME node-role.kubernetes.io/master=true:NoSchedule ``` + +## 参考文档 + +* [官方文档](https://kubernetes.io/zh/docs/setup/independent/create-cluster-kubeadm/) diff --git a/manifest b/manifest index f577b1ec6..a30a44a65 100644 --- a/manifest +++ b/manifest @@ -3,5 +3,6 @@ DOCKER_COMPOSE_VERSION=1.24.1 DOCKER_MACHINE_VERSION=0.16.1 ETCD_VERSION=3.4.0 KUBERNETES_VERSION=1.14.3 +KUBERNETES_DASHBOARD=2.0.0-beta8 UBUNTU=18.04 DEBIAN=9 From 9d450ffc262306ce6c435746184d027d5220dd13 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 9 Jan 2020 17:08:35 +0800 Subject: [PATCH 046/201] [Compose] Add lnmp Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 1 + SUMMARY.md | 1 + compose/lnmp.md | 3 +++ 3 files changed, 5 insertions(+) create mode 100644 compose/lnmp.md diff --git a/.vuepress/config.js b/.vuepress/config.js index c9e50b53a..5be167c28 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -132,6 +132,7 @@ module.exports = { 'django', 'rails', 'wordpress', + 'lnmp', ], '/install/': [ 'ubuntu', diff --git a/SUMMARY.md b/SUMMARY.md index 6f323ebde..04cbd7a01 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -86,6 +86,7 @@ * [实战 Django](compose/django.md) * [实战 Rails](compose/rails.md) * [实战 WordPress](compose/wordpress.md) + * [实战 LNMP](compose/lnmp.md) * [Swarm mode](swarm_mode/README.md) * [基本概念](swarm_mode/overview.md) * [创建 Swarm 集群](swarm_mode/create.md) diff --git a/compose/lnmp.md b/compose/lnmp.md new file mode 100644 index 000000000..6e89ed21f --- /dev/null +++ b/compose/lnmp.md @@ -0,0 +1,3 @@ +# 使用 compose 搭建 LNMP 环境 + +本项目的维护者 [khs1994](https://github.com/khs1994) 的开源项目 [khs1994-docker/lnmp](https://github.com/khs1994-docker/lnmp) 使用 Docker Compose 搭建了一套 LNMP 环境,各位开发者可以参考该项目在 Docker 或 Kubernetes 中运行 LNMP。 From 9a0a76a5bb40f6da0a171a7744b4d1681e3cb2a9 Mon Sep 17 00:00:00 2001 From: FirejqWei <895521320@qq.com> Date: Tue, 11 Feb 2020 02:03:57 +0800 Subject: [PATCH 047/201] Fix a markdown grammatical error --- image/commit.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/image/commit.md b/image/commit.md index 205da616b..1ae37b250 100644 --- a/image/commit.md +++ b/image/commit.md @@ -91,7 +91,8 @@ $ docker image ls nginx REPOSITORY TAG IMAGE ID CREATED SIZE nginx v2 07e334659748 9 seconds ago 181.5 MB nginx 1.11 05a60462f8ba 12 days ago 181.5 MB -nginx latest e43d811ce2f4 4 weeks ago 181.5 MB``` +nginx latest e43d811ce2f4 4 weeks ago 181.5 MB +``` 我们还可以用 `docker history` 具体查看镜像内的历史记录,如果比较 `nginx:latest` 的历史记录,我们会发现新增了我们刚刚提交的这一层。 From 5577c9caa65a698bc51b82f6bee22dd1e8b434fb Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sat, 1 Feb 2020 10:24:29 +0800 Subject: [PATCH 048/201] Change CoreOS to Fedora CoreOS(FCOS) Signed-off-by: Kang HuaiShuai --- .vuepress/config.js | 2 +- README.md | 2 +- SUMMARY.md | 10 +++++----- cloud/README.md | 2 +- coreos/README.md | 4 ++-- coreos/install.md | 46 +++++++++++++++++++++++++++++++++++++++++++ coreos/intro.md | 33 ++++++++++++++----------------- coreos/intro_tools.md | 13 ------------ 8 files changed, 71 insertions(+), 41 deletions(-) create mode 100644 coreos/install.md delete mode 100644 coreos/intro_tools.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 5be167c28..a4cf45c22 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -349,7 +349,7 @@ module.exports = { children: [ 'coreos/', 'coreos/intro', - 'coreos/intro_tools', + 'coreos/install', ], }, { diff --git a/README.md b/README.md index 30be2bf8b..24b6baa30 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS) -**v1.1.0** +**v1.2.0** | 语言 | 构建状态 | - | | :------------- | :------------- | :--- | diff --git a/SUMMARY.md b/SUMMARY.md index 04cbd7a01..2f63f24d0 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -114,9 +114,9 @@ * [安装](etcd/install.md) * [集群](etcd/cluster.md) * [使用 etcdctl](etcd/etcdctl.md) -* [CoreOS 项目](coreos/README.md) +* [Fedora CoreOS](coreos/README.md) * [简介](coreos/intro.md) - * [工具](coreos/intro_tools.md) + * [安装](coreos/install.md) * [Kubernetes - 开源容器编排引擎](kubernetes/README.md) * [简介](kubernetes/intro.md) * [基本概念](kubernetes/concepts.md) @@ -148,7 +148,7 @@ * [VS Code](IDE/vsCode.md) * [Docker 开源项目](opensource/README.md) * [LinuxKit](opensource/linuxkit.md) -* [podman -- 下一代 Linux 容器工具](podman/README.md) +* [podman - 下一代 Linux 容器工具](podman/README.md) * [附录](appendix/README.md) * [附录一:常见问题总结](appendix/faq/README.md) * [附录二:热门镜像介绍](appendix/repo/README.md) @@ -162,8 +162,8 @@ * [MongoDB](appendix/repo/mongodb.md) * [Redis](appendix/repo/redis.md) * [附录三:Docker 命令查询](appendix/command/README.md) - * [客户端命令 -- docker](appendix/command/docker.md) - * [服务端命令 -- dockerd](appendix/command/dockerd.md) + * [客户端命令 - docker](appendix/command/docker.md) + * [服务端命令 - dockerd](appendix/command/dockerd.md) * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) diff --git a/cloud/README.md b/cloud/README.md index 44e994c22..471656ef9 100644 --- a/cloud/README.md +++ b/cloud/README.md @@ -2,4 +2,4 @@ Docker 目前已经得到了众多公有云平台的支持,并成为除虚拟机之外的核心云业务。 -除了 AWS、Google、Azure 等,国内的各大公有云厂商,基本上都同时支持了虚拟机服务和基于 Kubernetes 的容器云业务。有的还推出了 [容器实例服务](https://cloud.tencent.com/act/cps/redirect?redirect=10230&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上快捷、灵活的部署 Docker 容器。 +除了 AWS、Google、Azure 等,国内的各大公有云厂商,基本上都同时支持了虚拟机服务和基于 Kubernetes 的容器云业务。有的还推出了其他服务,例如 [容器实例服务](https://cloud.tencent.com/act/cps/redirect?redirect=10230&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上快捷、灵活的部署 Docker 容器。[容器镜像服务](https://cloud.tencent.com/act/cps/redirect?redirect=11588&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上享有安全高效的镜像托管、分发等服务。 diff --git a/coreos/README.md b/coreos/README.md index dbde5c5ba..9fbf86091 100644 --- a/coreos/README.md +++ b/coreos/README.md @@ -1,6 +1,6 @@ -# CoreOS +# Fedora CoreOS -`CoreOS` 的设计是为你提供能够像谷歌一样的大型互联网公司一样的基础设施管理能力来动态扩展和管理的计算能力。 +`CoreOS` 是一个专门为安全和大规模运行容器化工作负载而构建的新 Fedora 版本,它是 Fedora Atomic Host 和 CoreOS Container Linux 的后续项目。 `CoreOS` 的安装文件和运行依赖非常小,它提供了精简的 Linux 系统。它使用 Linux 容器在更高的抽象层来管理你的服务,而不是通过常规的包管理工具 `yum` 或 `apt` 来安装包。 diff --git a/coreos/install.md b/coreos/install.md new file mode 100644 index 000000000..2e2b693a8 --- /dev/null +++ b/coreos/install.md @@ -0,0 +1,46 @@ +# 安装 Fedora CoreOS + +## 下载 ISO + +在 [下载页面](https://getfedora.org/coreos/download/) `Bare Metal & Virtualized` 标签页下载 ISO。 + +## 编写 FCC + +FCC 是 Fedora CoreOS Configuration (Fedora CoreOS 配置)的简称。 + +```yaml +# example.fcc +variant: fcos +version: 1.0.0 +passwd: + users: + - name: core + ssh_authorized_keys: + - ssh-rsa AAAA... +``` + +将 `ssh-rsa AAAA...` 替换为自己的 SSH 公钥(位于 `~/.ssh/id_rsa.pub`)。 + +## 转换 FCC 为 Ignition + +```bash +$ docker run -i --rm quay.io/coreos/fcct:v0.2.0 -pretty -strict < example.fcc > example.ign +``` + +## 启动虚拟机并安装 + +在虚拟机终端执行以下命令安装: + +```bash +$ sudo coreos-installer install /dev/sda --ignition example.ign +``` + +安装之后重新启动即可使用。 + +## 使用 + +```bash +$ ssh core@虚拟机IP + +$ docker --version +``` diff --git a/coreos/intro.md b/coreos/intro.md index 9b1a64da8..bef861bff 100644 --- a/coreos/intro.md +++ b/coreos/intro.md @@ -1,31 +1,28 @@ -# CoreOS 介绍 +# Fedora CoreOS 介绍 -[CoreOS](https://coreos.com/) 对 Docker 甚至容器技术的发展都带来了巨大的推动作用。其提供了运行现代基础设施的特性,支持大规模服务部署,使得在基于最小化的现代操作系统上构建规模化的计算仓库成为了可能。 +[Fedora CoreOS](https://getfedora.org/coreos/) 是一个自动更新的,最小的,整体的,以容器为中心的操作系统,不仅适用于集群,而且可独立运行,并针对运行 Kubernetes 进行了优化。它旨在结合 CoreOS Container Linux 和 Fedora Atomic Host 的优点,将 Container Linux 中的 [Ignition](https://github.com/coreos/ignition) 与 [rpm-ostree](https://github.com/coreos/rpm-ostree) 和 Project Atomic 中的 SELinux 强化等技术相集成。其目标是提供最佳的容器主机,以安全,大规模地运行容器化的工作负载。 -# CoreOS 特性 +## FCOS 特性 -## 一个最小化操作系统 +### 一个最小化操作系统 -CoreOS 被设计成一个基于容器的最小化的现代操作系统。它比现有的 Linux 安装平均节省 40% 的 RAM(大约 114M )并允许从 PXE 或 iPXE 非常快速的启动。 +FCOS 被设计成一个基于容器的最小化的现代操作系统。它比现有的 Linux 安装平均节省 40% 的 RAM(大约 114M )并允许从 PXE 或 iPXE 非常快速的启动。 -## 无痛更新 +### 系统初始化 -利用主动和被动双分区方案来更新 OS,使用分区作为一个单元而不是一个包一个包的更新。这使得每次更新变得快速,可靠,而且很容易回滚。 +Ignition 是一种配置实用程序,可读取配置文件(JSON 格式)并根据该配置配置 FCOS 系统。可配置的组件包括存储,文件系统,systemd 和用户。 -## Docker 容器 +Ignition 在系统首次启动期间(在 initramfs 中)仅运行一次。由于 Ignition 在启动过程中的早期运行,因此它可以在用户空间开始启动之前重新对磁盘分区,格式化文件系统,创建用户并写入文件。当 systemd 启动时,systemd 服务已被写入磁盘,从而加快了启动时间。 -应用作为 Docker 容器运行在 CoreOS 上。容器以包的形式提供最大得灵活性并且可以在几毫秒启动。 +### 自动更新 -## 支持集群 +FCOS 使用 rpm-ostree 系统进行事务性升级。无需像 yum 升级那样升级单个软件包,而是 rpm-ostree 将 OS 升级作为一个原子单元进行。新的 OS 部署在升级期间进行,并在下次重新引导时生效。如果升级出现问题,则一次回滚和重新启动会使系统返回到先前的状态。确保了系统升级对群集容量的影响降到最小。 -CoreOS 可以在一个机器上很好地运行,但是它被设计用来搭建集群。 +### 容器工具 -可以通过 k8s 很容易得使应用容器部署在多台机器上并且通过服务发现把他们连接在一起。 +对于诸如构建,复制和其他管理容器的任务,FCOS 用一组兼容的容器工具代替了 **Docker CLI** 工具。**podman CLI** 工具支持许多容器运行时功能,例如运行,启动,停止,列出和删除容器和镜像。**skopeo CLI** 工具可以复制,认证和签名镜像。您可以使用 **crictl CLI** 工具来处理 CRI-O 容器引擎中的容器和镜像。 -## 分布式系统工具 +## 参考文档 -内置诸如分布式锁和主选举等原生工具用来构建大规模分布式系统得构建模块。 - -## 服务发现 - -很容易定位服务在集群的那里运行并当发生变化时进行通知。它是复杂高动态集群必不可少的。 +* [官方文档](https://docs.fedoraproject.org/en-US/fedora-coreos/) +* [openshift 官方文档](https://docs.openshift.com/container-platform/4.3/architecture/architecture-rhcos.html) diff --git a/coreos/intro_tools.md b/coreos/intro_tools.md deleted file mode 100644 index 9144d4826..000000000 --- a/coreos/intro_tools.md +++ /dev/null @@ -1,13 +0,0 @@ -# CoreOS 工具介绍 - -`CoreOS` 内置了 `服务发现`,`容器管理` 工具。 - -## 服务发现 - -`CoreOS` 的第一个重要组件就是使用 `etcd` 来实现的服务发现。在 `CoreOS` 中 `etcd` 默认以 `rkt` 容器方式运行。 - -`etcd` 使用方法请查看 [etcd 章节](../etcd/)。 - -## 容器管理 - -第二个组件就是 `Docker`,它用来运行你的代码和应用。`CoreOS` 内置 `Docker`,具体使用请参考本书其他章节。 From a2e8595c4217de38d17f35b639c6dda8947c6eda Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sat, 22 Feb 2020 14:30:11 +0800 Subject: [PATCH 049/201] vuepress remove archived content Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 4 ++-- .vuepress/config.js | 31 ------------------------------- README.md | 2 +- 3 files changed, 3 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9c2d25da2..a02732029 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -44,9 +44,9 @@ jobs: env: PCIT_EMAIL: khs1994@khs1994.com PCIT_GIT_TOKEN: ${{ secrets.CODING_GIT_TOKEN }} - PCIT_GIT_URL: git.dev.tencent.com/khs1994/docker_practice + PCIT_GIT_URL: e.coding.net/dpsigs/docker_practice PCIT_KEEP_HISTORY: "true" PCIT_LOCAL_DIR: .vuepress/dist PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master - PCIT_USERNAME: khs1994 + PCIT_USERNAME: ptt0xjqzbke3 diff --git a/.vuepress/config.js b/.vuepress/config.js index a4cf45c22..b3c3bdf38 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -390,37 +390,6 @@ module.exports = { 'appendix/best_practices', 'appendix/debug', 'appendix/resources', - 'archive/', - { - title: "Docker Machine", - collapsable: false, - children: [ - 'machine/', - 'machine/install', - 'machine/usage', - ], - }, - { - title: 'Mesos', - collapsable: false, - children: [ - 'mesos/', - 'mesos/intro', - 'mesos/installation', - 'mesos/architecture', - 'mesos/configuration', - 'mesos/monitor', - 'mesos/framework', - 'mesos/summary', - ] - }, - { - title: 'Docker Swarm', - collapsable: false, - children: [ - "swarm/" - ] - } ], }, } diff --git a/README.md b/README.md index 24b6baa30..5f4f89a3d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ | 语言 | 构建状态 | - | | :------------- | :------------- | :--- | -| [zh-hans](https://github.com/yeasy/docker_practice) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh-cn) | +| [zh-hans](https://github.com/yeasy/docker_practice) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://vuepress.mirror.docker-practice.com/) | | [us-en](https://github.com/yeasy/docker_practice/tree/english) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=english)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/us-en) | | [zh-hant](https://github.com/yeasy/docker_practice/tree/zh-Hant) | [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=zh-hant)](https://travis-ci.org/yeasy/docker_practice)| [阅读](https://docker_practice.gitee.io/zh-hant) | From 6c0fc9e4168af22cee67a6ea0954f5e27042ac88 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sun, 23 Feb 2020 10:14:40 +0800 Subject: [PATCH 050/201] cp _images to vuepress dist Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a02732029..dc69604c5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,6 +23,23 @@ jobs: npm i npm run vuepress:build echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME + + cp -r _images .vuepress/dist + cp -r advanced_network/_images .vuepress/dist/advanced_network + cp -r appendix/_images .vuepress/dist/appendix + cp -r cases/ci/drone/_images .vuepress/dist/cases/ci/drone + cp -r cases/os/_images .vuepress/dist/cases/os + cp -r cloud/_images .vuepress/dist/cloud + cp -r data_management/_images .vuepress/dist/data_management + cp -r etcd/_images .vuepress/dist/etcd + cp -r image/_images .vuepress/dist/image + cp -r install/_images .vuepress/dist/install + cp -r introduction/_images .vuepress/dist/introduction + cp -r kubernetes/_images .vuepress/dist/kubernetes + cp -r mesos/_images .vuepress/dist/mesos + cp -r underly/_images .vuepress/dist/underly + + echo "include: [_images]" > .vuepress/dist/_config - name: Upload Vuepress dist uses: docker://pcit/pages if: github.repository == 'docker-practice/docker_practice' From 33c2b2216df92fc0f2cf02be89201fe40297c070 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sun, 23 Feb 2020 11:13:23 +0800 Subject: [PATCH 051/201] [actions] check md files link Signed-off-by: Kang HuaiShuai --- .github/workflows/check-link.yml | 24 ++++++++++++++++++++++++ .github/workflows/ci.yaml | 2 -- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/check-link.yml diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml new file mode 100644 index 000000000..355b6a759 --- /dev/null +++ b/.github/workflows/check-link.yml @@ -0,0 +1,24 @@ +name: check-link + +on: + push: + pull_request: + +jobs: + check-link: + name: check-link + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + with: + fetch-depth: 1 + - run: | + docker run -i --rm \ + -v $PWD:/mnt:ro \ + dkhamsing/awesome_bot \ + --white-list "localhost" \ + --allow-dupe \ + --allow-redirect \ + --skip-save-results \ + `find . -name "*.md"` + name: check-link diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dc69604c5..5d806ab1b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,8 +38,6 @@ jobs: cp -r kubernetes/_images .vuepress/dist/kubernetes cp -r mesos/_images .vuepress/dist/mesos cp -r underly/_images .vuepress/dist/underly - - echo "include: [_images]" > .vuepress/dist/_config - name: Upload Vuepress dist uses: docker://pcit/pages if: github.repository == 'docker-practice/docker_practice' From 1e026fb3a1f6df16bf9251b88aa8aa1e6d9ab02b Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sun, 23 Feb 2020 11:36:56 +0800 Subject: [PATCH 052/201] Remove 404 link Signed-off-by: Kang HuaiShuai --- .github/workflows/check-link.yml | 4 ++-- basic_concept/repository.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 355b6a759..a03abd8aa 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -16,9 +16,9 @@ jobs: docker run -i --rm \ -v $PWD:/mnt:ro \ dkhamsing/awesome_bot \ - --white-list "localhost" \ + --white-list "localhost","0.0.0.0","172.16.238.100","server","example.com",\ + "docker.domain.com","YourIP","registry" \ --allow-dupe \ - --allow-redirect \ --skip-save-results \ `find . -name "*.md"` name: check-link diff --git a/basic_concept/repository.md b/basic_concept/repository.md index f7255873d..d44f9dfe7 100644 --- a/basic_concept/repository.md +++ b/basic_concept/repository.md @@ -18,7 +18,7 @@ Docker Registry 公开服务是开放给用户使用、允许用户管理镜像 由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为**加速器**。常见的有 [阿里云加速器](https://cr.console.aliyun.com/#/accelerator)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 -国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [时速云镜像仓库](https://hub.tenxcloud.com/)、[网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com) 等。 +国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com) 等。 ## 私有 Docker Registry From d887c8bda6ab8592313aaca5c04b08856f690db8 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sun, 23 Feb 2020 12:18:53 +0800 Subject: [PATCH 053/201] Update link Signed-off-by: Kang HuaiShuai --- .github/workflows/check-link.yml | 46 +++++++++++++++++++-- appendix/repo/php.md | 2 +- appendix/resources.md | 2 +- cases/ci/actions/README.md | 2 +- cases/os/debian.md | 71 +++++++++++++++++++------------- image/list.md | 4 +- image/manifest.md | 2 +- image/other.md | 2 +- image/pull.md | 2 +- install/fedora.md | 2 +- install/mac.md | 2 +- install/raspberry-pi.md | 2 +- install/ubuntu.md | 2 +- introduction/what.md | 2 +- kubernetes/design.md | 2 +- opensource/linuxkit.md | 2 +- repository/nexus3_registry.md | 2 +- 17 files changed, 102 insertions(+), 47 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index a03abd8aa..027d7b9f2 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -16,9 +16,49 @@ jobs: docker run -i --rm \ -v $PWD:/mnt:ro \ dkhamsing/awesome_bot \ - --white-list "localhost","0.0.0.0","172.16.238.100","server","example.com",\ - "docker.domain.com","YourIP","registry" \ + --white-list "localhost","0.0.0.0",\ + "server","example.com","docker",\ + "docker.domain.com","YourIP","register",\ + "172.16.238.100","172.16.238.101","172.16.238.102",\ + "192.168.199.100",\ + "github.com/settings",\ + "github.com/docker/compose/releases/download",\ + "github.com/docker/machine/releases/download",\ + "github.com/etcd-io/etcd/releases/download",\ + "github.com/tianon/gosu/releases/download",\ + "github.com/yeasy/docker_practice",\ + "github.com/twang2218/gitlab-ce-zh.git",\ + "github.com/AliyunContainerService/k8s-for-docker-desktop/raw",\ + "dl-4.alpinelinux.org/alpine/edge/testing",\ + "www.w3.org/1999/xhtml",\ + "cr.console.aliyun.com",\ + "cloud.tencent.com",\ + "nodejs.org/dist/",\ + "c.163.com/hub",\ + "drone.yeasy.com",\ + "mirrors.ustc.edu.cn",\ + "docs.docker.com",\ + "dockerhub.azk8s.cn",\ + "vuepress.mirror.docker-practice.com",\ + "mc.qcloudimg.com/static/img",\ + "www.daocloud.io/mirror",\ + "download.docker.com",\ + "www.ubuntu.com",\ + "archive.ubuntu.com",\ + "security.ubuntu.com/ubuntu",\ + "nginx.com",\ + "img.shields.io/github/release/yeasy/docker_practice",\ + "travis-ci.org/yeasy/docker_practice.svg",\ + "launchpad.net",\ + "www.w3.org/1999",\ + "chat.freenode.net",\ + "en.wikipedia.org/wiki/UnionFS",\ + "product.china-pub.com",\ + "union-click.jd.com",\ + "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ - `find . -name "*.md"` + -t 5 \ + `find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" \) -prune -o -name "*.md" -exec ls {} \;` name: check-link + timeout-minutes: 25 diff --git a/appendix/repo/php.md b/appendix/repo/php.md index 7edbb85be..0d54c90a9 100644 --- a/appendix/repo/php.md +++ b/appendix/repo/php.md @@ -2,7 +2,7 @@ ## 基本信息 -[PHP](https://en.wikipedia.org/wiki/php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。 +[PHP](https://en.wikipedia.org/wiki/Php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。 该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 7.x 各个版本的镜像。 diff --git a/appendix/resources.md b/appendix/resources.md index 155038c3a..199d26865 100644 --- a/appendix/resources.md +++ b/appendix/resources.md @@ -3,7 +3,7 @@ ## 官方网站 * Docker 官方主页:https://www.docker.com -* Docker 官方博客:https://blog.docker.com/ +* Docker 官方博客:https://www.docker.com/blog/ * Docker 官方文档:https://docs.docker.com/ * Docker Hub:https://hub.docker.com * Docker 的源代码仓库:https://github.com/moby/moby diff --git a/cases/ci/actions/README.md b/cases/ci/actions/README.md index ce36b1d72..bd34f075b 100644 --- a/cases/ci/actions/README.md +++ b/cases/ci/actions/README.md @@ -25,4 +25,4 @@ jobs: ## 参考资料 -* [Actions Docs](https://help.github.com/en/categories/automating-your-workflow-with-github-actions) +* [Actions Docs](https://help.github.com/en/actions) diff --git a/cases/os/debian.md b/cases/os/debian.md index 6e8724197..b19c6d6e7 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -49,16 +49,22 @@ Debian GNU/Linux 8 ```bash $ docker search --filter=stars=10 ubuntu -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -ubuntu Official Ubuntu base image 840 [OK] -dockerfile/ubuntu Trusted automated Ubuntu (http://www.ubunt... 30 [OK] -crashsystems/gitlab-docker A trusted, regularly updated build of GitL... 20 [OK] -sylvainlasnier/memcached This is a Memcached 1.4.14 docker images b... 16 [OK] -ubuntu-upstart Upstart is an event-based replacement for ... 16 [OK] -mbentley/ubuntu-django-uwsgi-nginx 16 [OK] -clue/ttrss The Tiny Tiny RSS feed reader allows you t... 14 [OK] -dockerfile/ubuntu-desktop Trusted automated Ubuntu Desktop (LXDE) (h... 14 [OK] -tutum/ubuntu Ubuntu image with SSH access. For the root... 12 [OK] +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +ubuntu Ubuntu is a Debian-based Linux operating sys… 10539 [OK] +dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 395 [OK] +rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 243 [OK] +consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 210 [OK] +ubuntu-upstart Upstart is an event-based replacement for th… 105 [OK] +ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 98 [OK] +neurodebian NeuroDebian provides neuroscience research s… 64 [OK] +1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 50 [OK] +ubuntu-debootstrap debootstrap --variant=minbase --components=m… 42 [OK] +nuagebec/ubuntu Simple always updated Ubuntu docker images w… 24 [OK] +i386/ubuntu Ubuntu is a Debian-based Linux operating sys… 19 +1and1internet/ubuntu-16-apache-php-5.6 ubuntu-16-apache-php-5.6 14 [OK] +1and1internet/ubuntu-16-apache-php-7.0 ubuntu-16-apache-php-7.0 13 [OK] +eclipse/ubuntu_jdk8 Ubuntu, JDK8, Maven 3, git, curl, nmap, mc, … 12 [OK] +1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10 ubuntu-16-nginx-php-phpmyadmin-mariadb-10 11 [OK] ``` 根据搜索出来的结果,读者可以自行选择下载镜像并使用。 @@ -98,12 +104,26 @@ E: Unable to locate package curl ```bash root@7d93de07bf76:/# apt-get update -Ign http://archive.ubuntu.com trusty InRelease -Ign http://archive.ubuntu.com trusty-updates InRelease -Ign http://archive.ubuntu.com trusty-security InRelease -Ign http://archive.ubuntu.com trusty-proposed InRelease -Get:1 http://archive.ubuntu.com trusty Release.gpg [933 B] -... +Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB] +Get:2 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB] +Get:3 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [7348 B] +Get:4 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [823 kB] +Get:5 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB] +Get:6 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB] +Get:7 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [11.3 MB] +Get:8 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [31.0 kB] +Get:9 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [835 kB] +Get:10 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB] +Get:11 http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB] +Get:12 http://archive.ubuntu.com/ubuntu bionic/multiverse amd64 Packages [186 kB] +Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [1127 kB] +Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1350 kB] +Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [11.4 kB] +Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [44.7 kB] +Get:17 http://archive.ubuntu.com/ubuntu bionic-backports/main amd64 Packages [2496 B] +Get:18 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [4252 B] +Fetched 17.6 MB in 1min 25s (207 kB/s) +Reading package lists... Done ``` 首先,安装 `curl` 工具。 @@ -113,13 +133,9 @@ root@7d93de07bf76:/# apt-get install curl Reading package lists... Done Building dependency tree Reading state information... Done -The following extra packages will be installed: - ca-certificates krb5-locales libasn1-8-heimdal libcurl3 libgssapi-krb5-2 - libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal - libheimntlm0-heimdal libhx509-5-heimdal libidn11 libk5crypto3 libkeyutils1 - libkrb5-26-heimdal libkrb5-3 libkrb5support0 libldap-2.4-2 - libroken18-heimdal librtmp0 libsasl2-2 libsasl2-modules libsasl2-modules-db - libwind0-heimdal openssl +The following additional packages will be installed: + ca-certificates krb5-locales libasn1-8-heimdal libcurl4 libgssapi-krb5-2 libgssapi3-heimdal libhcrypto4-heimdal libheimbase1-heimdal libheimntlm0-heimdal libhx509-5-heimdal + libk5crypto3 libkeyutils1 libkrb5-26-heimdal libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common libnghttp2-14 libpsl5 libroken18-heimdal librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libsqlite3-0 libssl1.1 libwind0-heimdal openssl publicsuffix ... root@7d93de07bf76:/# curl curl: try 'curl --help' or 'curl --manual' for more information @@ -132,9 +148,8 @@ root@7d93de07bf76:/# apt-get install -y apache2 Reading package lists... Done Building dependency tree Reading state information... Done -The following extra packages will be installed: - apache2-bin apache2-data libapr1 libaprutil1 libaprutil1-dbd-sqlite3 - libaprutil1-ldap libxml2 sgml-base ssl-cert xml-core +The following additional packages will be installed: + apache2-bin apache2-data apache2-utils file libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libexpat1 libgdbm-compat4 libgdbm5 libicu60 liblua5.2-0 libmagic-mgc libmagic1 libperl5.26 libxml2 mime-support netbase perl perl-modules-5.26 ssl-cert xz-utils ... ``` @@ -150,7 +165,7 @@ root@7d93de07bf76:/# curl 127.0.0.1 @@ -169,7 +184,7 @@ root@7d93de07bf76:/# curl 127.0.0.1 * `Debian` 官方仓库:https://github.com/Debian * `Debian` 官方镜像:https://hub.docker.com/_/debian/ * `Debian` 官方镜像仓库:https://github.com/tianon/docker-brew-debian/ -* `Ubuntu` 官网:http://www.ubuntu.org.cn/global +* `Ubuntu` 官网:https://ubuntu.com * `Ubuntu` 官方仓库:https://github.com/ubuntu * `Ubuntu` 官方镜像:https://hub.docker.com/_/ubuntu/ * `Ubuntu` 官方镜像仓库:https://github.com/tianon/docker-brew-ubuntu-core diff --git a/image/list.md b/image/list.md index 107c36d1b..84efdf09d 100644 --- a/image/list.md +++ b/image/list.md @@ -19,7 +19,7 @@ ubuntu latest f753707788c5 4 weeks ago ## 镜像体积 -如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,`ubuntu:18.04` 镜像大小,在这里是 `127 MB`,但是在 [Docker Hub](https://hub.docker.com/r/library/ubuntu/tags/) 显示的却是 `50 MB`。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 `docker image ls` 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。 +如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,`ubuntu:18.04` 镜像大小,在这里是 `127 MB`,但是在 [Docker Hub](https://hub.docker.com/_/ubuntu?tab=tags) 显示的却是 `50 MB`。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 `docker image ls` 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。 另外一个需要注意的问题是,`docker image ls` 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。 @@ -123,7 +123,7 @@ f753707788c5 `--filter` 配合 `-q` 产生出指定范围的 ID 列表,然后送给另一个 `docker` 命令作为参数,从而针对这组实体成批的进行某种操作的做法在 Docker 命令行使用过程中非常常见,不仅仅是镜像,将来我们会在各个命令中看到这类搭配以完成很强大的功能。因此每次在文档看到过滤器后,可以多注意一下它们的用法。 -另外一些时候,我们可能只是对表格的结构不满意,希望自己组织列;或者不希望有标题,这样方便其它程序解析结果等,这就用到了 [Go 的模板语法](https://gohugo.io/templates/go-templates/)。 +另外一些时候,我们可能只是对表格的结构不满意,希望自己组织列;或者不希望有标题,这样方便其它程序解析结果等,这就用到了 [Go 的模板语法](https://gohugo.io/templates/introduction/)。 比如,下面的命令会直接列出镜像结果,并且只包含镜像ID和仓库名: diff --git a/image/manifest.md b/image/manifest.md index 78dd12851..382e6c338 100644 --- a/image/manifest.md +++ b/image/manifest.md @@ -161,4 +161,4 @@ $ docker manifest push username/test 详细了解 `manifest` 可以阅读官方博客。 -* https://blog.docker.com/2017/11/multi-arch-all-the-things/ +* https://www.docker.com/blog/multi-arch-all-the-things/ diff --git a/image/other.md b/image/other.md index 4d4dd1383..6029143b2 100644 --- a/image/other.md +++ b/image/other.md @@ -8,7 +8,7 @@ 压缩包可以是本地文件、远程 Web 文件,甚至是从标准输入中得到。压缩包将会在镜像 `/` 目录展开,并直接作为镜像第一层提交。 -比如我们想要创建一个 [OpenVZ](https://openvz.org) 的 Ubuntu 16.04 [模板](https://openvz.org/Download/template/precreated)的镜像: +比如我们想要创建一个 [OpenVZ](https://openvz.org) 的 Ubuntu 16.04 [模板](https://wiki.openvz.org/Download/template/precreated)的镜像: ```bash $ docker import \ diff --git a/image/pull.md b/image/pull.md index 51c47c90e..d2ed771b3 100644 --- a/image/pull.md +++ b/image/pull.md @@ -1,6 +1,6 @@ # 获取镜像 -之前提到过,[Docker Hub](https://hub.docker.com/explore/) 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像。 +之前提到过,[Docker Hub](https://hub.docker.com/search?q=&type=image) 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像。 从 Docker 镜像仓库获取镜像的命令是 `docker pull`。其命令格式为: diff --git a/install/fedora.md b/install/fedora.md index 05d0081fa..f415b234e 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -6,7 +6,7 @@ ### 系统要求 -Docker CE 支持以下版本的 [Fedora](https://fedoraproject.org/) 操作系统: +Docker CE 支持以下版本的 [Fedora](https://getfedora.org/) 操作系统: * 28 * 29 diff --git a/install/mac.md b/install/mac.md index 80a385dfe..a4c18cb4c 100644 --- a/install/mac.md +++ b/install/mac.md @@ -18,7 +18,7 @@ $ brew cask install docker 如果需要手动下载,请点击以下链接下载 [Stable](https://download.docker.com/mac/stable/Docker.dmg) 或 [Edge](https://download.docker.com/mac/edge/Docker.dmg) 版本的 Docker Desktop for Mac。 -如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://blog.docker.com/2013/10/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。 +如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。 ![](_images/install-mac-dmg.png) diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 36d48c895..d59ee127b 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -10,7 +10,7 @@ Docker CE 支持以下版本的 [Raspbian](https://www.raspberrypi.org/downloads * Raspbian Stretch -*注:* `Raspbian` 是树莓派的开发与维护机构 [树莓派基金会](http://www.raspberrypi.org/) 推荐用于树莓派的首选系统,其基于 `Debian`。 +*注:* `Raspbian` 是树莓派的开发与维护机构 [树莓派基金会](https://www.raspberrypi.org/) 推荐用于树莓派的首选系统,其基于 `Debian`。 ## 使用 APT 安装 diff --git a/install/ubuntu.md b/install/ubuntu.md index 2c5516500..ec9469dd7 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -6,7 +6,7 @@ ### 系统要求 -Docker CE 支持以下版本的 [Ubuntu](https://www.ubuntu.com/server) 操作系统: +Docker CE 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: * Disco 19.04 * Cosmic 18.10 diff --git a/introduction/what.md b/introduction/what.md index 1351afeaf..5ecf57381 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -2,7 +2,7 @@ **Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,它是基于 `dotCloud` 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。`Docker` 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://www.opencontainers.org/)。 -**Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 4 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://blog.docker.com/2013/10/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 +**Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 4 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 **Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [AUFS](https://en.wikipedia.org/wiki/Aufs) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 diff --git a/kubernetes/design.md b/kubernetes/design.md index 804402ab3..9eeb6d03c 100644 --- a/kubernetes/design.md +++ b/kubernetes/design.md @@ -26,7 +26,7 @@ 主节点上需要提供如下的管理服务: -* `apiserver` 是整个系统的对外接口,提供一套 RESTful 的 [Kubernetes API](https://github.com/kubernetes/kubernetes/tree/master/docs/api-reference),供客户端和其它组件调用; +* `apiserver` 是整个系统的对外接口,提供一套 RESTful 的 [Kubernetes API](https://kubernetes.io/zh/docs/concepts/overview/kubernetes-api/),供客户端和其它组件调用; * `scheduler` 负责对资源进行调度,分配某个 pod 到某个节点上。是 pluggable 的,意味着很容易选择其它实现方式; * `controller-manager` 负责管理控制器,包括 endpoint-controller(刷新服务和 pod 的关联信息)和 replication-controller(维护某个 pod 的复制为配置的数值)。 diff --git a/opensource/linuxkit.md b/opensource/linuxkit.md index ee491ebd7..087e9de00 100644 --- a/opensource/linuxkit.md +++ b/opensource/linuxkit.md @@ -15,7 +15,7 @@ $ brew install --HEAD linuxkit ## 克隆源代码 ```bash -$ git clone -b master --depth=1 https://github.com/linuxkit/linuxkit.git +$ git clone -b master --depth=1 https://github.com/linuxkit/linuxkit $ cd linuxkit ``` diff --git a/repository/nexus3_registry.md b/repository/nexus3_registry.md index 479e64478..5f35eddd5 100644 --- a/repository/nexus3_registry.md +++ b/repository/nexus3_registry.md @@ -1,6 +1,6 @@ # Nexus3.x 的私有仓库 -使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/download-oss-sonatype/) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 +使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/download-oss-sonatype) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 ## 启动 Nexus 容器 From d2f5e120ae241d82e612cf0e94ec296db81d7361 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sun, 23 Feb 2020 21:57:26 +0800 Subject: [PATCH 054/201] Fixed github pages Signed-off-by: Kang HuaiShuai --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5d806ab1b..dc69604c5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,6 +38,8 @@ jobs: cp -r kubernetes/_images .vuepress/dist/kubernetes cp -r mesos/_images .vuepress/dist/mesos cp -r underly/_images .vuepress/dist/underly + + echo "include: [_images]" > .vuepress/dist/_config - name: Upload Vuepress dist uses: docker://pcit/pages if: github.repository == 'docker-practice/docker_practice' From ca5502e2088edba81835bea45fcaa6f8052c5b18 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 27 Feb 2020 23:31:01 +0800 Subject: [PATCH 055/201] Update alpine content: replace default repo Signed-off-by: Kang HuaiShuai --- .github/workflows/check-link.yml | 4 ++-- cases/os/alpine.md | 9 ++++++++- install/README.md | 2 +- install/mac.md | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 027d7b9f2..b1aa12e39 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -29,7 +29,7 @@ jobs: "github.com/yeasy/docker_practice",\ "github.com/twang2218/gitlab-ce-zh.git",\ "github.com/AliyunContainerService/k8s-for-docker-desktop/raw",\ - "dl-4.alpinelinux.org/alpine/edge/testing",\ + "dl-cdn.alpinelinux.org/alpine/edge/testing",\ "www.w3.org/1999/xhtml",\ "cr.console.aliyun.com",\ "cloud.tencent.com",\ @@ -58,7 +58,7 @@ jobs: "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ - -t 5 \ + -t 10 \ `find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" \) -prune -o -name "*.md" -exec ls {} \;` name: check-link timeout-minutes: 25 diff --git a/cases/os/alpine.md b/cases/os/alpine.md index 7c10df046..6a1de447e 100644 --- a/cases/os/alpine.md +++ b/cases/os/alpine.md @@ -50,10 +50,17 @@ $ apk add --no-cache `Alpine` 中软件安装包的名字可能会与其他发行版有所不同,可以在 `https://pkgs.alpinelinux.org/packages` 网站搜索并确定安装包名称。如果需要的安装包不在主索引内,但是在测试或社区索引中。那么可以按照以下方法使用这些安装包。 ```bash -$ echo "http://dl-4.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +$ echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories $ apk --update add --no-cache ``` +由于在国内访问 `apk` 仓库较缓慢,建议在使用 `apk` 之前先替换仓库地址为国内镜像。 + +```docker +RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \ + && apk add --no-cache +``` + ## 相关资源 * `Alpine` 官网:https://www.alpinelinux.org/ diff --git a/install/README.md b/install/README.md index eb6180d80..a9db78b88 100644 --- a/install/README.md +++ b/install/README.md @@ -2,6 +2,6 @@ Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 -Docker CE 分为 `stable` `test` 和 `nightly` 三个更新频道。每六个月发布一个 `stable` 版本 (`18.09`, `19.03`, `19.09`...)。 +Docker CE 分为 `stable` `test` 和 `nightly` 三个更新频道。 官方网站上有各种环境下的 [安装指南](https://docs.docker.com/install/),这里主要介绍 Docker CE 在 `Linux` 、`Windows 10` 和 `macOS` 上的安装。 diff --git a/install/mac.md b/install/mac.md index a4c18cb4c..31eb13d1e 100644 --- a/install/mac.md +++ b/install/mac.md @@ -2,13 +2,13 @@ ## 系统要求 -[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Sierra 10.12。 +[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Catalina 10.13。 ## 安装 ### 使用 Homebrew 安装 -[Homebrew](https://brew.sh/) 的 [Cask](https://caskroom.github.io/) 已经支持 Docker Desktop for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装: +[Homebrew](https://brew.sh/) 的 [Cask](https://github.com/Homebrew/homebrew-cask) 已经支持 Docker Desktop for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装: ```bash $ brew cask install docker From 3a249016648618bae0950323c9dbf9bd8c12bf8f Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Wed, 4 Mar 2020 11:50:59 +0800 Subject: [PATCH 056/201] Change AUFS to OverlayFS Signed-off-by: Kang HuaiShuai --- appendix/faq/README.md | 4 ++-- cases/os/busybox.md | 43 +++++++++++++++++++++++++++++------------- image/internal.md | 2 +- introduction/what.md | 2 +- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/appendix/faq/README.md b/appendix/faq/README.md index 5870c85bd..d21fce91e 100644 --- a/appendix/faq/README.md +++ b/appendix/faq/README.md @@ -12,7 +12,7 @@ ### 本地的镜像文件都存放在哪里? -答:与 Docker 相关的本地资源默认存放在 `/var/lib/docker/` 目录下,以 `aufs` 文件系统为例,其中 `container` 目录存放容器信息,`graph` 目录存放镜像信息,`aufs` 目录下存放具体的镜像层文件。 +答:与 Docker 相关的本地资源默认存放在 `/var/lib/docker/` 目录下,以 `overlay2` 文件系统为例,其中 `containers` 目录存放容器信息,`image` 目录存放镜像信息,`overlay2` 目录下存放具体的镜像层文件。 ### 构建 Docker 镜像应该遵循哪些原则? @@ -149,7 +149,7 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker 答:LXC 利用 Linux 上相关技术实现了容器。Docker 则在如下的几个方面进行了改进: * 移植性:通过抽象容器配置,容器可以实现从一个平台移植到另一个平台; -* 镜像系统:基于 AUFS 的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储; +* 镜像系统:基于 OverlayFS 的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储; * 版本管理:类似于Git的版本管理理念,用户可以更方便的创建、管理镜像文件; * 仓库系统:仓库系统大大降低了镜像的分发和管理的成本; * 周边工具:各种现有工具(配置管理、云平台)对 Docker 的支持,以及基于 Docker的 PaaS、CI 等系统,让 Docker 的应用更加方便和多样化。 diff --git a/cases/os/busybox.md b/cases/os/busybox.md index 1eb471a97..b3527728f 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -85,22 +85,39 @@ Search for PATTERN in FILEs (or stdin) ```bash / # mount -rootfs on / type rootfs (rw) -none on / type aufs (rw,relatime,si=b455817946f8505c) +overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/BOTCI5RF24AMC4A2UWF4N6ZWFP:/var/lib/docker/overlay2/l/TWVP5T5DMKJGXZOROR7CAPWGFP,upperdir=/var/lib/docker/overlay2/801ef0bf6cce35288dbb8fe00a4f9cc47760444693bfdf339ed0bdcf926e12a3/diff,workdir=/var/lib/docker/overlay2/801ef0bf6cce35288dbb8fe00a4f9cc47760444693bfdf339ed0bdcf926e12a3/work) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) -tmpfs on /dev type tmpfs (rw,nosuid,mode=755) -shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k) +tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666) sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime) -/dev/disk/by-uuid/b1f2dba7-d91b-4165-a377-bf1a8bed3f61 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered) -/dev/disk/by-uuid/b1f2dba7-d91b-4165-a377-bf1a8bed3f61 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered) -/dev/disk/by-uuid/b1f2dba7-d91b-4165-a377-bf1a8bed3f61 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered) -devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000) -proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime) -proc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime) -proc on /proc/irq type proc (ro,nosuid,nodev,noexec,relatime) -proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime) -tmpfs on /proc/kcore type tmpfs (rw,nosuid,mode=755) +tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,relatime,mode=755) +cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd) +cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls,net_prio) +cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer) +cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct) +cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset) +cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio) +cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event) +cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory) +cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices) +cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids) +mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime) +shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k) +/dev/vda1 on /etc/resolv.conf type ext3 (rw,noatime,data=ordered) +/dev/vda1 on /etc/hostname type ext3 (rw,noatime,data=ordered) +/dev/vda1 on /etc/hosts type ext3 (rw,noatime,data=ordered) +devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666) +proc on /proc/bus type proc (ro,relatime) +proc on /proc/fs type proc (ro,relatime) +proc on /proc/irq type proc (ro,relatime) +proc on /proc/sys type proc (ro,relatime) +proc on /proc/sysrq-trigger type proc (ro,relatime) +tmpfs on /proc/acpi type tmpfs (ro,relatime) +tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /proc/sched_debug type tmpfs (rw,nosuid,size=65536k,mode=755) +tmpfs on /sys/firmware type tmpfs (ro,relatime) ``` `busybox` 镜像虽然小巧,但包括了大量常见的 `Linux` 命令,读者可以用它快速熟悉 `Linux` 命令。 diff --git a/image/internal.md b/image/internal.md index f22123b66..d36b209d6 100644 --- a/image/internal.md +++ b/image/internal.md @@ -6,4 +6,4 @@ Docker 镜像是怎么实现增量的修改和维护的? 通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。 -Docker 在 AUFS 上构建的容器也是利用了类似的原理。 +Docker 在 OverlayFS 上构建的容器也是利用了类似的原理。 diff --git a/introduction/what.md b/introduction/what.md index 5ecf57381..fe5ebd861 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -4,7 +4,7 @@ **Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 4 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 -**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [AUFS](https://en.wikipedia.org/wiki/Aufs) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 +**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [OverlayFS](https://docs.docker.com/storage/storagedriver/overlayfs-driver/) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 ![Docker 架构](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/media/docker-on-linux.png) From c720d6959ea40c74e2e157b11c181fa9c4261d6f Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 10 Mar 2020 13:39:27 +0800 Subject: [PATCH 057/201] Docker Desktop Support Windows Home Signed-off-by: Kang HuaiShuai --- appendix/faq/README.md | 2 +- cloud/alicloud.md | 2 +- install/windows.md | 3 ++- kubernetes/{qdvanced.md => advanced.md} | 0 kubernetes/concepts.md | 4 ++-- 5 files changed, 6 insertions(+), 5 deletions(-) rename kubernetes/{qdvanced.md => advanced.md} (100%) diff --git a/appendix/faq/README.md b/appendix/faq/README.md index d21fce91e..8b4a24814 100644 --- a/appendix/faq/README.md +++ b/appendix/faq/README.md @@ -18,7 +18,7 @@ 答:整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括 -* 尽量选取满足需求但较小的基础系统镜像,例如大部分时候可以选择 debian:wheezy 或 debian:stretch 镜像,仅有不足百兆大小; +* 尽量选取满足需求但较小的基础系统镜像,例如大部分时候可以选择 `alpine` 镜像,仅有不足六兆大小; * 清理编译生成文件、安装包的缓存等临时文件; diff --git a/cloud/alicloud.md b/cloud/alicloud.md index b8e59572b..97fbf28c4 100644 --- a/cloud/alicloud.md +++ b/cloud/alicloud.md @@ -4,7 +4,7 @@ [阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 创立于 2009 年,是中国较早的云计算平台。阿里云致力于提供安全、可靠的计算和数据处理能力。 -[阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 的客户群体中,活跃着微博、知乎、魅族、锤子科技、小咖秀等一大批明星互联网公司。在天猫双 11 全球狂欢节等极富挑战的应用场景中,阿里云保持着良好的运行纪录。 +[阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 的客户群体中,活跃着微博、知乎、魅族、小咖秀等一大批明星互联网公司。在天猫双 11 全球狂欢节等极富挑战的应用场景中,阿里云保持着良好的运行纪录。 [阿里云容器服务 Kubernetes 版 ACK](https://www.aliyun.com/product/kubernetes?source=5176.11533457&userCode=8lx5zmtu&type=copy) 提供了高性能、可伸缩的容器应用管理服务,支持在一组云服务器上通过 Docker 容器来进行应用生命周期管理。容器服务极大简化了用户对容器管理集群的搭建工作,无缝整合了阿里云虚拟化、存储、网络和安全能力。容器服务提供了多种应用发布方式和流水线般的持续交付能力,原生支持微服务架构,助力用户无缝上云和跨云管理。 diff --git a/install/windows.md b/install/windows.md index 0286c28df..e0d4ed8dd 100644 --- a/install/windows.md +++ b/install/windows.md @@ -2,7 +2,7 @@ ## 系统要求 -[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V。 +[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V,或者 64 位版本的 Windows 10 Home Insider Preview build 19018+。 ## 安装 @@ -31,3 +31,4 @@ Docker CE 启动之后会在 Windows 任务栏出现鲸鱼图标。 ## 参考链接 * [官方文档](https://docs.docker.com/docker-for-windows/install/) +* [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl-tech-preview/) diff --git a/kubernetes/qdvanced.md b/kubernetes/advanced.md similarity index 100% rename from kubernetes/qdvanced.md rename to kubernetes/advanced.md diff --git a/kubernetes/concepts.md b/kubernetes/concepts.md index ab3185b3b..b79bb37f3 100644 --- a/kubernetes/concepts.md +++ b/kubernetes/concepts.md @@ -11,10 +11,10 @@ * 标签(`labels`):标签是用来连接一组对象的,比如容器组。标签可以被用来组织和选择子对象。 * 接口权限(`accessing_the_api`):端口,IP 地址和代理的防火墙规则。 * web 界面(`ux`):用户可以通过 web 界面操作 Kubernetes。 -* 命令行操作(`cli`):`kubecfg`命令。 - +* 命令行操作(`cli`):`kubectl`命令。 ## 节点 + 在 `Kubernetes` 中,节点是实际工作的点,节点可以是虚拟机或者物理机器,依赖于一个集群环境。每个节点都有一些必要的服务以运行容器组,并且它们都可以通过主节点来管理。必要服务包括 Docker,kubelet 和代理服务。 ### 容器状态 From 5634eb2fdace402ad4e559528fff963845d267fd Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 10 Mar 2020 14:08:20 +0800 Subject: [PATCH 058/201] Update aliyun customer case Signed-off-by: Kang HuaiShuai --- cloud/alicloud.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/alicloud.md b/cloud/alicloud.md index 97fbf28c4..4abbf6c10 100644 --- a/cloud/alicloud.md +++ b/cloud/alicloud.md @@ -4,7 +4,7 @@ [阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 创立于 2009 年,是中国较早的云计算平台。阿里云致力于提供安全、可靠的计算和数据处理能力。 -[阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 的客户群体中,活跃着微博、知乎、魅族、小咖秀等一大批明星互联网公司。在天猫双 11 全球狂欢节等极富挑战的应用场景中,阿里云保持着良好的运行纪录。 +[阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 的客户群体中,活跃着微博、虎牙、魅族、优酷等一大批明星互联网公司。在天猫双 11 全球狂欢节等极富挑战的应用场景中,阿里云保持着良好的运行纪录。 [阿里云容器服务 Kubernetes 版 ACK](https://www.aliyun.com/product/kubernetes?source=5176.11533457&userCode=8lx5zmtu&type=copy) 提供了高性能、可伸缩的容器应用管理服务,支持在一组云服务器上通过 Docker 容器来进行应用生命周期管理。容器服务极大简化了用户对容器管理集群的搭建工作,无缝整合了阿里云虚拟化、存储、网络和安全能力。容器服务提供了多种应用发布方式和流水线般的持续交付能力,原生支持微服务架构,助力用户无缝上云和跨云管理。 From d8e5cfe097bea252c69cefebfe44e50c4b46401a Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 10 Mar 2020 14:24:46 +0800 Subject: [PATCH 059/201] Update install Signed-off-by: Kang HuaiShuai --- install/fedora.md | 9 +++++++-- install/raspberry-pi.md | 1 + install/ubuntu.md | 3 +-- install/windows.md | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/install/fedora.md b/install/fedora.md index f415b234e..fbc4d0442 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -8,9 +8,8 @@ Docker CE 支持以下版本的 [Fedora](https://getfedora.org/) 操作系统: -* 28 -* 29 * 30 +* 31 ### 卸载旧版本 @@ -90,6 +89,12 @@ docker-ce.x86_64 18.06.1.ce-3.fc28 docker-ce-stable $ sudo dnf -y install docker-ce-18.06.1.ce ``` +由于 Fedora 31 默认启用了 **Cgroupv2**,暂时 Docker 与 Cgroupv2 不兼容,请执行以下命令切换到 **Cgroupv1** 并重启计算机: + +```bash +$ sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" +``` + ## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index d59ee127b..c3a29be11 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -8,6 +8,7 @@ Docker CE 不仅支持 `x86_64` 架构的计算机,同时也支持 `ARM` 架 Docker CE 支持以下版本的 [Raspbian](https://www.raspberrypi.org/downloads/raspbian/) 操作系统: +* Raspbian Buster * Raspbian Stretch *注:* `Raspbian` 是树莓派的开发与维护机构 [树莓派基金会](https://www.raspberrypi.org/) 推荐用于树莓派的首选系统,其基于 `Debian`。 diff --git a/install/ubuntu.md b/install/ubuntu.md index ec9469dd7..804048f6d 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -8,8 +8,7 @@ Docker CE 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: -* Disco 19.04 -* Cosmic 18.10 +* Eoan 19.10 * Bionic 18.04 (LTS) * Xenial 16.04 (LTS) diff --git a/install/windows.md b/install/windows.md index e0d4ed8dd..841fe4a56 100644 --- a/install/windows.md +++ b/install/windows.md @@ -12,7 +12,7 @@ ## 运行 -在 Windows 搜索栏输入 Docker 点击 Docker for Windows 开始运行。 +在 Windows 搜索栏输入 **Docker** 点击 **Docker Desktop** 开始运行。 ![](_images/install-win-docker-app-search.png) From e4a68ea7e43ad52e18f5c86e7c2d667a75d251aa Mon Sep 17 00:00:00 2001 From: Touko Date: Thu, 12 Mar 2020 14:23:20 +0800 Subject: [PATCH 060/201] Fix issue #440 http://mirrors.ustc.edu.cn/help/docker-ce.html#id7 --- install/centos.md | 1 + 1 file changed, 1 insertion(+) diff --git a/install/centos.md b/install/centos.md index c368cae3c..65a2bf06c 100644 --- a/install/centos.md +++ b/install/centos.md @@ -43,6 +43,7 @@ $ sudo yum install -y yum-utils \ $ sudo yum-config-manager \ --add-repo \ https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo +$ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo # 官方源 From fced7854ee014f0772cfd456e42ddf101e676133 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 12 Mar 2020 14:47:09 +0800 Subject: [PATCH 061/201] Fixed #440 on fedora Signed-off-by: Kang HuaiShuai --- install/centos.md | 2 +- install/fedora.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/install/centos.md b/install/centos.md index 65a2bf06c..cdf8831b2 100644 --- a/install/centos.md +++ b/install/centos.md @@ -43,8 +43,8 @@ $ sudo yum install -y yum-utils \ $ sudo yum-config-manager \ --add-repo \ https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo -$ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo +$ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo # 官方源 # $ sudo yum-config-manager \ diff --git a/install/fedora.md b/install/fedora.md index fbc4d0442..384dfd696 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -45,6 +45,7 @@ $ sudo dnf config-manager \ --add-repo \ https://mirrors.ustc.edu.cn/docker-ce/linux/fedora/docker-ce.repo +$ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo # 官方源 # $ sudo dnf config-manager \ From c887661c0889364445373cca1a024593b33c6d03 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 12 Mar 2020 14:50:34 +0800 Subject: [PATCH 062/201] Add docker roadmap Signed-off-by: Kang HuaiShuai --- appendix/resources.md | 1 + 1 file changed, 1 insertion(+) diff --git a/appendix/resources.md b/appendix/resources.md index 199d26865..9694d0495 100644 --- a/appendix/resources.md +++ b/appendix/resources.md @@ -7,6 +7,7 @@ * Docker 官方文档:https://docs.docker.com/ * Docker Hub:https://hub.docker.com * Docker 的源代码仓库:https://github.com/moby/moby +* Docker 路线图 https://github.com/docker/roadmap/projects * Docker 发布版本历史:https://docs.docker.com/release-notes/ * Docker 常见问题:https://docs.docker.com/engine/faq/ * Docker 远端应用 API:https://docs.docker.com/develop/sdk/ From e38ea82f379fd653554328e602400b1592f35e98 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 12 Mar 2020 15:04:21 +0800 Subject: [PATCH 063/201] remove github actions files on gitbook dist Signed-off-by: Kang HuaiShuai --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e98d6bbb9..923e08ba9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ after_success: - docker push dockerpracticesig/docker_practice - cd _book +- rm -rf .github/workflows - git init - git remote add origin "$DEPLOY_REPO" - git add . From bd74c85bb792db81fd1dd6c25ec191e2b4e031e6 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Thu, 12 Mar 2020 15:07:44 +0800 Subject: [PATCH 064/201] gitbook dist commit message include main repo sha Signed-off-by: Kang HuaiShuai --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 923e08ba9..fb2dc2e5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,7 @@ after_success: - git remote add origin "$DEPLOY_REPO" - git add . - COMMIT=`date "+%F %T"` -- git commit -m "Travis CI Site updated $COMMIT" +- git commit -m "Travis CI Site updated $COMMIT yeasy/docker_practice@${TRAVIS_COMMIT}" - git push -f origin master:"$DEPLOY_BRANCH" env: From 44fdf58ba58b2c44cd2772a00df023841111cbac Mon Sep 17 00:00:00 2001 From: "bob.liu" Date: Tue, 31 Mar 2020 18:23:17 +0800 Subject: [PATCH 065/201] Correct the wrong word --- cases/os/alpine.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cases/os/alpine.md b/cases/os/alpine.md index 6a1de447e..0a36fc12e 100644 --- a/cases/os/alpine.md +++ b/cases/os/alpine.md @@ -2,7 +2,7 @@ ## 简介 -![Apline Linux 操作系统](_images/alpinelinux-logo.png) +![Alpine Linux 操作系统](_images/alpinelinux-logo.png) `Alpine` 操作系统是一个面向安全的轻型 `Linux` 发行版。它不同于通常 `Linux` 发行版,`Alpine` 采用了 `musl libc` 和 `busybox` 以减小系统的体积和运行时资源消耗,但功能上比 `busybox` 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,`Alpine` 还提供了自己的包管理工具 `apk`,可以通过 `https://pkgs.alpinelinux.org/packages` 网站上查询包信息,也可以直接通过 `apk` 命令直接查询和安装各种软件。 From a691aa607aaa6b870f25cb6336c1721f193c7b3c Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Sat, 4 Apr 2020 22:54:32 +0800 Subject: [PATCH 066/201] remove azk8s.cn mirror Signed-off-by: Kang HuaiShuai --- .github/workflows/check-link.yml | 1 + cloud/README.md | 2 +- install/mirror.md | 22 ++++++++-------------- kubernetes/setup/docker-desktop.md | 4 +--- kubernetes/setup/kubeadm.md | 2 +- machine/usage.md | 4 ++-- repository/registry.md | 2 +- 7 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index b1aa12e39..42fb287ff 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -39,6 +39,7 @@ jobs: "mirrors.ustc.edu.cn",\ "docs.docker.com",\ "dockerhub.azk8s.cn",\ + "mirror.ccs.tencentyun.com",\ "vuepress.mirror.docker-practice.com",\ "mc.qcloudimg.com/static/img",\ "www.daocloud.io/mirror",\ diff --git a/cloud/README.md b/cloud/README.md index 471656ef9..6cc5824e3 100644 --- a/cloud/README.md +++ b/cloud/README.md @@ -2,4 +2,4 @@ Docker 目前已经得到了众多公有云平台的支持,并成为除虚拟机之外的核心云业务。 -除了 AWS、Google、Azure 等,国内的各大公有云厂商,基本上都同时支持了虚拟机服务和基于 Kubernetes 的容器云业务。有的还推出了其他服务,例如 [容器实例服务](https://cloud.tencent.com/act/cps/redirect?redirect=10230&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上快捷、灵活的部署 Docker 容器。[容器镜像服务](https://cloud.tencent.com/act/cps/redirect?redirect=11588&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上享有安全高效的镜像托管、分发等服务。 +除了 AWS、Google、Azure 等,国内的各大公有云厂商,基本上都同时支持了虚拟机服务和基于 Kubernetes 的容器云业务。有的还推出了其他服务,例如 [容器镜像服务](https://cloud.tencent.com/act/cps/redirect?redirect=11588&cps_key=3a5255852d5db99dcd5da4c72f05df61) 让用户在云上享有安全高效的镜像托管、分发等服务。 diff --git a/install/mirror.md b/install/mirror.md index 8cfb8fba2..f2937d7c6 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -2,15 +2,14 @@ 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如: -* [Azure 中国镜像 `https://dockerhub.azk8s.cn`](https://github.com/Azure/container-service-for-azure-china/blob/master/aks/README.md#22-container-registry-proxy) -* [阿里云加速器(需登录账号获取)](https://cr.console.aliyun.com/cn-hangzhou/mirrors) * [网易云加速器 `https://hub-mirror.c.163.com`](https://www.163yun.com/help/documents/56918246390157312) +* [阿里云加速器(需登录账号获取)](https://cr.console.aliyun.com/cn-hangzhou/mirrors) > 由于镜像服务可能出现宕机,建议同时配置多个镜像。各个镜像站测试结果请到 [docker-practice/docker-registry-cn-mirror-test](https://github.com/docker-practice/docker-registry-cn-mirror-test/actions) 查看。 > 国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考官方文档。 -本节我们以 Azure 中国镜像 `https://dockerhub.azk8s.cn` 为例进行介绍。 +本节我们以 [网易云](https://www.163yun.com/) 镜像服务 `https://hub-mirror.c.163.com` 为例进行介绍。 ## Ubuntu 16.04+、Debian 8+、CentOS 7 @@ -19,7 +18,6 @@ ```json { "registry-mirrors": [ - "https://dockerhub.azk8s.cn", "https://hub-mirror.c.163.com" ] } @@ -34,7 +32,7 @@ $ sudo systemctl daemon-reload $ sudo systemctl restart docker ``` ->注意:如果您之前查看旧教程,修改了 `docker.service` 文件内容,请去掉您添加的内容(`--registry-mirror=https://dockerhub.azk8s.cn`)。 +>注意:如果您之前查看旧教程,修改了 `docker.service` 文件内容,请去掉您添加的内容(`--registry-mirror=https://hub-mirror.c.163.com`)。 ## Windows 10 @@ -43,7 +41,6 @@ $ sudo systemctl restart docker ```json { "registry-mirrors": [ - "https://dockerhub.azk8s.cn", "https://hub-mirror.c.163.com" ] } @@ -56,7 +53,6 @@ $ sudo systemctl restart docker ```json { "registry-mirrors": [ - "https://dockerhub.azk8s.cn", "https://hub-mirror.c.163.com" ] } @@ -68,15 +64,13 @@ $ sudo systemctl restart docker ```bash Registry Mirrors: - https://dockerhub.azk8s.cn/ + https://hub-mirror.c.163.com/ ``` -## gcr.io 镜像 +## 云服务商 -国内无法直接获取 `gcr.io/*` 镜像,我们可以将 `gcr.io//:` 替换为 `gcr.azk8s.cn//:` ,例如 +某些云服务商提供了仅供内部访问的镜像服务,当您的 Docker 运行在云平台时可以选择它们。 -```bash -# $ docker pull gcr.io/google_containers/hyperkube-amd64:v1.9.2 +* [Azure 中国镜像 `https://dockerhub.azk8s.cn`](https://github.com/Azure/container-service-for-azure-china/blob/master/aks/README.md#22-container-registry-proxy) -$ docker pull gcr.azk8s.cn/google_containers/hyperkube-amd64:v1.9.2 -``` +* [腾讯云 `https://mirror.ccs.tencentyun.com`](https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61) diff --git a/kubernetes/setup/docker-desktop.md b/kubernetes/setup/docker-desktop.md index 20040087c..a26c50ae8 100644 --- a/kubernetes/setup/docker-desktop.md +++ b/kubernetes/setup/docker-desktop.md @@ -4,9 +4,7 @@ ## 获取 `k8s.gcr.io` 镜像 -我们可以先从国内镜像 `gcr.azk8s.cn` 拉取镜像,再通过 `$ docker tag` 命令重新将镜像标记为 `k8s.gcr.io` 镜像。 - -开源项目 [AliyunContainerService/k8s-for-docker-desktop](https://github.com/AliyunContainerService/k8s-for-docker-desktop) 使用 `powershell` 或 `shell` 脚本简化了以上步骤,建议读者使用该开源项目获取 `k8s.gcr.io` 镜像。 +由于国内拉取不到 `k8s.gcr.io` 镜像,我们可以使用开源项目 [AliyunContainerService/k8s-for-docker-desktop](https://github.com/AliyunContainerService/k8s-for-docker-desktop) 来获取所需的镜像。 ## 启用 Kubernetes diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md index e764c74ae..828d566d1 100644 --- a/kubernetes/setup/kubeadm.md +++ b/kubernetes/setup/kubeadm.md @@ -77,7 +77,7 @@ $ sudo systemctl daemon-reload ### master ```bash -$ sudo kubeadm init --image-repository gcr.azk8s.cn/google-containers \ +$ sudo kubeadm init --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --pod-network-cidr 10.244.0.0/16 \ --v 5 \ --ignore-preflight-errors=all diff --git a/machine/usage.md b/machine/usage.md index f9b90d416..a790f8ce4 100644 --- a/machine/usage.md +++ b/machine/usage.md @@ -16,7 +16,7 @@ $ docker-machine create -d virtualbox test `--engine-opt dns=114.114.114.114` 配置 Docker 的默认 DNS -`--engine-registry-mirror https://dockerhub.azk8s.cn` 配置 Docker 的仓库镜像 +`--engine-registry-mirror https://hub-mirror.c.163.com` 配置 Docker 的仓库镜像 `--virtualbox-memory 2048` 配置主机内存 @@ -37,7 +37,7 @@ $ docker-machine create \ -d xhyve \ # --xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso \ --engine-opt dns=114.114.114.114 \ - --engine-registry-mirror https://dockerhub.azk8s.cn \ + --engine-registry-mirror https://hub-mirror.c.163.com \ --xhyve-memory-size 2048 \ --xhyve-rawdisk \ --xhyve-cpu-count 2 \ diff --git a/repository/registry.md b/repository/registry.md index 433262ab0..82bf695f6 100644 --- a/repository/registry.md +++ b/repository/registry.md @@ -104,7 +104,7 @@ REPOSITORY TAG IMAGE ID CREAT ```json { "registry-mirror": [ - "https://dockerhub.azk8s.cn" + "https://hub-mirror.c.163.com" ], "insecure-registries": [ "192.168.199.100:5000" From e0797515d3d9bab51020a8e432e8f86a3919b388 Mon Sep 17 00:00:00 2001 From: Kang HuaiShuai Date: Tue, 7 Apr 2020 09:18:40 +0800 Subject: [PATCH 067/201] Update buildx image Signed-off-by: Kang HuaiShuai --- buildx/multi-arch-images.md | 7 +++++-- compose/compose_file.md | 1 + install/mirror.md | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/buildx/multi-arch-images.md b/buildx/multi-arch-images.md index 4a6a2c02e..1bc8b96e4 100644 --- a/buildx/multi-arch-images.md +++ b/buildx/multi-arch-images.md @@ -12,10 +12,13 @@ Docker for Linux 不支持构建 `arm` 架构镜像,我们可以运行一个 $ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3 ``` -由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。 +由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。同时由于国内拉取镜像较缓慢,我们可以使用配置了 [镜像加速地址](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) 的 [`dockerpracticesig/buildkit:master`](https://github.com/docker-practice/buildx) 镜像替换官方镜像。 ```bash -$ docker buildx create --name mybuilder --driver docker-container +# 适用于国内环境 +$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master + +# $ docker buildx create --name mybuilder --driver docker-container $ docker buildx use mybuilder ``` diff --git a/compose/compose_file.md b/compose/compose_file.md index f99fb16b3..1b866c0cf 100644 --- a/compose/compose_file.md +++ b/compose/compose_file.md @@ -576,3 +576,4 @@ MONGO_VERSION=3.6 ## 参考资料 * [官方文档](https://docs.docker.com/compose/compose-file/) +* [awesome-compose](https://github.com/docker/awesome-compose) diff --git a/install/mirror.md b/install/mirror.md index f2937d7c6..6058b0c67 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -67,6 +67,20 @@ Registry Mirrors: https://hub-mirror.c.163.com/ ``` +## `k8s.gcr.io` 镜像 + +可以登录 [阿里云 容器镜像服务](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu&type=copy) **镜像中心** -> **镜像搜索** 查找。 + +例如 `k8s.gcr.io/coredns:1.6.7` 镜像可以用 `registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7` 代替。 + +一般情况下有如下对应关系: + +```bash +# $ docker pull k8s.gcr.io/xxx + +$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/xxx +``` + ## 云服务商 某些云服务商提供了仅供内部访问的镜像服务,当您的 Docker 运行在云平台时可以选择它们。 From 34b6b617b9792b3553c8c72d694f9f1ad9fd0211 Mon Sep 17 00:00:00 2001 From: Daiwj Date: Sun, 12 Apr 2020 19:13:38 +0800 Subject: [PATCH 068/201] =?UTF-8?q?docker=E9=95=9C=E5=83=8F=E7=9A=84?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E5=92=8C=E5=AF=BC=E5=87=BA=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=E7=AB=A0=E8=8A=82=E5=90=8D=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- image/other.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/other.md b/image/other.md index 6029143b2..f139f5d20 100644 --- a/image/other.md +++ b/image/other.md @@ -37,7 +37,7 @@ IMAGE CREATED CREATED BY SIZE f477a6e18e98 About a minute ago 214.9 MB Imported from http://download.openvz.org/template/precreated/ubuntu-16.04-x86_64.tar.gz ``` -## `docker save` 和 `docker load` +## Docker 镜像的导入和导出 `docker save` 和 `docker load` Docker 还提供了 `docker save` 和 `docker load` 命令,用以将镜像保存为一个文件,然后传输到另一个位置上,再加载进来。这是在没有 Docker Registry 时的做法,现在已经不推荐,镜像迁移应该直接使用 Docker Registry,无论是直接使用 Docker Hub 还是使用内网私有 Registry 都可以。 From ff28d7219d45c34fda390b7429336faccddadcf2 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 26 Apr 2020 09:42:59 +0800 Subject: [PATCH 069/201] Recommit (#446) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加离线部署docker和离线部署minio实践 Signed-off-by: Kang Huaishuai Co-authored-by: Daiwj --- .vuepress/config.js | 2 + SUMMARY.md | 2 + appendix/repo/minio.md | 62 +++++ install/_images/image-20200412202617411.png | Bin 0 -> 120599 bytes install/offline.md | 249 ++++++++++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 appendix/repo/minio.md create mode 100644 install/_images/image-20200412202617411.png create mode 100644 install/offline.md diff --git a/.vuepress/config.js b/.vuepress/config.js index b3c3bdf38..ac3b2bed0 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -140,6 +140,7 @@ module.exports = { 'fedora', 'centos', 'raspberry-pi', + 'offline', 'mac', 'windows', 'mirror', @@ -376,6 +377,7 @@ module.exports = { 'appendix/repo/wordpress', 'appendix/repo/mongodb', 'appendix/repo/redis', + 'appendix/repo/minio', ], }, { diff --git a/SUMMARY.md b/SUMMARY.md index 2f63f24d0..c655207f4 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -16,6 +16,7 @@ * [Fedora](install/fedora.md) * [CentOS](install/centos.md) * [Raspberry Pi](install/raspberry-pi.md) + * [Linux 离线安装](install/offline.md) * [macOS](install/mac.md) * [Windows 10](install/windows.md) * [镜像加速器](install/mirror.md) @@ -161,6 +162,7 @@ * [WordPress](appendix/repo/wordpress.md) * [MongoDB](appendix/repo/mongodb.md) * [Redis](appendix/repo/redis.md) + * [Minio](appendix/repo/minio.md) * [附录三:Docker 命令查询](appendix/command/README.md) * [客户端命令 - docker](appendix/command/docker.md) * [服务端命令 - dockerd](appendix/command/dockerd.md) diff --git a/appendix/repo/minio.md b/appendix/repo/minio.md new file mode 100644 index 000000000..c36d02d5d --- /dev/null +++ b/appendix/repo/minio.md @@ -0,0 +1,62 @@ +# minio +[TOC] +MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。 + +MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。 + +[官方文档](https://docs.min.io/) + +## 简单使用 + +测试、开发环境下不考虑数据存储的情况下可以使用下面的命令快速开启服务。 + +```bash +docker pull minio/minio +docker run -p 9000:9000 minio/minio server /data +``` + + + +## 离线部署 + +许多生产环境是一般是没有公网资源的,这就需要从有公网资源的服务器上把镜像导出,然后导入到需要运行镜像的内网服务器。 + +### 导出镜像 + +在有公网资源的服务器上下载好`minio/minio`镜像 + +```bash +docker save -o minio.tar minio/minio:latest +``` + + + +### 导入镜像 + +把压缩文件复制到内网服务器上,使用下面的命令导入镜像 + +```bash +docker load minio.tar +``` + +### 运行 minio + +- 把/mnt/data 改成要替换的数据目录 +- 替换 MINIO_ACCESS_KEY +- 替换 MINIO_SECRET_KEY +- 替换 name,minio1(可选) +- 如果9000端口冲突,替换端口前面的如:9009:9000 + +```bash +sudo docker run -d -p 9000:9000 --name minio1 \ + -e "MINIO_ACCESS_KEY=改成自己需要的" \ + -e "MINIO_SECRET_KEY=改成自己需要的" \ + -v /mnt/data:/data \ + --restart=always \ + minio/minio server /data +``` + +### 访问 web 管理页面 + +http://x.x.x.x:9000/minio/ + diff --git a/install/_images/image-20200412202617411.png b/install/_images/image-20200412202617411.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5caf25253f5fcf9dfa0dfc08dc290fa187196b GIT binary patch literal 120599 zcmeFZWmuG77e0z~gQS3jBHb;GAR#RnKb6w{HTn|s|z4qGoTI=3xugwQlWmz0da!dpS1e_Og&(#nRP!JIikU7y& z;dh!J(vBe@U{+d5NvXb&lA=*{asXP{nj;{{eTa!g(}?aN>Ds(%K9R(F_n7V^+yzmt zG~=9}`BBC@0yCQYDg66dj%@Gc)HNMnN_+({RgiSN36w7P_j&vNV*@*hZT=TL_jmK> zgI@bz{00ZE2M1Dw-ROBX^${3VrVyW@vLZ>)i|akuSRH)-AJTUh)a0F|hvK?Ui2)s{m675(3d1r^f;z(I1XpkC!+ix7i|m5*aUT z64B%QcJ(rrG!rFrj_Vr}&z$hL4?L`?;UCbCB`!n}kTH|k6z}=5x;cofx&IjW;^~vdw^>b*XeH18KJ1V&ze1D`exjh6kalPoo z@vi;>-UlN_%;@oC)|1#>E}k8ZtCjL6hY!#6MW?~{o1H)XN#aE*y#Vxscxh#fjBBb#fStt5hFuTuM*Q+Lf0Sp zcq7629--WrYsp{Z6UIAZL2Vq!TS-;ynzsh&1mpffj`$BzWuFN@#Ta}Ovcz16Yyb92 z0$Zk4ffH5C9|Qf(0X}i&v))gr*;r&!vG{~eL0{4l7_mPF5~LHo$NP{zF^ro3fH{CU z!$%eA1j_|c2+JVoGNW-ApBJ+!u(=goF<{+cPC`?o`FTFbL#4}38qXb~RKx;!W3l8%3mMiAQZsOLStP6*K>b2+xrP?yJ|-Ad0x zzetLiIX)l{3gG(o)YO|R@&PW849Et=$|Z2d9}5zUsQ*CL7HZOL2G#}?aY63&wRIY+ zm-UqgPI23c))0H$^P&)bbK~E>y!F&4nR1YnG(@4jxXteC-q-4-2FIH^lewo<5n7!T zt0@Ox-TB2RjNX^FQn#gjU2Kh562IS#jPr)>YZAWf65$bs`8%05t2UfAo;Ku{LHPHuirdT7-bNQd@N^`eVXm0#sfu!-h)ymC_*03MoaaGI8oIn zd%yGkAoBcHF*57HOA*FHqWk77>j*g^PH{)!@;Tct4ZyF*ZMQY8kxn0;-am~dQtDOw zNcSy9mjOUGK@XDJuI7EIt2LwKS?*Hel5oNWwHYma^`6_4n~K{up_&`O&F~7l1G-=O6e zV@A%o2V|j6ogSU>xdpkUxpK~Fz_g8bvCW#2FGX1?233n{ z<>*0CgG_dH0f1YreFRKa)Tha^Ny&51bLceYMCY>pQt1*8J0F!DwGZ1G$DV8jJ0S=f zI@l}Rj1}p=RnG7{C(=$swq+0bQEc(!dv6u~cHT>Ch8<=P|^GfKIi~tsApMZ^k zm#C42@7y)zvDb#5KrPo0=c0q}qU2!P(Bs9-v6bSSNV=|y-lJIJiQZZ36hQC1MSt3^$+fs?j#;(9z7n?o&ZnLBgm2Rq5TonarvRn z`q+BN>FN3WvT(PW*=uc_A}(>^7Czt28>ZXk+nC!3q)^0n_fi5J(~Xt}ThX31JiAUm zGsf@7Tp+vVd@lYaUq09)Gaz6KPoS=(->@!{XXU7&#ib@C)}j_@9=2I738X#bKMXuX3OOMy)^_nI z?_CM~mKQ6>VZtF8>#y`)*;4U)FD`JhqKi=H!^8)(hj@ebg9;@qwV#C(*FI}Rov=tyK!2^vi{LdKTxuK!&>p|_x~(A~A# zX%0*58CEDtAmSl+uz6!_7{*QDsg5cnvnbrwqv{Y!O!l7tV~|s_bAgi>TZFE!ZQw5E z?Z<@}85V(3@7SG`t7GPV=D`BkL}KA&DV6SO4RBG{(r#r22AbKygoLeKtWoN#=%zK_ z)_NabM_r#&WD2;D_HoPiZg$7+D|At<`}y(E9PdP+#)v*_BLPH@(+$$(j06 zSM+^{WH6RRT=!c0c6AN1R_rrtTe~+OK0CN5R@QFb^_5^cYA$LyB|vyqo-9W?XWxx& z8dTrkPy`gPs=P+HR*8_2B z?&9;)o0X--nx!>GxLR@Q=PrKZx2b6f;sWD^*!mZ*oVh>yoyx$r~No85D*3j3z z80Yn5yd6GmPYo7MR7yIp9@hI9;ZK`M%i;UtyZKW7-3ZLA-)x`@6roi+sv9zsUK3+y zwg=u@37-nTCG=%z5T+E?^W(cZZGABi4ag%>wi8woGH~=fQiLTOvOk+FtYoqXZj5tT z6eo3tK`w@meMql4^c%K(4)r7Sh7uH%%3PmkL9lbvxRm|{7uCz)7Ow0i`hxn z0hn$V=xQhB2J2E~(XsyZS?=aQNUe5l$pUV}yg0s~qXnn0s&}y0=EZzyqXTSxE~zf< z9N{W`E2F=?Lbf2n+E3uRN!pf0jBibF{OalT;f=}QK_7#TN^>}oNRAkrSMFiaa{c;o zbk;)Fq!Ft(*OA(R(+Xgjy24MRh2P!hT4hq)tIM=gW&wRsv3dST`C>lc9J1foCDlpo z(|yf(SiTi~l=n6*AtUK|0>5^qf`>!u~ikq?MDIC{tfI1kB<=0CAu(O#-)^Ii2d=$AM4+< zHK!~0V`iD|b)qM&r?gY*rDs^o@Oiv|@9*$7I+}1VI(l(?#B~4O@Tp0zN?KI^BLsaF z9nNATRF|?Pqf@*YWmH{a=Et{i7K`C1r{j!(KtlK9=iUpoCkF@!5(qDzKhto(w>z(= zs;~71b`haS^8%j{Wy4g0=E=LjP$sjUC|yz`#zF(@#=Vb1_itRNEHbmqOdGNqET}xG zST%U?7(AJkJ3ctm11~!ilj9X+lefb2T^r@;`bb~!N0IlaWwd=RyH9|K(J!4&gsz6+ zkx+dsL;nQ*2|LEM8`@*%{pv}>o!Zx;-c9TTXo%=E{s@TZtVt4MvPz^XsUp)~Y>CzG z|8x7VXEbGsh|oR_yota6^7p6vluK*1L5+)yFM)9H-(NHn$hKez&CFYPYyZ6X^Hm>* z1b*Fh?)dwkZ~ptDL@x$Da_$^U#mljaM9KSJ$) zf%#K6f5P7XYwu+j{l`-zSKwru{5;q)E0j?IyCLY)zwMCa(GN!`1#xa>Z6Pu`N917xm_Iqzy*Q2tj{%8$q+Ws`0fkwDWQol(3PfN!2 z$moc13Q?YaY+23(-ZGJ|ATQ1z#abtjGb;I*|F6uUf14T&$)Dl#Um*SeSO4cVl%$vr z&B_g7P)W62cr~Bf__IW1xX7cE&nT=O|LrbzWNDOSM?cs2&L}9{|H*=l$Iz$vl~kaN zzejiY3@2&(-w#OozCH%}0m}el{J(>=en29a;7@4!fASu`zr>97$@2c)?LH5)Ys<-E zUJlexQC+vkS|r+n#=q4W9eJWuVrgj6XLD~+M3!yt<8N-B=}Fm2BWjx9`9xYa)A#+c z(NRPB4Bsó|GQOc>9zFi<<(#wA^`I{jb-=G(1)XaJWY7A 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
b34EhV0ai|0=hR# zlT@UsFN|T!Gz`@>X{au+4rxL=P{CJ24PQ6WO&=HkM4E77SR=<^|L6y}SRuY>(;2&X zcGP_C1fa8v6R%-aUVO}Js*;pJXb*HyS(m;S&M6{%^78VQi-sMm^IA%7b`0V00UFDR z7S;|O*q^=quk*&aa3F=#YxqxZY$?M7777V{AP?LzTOS%48bE-rnT$0syPLXgi?nU- zJid_*_}6XM-&*^3c_1rstelDaTu4e1$^z8vd%)9y;x;4JmGnd1749 zecoKfjcJ5o-cB^;O!XeG4t$54g;Zox%*}XDe_gGZdLji6ly9t+WS|{^ii*&z;ir?5 zl1jrpCsyxGzm(*|jfREbA{XYA3o*{%&X>BcZ;$!Gl?E9*JBLzZtxz*_djm8r5W@;JHfG3gQasx`*68t(##>~- zZ+-nbZE-+7RDH-I`FZ4yI9a;ulCxJ6F_>g_lIAi?b>a^#FhLS=cn$MR#jl$+PL4R)umj@o6 z9*F6pG8aM9&bCS7h6)e|fOr0rXQV4Hik;>%d$^AN)z(f~@0WCxtsg6wL-c&BRZ5C- zw+01IWM!ofn@s_nj1>PBB8NVG%{?~A?nqdNBU*JWI9os4^;>0at%K&mn$_d2l&PSW zOcGqGN~(Ze+1T*l@x$mZWg_5pQE_n|c*M&2KVG-Fh~Z?0v4L$xJc=I`xfBn(ubHvp zR@*?*-E+QWB>htMr@XxUZ7TA=gdk3%KqY}r91}Qcl`n|b zQ({)Y@Az8wr-_YnGfIxUspWwNrr+2}HV9Hry5@9}=AjI}s0i)uO+zBb5VZ~(KK|6Jw>px@~4|h_Hy7~Aa;z?K4 z9kk++tsEmOD(E9mCA)jUbn&d7b`bbx=vhHQ!5q!Uq=&>1bth>Dxy8X=?2=Uz<;d1Y z{(?IyDihv!IXIf@5T{SylB0Q46O>pG_%p*bm!->$##Z$x5USt;;qy5(w@4w3&NCsJ zHY@C@UWikJ;7;0d1}KXOu0D&UJ7lAL?@-2oy_{!%=Z-+3AWlTTt=)?T(o8Nq(cCB*Yk4%(io_LL2!nJ=;Ph%&(67eE(ER1xZKC*5c1?PM8S= z24k!M>@DC7$>`^&Z&b&HDl`?Y@fC!XJV#6hgUlq~TaUGnS*vkU#(&{T^mOU?&57*NAoL}LzL}Ux+`Q==ns6p{nGU|%1JfWx8 zRMLxS7mY$KJ1aSS;;?`FcHQ*qYhiwV{`<3uwn?TYR@8qPLdFM~Y404Xf+U~nv`sx( z`(R&M0w%9KzfS=&2qICe-BL`E6N<5dxT{89^*#0d@*l!38$ibaMm`POX^of`3lT?^ zFh?{%FBiewN*APmWM5}aHWL(5(e9uB7Ko-)u*AjxXm*fk@XQBw>{eApAAa9zIuP$cQdsKKc*cK zID2VJ<8J^~QpgZ?MEmqJJ(9j~&I)X9nVgWR1-m%UQ$hSAriKd(kOB=ng;YLn0In3& zZjO0>ED^@#DKv~5u)R=O2owPk=DB=LkE?oPC6?2=&6Njwdw96aATHhH{)-B%yD>G@ z_#;o`R?gQ-*E#mEfGj#l?GK`W&%bNW9H%lWAnB+1<4w(1&Ns<*3ZT!;Mn&xU4g5e-Tww}z3Es_F zNGnlu5t^o9;j|*|QuVxH<_8vQ{N=LouBE$8vme6=X8tp09;My?#y6kReTAQh+9PVPJ6|~OH-G}L++K)aTrKGDT3q9*!Oh`E0ug$M`zVXHN34Oq;B%l7fDi@YC zE!Zj!f*H)VM9!S~20?oJ)8uc?2D+)^7g&X|O0vBT@*%i-j+ z?Vbtt-+iHMY+o;E56kmwX!hSamvpv_wEuSL{b#8@^Up&yuB@D<_^LmHbK>&UtwxDf zTh&P=XF_jV$crv(iu-gfkjj?vKqyb*iDUX_XT^0``FGH3?U&>hy;^101MO;n9Ext2 z?uaLR%iEIFRkZH2I2?cf{`~;8Ra94-nKPxNGLX%|Ni-vBzwv2p6grBkyUe~mH}|!n zzOL6ak1914?OV|39wDX1N<7(iKFjSH_JBeY%2u4CB;`TTUh3L|Gnwu#*jJ!gDKh%S z74Kep)n>xOo^R!T?yB*vtOotzlH0%~l!Mahf-~g-nSDgVfyVv&_k~Qtgul;}x;o%S zu+T)WX6nf0f!BSpSQ)ok0X6PA)%|=R_ClX{%@2p|Heoi~M?}eIPo6xf?B?#w-RKI| zJ)wrlJoLLylmGQ$EM#tZ4!dJ-NO|G@>PHDc z7KFxG2Tj?aH&<2Pfy<`TE+HRAJRnMVR8dheCBHX8x!k0nlP*1X6mcFX1awI~P#BVK z0f(Ost|rpl#V!D|E(WG`T4yiSp;_8|vs5FI(>E-|&a6;TwSJsra~2 zXDZ0IPJm3tLpj)n8^Z&mBUR8U-5T>=b@&<0=bH4_9dRiY;AcPI zjuG19G&}JaEjeheqp7)zYdWl&7hAV^{NisqA_I%B2#n~Bj+Km}hW`>|2owoOR{Wv=*;a*-7K0D5!`B(s(pHy&H3Nl86v&+l1=Bp`5IgCgbnNY#BwUe4hq0k4^8w zDsXVYoF}769&-$vfTkXOH{X>L%EPgiHTBO$xn;?jPP@+KU!X+mmu~klm&+uGT zJ`5E*$RQ*oWY)L^tSg}w1bH$c2zT$)e~$Hw$rv@fe*Y7#h#J`Bc<`WnD1tGRO4fy?c?a|bpn<0!Nnurq|znSKszbsxCa1KX#N>q6S{WL zR*9^J;DnAMl?+E9#ujuT#SK|_J-;R}91ZpWmuY7tH@rE9A6s}3`NU;jKaDbl-`y&( zcTok;5>tKc+BMq3T-LBaK`NMk*Z@dq4p+0{&6p>w+K-O6`+!OslB4F0$^SeSE((pN zGAy!G=C_Q6o0ASAT%x1Mf&NdXVLNdSpYcPvN+t;{BH^Cm{C9Q zQ50b)CvkCc9Z<5B*s*W+i_yr^1)Ih|Nu!_As_;0QIt#KXUzJvhKPlAT3#9e-`V8Qu z!R>R*%2a!#39mtch*6A;BN$Nu2M?=h<)8z$agqml(phcI)%m~K0hE%<833@n-}MbhFX!4`d~i zMLhv7p+MPVf(#@u%+-W?RRp^rW8();l!@(rp3Z3tY(~TcE+W_9T>06A_aAWQ3f)4F zK1Wo{#2Igq$#nSBSNPB{YCye&H9{D-=mhZnUw7bt(0Da*h?>cu(d)*_Wj#A`-Y66T z9h!m4_$c=;Win52ow;hB6e?meduS`S43SZAI)0EH2^=0+edD|r$H>D?GJ6pd832m| zXh2~D!4!*$;O1M zgZ^RZuM0GSs$wq9yAz>;XIHuRCqhd-|DuNk9+;3Iy!%h~|*QuUo`P~J-SVnc1A>M6*`WCDdH9G6~5 z3gg%qzy^rOVvT6yO?o1!G3}k6|GUkP1R`5`&4k!t|V6)=3P-(k9m~cA)Vw z40kN9n+5s~zC?b$?6?*2cYa*FI*9;9s?VSp^Zn$(XmBlaAf|b66L@JB&;ftK63BN~ z4H&C1C#cv7R~e<8`DX>lRltnG&85L;5OmKHBljKy=W*I3c(s}Af%8bv!1$NGzWoUh zd;7d*b0zt~TwtHlWAyWvT}A&Y`7a~Rh=(x z)nxwJw_v9GxL?ZhwCwzq=^quxpm3eQVh50Y=mGCVt5ra_Yr?wP$Z)dY#^ax8K35HJ z(*rG#5hL*Dod1sjK)(V|E6ZjQa_BSLk?0n_Cg8!gA^qjHJH(RY;0!M>@2!lMoAuz% zG#!vr&5d()MjcUseteV_xXyfxm9Dw<@h_JHC}|AqeD2|nyFJ-L#T3=}H<(I5cUOBq zf2ITt3wOB+Ya!4u&R_w4(F30*=a+gQ%ZayeJ7kkTFYn|Ym-LRP#8b=d(3mdZ>bqT6$!(9Z0VV<_Wo;1Zw)CUrjcezh zF~R9PI(e*31!=YdnGZ!yp8}N$J1eUR*y;gd#{BSRdJY#PIDkX+ui69sM>`_|aueA; zN=RkHanM z|GK3g&p^K{jmF9s+&`gc0ScG~rvnkW_`H1fz+Dqtl8n_`x6$ytLf~8q2PbmCf}<+Y zgybI^_-&40Bv`#5s8!4<;?*!XEF$23L~Hn)Q>4%0aY3U;b~*AVP773eLyErcB=qqPHv4GiyB;n)@cWbLVb4+T-^WV#wpcHkf(hld3jZb%g2V2KxteAWZ}*tr(Ma87J<5< z^rsFhdWXIv_)o`$j0JZBA}_cat3xe)xlLq`L%@e_W9~DsqxXu=4TX?~;OGDbTqUwu zJW}tdOMx?ka(R}c8z&vt&xzE)d z7hM3cBp0kr=yt6KtcrVRA`96HcQm2R z2k`$MptW=>^a1a`O8e&;U%_IbH;V{_vU8M0&;r%N=0V=w-Q7bX^DlRTstYa8<0Jw4 zSU^22(7&2hzj^R05~4Lgh9VEz54;LgdmKv<6)xl>!Ia>7pTD3+toM41Dwu5_^gk{9 zX>I)f%>3^~D$V6dB1I~nx22`$@lTk4$ZsMw5w&azQ?zC^>)b-6PEIM)%%6v}z?aTT zUHF|`*#74(k4^(4&|?&N26nVMpI&gigEN5n6uhy_E~SXM!mew#-|J!#08RoI8SQX{ zx1_%238FfIu$RIq3jPoH2K0~_Voi0RYHDhFstFxhD1HO87eAsJ4@ z3E{v6AXO)U_~X6#{~5@})G#<)g7CvQ4G#~;ZlQ8c!U+NVjF%7!V)WvjB-L%lwy?BI zdczt0O`817#b{imqz9JM29R^FE@z-#b!K@MeASf3OZw{dBBy}j}b4+fq z6mQIjjUNlkF{9c}uVVbThlW1o^Da9K=`Y3EXujq#5-ST24v#8~Ld%eyL1kP;URz%6 zuYOJB^!mf*shKMG)x(3;!^6s~gT}~1eAKfO2&#nQ$R~kZ0eHV(BY$)iB?)Dw+N*c3 z!0t1X?OEmhG$n`26|BaeXWW{T-)f*F5mOCJ;w*HAKvAUSQyRxFNc;6RK-}vy3>6@3 zLOwd)L|JQshrxjpr?;6T0^Uml{zR!j$G1B@b9s1p4$bB$_LO{Q>@Bcq zb^ae5%MXVP>Ua98?XF&X8;A}hn5V9=kP^E1XC1%kvZmf@5wDx*KH2F1q87j0jta}m z410HL=%BI6eNpOXq(Xh>?%v7MM(p%6hUXy%)Va*E;{Q;i4!IA@e|ce35e%$vj!~80 z=~+ohNm;$E&b}5u`+|_z{L4g>)>QFMWGGE;G+^$vz`3%&MDg>3*Vx*q}LQz=YSfD<%I!yKw9kC`TLA zt;Z6l$`>lHT6J)2MYimrc6O{{+P-YZr0-1=$aaRc&G^Bm)9Ii-Ju#D_m*IcbfSRGV zxP^5gjgiOEAqD-);#@!oJ!BAEbIkn0%<5xcE_}NXtM%?x;2K_KF*fhJ*^P)!L~3XZqjF zP}74%65{*6a3ym5ytDtXjun^;`QzsGB0^ZC-{J0fm*(gDdU<3xEp4DofBQc+wg45b z!M?8`gqgcknr!AY`}f3O!w(dmnVa*^{Z4f7%J1g&Qmw=2msj?;#j<-EU!M6Z$Tfll zE|EHN+asbBq0D>3*^NOF+xVVLs_yex$>sA~yUZdo3>wYs&^LU@Nc0yU$7la-V-Q%J z0@_gIqBne{9}lxSzo@s&R-tOZa1eZ;psq@G=-VeY5-mUtv;d0YSNRn2zYJ7{$y8;u zMy`xh>J>Dg<@@6G+8xMfFU(T3 zu&Wt_(E6N$(7jOq=d}d><`05bLwKwhP%m-L?OkL@;L$IS-YL>yfcYSQum(x}uuy$B ze|SOOPqhEup|DF{QRiKJm51XCV7G+A@y1H9xtI|U|^{aI`OH5 znaiNSY&4^OM7#65RP>Q9SieS7`e7eHfy!{4W88A*DV*nc*5ZEH1rp2p{VZYM1+$Ri z%gfvh7EjRJ{zy8?Bdu+Q6FSxldQ~v?=DSIH{?xnjbH*p9m;(d8U*nR+ z*~Jj_>#mblD9r!!jLZ4gO@}!OXdmChn30hYejv31+cJt$9ep6%wjJx!41eqs9S9q7 z+@zfIo>0tBT$NRe#Bn|<4X3J#n@$I_P6zfN6y*CG-Z#e&JioIeEG53o=S%P^ORejp zUd}UGz;l<#aOe?%+@%4k*JURqQ@_}}bcVmI3^-8qP{`Tpk$JoQ^f2k3iK6bYQg9Ny z6TDZQlVhKKaCf2p^I7~IF_nikIkotQml&9as1l_PvN`tWRhyFzg17i29-!X??RTE= zF!}vbY_PzW(69JY>K{YdC zuLK-ASnasrpHX(>FnL2@Pkd+Rz0-cbQ|cG{Au2;L;53Aoc$ogG4)^1LOJ5E)uhYlZ zg~zf^IkZT|%RAJZV^ux!jTU22DNoGnx&!Ciw{KSy{y50FS$IKOdROPuP1jID;zRcu zGJoI|#lKbh=RlfFeD~#XeUkDf&Gx%6dQM=V!LRTBeftfvmvmnEy8LJJ7ipKSUf!Qs zN;r72q4nZiiqi39MbNM9tKXA8c>e6Op3YkCl9tNGJg(m#t{=VWLvbf*g?!YX6KnL@ zw0~bU9BqkVT!jm$1hAtX_e@>?V}&Sd`mG6867l$RuB{>5$DXB$p_}jYSk?WXw@Y4a zJ*o@&L3u4QN$VA<6a&WpAh~`!S!_yUnS3i}=OzsDpmyl|sE02T|1fR6Xw)FRAezCh zC&>B;Jsf>Sg+rxo?DAjFe+siF7mO!0^eOaZRuG}HSm&_v7>vDY5EK>vl~xBo>VKEZx4xW}sW#|Z5CO6D>_~PF?P*O6|4ku(@OBS|6tc8}moH++2 z22na8Dm3P=TYV#tAuHs^Sg`l7v$;BC>eqT>1M=Y`S^iNwFJ?Cje%J^&pKu~|o7|~8 zK-v4(Tx31FU<^TH?u(^F%BD zavX-OStbwgpzT~Dl9Jn-NhPAwAGdhgy(;%UxWym8Jss6Y+l?Oc{JEmyghpe>jYu;G zd@eme$tQN5FS)4^7)}k0Tr@K25$A7dC-Px|yLw|DYFe9LD(=_zQEVf^D)Eg%-qFht zqm?ln2NN9O+YrhH`%ATu#*fQA78w7`TH-_QCB|xahk5`Klainobi7Vh0-4@#)Ljdb zuTC*R;khYj%0|Z%bsQcErpNr%SINlAYR>gf*eN@7oT!D&(a@diWdZT0H#XGY%0{EZ zv{xCyYkEde_E-zl2vKoPr6K|nOzbclq(unQz+iyixZIIVl!9gV?4|G2$J{(|;`Es_ zV)tJkmhXJchsdsKk`|hppSVk634=G{hm85Maqg9WJ=<;QyEQ5?aF-DUM`4ApG!e@k zzpUz5N1^Ak?}rfhn&f?ieR@LR>a2x_X4e1-RfpEs;fk8FNC z@naMOmI-11?RMX!5OP!ybgk|pvG64KA9sugeRC>Dj~kZ!zQ)-@FmX3gyj+o-_tRLPGZaBaG>L0X7M+OSonu@gL3nYdiM{!Yc{I zoyJU@#1ffJgbc*}mo&y~V+DA)s1gKp0$qO5h5SfTv-2&7KBjqRRc6S@KZ?g_hR>K9 zM7UFMFPSN+#)GgAT!;G;N|Cim#MfRufeV!4EsyCwj^=>2pBBj+wJM6Td3VbG*8K3vNx8C; z3Hq2Jp=X5}ZX&}c`FmM}BsKRZn-1=X`l{yCCF5BT`axcc;X>67=sRzw4fGqwuQ=Q` ztg6|3tOiI6Ntl`cex8)5?S63n*yf(gv`!kZD=}zGHzu}{)>8pdN^omacX#{BeHavq z@`yxQAcH)Q7aoVqn8}L!oF))CH{X*<6pxTDR^vnsnEThNxd;l|*w`LYUe6s#RQ`<4 zxRX1GNEYu4lNA5@bMg^9BM_!apfXjePCf@`bZ>MgAkZ~0H|j4iW^jLk5BTE(ZR9GS zDc*p(NvtT3ewoiRHm>bqL6FJ6sYfO@%9j9u!1>PGhm=Z<9M$~J8wS;zV$%Da5rRC> zO3^JQ;UH$rMaOMR$NCfV<2!kIvFp7wqJd<0!0=MgOWAsIbsnZWM4^`S8MkV+nadnw zeU|g=f6!S2!Ulmji%caRA&ZFxlyN*7N;@;7aGa2!uF+z(!_xNWn1^=_ib$TuSoNkU z_vz|g;~N?pDvEXnkWL?oX58^EDc8yO@aGhY=l}NPrfdG4;bP?r&tg?lrvM9rV7E3E z>6cDMbwD+TfRbs=@@fzLRvBfOncw$MlQjaL51SMb{O><$Q-OyYrS^y}%-5XB^jvM} zu(eVS{^BskT`9TumX*DyvoyW&m}MbW4#D;V8cO^6Mh1pdi|0TbLjs-LV#Z}T?R~h_ zrLN-f9H|KK0X%dfr!F$I9i07Cd_li#EErifuZXxn4}Cb(C<@cp#e7C7q>^Hjv@Tsz z9__alTS!Swwzje%aP?4GaK=ML;VqlB2Fk*sO)VscWdRO6_`%2V%kc=jL2d=j7m3|G z8D)5eRms8~*22r$`#c8{Ia2mP0BNNDaHN3W(^w!bVNNm(5Bil<dClnF*0 z%ROVqSJIL#wW8!)ORf*JdYF<|RNUI{&;zyvsmF1b0LNV(+?wBfug!RQ6sGwQ-RpUA z_ToU!tl8<=r}KTeBWziX5SS0pEgxDc zH9=IY<0c&Ts(tSxnUXi%lRfF|&-z zp>XjpPO9bYAZfw^&;KNs<&d3XE~^l788KgN0p*DO^edu z+NGJdjN5o|F7bXw*%pq@6y;TY%rd zpV8k)tlJI*+OCg^IsXb&zj%fS!IOnrWjG%r#sA_3%8fQd)uKxF%D1Co3ag;(c0aA} z$>bQrSB|mbZ}way1@Pg*1pL@5kka4U)^A4UR^FQ&U~|65@I%RyP= z;Nm}s;`iXkye|xgl98LKm=yo1a`j%Z!1NBUuh`m8qu3&JjiWg-AARnHh` zr%PQgLQo}Xi1O!x?-+}-dXH~uadoA>e&B0-klufvGMXf6r3+^)))K z)a;q79})^iB3GiL>G(DuDcw~9dW;|jo}d1Z3VbZ~%#C=0Mg3e@7G!uCoFX0%Sts4y4EA-aJZ1AKgviERNj-&3W#;;3p;pz! zuboC&lZmH_I=Z>wH_(SvAA~0NPpp88Do-^TMl~j4ho#>hbb} z7eQjP=bC-;pEtRVv)q;!oRedEtamAXnobr`|1Mjt$^Rj2ln{RTeN-{d>QF4Vr2YGuIF*OnE%3QNW=+(6qlI}qlJECzwVvb zSC&J1HW43h-}brKvh?Kj)MH5tp_E77+dt5}y-pVk-Eu~Xc%XwS zMnT!4bG}B!gAs)u7SHnZlJKi4JUhGReItExxhiXM$%u(G#lzY6NbdjuNS4PiUg*; z%D9rT)Bo+%&^0~8S7P1rK|3qDU?m)bv;cz~#_TpZ>sa1-Q?shCp^z53GK3_kU#7dj zYw`3IZ+iSIi4(3HrcqY5-am4$dC2=3zMX_MO`5R#4w~>uCnvv{?QxY(<)qgX!8`X| zkqdA7v1rwdZapDXNwg+W-92GRyHae4)bhj^hnRVVLJB+Sd!mfH0);1tChf+MFNe-O zuf;;ePsc%>u!8FsD0ag}-0d%~C*82RLvmJ>Q;D|4x3rKMD=u0W0}gKn)cwX@B2&oD>a zP``GwaOrIrS%@~}yEgtj6-xPJRv$PEf;FFZ>+;Jx6_NE`;=P|w>eF0eh+_O9>H%X?JoAC=c-_6 zeT8OYHbtce58Vj!9cdn?5ZzCMXWPfJ)1N*{Xy~`Q%f$73f9};eIFqa1c%k(Tb;ZWl zQzmcL+OJf)eG^<*C%WRxP;IRn3c7HTyPRo>^0wZd$tn78k#jvCXO(&x=?h8ukzewy ze6(JX-{U&-_KI2dS^e^><2Esyr{0NMq!p-Q1ne>$n{ctpLhi^rz4QLQ%}{d3&T4<8 z=#Ds-)i3N}hS1!wRoDM&5JPh6dB8#73C0zs)2ZHybK&3pL>@bsT2pmP_-uB*mVaX; zFm!5MP51EW>+%J;?N*MNl72Z1`CG|dq4sSLa_%zo-suBJ`vy|pnT`da?LK_>I=rb{ z<$HTI!tm3xw}*@v>{aAVyE(mlQ`p#w?VBjGL-RYW4w@6iChpCJ@#SWk=1X-reNGEI zkT6znt9q^ZVfX7yUP)?$S#(H@x>A`+clTH(YH*C*POie>_T#;$YI9-lO4Fhpt#XTs z7L0#(^15v~3J9A=qy0^p557A-h@Xy)kFXW9BF(vuxHaUxroB)r!IiouD&P=a!g}2D z3GfhZIIH$Ue)64n;@HZkof7>(C;IHaNQwTmh_A4pa2|opLX{xH_(9^2OODZvIv4IU z+;e_H;f;TZlb~2=Sjd6*Yu2p+xi@@2+?%VvC;B^9L6dV+XI}ZP`eV{d3Jg8Y8{E2` zZE}DRG0(VLB>(QE|8hZ&o4P@ysR?tG)DU=vg@b$hL-FCg29cO^>|VF}l~2F*l;^2_ zyIz`|WGr23)1K!lAM?HT_N#JH#W;hp)%EznQ{I&FXR>ZI$cz)`O*N5AzS<;*)$TEL zcqK>iubM^4O?jT$&+1)EtiMF;7nJi1LTE?Izx@tvS^6lE$obYIrD9)K zt3%&dM3~6?D&9Z80*-((@p-KTQ0Ta{c83X5S=Sac4Yv!Kp*tkIg;qDV@U{AVDu?@o z26p9R%?_V`tqpyN*&#NCWg2cAu3PEeOpIIVF?gw$-B{w879B6Gq%7Uf3@vExy7&t|xDgKDR_u)W;Ducfq~@S#LCNQf93~-pV4SwO1PN-K6h%nS#wr z<${j=*A&*f8>Z0%ojcH+pG4{XCtEAWt~B4hsx(v_ietADDDTh7KOV z`-Z!X=oqY?z(Gw2f=c9mdjwfT%ksmUAJ4a?A`xvfQ8&m*^4Gf7#FNw7bWbZwahQM6 zzs&bDIJ5UnPhFc|s(JodV-i(ganbQ|^&~ex^q4-^;Mvo>I_@7!b_d#`>Xi(yJQQ6z zXEv?reNa2hB(*sIvOAc{<9IK( zu659O>%!W@6sbkw3cB{r7OWARAug}7Ligjq>wpcoTLh)Lzq3M2;T}k;U0>d}&-!7) zwAMLp`?8SknVRnu#Y5R(^Cw@H?`eH|U+nT^ILrJ&q`1@egN7S((CV0}^fum6`>f&@ zS4jk251+~!<9ipCq1xjEAw6%ko5#3O@A}to^NG8w*ZUDj37fdPn5-2p975cK!lbv54lq zqMn#fOt#l09$&qB-M#g#{Oi|^VZ0v{eFwgIEMp5wsNv9Wd%jb?E^8gtPZf|;9<^+} zeq1{LkG;2yimPebMiW935-fOdf)m``LU0Z4?hqij6OsVI-QC^YAqnp8?lL%o!`VRW ze%||8=ifPJz2{qNm^Cx(y}NgHb#+zsRoBKa(T9H$BlZFR-6~?X8Z*Ay6v(q#QS+Gks8q2N4rNQltm4k@ai zPPCAcJ6YrtzX&7pInAS4-(rVH?5IYrmW|V{>5QgP*>atthxKS-j2q5YkJb&J@IBKvy@`UivejT*< z$q2my)BOkSMxDJh8#hHn>r=b-)tr(yyMGuu#fqbvej6gK8`RZ>+A}x`@}(3Hlf=$oHboFOBO%osM|faKag&P2)4y6 z+=H<;`;iI1kwV$JNQTjJc;#jfF*ByAf!BoQs&7fhVxIhAoRL1*6%G>4%SO)7>j{Lx zna`KCUM>hI-6SB<14`)MN$+lShHxi4%pxWI8JeZ}@U*NYgcxvV%9OWISX78jurD8n zV$b3zh1bG&C4^`>fW{rn`*TzkzRoC=$~#5zYnWnnKC^l3E1`+iK^7{AYaXO?eR=%x z3o1;7(2)Dg;6==?y1>DwPX9${B#gvGQ&xGhqc+?NsA2Bc{tEVdQ_fGpMH!iFA zYOd-hAgaf6VwZ!}Y-aHW4K=*t*rygS6LJpGD-yZ0sY}D;%|qV9n?{D9>%8+~m*^-C z;E~YUolTN!7#>~e;&IBn`H>XoxD~>2r5oC4mvUoa!D2ps{H~TY1hb;Q{ZauIPH!FL zf_56E6M9^OBlv?zG*Zr5aFm<^b5nEh#8cm}mQoo#EqTZ^>r5K8G< zyHsRDHI9exV%f*$B1Jjf6LOi1W^a=6#tvngo043Y#3rZcf*#+gIu;NV;KBfdq8{gl z4|wlDNWcmA{5}!!0K({1Qgh8)Ze4$PNO{j=_^uJHBKM6E@0y>_?6C_uk<;figeP?7HSkS=Hk!Yryd!HdVxsvBL@IvJ~PWHYX(pI&_ zEISsfRMe*fM~9;7cb}cy32Hb5_&;-;T{59>nnl8M4|>qn>AWM+E6S8Hjol4=4(VCo z*QhXRFBBu_M*LpjLypb4#pRb=91s0RWr+OE~^S7^}eL@S8$i8lyKLR@Ski1sr#oXQx+#Ak+X~?(Y|GN zE=5Ka&fhmSJitk?4d|MAhpq3t7O*_4fV7z&8A?s0muyj>lcmy|XcD@h`J#x&mTO`KSbQ~G=OFl%6*0l_%{5L|%^%rCl za(c&LKZZ{!%)NE5(dw6i37{2gcMs`KOP6L7%yniAR-{{o24$HVxlG}(t)@_--ye~v zq?>k*v0hkb>$des>WQF{6~C;E#))|7mRWO9viNn&(o}9Rs{ow*u$pt4x{{z51J@d^ zF*`Xak^e#z4(11X?^YudbD^RWUj+XO;Uelq6Ku8fM#xd1$2nZgbK{lbK4xFanDJOa zxx-gVCbdbqXeaAvO;p$hb762M#SGhfurmpXx_;Vso2mV*hDIlbC(gIYppXT(7mJrd zK`{KOFu&4VJm=4cVU$LbfcFz0N5w8rg?+UNb*ZyF0RAX~d zdwgZ2I(Y31uY0(F{Q(tvKzE41a>ri=5em1awPvNqZRY@%_IOR&Wsh|t+(}8DYap9^ z5#tctQ-RX{=qWBV)gVGR+tev7<1oFYKUL5x1p2AR1?`cX80+T~`%JqN1*4_X$J08} z$hn7V^C4gDN|7VcyzQ)u1SofnCh9qY;}02xBFHhB%!hfBp73F-S=tCaimDOYJMA&K z92$5z-w|R<#ktp$|RN#>s^T0x6_dDxkf3)+cr% zx@Fth3&JECTS3mGiqkGpyvk*(ZP{QT7C3ruVuBNrIf~NdAv5XQ|MeA{XF8vknOz*S zusfVy!OgT;wl|tEjP4zB?u8)WT0h{cMGJze8`^nHC=ZV3neTM8V*a^Qwi~(|RbQ$* z(R{2(uh11{th>5;QXmxQCX_{cqZyhju3np!i@2qYw#NQC&9Q9A?FJ$nVC8=_nv`6C z?9@;z_T2w;u-h;M#}dvsiEPncvqgzON|uT-mPu4xxS|&c2Z|~>tM@2~9%>}JkzU$gWyg3=z z9a3XFO#{Qj*yJ3lEn9a@hU7~dZHB3HjyWupm~u~(juo6LIFHV{VW9aH8|^+_y6L7T z@D-3&D7^8k&v~9J2f>T z`v(fiNQw7#Iq5^EOt|l`N3G;pkv$cxb}C4fRNMQ~)1cK=OWNZ`d^L>aEpvAA>mYgA)rjM8?FjYg;TEdr zru>!~AF^d-!$gYn`{%xQ+j-O5>m`_;sp@pky6z;Cx#7`7*$dk~-vW#9^^sfls8R>+ zMDe|#DZ=w?z}#1>i)JrHonvXthEeT{U5QGAQ=fksT48S=&i z_5tUxC+mY+Uhh11T~%tqxA?hjJt%aaa=?)LnnMx((JD(#qU@>Xc8uOyL#yVV5!K21 z%^tQ|7GG`P#OBHdpZ@@P_2wJoO7ps1*iG~^6lPPj_yh@NH92tbm3D)Jpn$oJNZ<^V zb+n$KO!$fE5`q692wuPe{>OPB70m&8pWHeGaq%0q*2iX7jeA!6P8Z_UOOGe<%}w*1 zF&p&SHl@%Kc(x`i)*Xz#vY?*R5IAQXZk!oxmoA@sKK2S}ouNM{lIJ9ajprOpemEm6 zn8dD;J>5uKrYJZK^G%ZFV)<>9lZ%e{=|tAmTkf(c<5=B5by`l%x6zC*409sBYYc16 zyQ?0l7aGCy5a^>{hm|pvTx@)oM!_(maCvXuKCwfqMqwW>I~*p=j|V>sAUxb1faU6} z$?)V-18cJ0;Tl@GVcFX?L$RSYg#P!E#S4+jJh|NC>z?4qW~VarFxwlG*#~9>GD?it z4Y$DCiT>itS%{xns0`X8-U{h6Rlf1g!cn@3C_5ST(hCTM(aooy$*=WIH1`*3c&npx z>#xnqy<0zOn+@>tRQgSMrB$vWRS(RN>o~w3{P-N)TpNYnv#)8lMQ%AIkLMoX)a%Xi zI9A5hLE9UOP@=2fpy4ua%Xbwk=$I27mc@9lY^faFAMeZDt0VCSc6_3CB_HYib@gNZ z=f>sCIw`Zs67fsa)|FLG?wQnVFszFzX*Pi;d~R>qdRW_$KL$E6OWfuN_JK{i#i<|c zfSDr({ydA1YWH1<70=m&34V*=0|eYgjfFDR@t04EOxWKXlX}M#sN0hf;+noSQ>hKV zavW+3w^Qc?bty9?^ef}rZ0!gsH1g$~>>Qmufg!Z$3_o$Y#P!kZ<7=4x=w6C~ z5tY}EsCu48X+e5E!%4Z6nreAb`fvkuBkTDD6l~SKv52%#51})H&o=Z!a2p(?vKUs} z2RC;FZ(D&XqID_>JkFACy|1Pz0_|e4N-%!#Loxlq_8z}OEvEvGNnH9(+z?eft}7mh zGkKvlV^HAC*=lhMtMcj9s6Lqz+V&cnlIK^+R+{}HN;A7otmuJ#=|y7Lu7F#x4qgMW z#q1nA(Fdr9pW%uAO#uZl|7qY`-wrR6J7myZ-s%&CS@B#A#cskb4EUT*0)=@yvJFGK zTO%@-3YUYZ({vm?*d+o}L*+qkZC zgMtp*)FXUrp6_<|Ft#P=S8O_FS46ku!%R#L6lLbmRK^tQzoc$oPe?$mgwtShtY-D( zia2q+G-Rzta4+6iki2r(NFh%52QO4A+fKk^Jci zv*^2VDHQ_$?_79eT-QQuPX5WY$@xh&N?eV(OlIbs1nD|yDy|=j$LxZ$g+|*z!Wf+j zSoM}*KR)bB_+b}G;%^dOwr$JxG6rcvF7;&Py(a?NnJ{YKaRAMFA$k}5AJqekf)e2p zj(d}?^XstN<>GepQ(Cc!3}lWK+WWQFR6l#_!oeu#D^g2Gg-EiJf&=5CJeZ1gKc+w# z(;zp8D!@hHk)q6`LXm(1L_qn<`iuFsg#6I$xPDEklT+BUvwdGWtvvay!SKt=52@|; zngPfwCSOR0y~VrbW5Z-qBR{>3Yw4KuGWc1%6cx&3Ry zTL=#Lo1r>Y8j(QV86Y`S0-jp5{?wV&8E9v;kTcGsAvwCpkdoh+P%;9|V4ocAjibU@ zW6JzcPIzYiV?^J)0R9RtS!&Mw_~7sF36O+8fXpVCbf{P(ySSZHlSrogOulh@K7HuF zG{H)|J8f0a(ZMrEYknZk7~Cvi(m|Zvr9q&lw`DW3_@?;FW2Eng@K1V1wtLOdV0=SVUP%}wO8z)Ys3PoPUQ1En>r8MRs>|^#cK&?&; zMXSwBD+g%zM+D(o)Jt21*opN)9qX`pth?(Xt-&V5v6p;B@wBS>H7Pqw7n?48Wrrrq z{Z?D)S7N!=js(>;DJ4A$JKNd8U-6R4tCVfG?Rj#179mZ_4HAm08A!LFsNOEJ>*tz= z2!aXKr3hJ)Q;>z?sklm7owA>>wK=8LPhsZ3fHPnqRmrz7_3ED_`}Zh9XIx0vR-&2w zusV!iZM;pU+(wv>JZ&YX5GLzcZUjQMEY>q~mtUi$|AhMhx-6fRrB%4iFcZYM!YD2O za$<{IJv~p)|DfCIq^pVmT=If7!Wp)SU!%U_jZ<%abdc$x3$0TpzXpQs59wDIw!2~M z7{|2d&oI7QjG-!s2>($}%%(eZ^{ zVf5mWM)RemkM5X`*C*Vy^3X;lIBvPuGHh)rCpTqOtgX`@M-9tz)Fef~F-*}p;JzM( zs&}@`5=IZi_@XgR=~re*VogNqDw$Wpg>0%tM@`2mP^#^83GF_EW#a})>1(Ah;ISe$ z8_cTXRS>Wo)drk}VpjOj$w?!{G0D@U6l^8RP|T*u0t>NGbUcI!uGeiPjjF8u^Qfr? z90?mn+nE(dJKql~BH>(4C!LjdWi59p6DY^VlVIkO>rIDK!}=d1)Wa|@SEpTNWKaZP zD~ijy_P+Yavw9b0qR+Wb)(@Y~easssB~HHwtKcz0DhHI=`-N0sy-)TR|0HO8nO|Ao zM<5kO&2eq083}+5gb>}`SkENh3P)_sZFFB)JNJXfeW@E>Ivjot*?Z_djFdDZT5llW zO)sgb?^HGjQa?%*qTfZA`nih}ApunDBv44c-80&tBO&=22Hb-+0I&!o1e#e}__G2cvwk5-fgFX^^9g=#Aw zly%pBNz|m?D3 zzExq@nY!B<{sEk1dHa=7t+lGNB%9-vYjFuZiqO?(_VnTm(#`GR_}IaLfhA5ZWhpYJ z9OrVoK-;c;=BXblSD)A%Hajv{IYYBBDb60k+E31Cm-bw%MqZAR#Vuf8#5WqV4wewS zL*ZCtb-Aq(DIP4V8@5yiDmn73+;vm~=S1AxTt6I8k||b7V8r4+cZQW&jkh&N2=oEo z?4#{Auϥ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 Rj5jj?fv2mV%Q~loCIF<^!My+g literal 0 HcmV?d00001 diff --git a/install/offline.md b/install/offline.md new file mode 100644 index 000000000..d01e47629 --- /dev/null +++ b/install/offline.md @@ -0,0 +1,249 @@ +# 离线部署Docker + +[TOC] + +生产环境中一般都是没有公网资源的,本文介绍如何在生产服务器上离线部署`Docker` + + + +括号内的字母表示该操作需要在哪些服务器上执行 + +Docker-offile-install-top + +## Centos7 离线安装Docker + +### YUM本地文件安装(推荐) + +推荐这种方式,是因为在生产环境种一般会选定某个指定的文档软件版本使用。 + +#### 查询可用的软件版本(A) + +```bash +#下载清华的镜像源文件 +wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo + +sudo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo + +yum update +``` + +```bash +sudo yum list docker-ce --showduplicates|sort -r + +Loading mirror speeds from cached hostfile +Loaded plugins: fastestmirror +docker-ce.x86_64 3:19.03.8-3.el7 docker-ce-stable +docker-ce.x86_64 3:19.03.7-3.el7 docker-ce-stable +docker-ce.x86_64 3:19.03.6-3.el7 docker-ce-stable +docker-ce.x86_64 3:19.03.5-3.el7 docker-ce-stable +docker-ce.x86_64 3:19.03.4-3.el7 docker-ce-stable +docker-ce.x86_64 3:19.03.3-3.el7 docker-ce-stable +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 +.... +``` + +#### 下载到指定文件夹(A) + +```bash +sudo yum install --downloadonly --downloaddir=/tmp/docker-19.03 docker-ce-19.03.8-3.el7 docker-ce-cli-19.03.8-3.el7 +``` + +```bash +Dependencies Resolved + +==================================================================================================================================================================================== + Package Arch Version Repository Size +==================================================================================================================================================================================== +Installing: + docker-ce x86_64 3:19.03.8-3.el7 docker 25 M +Installing for dependencies: + container-selinux noarch 2:2.107-3.el7 extras 39 k + containerd.io x86_64 1.2.13-3.1.el7 docker 23 M + docker-ce-cli x86_64 1:19.03.8-3.el7 docker 40 M + +Transaction Summary +==================================================================================================================================================================================== +Install 1 Package (+3 Dependent packages) + +Total download size: 87 M +Installed size: 363 M +Background downloading packages, then exiting: +(1/4): container-selinux-2.107-3.el7.noarch.rpm | 39 kB 00:00:00 +(2/4): containerd.io-1.2.13-3.1.el7.x86_64.rpm | 23 MB 00:00:00 +(3/4): docker-ce-19.03.8-3.el7.x86_64.rpm | 25 MB 00:00:00 +(4/4): docker-ce-cli-19.03.8-3.el7.x86_64.rpm | 40 MB 00:00:00 +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +Total 118 MB/s | 87 MB 00:00:00 +exiting because "Download Only" specified +``` +#### 复制到目标服务器之后进入文件夹安装(C-N) + +```bash +yum install *.rpm +``` + +#### 锁定软件版本(C-N) + +##### 下载锁定版本软件 +可参考下文的网络源搭建 +```bash +sudo yum install yum-plugin-versionlock +``` + +##### 锁定软件版本 + +```bash +sudo yum versionlock add docker +``` + +##### 查看锁定列表 + +```bash +sudo yum versionlock list +``` + +```bash +Loaded plugins: fastestmirror, versionlock +3:docker-ce-18.09.9-3.el7.* +versionlock list done +``` + +##### 锁定后无法再更新 + +```bash +sudo yum install docker-ce +Loaded plugins: fastestmirror, versionlock +Loading mirror speeds from cached hostfile +Excluding 1 update due to versionlock (use "yum versionlock status" to show it) +Package 3:docker-ce-18.09.9-3.el7.x86_64 already installed and latest version +Nothing to do +``` + +##### 解锁指定软件 + +```bash +sudo yum versionlock delete docker-ce +``` + +```bash +Loaded plugins: fastestmirror, versionlock +Deleting versionlock for: 3:docker-ce-18.09.9-3.el7.* +versionlock deleted: 1 +``` + +##### 解锁所有软件 + +```bash +sudo yum versionlock delete all +``` + + + +### YUM 本地源服务器搭建安装Docker + +#### 挂载 ISO 镜像搭建本地 File 源(AB) + +```bash +# 删除其他网络源 +rm -f /etc/yum.repo.d/* +# 挂载光盘或者iso镜像 +mount /dev/cdrom /mnt +``` + +```bash +# 添加本地源 +cat >/etc/yum.repos.d/local_files.repo<< EOF +[Local_Files] +name=Local_Files +baseurl=file:///mnt +enable=1 +gpgcheck=0 +gpgkey=file:///mnt/RPM-GPG-KEY-CentOS-7 +EOF +``` + +```bash +# 测试刚才的本地源,安装createrepo软件 +yum clean all +yum install createrepo -y +``` + + + +#### 根据本地文件搭建BASE网络源(B) + +```bash +# 安装apache 服务器 +yum install httpd -y +# 挂载光盘 +mount /dev/cdrom /mnt +# 新建centos目录 +mkdir /var/www/html/base +# 复制光盘内的文件到刚才新建的目录 +cp -R /mnt/Packages/* /var/www/html/base/ +createrepo /var/www/html/centos/ +systemctl enable httpd +systemctl start httpd +``` + +#### 下载Docker-CE 镜像仓库(A) + +在有网络的服务器上下载Docker-ce镜像 + +```bash +# 下载清华的镜像源文件 +wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo +sudo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo +``` + +```bash +# 新建 docker-ce目录 +mkdir /tmp/docker-ce/ +# 把镜像源同步到镜像文件中 +reposync -r docker-ce-stable -p /tmp/docker-ce/ +``` + +#### 创建仓库索引(B) + +把下载的 docker-ce 文件夹复制到离线的服务器 + +```bash +# 把docker-ce 文件夹复制到/var/www/html/docker-ce +# 重建索引 +createrepo /var/www/html/docker-ce/ +``` + +#### YUM 客户端设置(C...N) + +```bash +rm -f /etc/yum.repo.d/* +cat >/etc/yum.repos.d/local_files.repo<< EOF +[local_base] +name=local_base +# 改成B服务器地址 +baseurl=http://x.x.x.x/base +enable=1 +gpgcheck=0 +proxy=_none_ +[docker_ce] +name=docker_ce +# 改成B服务器地址 +baseurl=http://x.x.x.x/base +enable=1 +gpgcheck=0 +proxy=_none_ +EOF + +``` + +#### Docker 安装(C...N) + +```bash +sudo yum makecache fast +sudo yum install docker-ce docker-ce-cli containerd.io +sudo systemctl enable docker +``` + + + From 4561243c237052fb4554aa0b531669418dbef0a7 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 26 Apr 2020 09:57:39 +0800 Subject: [PATCH 070/201] FCOS live iso require 3GB RAM Signed-off-by: Kang Huaishuai --- coreos/demo/example.fcc | 7 +++++++ coreos/install.md | 12 +++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 coreos/demo/example.fcc diff --git a/coreos/demo/example.fcc b/coreos/demo/example.fcc new file mode 100644 index 000000000..59c557680 --- /dev/null +++ b/coreos/demo/example.fcc @@ -0,0 +1,7 @@ +variant: fcos +version: 1.0.0 +passwd: + users: + - name: core + ssh_authorized_keys: + - ssh-rsa AAAA... diff --git a/coreos/install.md b/coreos/install.md index 2e2b693a8..8e3b7a746 100644 --- a/coreos/install.md +++ b/coreos/install.md @@ -24,15 +24,17 @@ passwd: ## 转换 FCC 为 Ignition ```bash -$ docker run -i --rm quay.io/coreos/fcct:v0.2.0 -pretty -strict < example.fcc > example.ign +$ docker run -i --rm quay.io/coreos/fcct:v0.5.0 --pretty --strict < example.fcc > example.ign ``` -## 启动虚拟机并安装 +## 挂载 ISO 启动虚拟机并安装 + +> 虚拟机需要分配 3GB 以上内存,否则会无法启动。 在虚拟机终端执行以下命令安装: ```bash -$ sudo coreos-installer install /dev/sda --ignition example.ign +$ sudo coreos-installer install /dev/sda --ignition-file example.ign ``` 安装之后重新启动即可使用。 @@ -44,3 +46,7 @@ $ ssh core@虚拟机IP $ docker --version ``` + +## 参考链接 + +* [官方文档](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/) From 0fd981acc28c41957480017778eedb6cdd20b487 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 26 Apr 2020 10:17:19 +0800 Subject: [PATCH 071/201] [buildx] buildkit image support tencent cloud env Signed-off-by: Kang Huaishuai --- buildx/multi-arch-images.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/buildx/multi-arch-images.md b/buildx/multi-arch-images.md index 1bc8b96e4..79b66aef2 100644 --- a/buildx/multi-arch-images.md +++ b/buildx/multi-arch-images.md @@ -14,10 +14,15 @@ $ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd44 由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。同时由于国内拉取镜像较缓慢,我们可以使用配置了 [镜像加速地址](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) 的 [`dockerpracticesig/buildkit:master`](https://github.com/docker-practice/buildx) 镜像替换官方镜像。 +> 如果你有私有的镜像加速器,可以基于 https://github.com/docker-practice/buildx 构建自己的 buildkit 镜像并使用它。 + ```bash # 适用于国内环境 $ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master +# 适用于腾讯云环境(腾讯云主机、coding.net 持续集成) +$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master-tencent + # $ docker buildx create --name mybuilder --driver docker-container $ docker buildx use mybuilder From 18ab3069a318680153a786f497395664f61e7473 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 26 Apr 2020 10:34:02 +0800 Subject: [PATCH 072/201] Update soft to latest version Signed-off-by: Kang Huaishuai --- appendix/repo/nginx.md | 2 +- appendix/repo/nodejs.md | 2 +- appendix/repo/redis.md | 2 +- appendix/repo/ubuntu.md | 4 ++-- compose/install.md | 8 ++++---- install/mac.md | 4 ++-- kubernetes/setup/dashboard.md | 2 +- manifest | 10 +++++++--- 8 files changed, 19 insertions(+), 15 deletions(-) diff --git a/appendix/repo/nginx.md b/appendix/repo/nginx.md index 36b11c0e5..eb4eb662f 100644 --- a/appendix/repo/nginx.md +++ b/appendix/repo/nginx.md @@ -4,7 +4,7 @@ [Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。 -该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.17.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.18.x 各个版本的镜像。 ## 使用方法 diff --git a/appendix/repo/nodejs.md b/appendix/repo/nodejs.md index ffe426743..d44563aa6 100644 --- a/appendix/repo/nodejs.md +++ b/appendix/repo/nodejs.md @@ -4,7 +4,7 @@ [Node.js](https://en.wikipedia.org/wiki/Node.js) 是基于 JavaScript 的可扩展服务端和网络软件开发平台。 -该仓库位于 `https://hub.docker.com/_/node/` ,提供了 Node.js 0.10 ~ 12.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/node/` ,提供了 Node.js 0.10 ~ 14.x 各个版本的镜像。 ## 使用方法 diff --git a/appendix/repo/redis.md b/appendix/repo/redis.md index 9f06dedea..d14a73634 100644 --- a/appendix/repo/redis.md +++ b/appendix/repo/redis.md @@ -4,7 +4,7 @@ [Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。 -该仓库位于 `https://hub.docker.com/_/redis/` ,提供了 Redis 3.x ~ 5.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/redis/` ,提供了 Redis 3.x ~ 6.x 各个版本的镜像。 ## 使用方法 diff --git a/appendix/repo/ubuntu.md b/appendix/repo/ubuntu.md index c904d991c..c2f534eef 100644 --- a/appendix/repo/ubuntu.md +++ b/appendix/repo/ubuntu.md @@ -4,14 +4,14 @@ [Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。 -该仓库位于 `https://hub.docker.com/_/ubuntu/` ,提供了 Ubuntu 从 12.04 ~ 19.04 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/ubuntu/` ,提供了 Ubuntu 从 12.04 ~ 20.04 各个版本的镜像。 ## 使用方法 默认会启动一个最小化的 Ubuntu 环境。 ```bash -$ docker run --name some-ubuntu -it ubuntu:18.04 +$ docker run --name some-ubuntu -it ubuntu:20.04 root@523c70904d54:/# ``` diff --git a/compose/install.md b/compose/install.md index b9625e93d..92ae6fc3d 100644 --- a/compose/install.md +++ b/compose/install.md @@ -9,7 +9,7 @@ ```bash $ docker-compose --version -docker-compose version 1.24.1, build 4667896b +docker-compose version 1.25.5, build 4667896b ``` Linux 系统请使用以下介绍的方法安装。 @@ -21,7 +21,7 @@ Linux 系统请使用以下介绍的方法安装。 例如,在 Linux 64 位系统上直接下载对应的二进制包。 ```bash -$ sudo curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose +$ sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose ``` @@ -42,7 +42,7 @@ $ sudo pip install -U docker-compose ```bash Collecting docker-compose - Downloading docker-compose-1.24.1.tar.gz (149kB): 149kB downloaded + Downloading docker-compose-1.25.5.tar.gz (149kB): 149kB downloaded ... Successfully installed docker-compose cached-property requests texttable websocket-client docker-py dockerpty six enum34 backports.ssl-match-hostname ipaddress ``` @@ -50,7 +50,7 @@ Successfully installed docker-compose cached-property requests texttable websock ## bash 补全命令 ```bash -$ curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose +$ curl -L https://raw.githubusercontent.com/docker/compose/1.25.5/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose ``` ## 卸载 diff --git a/install/mac.md b/install/mac.md index 31eb13d1e..e84ac09a6 100644 --- a/install/mac.md +++ b/install/mac.md @@ -44,9 +44,9 @@ $ brew cask install docker ```bash $ docker --version -Docker version 19.03.1, build 74b1e89 +Docker version 19.03.8, build afacb8b $ docker-compose --version -docker-compose version 1.24.1, build 4667896b +docker-compose version 1.25.5, build 8a1c60f6 $ docker-machine --version docker-machine version 0.16.1, build cce350d7 ``` diff --git a/kubernetes/setup/dashboard.md b/kubernetes/setup/dashboard.md index e7275d820..0c51b1cc7 100644 --- a/kubernetes/setup/dashboard.md +++ b/kubernetes/setup/dashboard.md @@ -9,7 +9,7 @@ 执行以下命令即可部署 Dashboard: ```bash -kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml ``` ## 访问 diff --git a/manifest b/manifest index a30a44a65..dafda1705 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,12 @@ -DOCKER_VERSION=19.03.1 -DOCKER_COMPOSE_VERSION=1.24.1 +DOCKER_VERSION=19.03.8 +DOCKER_COMPOSE_VERSION=1.25.5 DOCKER_MACHINE_VERSION=0.16.1 ETCD_VERSION=3.4.0 KUBERNETES_VERSION=1.14.3 -KUBERNETES_DASHBOARD=2.0.0-beta8 +KUBERNETES_DASHBOARD=2.0.0 UBUNTU=18.04 DEBIAN=9 +NGINX_VERSION=1.18.x +NODE_VERSION=14.x +PHP_VERSION=7.x +REDIS_VERSION=6.x From 41da49b1278ca3f0e7f5173f12d64a8ec07bcb38 Mon Sep 17 00:00:00 2001 From: Baohua Yang Date: Wed, 29 Apr 2020 11:36:50 -0700 Subject: [PATCH 073/201] Migrating to new gitbook link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f4f89a3d..536347248 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 -* 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbooks.io/docker_practice/content/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) +* 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbook.io/docker_practice/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) From bdc8bd618cd9a38c5799bbbffc82f856fb6258dc Mon Sep 17 00:00:00 2001 From: Nie Shicong Date: Fri, 8 May 2020 19:20:23 +0800 Subject: [PATCH 074/201] =?UTF-8?q?Fix=20issue=20#447:=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E4=BA=86=E4=B8=80=E4=B8=AA=E5=A4=9A=E4=BD=99=E7=9A=84?= =?UTF-8?q?"=E5=AF=B9"=20(line=2097)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nie Shicong --- image/build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/build.md b/image/build.md index 6fde477d6..1e34a7e0d 100644 --- a/image/build.md +++ b/image/build.md @@ -94,7 +94,7 @@ RUN buildDeps='gcc libc6-dev make wget' \ && apt-get purge -y --auto-remove $buildDeps ``` -首先,之前所有的命令只有一个目的,就是编译、安装 redis 可执行文件。因此没有必要建立很多层,这只是一层的事情。因此,这里没有使用很多个 `RUN` 对一一对应不同的命令,而是仅仅使用一个 `RUN` 指令,并使用 `&&` 将各个所需命令串联起来。将之前的 7 层,简化为了 1 层。在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。 +首先,之前所有的命令只有一个目的,就是编译、安装 redis 可执行文件。因此没有必要建立很多层,这只是一层的事情。因此,这里没有使用很多个 `RUN` 一一对应不同的命令,而是仅仅使用一个 `RUN` 指令,并使用 `&&` 将各个所需命令串联起来。将之前的 7 层,简化为了 1 层。在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。 并且,这里为了格式化还进行了换行。Dockerfile 支持 Shell 类的行尾添加 `\` 的命令换行方式,以及行首 `#` 进行注释的格式。良好的格式,比如换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯。 From 683cf95ca7c85c541d6259336b9521a69920170a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 28 Apr 2020 22:39:47 +0800 Subject: [PATCH 075/201] build vuepress docker image Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 3 +++ .github/workflows/ci.yaml | 21 +++++++++++++++++++++ .travis.yml | 10 +++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 42fb287ff..2d75c1d9a 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -12,6 +12,7 @@ jobs: - uses: actions/checkout@master with: fetch-depth: 1 + # search Issues :-( - run: | docker run -i --rm \ -v $PWD:/mnt:ro \ @@ -56,6 +57,8 @@ jobs: "en.wikipedia.org/wiki/UnionFS",\ "product.china-pub.com",\ "union-click.jd.com",\ + "x.x.x.x/base",\ + "x.x.x.x:9000/minio/",\ "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dc69604c5..8b4db364a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -67,3 +67,24 @@ jobs: PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT PCIT_TARGET_BRANCH: master PCIT_USERNAME: ptt0xjqzbke3 + - name: Build vuepress docker image + if: github.repository == 'docker-practice/docker_practice' + run: | + sudo rm -rf .vuepress/dist/.git + + echo "FROM nginx:alpine" >> Dockerfile + echo "COPY .vuepress/dist /usr/share/nginx/html" >> Dockerfile + + echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + + VCS_REF=`git rev-parse --short HEAD` + + docker build -t dockerpracticesig/docker_practice:vuepress \ + --label org.opencontainers.image.revision=$VCS_REF \ + --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + . + + docker push dockerpracticesig/docker_practice:vuepress + env: + DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} + DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} diff --git a/.travis.yml b/.travis.yml index fb2dc2e5a..a43b38b8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,14 +22,22 @@ after_success: - echo "COPY _book /usr/share/nginx/html" >> Dockerfile - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin +- export VCS_REF=`git rev-parse --short HEAD` +- | + docker build \ + -t dockerpracticesig/docker_practice \ + -t dockerpracticesig/docker_practice:gitbook \ + --label org.opencontainers.image.revision=$VCS_REF \ + --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + . -- docker build -t dockerpracticesig/docker_practice . - docker run -dit --rm -p 4000:80 dockerpracticesig/docker_practice - sleep 5 - curl 127.0.0.1:4000 - docker push dockerpracticesig/docker_practice +- docker push dockerpracticesig/docker_practice:gitbook - cd _book - rm -rf .github/workflows From 9cfd1fda2b6dfb3a75639120616225f7bdb0bb0c Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 28 Apr 2020 23:26:55 +0800 Subject: [PATCH 076/201] offline read docker image add tips Signed-off-by: Kang Huaishuai --- .docker/docker-entrypoint.sh | 9 +++++++++ .github/workflows/ci.yaml | 3 +++ .travis.yml | 3 +++ 3 files changed, 15 insertions(+) create mode 100644 .docker/docker-entrypoint.sh diff --git a/.docker/docker-entrypoint.sh b/.docker/docker-entrypoint.sh new file mode 100644 index 000000000..5451d8ee7 --- /dev/null +++ b/.docker/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +echo +echo +echo "Please open your browser: 127.0.0.1:4000" +echo +echo + +exec nginx -g "daemon off;" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8b4db364a..1f86ec31e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -74,6 +74,8 @@ jobs: echo "FROM nginx:alpine" >> Dockerfile echo "COPY .vuepress/dist /usr/share/nginx/html" >> Dockerfile + echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile + echo "CMD [\"sh\", \"/docker-entrypoint.sh\"]" >> Dockerfile echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin @@ -82,6 +84,7 @@ jobs: docker build -t dockerpracticesig/docker_practice:vuepress \ --label org.opencontainers.image.revision=$VCS_REF \ --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + --label maintainer="https://github.com/docker-practice" \ . docker push dockerpracticesig/docker_practice:vuepress diff --git a/.travis.yml b/.travis.yml index a43b38b8d..419c1a522 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,8 @@ after_success: - echo "FROM nginx:alpine" >> Dockerfile - echo "COPY _book /usr/share/nginx/html" >> Dockerfile +- echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile +- echo "CMD [\"sh\", \"/docker-entrypoint.sh\"]" >> Dockerfile - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - export VCS_REF=`git rev-parse --short HEAD` @@ -29,6 +31,7 @@ after_success: -t dockerpracticesig/docker_practice:gitbook \ --label org.opencontainers.image.revision=$VCS_REF \ --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + --label maintainer="https://github.com/docker-practice" \ . - docker run -dit --rm -p 4000:80 dockerpracticesig/docker_practice From 1316e412221a1f2e35793ec11b9458f92a1f4e37 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 29 Apr 2020 00:00:30 +0800 Subject: [PATCH 077/201] offline read image use cn mirror image Signed-off-by: Kang Huaishuai --- .docker/docker-entrypoint.sh | 2 ++ README.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.docker/docker-entrypoint.sh b/.docker/docker-entrypoint.sh index 5451d8ee7..18b1687f4 100644 --- a/.docker/docker-entrypoint.sh +++ b/.docker/docker-entrypoint.sh @@ -4,6 +4,8 @@ echo echo echo "Please open your browser: 127.0.0.1:4000" echo +echo "欢迎加入 QQ 群:【 145983035 】 分享 Docker 资源,交流 Docker 技术" +echo echo exec nginx -g "daemon off;" diff --git a/README.md b/README.md index 536347248..eaf509c0d 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ * 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbook.io/docker_practice/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) -* [离线阅读 `$ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) +* [离线阅读 `$ docker run -it --rm -p 4000:80 ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice:vuepress`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初学者使用最新稳定版本的 Docker 进行学习实践。欢迎 [参与项目维护](CONTRIBUTING.md)。 From acc5c6e723220929dacf0b67761de15648899e87 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 10 May 2020 10:43:51 +0800 Subject: [PATCH 078/201] Add link Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 + basic_concept/repository.md | 4 ++-- coreos/intro.md | 2 +- security/daemon_sec.md | 2 +- security/other_feature.md | 2 +- security/summary.md | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 2d75c1d9a..7ebcd1843 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -59,6 +59,7 @@ jobs: "union-click.jd.com",\ "x.x.x.x/base",\ "x.x.x.x:9000/minio/",\ + "https://www.freedesktop.org/wiki/Software/systemd/",\ "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ diff --git a/basic_concept/repository.md b/basic_concept/repository.md index d44f9dfe7..c7c8d03c8 100644 --- a/basic_concept/repository.md +++ b/basic_concept/repository.md @@ -14,9 +14,9 @@ Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 -最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 [CoreOS](https://coreos.com/) 的 [Quay.io](https://quay.io/repository/),CoreOS 相关的镜像存储在这里;Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务。 +最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 Red Hat 的 [Quay.io](https://quay.io/repository/);Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务。 -由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为**加速器**。常见的有 [阿里云加速器](https://cr.console.aliyun.com/#/accelerator)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 +由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为 **加速器**。常见的有 [阿里云加速器](https://cr.console.aliyun.com/#/accelerator)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com) 等。 diff --git a/coreos/intro.md b/coreos/intro.md index bef861bff..d73998fd4 100644 --- a/coreos/intro.md +++ b/coreos/intro.md @@ -20,7 +20,7 @@ FCOS 使用 rpm-ostree 系统进行事务性升级。无需像 yum 升级那样 ### 容器工具 -对于诸如构建,复制和其他管理容器的任务,FCOS 用一组兼容的容器工具代替了 **Docker CLI** 工具。**podman CLI** 工具支持许多容器运行时功能,例如运行,启动,停止,列出和删除容器和镜像。**skopeo CLI** 工具可以复制,认证和签名镜像。您可以使用 **crictl CLI** 工具来处理 CRI-O 容器引擎中的容器和镜像。 +对于诸如构建,复制和其他管理容器的任务,FCOS 用一组兼容的容器工具代替了 **Docker CLI** 工具。**podman CLI** 工具支持许多容器运行时功能,例如运行,启动,停止,列出和删除容器和镜像。**skopeo CLI** 工具可以复制,认证和签名镜像。您还可以使用 **crictl CLI** 工具来处理 CRI-O 容器引擎中的容器和镜像。 ## 参考文档 diff --git a/security/daemon_sec.md b/security/daemon_sec.md index 7389ffba8..014ba12ae 100644 --- a/security/daemon_sec.md +++ b/security/daemon_sec.md @@ -13,6 +13,6 @@ 终极目标是改进 2 个重要的安全特性: * 将容器的 root 用户映射到本地主机上的非 root 用户,减轻容器和主机之间因权限提升而引起的安全问题; -* 允许 Docker 服务端在非 root 权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。 +* 允许 Docker 服务端在 [非 root 权限](https://docs.docker.com/engine/security/rootless/) 下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。 最后,建议采用专用的服务器来运行 Docker 和相关的管理服务(例如管理服务比如 ssh 监控和进程监控、管理工具 nrpe、collectd 等)。其它的业务服务都放到容器中去运行。 diff --git a/security/other_feature.md b/security/other_feature.md index 3a288c9f2..95cd6a71d 100644 --- a/security/other_feature.md +++ b/security/other_feature.md @@ -1,5 +1,5 @@ # 其它安全特性 -除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等。 +除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, Seccomp, SELinux, GRSEC 等。 Docker 当前默认只启用了能力机制。用户可以采用多种方案来加强 Docker 主机的安全,例如: * 在内核中启用 GRSEC 和 PAX,这将增加很多编译和运行时的安全检查;通过地址随机化避免恶意探测等。并且,启用该特性不需要 Docker 进行任何配置。 diff --git a/security/summary.md b/security/summary.md index 90d144b8f..3ec846730 100644 --- a/security/summary.md +++ b/security/summary.md @@ -1,4 +1,4 @@ # 总结 总体来看,Docker 容器还是十分安全的,特别是在容器内不使用 root 权限来运行进程的话。 -另外,用户可以使用现有工具,比如 Apparmor, SELinux, GRSEC 来增强安全性;甚至自己在内核中实现更复杂的安全机制。 +另外,用户可以使用现有工具,比如 [Apparmor](https://docs.docker.com/engine/security/apparmor/), [Seccomp](https://docs.docker.com/engine/security/seccomp/), SELinux, GRSEC 来增强安全性;甚至自己在内核中实现更复杂的安全机制。 From f580130be0851d4b6da4653b2eab165cf76f915a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 11 May 2020 19:01:06 +0800 Subject: [PATCH 079/201] Add baidu registry mirror Signed-off-by: Kang Huaishuai --- install/mirror.md | 12 ++++++++---- repository/registry.md | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/install/mirror.md b/install/mirror.md index 6058b0c67..fefc5cc74 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -3,9 +3,10 @@ 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如: * [网易云加速器 `https://hub-mirror.c.163.com`](https://www.163yun.com/help/documents/56918246390157312) +* [百度云加速器 `https://mirror.baidubce.com`](https://cloud.baidu.com/doc/CCE/s/Yjxppt74z#%E4%BD%BF%E7%94%A8dockerhub%E5%8A%A0%E9%80%9F%E5%99%A8) * [阿里云加速器(需登录账号获取)](https://cr.console.aliyun.com/cn-hangzhou/mirrors) -> 由于镜像服务可能出现宕机,建议同时配置多个镜像。各个镜像站测试结果请到 [docker-practice/docker-registry-cn-mirror-test](https://github.com/docker-practice/docker-registry-cn-mirror-test/actions) 查看。 +**由于镜像服务可能出现宕机,建议同时配置多个镜像。各个镜像站测试结果请到 [docker-practice/docker-registry-cn-mirror-test](https://github.com/docker-practice/docker-registry-cn-mirror-test/actions) 查看。** > 国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考官方文档。 @@ -18,7 +19,8 @@ ```json { "registry-mirrors": [ - "https://hub-mirror.c.163.com" + "https://hub-mirror.c.163.com", + "https://mirror.baidubce.com" ] } ``` @@ -41,7 +43,8 @@ $ sudo systemctl restart docker ```json { "registry-mirrors": [ - "https://hub-mirror.c.163.com" + "https://hub-mirror.c.163.com", + "https://mirror.baidubce.com" ] } ``` @@ -53,7 +56,8 @@ $ sudo systemctl restart docker ```json { "registry-mirrors": [ - "https://hub-mirror.c.163.com" + "https://hub-mirror.c.163.com", + "https://mirror.baidubce.com" ] } ``` diff --git a/repository/registry.md b/repository/registry.md index 82bf695f6..cb0179a2a 100644 --- a/repository/registry.md +++ b/repository/registry.md @@ -104,7 +104,8 @@ REPOSITORY TAG IMAGE ID CREAT ```json { "registry-mirror": [ - "https://hub-mirror.c.163.com" + "https://hub-mirror.c.163.com", + "https://mirror.baidubce.com" ], "insecure-registries": [ "192.168.199.100:5000" From 4d3d2d21fe4432a0e4db755944f6ada0f038872d Mon Sep 17 00:00:00 2001 From: staticdax Date: Wed, 20 May 2020 01:33:03 +0800 Subject: [PATCH 080/201] =?UTF-8?q?fix=20typo:=20"=E8=BF=90=E7=94=A8"?= =?UTF-8?q?=E7=96=91=E4=BC=BC=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kubernetes/concepts.md | 6 +++--- kubernetes/intro.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kubernetes/concepts.md b/kubernetes/concepts.md index b79bb37f3..948bbcf66 100644 --- a/kubernetes/concepts.md +++ b/kubernetes/concepts.md @@ -83,11 +83,11 @@ Kubernetes 校验节点可用依赖于 ID。在当前的版本中,有两个接 ### 容器组管理 -容器组是一个运用管理和部署的高层次抽象,同时也是一组容器的接口。容器组是部署、水平放缩的最小单位。 +容器组是一个应用管理和部署的高层次抽象,同时也是一组容器的接口。容器组是部署、水平放缩的最小单位。 ### 容器组的使用 -容器组可以通过组合来构建复杂的运用,其本来的意义包含: +容器组可以通过组合来构建复杂的应用,其本来的意义包含: * 内容管理,文件和数据加载以及本地缓存管理等。 * 日志和检查点备份,压缩,快照等。 @@ -101,7 +101,7 @@ Kubernetes 校验节点可用依赖于 ID。在当前的版本中,有两个接 * 1.透明化。为了使容器组中的容器保持一致的基础设施和服务,比如进程管理和资源监控。这样设计是为了用户的便利性。 * 2.解偶软件之间的依赖。每个容器都可能重新构建和发布,Kubernetes 必须支持热发布和热更新(将来)。 -* 3.方便使用。用户不必运行独立的程序管理,也不用担心每个运用程序的退出状态。 +* 3.方便使用。用户不必运行独立的程序管理,也不用担心每个应用程序的退出状态。 * 4.高效。考虑到基础设施有更多的职责,容器必须要轻量化。 ### 容器组的生命状态 diff --git a/kubernetes/intro.md b/kubernetes/intro.md index 5666fc997..6ecce9453 100644 --- a/kubernetes/intro.md +++ b/kubernetes/intro.md @@ -2,7 +2,7 @@ ![](_images/kubernetes_logo.png) -Kubernetes 是 Google 团队发起的开源项目,它的目标是管理跨多个主机的容器,提供基本的部署,维护以及运用伸缩,主要实现语言为 Go 语言。Kubernetes 是: +Kubernetes 是 Google 团队发起的开源项目,它的目标是管理跨多个主机的容器,提供基本的部署,维护以及应用伸缩,主要实现语言为 Go 语言。Kubernetes 是: * 易学:轻量级,简单,容易理解 * 便携:支持公有云,私有云,混合云,以及多种云平台 From f0568ebffd7befb26e3c70fcb80e80c881244f6f Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 17 Jun 2020 00:10:09 +0800 Subject: [PATCH 081/201] Update install content Signed-off-by: Kang Huaishuai --- install/ubuntu.md | 1 + install/windows.md | 4 ++-- underly/container_format.md | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/install/ubuntu.md b/install/ubuntu.md index 804048f6d..bee34bbf1 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -8,6 +8,7 @@ Docker CE 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: +* Ubuntu Focal 20.04 (LTS) * Eoan 19.10 * Bionic 18.04 (LTS) * Xenial 16.04 (LTS) diff --git a/install/windows.md b/install/windows.md index 841fe4a56..1df1335d4 100644 --- a/install/windows.md +++ b/install/windows.md @@ -2,7 +2,7 @@ ## 系统要求 -[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V,或者 64 位版本的 Windows 10 Home Insider Preview build 19018+。 +[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V(若版本为 v2004 及以上则无需开启 Hyper-V),或者 64 位版本的 Windows 10 Home v2004 及以上版本。 ## 安装 @@ -31,4 +31,4 @@ Docker CE 启动之后会在 Windows 任务栏出现鲸鱼图标。 ## 参考链接 * [官方文档](https://docs.docker.com/docker-for-windows/install/) -* [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl-tech-preview/) +* [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl/) diff --git a/underly/container_format.md b/underly/container_format.md index 983992538..1f943aad1 100644 --- a/underly/container_format.md +++ b/underly/container_format.md @@ -1,5 +1,3 @@ # 容器格式 最初,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)。 - -对更多容器格式的支持,还在进一步的发展中。 From d4d09f5154e8cd5293a960c82d928dc197632d2c Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 17 Jun 2020 00:42:01 +0800 Subject: [PATCH 082/201] docker hub support buildx Signed-off-by: Kang Huaishuai --- appendix/repo/nginx.md | 2 +- buildx/buildkit.md | 4 +++- buildx/buildx.md | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/appendix/repo/nginx.md b/appendix/repo/nginx.md index eb4eb662f..8abac44e7 100644 --- a/appendix/repo/nginx.md +++ b/appendix/repo/nginx.md @@ -4,7 +4,7 @@ [Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。 -该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.18.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.19.x 各个版本的镜像。 ## 使用方法 diff --git a/buildx/buildkit.md b/buildx/buildkit.md index f1b7e9f1d..235e1e60c 100644 --- a/buildx/buildkit.md +++ b/buildx/buildkit.md @@ -2,10 +2,12 @@ **BuildKit** 是下一代的镜像构建组件,在 https://github.com/moby/buildkit 开源。 -**注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(Docker Hub 自动构建、腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)** +**注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)** **注意:docker-compose build 命令暂时不支持 BuildKit** +目前,Docker Hub 自动构建已经支持 buildkit,具体请参考 https://github.com/docker-practice/docker-hub-buildx + ## `Dockerfile` 新增指令详解 启用 `BuildKit` 之后,我们可以使用下面几个新的 `Dockerfile` 指令来加快镜像构建。 diff --git a/buildx/buildx.md b/buildx/buildx.md index 02c7ca5fc..cec0a543e 100644 --- a/buildx/buildx.md +++ b/buildx/buildx.md @@ -2,7 +2,7 @@ ## 启用 Buildx -`buildx` 命令属于实验特性,参考 [开启实验特性](../install/experimental.md) 一节。 +`buildx` 命令属于实验特性,参考 [开启实验特性](../install/experimental.md) 一节开启 Docker CLI 实验特性。 ## 使用 From 67213bc2f55f7c0e2b6535b7b765e6d9efd012d3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 17 Jun 2020 00:49:13 +0800 Subject: [PATCH 083/201] Update ide content Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 4 ++-- SUMMARY.md | 4 ++-- buildx/buildx.md | 2 +- {IDE => ide}/README.md | 0 {IDE => ide}/vsCode.md | 0 5 files changed, 5 insertions(+), 5 deletions(-) rename {IDE => ide}/README.md (100%) rename {IDE => ide}/vsCode.md (100%) diff --git a/.vuepress/config.js b/.vuepress/config.js index ac3b2bed0..ce8fed5ed 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -176,8 +176,8 @@ module.exports = { title: "在 IDE 中使用 Docker", collapsable: false, children: [ - '/IDE/', - '/IDE/vsCode', + '/ide/', + '/ide/vsCode', ], }, ], diff --git a/SUMMARY.md b/SUMMARY.md index c655207f4..3fba08427 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -145,8 +145,8 @@ * [Drone](cases/ci/drone/README.md) * [部署 Drone](cases/ci/drone/install.md) * [Travis CI](cases/ci/travis/README.md) -* [在 IDE 中使用 Docker](IDE/README.md) - * [VS Code](IDE/vsCode.md) +* [在 IDE 中使用 Docker](ide/README.md) + * [VS Code](ide/vsCode.md) * [Docker 开源项目](opensource/README.md) * [LinuxKit](opensource/linuxkit.md) * [podman - 下一代 Linux 容器工具](podman/README.md) diff --git a/buildx/buildx.md b/buildx/buildx.md index cec0a543e..ee7ec45c8 100644 --- a/buildx/buildx.md +++ b/buildx/buildx.md @@ -2,7 +2,7 @@ ## 启用 Buildx -`buildx` 命令属于实验特性,参考 [开启实验特性](../install/experimental.md) 一节开启 Docker CLI 实验特性。 +`buildx` 命令属于实验特性,请参考 [开启实验特性](../install/experimental.md) 一节开启 Docker CLI 实验特性。 ## 使用 diff --git a/IDE/README.md b/ide/README.md similarity index 100% rename from IDE/README.md rename to ide/README.md diff --git a/IDE/vsCode.md b/ide/vsCode.md similarity index 100% rename from IDE/vsCode.md rename to ide/vsCode.md From 139b0ca65c279eb7b7c9395e67b34bd5767b485a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 17 Jun 2020 18:28:29 +0800 Subject: [PATCH 084/201] Update raspberry os name Signed-off-by: Kang Huaishuai --- install/raspberry-pi.md | 11 +++++------ introduction/what.md | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index c3a29be11..66ee99be3 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -6,12 +6,11 @@ Docker CE 不仅支持 `x86_64` 架构的计算机,同时也支持 `ARM` 架构的计算机,本小节内容以树莓派单片电脑为例讲解 `ARM` 架构安装 Docker CE。 -Docker CE 支持以下版本的 [Raspbian](https://www.raspberrypi.org/downloads/raspbian/) 操作系统: +Docker CE 支持以下版本的 [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspberry-pi-os/) 操作系统: -* Raspbian Buster -* Raspbian Stretch +* Raspberry Pi OS Buster -*注:* `Raspbian` 是树莓派的开发与维护机构 [树莓派基金会](https://www.raspberrypi.org/) 推荐用于树莓派的首选系统,其基于 `Debian`。 +*注:* `Raspberry Pi OS` 由树莓派的开发与维护机构 [树莓派基金会](https://www.raspberrypi.org/) 官方支持,并推荐用作树莓派的首选系统,其基于 `Debian`。 ## 使用 APT 安装 @@ -71,7 +70,7 @@ $ sudo apt-get install docker-ce ## 使用脚本自动安装 -在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspbian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: +在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspberry Pi OS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: ```bash $ curl -fsSL get.docker.com -o get-docker.sh @@ -141,7 +140,7 @@ For more examples and ideas, visit: 若能正常输出以上信息,则说明安装成功。 -*注意:* ARM 平台不能使用 `x86` 镜像,查看 Raspbian 可使用镜像请访问 [arm32v7](https://hub.docker.com/u/arm32v7/)。 +*注意:* ARM 平台不能使用 `x86` 镜像,查看 Raspberry Pi OS 可使用镜像请访问 [arm32v7](https://hub.docker.com/u/arm32v7/) 或者 [arm64v8](https://hub.docker.com/u/arm64v8/)。 ## 镜像加速 diff --git a/introduction/what.md b/introduction/what.md index fe5ebd861..0787de110 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -1,6 +1,6 @@ # 什么是 Docker -**Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,它是基于 `dotCloud` 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。`Docker` 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://www.opencontainers.org/)。 +**Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,它是基于 `dotCloud` 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。`Docker` 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://opencontainers.org/)。 **Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 4 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 From 8b186fb7e709832bbe423df68b52866870d5fd55 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 22 Jun 2020 09:22:53 +0800 Subject: [PATCH 085/201] [windows] install by winget Signed-off-by: Kang Huaishuai --- install/windows.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/install/windows.md b/install/windows.md index 1df1335d4..a683d9ec1 100644 --- a/install/windows.md +++ b/install/windows.md @@ -6,10 +6,22 @@ ## 安装 +**手动下载安装** + 点击以下链接下载 [Stable](https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe) 或 [Edge](https://download.docker.com/win/edge/Docker%20Desktop%20Installer.exe) 版本的 Docker Desktop for Windows。 下载好之后双击 `Docker Desktop Installer.exe` 开始安装。 +**使用 [winget](https://docs.microsoft.com/zh-cn/windows/package-manager/) 安装** + +```powershell +# stable +$ winget install Docker.DockerDesktop + +# edge +$ winget install Docker.DockerDesktopEdge +``` + ## 运行 在 Windows 搜索栏输入 **Docker** 点击 **Docker Desktop** 开始运行。 From 911ce1a2e4e345b95962e16571ffafb114b111a3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 3 Jul 2020 12:10:24 +0800 Subject: [PATCH 086/201] Fixed #454 Signed-off-by: Kang Huaishuai --- .docker/docker-entrypoint.sh | 0 .github/workflows/ci.yaml | 6 +++++- .travis.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) mode change 100644 => 100755 .docker/docker-entrypoint.sh diff --git a/.docker/docker-entrypoint.sh b/.docker/docker-entrypoint.sh old mode 100644 new mode 100755 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1f86ec31e..cb310cb57 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -75,7 +75,7 @@ jobs: echo "FROM nginx:alpine" >> Dockerfile echo "COPY .vuepress/dist /usr/share/nginx/html" >> Dockerfile echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile - echo "CMD [\"sh\", \"/docker-entrypoint.sh\"]" >> Dockerfile + echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin @@ -88,6 +88,10 @@ jobs: . docker push dockerpracticesig/docker_practice:vuepress + + docker run -it --rm -d -p 4000:80 dockerpracticesig/docker_practice:vuepress + + curl 127.0.0.1:4000 env: DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} diff --git a/.travis.yml b/.travis.yml index 419c1a522..3f12f43f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ after_success: - echo "FROM nginx:alpine" >> Dockerfile - echo "COPY _book /usr/share/nginx/html" >> Dockerfile - echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile -- echo "CMD [\"sh\", \"/docker-entrypoint.sh\"]" >> Dockerfile +- echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - export VCS_REF=`git rev-parse --short HEAD` From 6c668a94dfca99182faca16134f430265024347d Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 4 Jul 2020 13:01:22 +0800 Subject: [PATCH 087/201] Update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 调整章节顺序 Signed-off-by: Kang Huaishuai --- README.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index eaf509c0d..c86613629 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Docker — 从入门到实践 -[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS) +[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] **v1.2.0** @@ -14,7 +14,7 @@ 无论是应用开发者、运维人员、还是其他信息技术从业人员,都有必要认识和掌握 Docker,节约有限的生命。 -本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 13 章介绍了容器生态中的几个核心项目;14、15 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、CoreOS、Kubernetes、Mesos、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 +本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 12 章介绍了容器生态中的几个核心项目;13、14 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、Fedora CoreOS、Kubernetes、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 * 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbook.io/docker_practice/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) * 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) @@ -58,17 +58,11 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 ## 进阶学习 -[![](https://github.com/yeasy/docker_practice/raw/master/_images/docker_primer3.png)](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS) +[![](https://github.com/yeasy/docker_practice/raw/master/_images/docker_primer3.png)][1] -《[Docker 技术入门与实战](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS)》第三版已经面世,介绍最新的容器技术栈,欢迎大家阅读使用并反馈建议。 +《[Docker 技术入门与实战][1]》第三版已经面世,介绍最新的容器技术栈,欢迎大家阅读使用并反馈建议。 -

- -

- -

微信扫码购买~

- -* [京东图书](https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS) +* [京东图书][1] * [China-Pub](http://product.china-pub.com/8052127) ## 鼓励项目 @@ -78,3 +72,5 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初

欢迎鼓励项目一杯 coffee~

+ +[1]: https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS From 6efe0297fe3616273ad0ba9a9cb9b84c0445daf7 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 14 Jul 2020 00:08:15 +0800 Subject: [PATCH 088/201] Remove download link #455 Signed-off-by: Kang Huaishuai --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index c86613629..b094072ee 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 12 章介绍了容器生态中的几个核心项目;13、14 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、Fedora CoreOS、Kubernetes、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 * 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbook.io/docker_practice/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) -* 下载:[pdf](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD),[epub](https://github.com/yeasy/docker_practice/wiki/%E4%B8%8B%E8%BD%BD) * [离线阅读 `$ docker run -it --rm -p 4000:80 ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice:vuepress`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初学者使用最新稳定版本的 Docker 进行学习实践。欢迎 [参与项目维护](CONTRIBUTING.md)。 From 4aa20ecce35b4fdb9c10dadfdf278d80dc03b03a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 14 Jul 2020 00:09:11 +0800 Subject: [PATCH 089/201] Update actions 301 link Signed-off-by: Kang Huaishuai --- cases/ci/actions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cases/ci/actions/README.md b/cases/ci/actions/README.md index bd34f075b..204865208 100644 --- a/cases/ci/actions/README.md +++ b/cases/ci/actions/README.md @@ -25,4 +25,4 @@ jobs: ## 参考资料 -* [Actions Docs](https://help.github.com/en/actions) +* [Actions Docs](https://docs.github.com/en/actions) From c815720349a905a712a001f097f8dd8d83c24fa4 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 14 Jul 2020 16:20:36 +0800 Subject: [PATCH 090/201] Update image link Signed-off-by: Kang Huaishuai --- README.md | 6 +++--- appendix/repo/php.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b094072ee..a2bda5734 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 ## 微信小程序

- +

微信扫码 随时随地阅读~

@@ -50,10 +50,10 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 >如果有容器相关的疑问,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。

- +

-

微信扫码 加入群聊~

+

微信扫码 加入群聊~ 或者微信添加 dpsigs 邀请入群

## 进阶学习 diff --git a/appendix/repo/php.md b/appendix/repo/php.md index 0d54c90a9..5ef53b845 100644 --- a/appendix/repo/php.md +++ b/appendix/repo/php.md @@ -4,7 +4,7 @@ [PHP](https://en.wikipedia.org/wiki/Php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。 -该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 7.x 各个版本的镜像。 +该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 8.x 各个版本的镜像。 ## 使用方法 From 61bda4b259e98bb9bc79e0934905484f5c71f6c8 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 14 Jul 2020 16:58:22 +0800 Subject: [PATCH 091/201] Fixed docker image Signed-off-by: Kang Huaishuai --- .travis/Dockerfile | 4 ++-- podman/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis/Dockerfile b/.travis/Dockerfile index cee1e5e2b..cb4c7f36d 100644 --- a/.travis/Dockerfile +++ b/.travis/Dockerfile @@ -1,4 +1,4 @@ -FROM node:alpine +FROM node:14.4.0-alpine ENV TZ=Asia/Shanghai @@ -8,7 +8,7 @@ COPY book.json book.json COPY docker-entrypoint.sh /usr/local/bin/ -RUN apk add --no-cache \ +RUN set -x && apk add --no-cache \ tzdata \ && npm install -g gitbook-cli \ && gitbook install \ diff --git a/podman/README.md b/podman/README.md index b24215200..1930d0454 100644 --- a/podman/README.md +++ b/podman/README.md @@ -1,6 +1,6 @@ # podman -[`podman`](https://github.com/containers/libpod) 是一个无守护程序与 docker 命令兼容的下一代 Linux 容器工具。 +[`podman`](https://github.com/containers/podman) 是一个无守护程序与 docker 命令兼容的下一代 Linux 容器工具。 ## 安装 From 83fbb87fd1559480c627c243a85f6c6e6fea2ba6 Mon Sep 17 00:00:00 2001 From: huiyifyj Date: Thu, 30 Jul 2020 09:26:49 +0800 Subject: [PATCH 092/201] Add the word to read more fluently --- data_management/volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_management/volume.md b/data_management/volume.md index 5fc3193cf..6949adde5 100644 --- a/data_management/volume.md +++ b/data_management/volume.md @@ -10,7 +10,7 @@ * `数据卷` 默认会一直存在,即使容器被删除 ->注意:`数据卷` 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 `数据卷`。 +>注意:`数据卷` 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看到的是挂载的 `数据卷`。 ## 创建一个数据卷 From 85b2325513002fe10717114ef7e885e3112f68ca Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 23 Jul 2020 22:09:38 +0800 Subject: [PATCH 093/201] Update link Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 2 +- cloud/tencentCloud.md | 6 +++--- install/mirror.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index ce8fed5ed..688907437 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -82,7 +82,7 @@ module.exports = { // }, { text: '腾讯云容器服务', - link: 'https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' + link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' }, // { // text: '语言', diff --git a/cloud/tencentCloud.md b/cloud/tencentCloud.md index 4af43eea4..383aa9391 100644 --- a/cloud/tencentCloud.md +++ b/cloud/tencentCloud.md @@ -2,10 +2,10 @@ ![腾讯云](_images/qcloud-logo.jpg) -[腾讯云](https://cloud.tencent.com/redirect.php?redirect=1040&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console) 在架构方面经过多年积累,并且有着多年对海量互联网服务的经验。不管是社交、游戏还是其他领域,都有多年的成熟产品来提供产品服务。腾讯在云端完成重要部署,为开发者及企业提供云服务、云数据、云运营等整体一站式服务方案。 +[腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=1040&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console) 在架构方面经过多年积累,并且有着多年对海量互联网服务的经验。不管是社交、游戏还是其他领域,都有多年的成熟产品来提供产品服务。腾讯在云端完成重要部署,为开发者及企业提供云服务、云数据、云运营等整体一站式服务方案。 -具体包括 [云服务器](https://cloud.tencent.com/redirect.php?redirect=1001&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console)、[云存储](https://cloud.tencent.com/redirect.php?redirect=1020&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console)、[云数据库](https://cloud.tencent.com/redirect.php?redirect=1003&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console)、[视频与CDN](https://cloud.tencent.com/redirect.php?redirect=1019&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console) 和 [域名注册](https://dnspod.cloud.tencent.com) 等基础云服务;腾讯云分析(MTA)、腾讯云推送(信鸽)等腾讯整体大数据能力;以及 QQ互联、QQ 空间、微云、微社区等云端链接社交体系。这些正是腾讯云可以提供给这个行业的差异化优势,造就了可支持各种互联网使用场景的高品质的腾讯云技术平台。 +具体包括 [云服务器](https://cloud.tencent.com/act/cps/redirect?redirect=1001&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console)、[云存储](https://cloud.tencent.com/act/cps/redirect?redirect=1020&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console)、[云数据库](https://cloud.tencent.com/act/cps/redirect?redirect=1003&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console)、[视频与CDN](https://cloud.tencent.com/act/cps/redirect?redirect=1019&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console) 和 [域名注册](https://dnspod.cloud.tencent.com) 等基础云服务;腾讯云分析(MTA)、腾讯云推送(信鸽)等腾讯整体大数据能力;以及 QQ互联、QQ 空间、微云、微社区等云端链接社交体系。这些正是腾讯云可以提供给这个行业的差异化优势,造就了可支持各种互联网使用场景的高品质的腾讯云技术平台。 -[腾讯云容器服务 TKE](https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61) 是高度可扩展的高性能容器管理服务,用户可以在托管的云服务器实例集群上轻松运行应用程序。使用该服务,将无需安装、运维、扩展用户的集群管理基础设施,只需进行简单的 API 调用,便可启动和停止 Docker 应用程序,查询集群的完整状态,以及使用各种云服务。用户可以根据用户的资源需求和可用性要求在用户的集群中安排容器的置放,满足业务或应用程序的特定要求。 +[腾讯云容器服务 TKE](https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61) 是高度可扩展的高性能容器管理服务,用户可以在托管的云服务器实例集群上轻松运行应用程序。使用该服务,将无需安装、运维、扩展用户的集群管理基础设施,只需进行简单的 API 调用,便可启动和停止 Docker 应用程序,查询集群的完整状态,以及使用各种云服务。用户可以根据用户的资源需求和可用性要求在用户的集群中安排容器的置放,满足业务或应用程序的特定要求。 ![](https://mc.qcloudimg.com/static/img/0581dbeb97c869bbe6e62025dbc592d7/image.png) diff --git a/install/mirror.md b/install/mirror.md index fefc5cc74..19184a333 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -91,4 +91,4 @@ $ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/xxx * [Azure 中国镜像 `https://dockerhub.azk8s.cn`](https://github.com/Azure/container-service-for-azure-china/blob/master/aks/README.md#22-container-registry-proxy) -* [腾讯云 `https://mirror.ccs.tencentyun.com`](https://cloud.tencent.com/redirect.php?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61) +* [腾讯云 `https://mirror.ccs.tencentyun.com`](https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61) From acb8662c43ab97a925b0698c5e9fcf64fa343a67 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 10 Aug 2020 13:40:04 +0800 Subject: [PATCH 094/201] wechat is first Signed-off-by: Kang Huaishuai --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a2bda5734..4daed698c 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 ## 技术交流 +

+ +

+ +

微信扫码 加入群聊~ 或者微信添加 dpsigs 邀请入群

+ 欢迎加入 Docker 技术交流 QQ 群,分享 Docker 资源,交流 Docker 技术。 * QQ 群 I (已满):341410255 @@ -49,12 +55,6 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 >如果有容器相关的疑问,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。 -

- -

- -

微信扫码 加入群聊~ 或者微信添加 dpsigs 邀请入群

- ## 进阶学习 [![](https://github.com/yeasy/docker_practice/raw/master/_images/docker_primer3.png)][1] From edf1a3a07b1a9e9c9d5226429163fdea9e779581 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 10 Aug 2020 13:41:36 +0800 Subject: [PATCH 095/201] remove outdated content #458 Signed-off-by: Kang Huaishuai --- image/rm.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/image/rm.md b/image/rm.md index 07b0f19e4..026a51ce7 100644 --- a/image/rm.md +++ b/image/rm.md @@ -85,15 +85,3 @@ $ docker image rm $(docker image ls -q -f before=mongo:3.2) ``` 充分利用你的想象力和 Linux 命令行的强大,你可以完成很多非常赞的功能。 - -## CentOS/RHEL 的用户需要注意的事项 - -> 以下内容仅适用于 Docker CE 18.09 以下版本,在 Docker CE 18.09 版本中默认使用的是 `overlay2` 驱动。 - -~~在 Ubuntu/Debian 上有 `UnionFS` 可以使用,如 `aufs` 或者 `overlay2`,而 CentOS 和 RHEL 的内核中没有相关驱动。因此对于这类系统,一般使用 `devicemapper` 驱动利用 LVM 的一些机制来模拟分层存储。这样的做法除了性能比较差外,稳定性一般也不好,而且配置相对复杂。Docker 安装在 CentOS/RHEL 上后,会默认选择 `devicemapper`,但是为了简化配置,其 `devicemapper` 是跑在一个稀疏文件模拟的块设备上,也被称为 `loop-lvm`。这样的选择是因为不需要额外配置就可以运行 Docker,这是自动配置唯一能做到的事情。但是 `loop-lvm` 的做法非常不好,其稳定性、性能更差,无论是日志还是 `docker info` 中都会看到警告信息。官方文档有明确的文章讲解了如何配置块设备给 `devicemapper` 驱动做存储层的做法,这类做法也被称为配置 `direct-lvm`。~~ - -~~除了前面说到的问题外,`devicemapper` + `loop-lvm` 还有一个缺陷,因为它是稀疏文件,所以它会不断增长。用户在使用过程中会注意到 `/var/lib/docker/devicemapper/devicemapper/data` 不断增长,而且无法控制。很多人会希望删除镜像或者可以解决这个问题,结果发现效果并不明显。原因就是这个稀疏文件的空间释放后基本不进行垃圾回收的问题。因此往往会出现即使删除了文件内容,空间却无法回收,随着使用这个稀疏文件一直在不断增长。~~ - -~~所以对于 CentOS/RHEL 的用户来说,在没有办法使用 `UnionFS` 的情况下,一定要配置 `direct-lvm` 给 `devicemapper`,无论是为了性能、稳定性还是空间利用率。~~ - -~~*或许有人注意到了 CentOS 7 中存在被 backports 回来的 `overlay` 驱动,不过 CentOS 里的这个驱动达不到生产环境使用的稳定程度,所以不推荐使用。*~~ From 9a4660492ca79413a4c319cc0d42cedaa9df804a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 10 Aug 2020 13:43:33 +0800 Subject: [PATCH 096/201] ip.cn not support https Signed-off-by: Kang Huaishuai --- image/dockerfile/entrypoint.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/image/dockerfile/entrypoint.md b/image/dockerfile/entrypoint.md index 25090dd46..3f7ebfa29 100644 --- a/image/dockerfile/entrypoint.md +++ b/image/dockerfile/entrypoint.md @@ -21,7 +21,7 @@ FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* -CMD [ "curl", "-s", "https://ip.cn" ] +CMD [ "curl", "-s", "http://ip.cn" ] ``` 假如我们使用 `docker build -t myip .` 来构建镜像的话,如果我们需要查询当前公网 IP,只需要执行: @@ -38,12 +38,12 @@ $ docker run myip -i docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"-i\\\": executable file not found in $PATH\"\n". ``` -我们可以看到可执行文件找不到的报错,`executable file not found`。之前我们说过,跟在镜像名后面的是 `command`,运行时会替换 `CMD` 的默认值。因此这里的 `-i` 替换了原来的 `CMD`,而不是添加在原来的 `curl -s https://ip.cn` 后面。而 `-i` 根本不是命令,所以自然找不到。 +我们可以看到可执行文件找不到的报错,`executable file not found`。之前我们说过,跟在镜像名后面的是 `command`,运行时会替换 `CMD` 的默认值。因此这里的 `-i` 替换了原来的 `CMD`,而不是添加在原来的 `curl -s http://ip.cn` 后面。而 `-i` 根本不是命令,所以自然找不到。 那么如果我们希望加入 `-i` 这参数,我们就必须重新完整的输入这个命令: ```bash -$ docker run myip curl -s https://ip.cn -i +$ docker run myip curl -s http://ip.cn -i ``` 这显然不是很好的解决方案,而使用 `ENTRYPOINT` 就可以解决这个问题。现在我们重新用 `ENTRYPOINT` 来实现这个镜像: @@ -53,7 +53,7 @@ FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* -ENTRYPOINT [ "curl", "-s", "https://ip.cn" ] +ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] ``` 这次我们再来尝试直接使用 `docker run myip -i`: From 9bc245dfdc557bcfeb9f93d29c4980bf2527481c Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 22 Aug 2020 09:38:34 +0800 Subject: [PATCH 097/201] [Windows] v1903+ support WSL2 Signed-off-by: Kang Huaishuai --- install/windows.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/windows.md b/install/windows.md index a683d9ec1..d62c0cc94 100644 --- a/install/windows.md +++ b/install/windows.md @@ -2,7 +2,7 @@ ## 系统要求 -[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V(若版本为 v2004 及以上则无需开启 Hyper-V),或者 64 位版本的 Windows 10 Home v2004 及以上版本。 +[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 10 Pro,且必须开启 Hyper-V(若版本为 v1903 及以上则无需开启 Hyper-V),或者 64 位版本的 Windows 10 Home v1903 及以上版本。 ## 安装 @@ -44,3 +44,4 @@ Docker CE 启动之后会在 Windows 任务栏出现鲸鱼图标。 * [官方文档](https://docs.docker.com/docker-for-windows/install/) * [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl/) +* [WSL 2 Support is coming to Windows 10 Versions 1903 and 1909](https://devblogs.microsoft.com/commandline/wsl-2-support-is-coming-to-windows-10-versions-1903-and-1909/) From 6eb603a33b4db2dd95305d5a5a8d4442f76fabc8 Mon Sep 17 00:00:00 2001 From: mayingchun Date: Tue, 25 Aug 2020 14:19:23 +0800 Subject: [PATCH 098/201] Fix issue #459 --- data_management/volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_management/volume.md b/data_management/volume.md index 6949adde5..89d6d731b 100644 --- a/data_management/volume.md +++ b/data_management/volume.md @@ -73,7 +73,7 @@ $ docker inspect web "Type": "volume", "Name": "my-vol", "Source": "/var/lib/docker/volumes/my-vol/_data", - "Destination": "/app", + "Destination": "/webapp", "Driver": "local", "Mode": "", "RW": true, From ee26243625558e74ff6939f09f9a617a993d2ab7 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 25 Aug 2020 16:54:59 +0800 Subject: [PATCH 099/201] use nginx:alpine as demo Signed-off-by: Kang Huaishuai --- container/stop.md | 1 - data_management/bind-mounts.md | 22 ++++++++--------- data_management/volume.md | 14 +++++------ network/port_mapping.md | 43 ++++++++++++++++------------------ 4 files changed, 37 insertions(+), 43 deletions(-) diff --git a/container/stop.md b/container/stop.md index 77dd73269..1c00fe4d8 100644 --- a/container/stop.md +++ b/container/stop.md @@ -12,7 +12,6 @@ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba267838cc1b ubuntu:18.04 "/bin/bash" 30 minutes ago Exited (0) About a minute ago trusting_newton -98e5efa7d997 training/webapp:latest "python app.py" About an hour ago Exited (0) 34 minutes ago backstabbing_pike ``` 处于终止状态的容器,可以通过 `docker container start` 命令来重新启动。 diff --git a/data_management/bind-mounts.md b/data_management/bind-mounts.md index 8c9ac30c6..278d12ff2 100644 --- a/data_management/bind-mounts.md +++ b/data_management/bind-mounts.md @@ -7,29 +7,27 @@ ```bash $ docker run -d -P \ --name web \ - # -v /src/webapp:/opt/webapp \ - --mount type=bind,source=/src/webapp,target=/opt/webapp \ - training/webapp \ - python app.py + # -v /src/webapp:/usr/share/nginx/html \ + --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \ + nginx:alpine ``` -上面的命令加载主机的 `/src/webapp` 目录到容器的 `/opt/webapp`目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,以前使用 `-v` 参数时如果本地目录不存在 Docker 会自动为你创建一个文件夹,现在使用 `--mount` 参数时如果本地目录不存在,Docker 会报错。 +上面的命令加载主机的 `/src/webapp` 目录到容器的 `/usr/share/nginx/html`目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,以前使用 `-v` 参数时如果本地目录不存在 Docker 会自动为你创建一个文件夹,现在使用 `--mount` 参数时如果本地目录不存在,Docker 会报错。 Docker 挂载主机目录的默认权限是 `读写`,用户也可以通过增加 `readonly` 指定为 `只读`。 ```bash $ docker run -d -P \ --name web \ - # -v /src/webapp:/opt/webapp:ro \ - --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \ - training/webapp \ - python app.py + # -v /src/webapp:/usr/share/nginx/html:ro \ + --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html,readonly \ + nginx:alpine ``` -加了 `readonly` 之后,就挂载为 `只读` 了。如果你在容器内 `/opt/webapp` 目录新建文件,会显示如下错误 +加了 `readonly` 之后,就挂载为 `只读` 了。如果你在容器内 `/usr/share/nginx/html` 目录新建文件,会显示如下错误 ```bash -/opt/webapp # touch new.txt +/usr/share/nginx/html # touch new.txt touch: new.txt: Read-only file system ``` @@ -48,7 +46,7 @@ $ docker inspect web { "Type": "bind", "Source": "/src/webapp", - "Destination": "/opt/webapp", + "Destination": "/usr/share/nginx/html", "Mode": "", "RW": true, "Propagation": "rprivate" diff --git a/data_management/volume.md b/data_management/volume.md index 89d6d731b..27f388aec 100644 --- a/data_management/volume.md +++ b/data_management/volume.md @@ -10,7 +10,7 @@ * `数据卷` 默认会一直存在,即使容器被删除 ->注意:`数据卷` 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看到的是挂载的 `数据卷`。 +>注意:`数据卷` 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。 ## 创建一个数据卷 @@ -23,6 +23,7 @@ $ docker volume create my-vol ```bash $ docker volume ls +DRIVER VOLUME NAME local my-vol ``` @@ -46,15 +47,14 @@ $ docker volume inspect my-vol 在用 `docker run` 命令的时候,使用 `--mount` 标记来将 `数据卷` 挂载到容器里。在一次 `docker run` 中可以挂载多个 `数据卷`。 -下面创建一个名为 `web` 的容器,并加载一个 `数据卷` 到容器的 `/webapp` 目录。 +下面创建一个名为 `web` 的容器,并加载一个 `数据卷` 到容器的 `/usr/share/nginx/html` 目录。 ```bash $ docker run -d -P \ --name web \ - # -v my-vol:/wepapp \ - --mount source=my-vol,target=/webapp \ - training/webapp \ - python app.py + # -v my-vol:/usr/share/nginx/html \ + --mount source=my-vol,target=/usr/share/nginx/html \ + nginx:alpine ``` ## 查看数据卷的具体信息 @@ -73,7 +73,7 @@ $ docker inspect web "Type": "volume", "Name": "my-vol", "Source": "/var/lib/docker/volumes/my-vol/_data", - "Destination": "/webapp", + "Destination": "/usr/share/nginx/html", "Driver": "local", "Mode": "", "RW": true, diff --git a/network/port_mapping.md b/network/port_mapping.md index ef42475a3..022287aef 100644 --- a/network/port_mapping.md +++ b/network/port_mapping.md @@ -2,35 +2,33 @@ 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 `-P` 或 `-p` 参数来指定端口映射。 -当使用 `-P` 标记时,Docker 会随机映射一个 `49000~49900` 的端口到内部容器开放的网络端口。 +当使用 `-P` 标记时,Docker 会随机映射一个端口到内部容器开放的网络端口。 -使用 `docker container ls` 可以看到,本地主机的 49155 被映射到了容器的 5000 端口。此时访问本机的 49155 端口即可访问容器内 web 应用提供的界面。 +使用 `docker container ls` 可以看到,本地主机的 32768 被映射到了容器的 80 端口。此时访问本机的 32768 端口即可访问容器内 NGINX 默认页面。 ```bash -$ docker run -d -P training/webapp python app.py +$ docker run -d -P nginx:alpine $ docker container ls -l -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +fae320d08268 nginx:alpine "/docker-entrypoint.…" 24 seconds ago Up 20 seconds 0.0.0.0:32768->80/tcp bold_mcnulty ``` -同样的,可以通过 `docker logs` 命令来查看应用的信息。 +同样的,可以通过 `docker logs` 命令来查看访问记录。 ```bash -$ docker logs -f nostalgic_morse -* Running on http://0.0.0.0:5000/ -10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - -10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 - +$ docker logs fa +172.17.0.1 - - [25/Aug/2020:08:34:04 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0" "-" ``` `-p` 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 `ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。 ## 映射所有接口地址 -使用 `hostPort:containerPort` 格式本地的 5000 端口映射到容器的 5000 端口,可以执行 +使用 `hostPort:containerPort` 格式本地的 80 端口映射到容器的 80 端口,可以执行 ```bash -$ docker run -d -p 5000:5000 training/webapp python app.py +$ docker run -d -p 80:80 nginx:alpine ``` 此时默认会绑定本地所有接口上的所有地址。 @@ -40,21 +38,21 @@ $ docker run -d -p 5000:5000 training/webapp python app.py 可以使用 `ip:hostPort:containerPort` 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1 ```bash -$ docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py +$ docker run -d -p 127.0.0.1:80:80 nginx:alpine ``` ## 映射到指定地址的任意端口 -使用 `ip::containerPort` 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。 +使用 `ip::containerPort` 绑定 localhost 的任意端口到容器的 80 端口,本地主机会自动分配一个端口。 ```bash -$ docker run -d -p 127.0.0.1::5000 training/webapp python app.py +$ docker run -d -p 127.0.0.1::80 nginx:alpine ``` 还可以使用 `udp` 标记来指定 `udp` 端口 ```bash -$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py +$ docker run -d -p 127.0.0.1:80:80/udp nginx:alpine ``` ## 查看映射端口配置 @@ -62,12 +60,12 @@ $ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py 使用 `docker port` 来查看当前映射的端口配置,也可以查看到绑定的地址 ```bash -$ docker port nostalgic_morse 5000 -127.0.0.1:49155. +$ docker port fa 80 +0.0.0.0:32768 ``` 注意: -* 容器有自己的内部网络和 ip 地址(使用 `docker inspect` 可以获取所有的变量,Docker 还可以有一个可变的网络配置。) +* 容器有自己的内部网络和 ip 地址(使用 `docker inspect` 查看,Docker 还可以有一个可变的网络配置。) * `-p` 标记可以多次使用来绑定多个端口 @@ -75,8 +73,7 @@ $ docker port nostalgic_morse 5000 ```bash $ docker run -d \ - -p 5000:5000 \ - -p 3000:80 \ - training/webapp \ - python app.py + -p 80:80 \ + -p 443:443 \ + nginx:alpine ``` From 4682ba336ff0cddc2b98f184b827082b1572d0aa Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 25 Aug 2020 18:01:53 +0800 Subject: [PATCH 100/201] improve content Signed-off-by: Kang Huaishuai --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- .github/workflows/check-link.yml | 1 - basic_concept/container.md | 2 +- image/build.md | 26 ++++++++++++++++---------- image/commit.md | 6 +++--- image/pull.md | 6 ++---- introduction/what.md | 2 +- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 39d35fdc7..c33735a4e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ See [CONTRIBUTING](CONTRIBUTING.md) for contribution guidelines. --> -### Proposed changes (Mandatory) +**Proposed changes (Mandatory)** -### Fix issues (Optional) +**Fix issues (Optional)** +Step 2/3 : COPY hello / + ---> ac779757d46e +Step 3/3 : CMD ["/hello"] + ---> Running in d2a513a760ed +Removing intermediate container d2a513a760ed + ---> 038ad4142d2b +Successfully built 038ad4142d2b ``` -这行命令指定了构建所需的 Git repo,并且指定默认的 `master` 分支,构建目录为 `/11.1/`,然后 Docker 就会自己去 `git clone` 这个项目、切换到指定分支、并进入到指定目录后开始构建。 +这行命令指定了构建所需的 Git repo,并且指定分支为 `master`,构建目录为 `/amd64/hello-world/`,然后 Docker 就会自己去 `git clone` 这个项目、切换到指定分支、并进入到指定目录后开始构建。 ### 用给定的 tar 压缩包构建 diff --git a/image/commit.md b/image/commit.md index 1ae37b250..6dcc23103 100644 --- a/image/commit.md +++ b/image/commit.md @@ -16,7 +16,7 @@ $ docker run --name webserver -d -p 80:80 nginx 这条命令会用 `nginx` 镜像启动一个容器,命名为 `webserver`,并且映射了 80 端口,这样我们可以用浏览器去访问这个 `nginx` 服务器。 - 如果是在 Linux 本机运行的 Docker,或者如果使用的是 Docker Desktop for Mac/Windows,那么可以直接访问:;如果使用的是 Docker Toolbox,或者是在虚拟机、云服务器上安装的 Docker,则需要将 `localhost` 换为虚拟机地址或者实际云服务器地址。 + 如果是在本机运行的 Docker,那么可以直接访问:`http://localhost` ,如果是在虚拟机、云服务器上安装的 Docker,则需要将 `localhost` 换为虚拟机地址或者实际云服务器地址。 直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。 @@ -116,7 +116,7 @@ e43d811ce2f4 4 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "da docker run --name web2 -d -p 81:80 nginx:v2 ``` -这里我们命名为新的服务为 `web2`,并且映射到 `81` 端口。如果是 Docker Desktop for Mac/Windows 或 Linux 桌面的话,我们就可以直接访问 看到结果,其内容应该和之前修改后的 `webserver` 一样。 +这里我们命名为新的服务为 `web2`,并且映射到 `81` 端口。访问 `http://localhost:81` 看到结果,其内容应该和之前修改后的 `webserver` 一样。 至此,我们第一次完成了定制镜像,使用的是 `docker commit` 命令,手动操作给旧的镜像添加了新的一层,形成新的镜像,对镜像多层存储应该有了更直观的感觉。 @@ -124,7 +124,7 @@ docker run --name web2 -d -p 81:80 nginx:v2 使用 `docker commit` 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。 -首先,如果仔细观察之前的 `docker diff webserver` 的结果,你会发现除了真正想要修改的 `/usr/share/nginx/html/index.html` 文件外,由于命令的执行,还有很多文件被改动或添加了。这还仅仅是最简单的操作,如果是安装软件包、编译构建,那会有大量的无关内容被添加进来,如果不小心清理,将会导致镜像极为臃肿。 +首先,如果仔细观察之前的 `docker diff webserver` 的结果,你会发现除了真正想要修改的 `/usr/share/nginx/html/index.html` 文件外,由于命令的执行,还有很多文件被改动或添加了。这还仅仅是最简单的操作,如果是安装软件包、编译构建,那会有大量的无关内容被添加进来,将会导致镜像极为臃肿。 此外,使用 `docker commit` 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 **黑箱镜像**,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具体的操作。这种黑箱镜像的维护工作是非常痛苦的。 diff --git a/image/pull.md b/image/pull.md index d2ed771b3..63520a712 100644 --- a/image/pull.md +++ b/image/pull.md @@ -10,7 +10,7 @@ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] 具体的选项可以通过 `docker pull --help` 命令看到,这里我们说一下镜像名称的格式。 -* Docker 镜像仓库地址:地址的格式一般是 `<域名/IP>[:端口号]`。默认地址是 Docker Hub。 +* Docker 镜像仓库地址:地址的格式一般是 `<域名/IP>[:端口号]`。默认地址是 Docker Hub(docker.io)。 * 仓库名:如之前所说,这里的仓库名是两段式名称,即 `<用户名>/<软件名>`。对于 Docker Hub,如果不给出用户名,则默认为 `library`,也就是官方镜像。 比如: @@ -40,9 +40,7 @@ Status: Downloaded newer image for ubuntu:18.04 有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 `ubuntu:18.04` 为例,如果我们打算启动里面的 `bash` 并且进行交互式操作的话,可以执行下面的命令。 ```bash -$ docker run -it --rm \ - ubuntu:18.04 \ - bash +$ docker run -it --rm ubuntu:18.04 bash root@e7009c6ce357:/# cat /etc/os-release NAME="Ubuntu" diff --git a/introduction/what.md b/introduction/what.md index 0787de110..55cdffb68 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -2,7 +2,7 @@ **Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,它是基于 `dotCloud` 公司多年云服务技术的一次革新,并于 [2013 年 3 月以 Apache 2.0 授权协议开源][docker-soft],主要项目代码在 [GitHub](https://github.com/moby/moby) 上进行维护。`Docker` 项目后来还加入了 Linux 基金会,并成立推动 [开放容器联盟(OCI)](https://opencontainers.org/)。 -**Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 4 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 +**Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 7 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 **Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [OverlayFS](https://docs.docker.com/storage/storagedriver/overlayfs-driver/) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 From c25c7283cf8915f26a6796b7b958839257f3d0d5 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 25 Aug 2020 19:42:35 +0800 Subject: [PATCH 101/201] remove opensource Signed-off-by: Kang Huaishuai --- opensource/README.md | 3 --- opensource/linuxkit.md | 51 ------------------------------------------ 2 files changed, 54 deletions(-) delete mode 100644 opensource/README.md delete mode 100644 opensource/linuxkit.md diff --git a/opensource/README.md b/opensource/README.md deleted file mode 100644 index d9f54502a..000000000 --- a/opensource/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Docker 开源项目 - -本章介绍 Docker 开源的项目。随着 Docker 功能的越来越多,Docker 也加快了开源的步伐,Docker 未来会将引擎拆分为更多开放组件,对用于组装 Docker 产品的各种新型工具与组件进行开源并供技术社区使用。 diff --git a/opensource/linuxkit.md b/opensource/linuxkit.md deleted file mode 100644 index 087e9de00..000000000 --- a/opensource/linuxkit.md +++ /dev/null @@ -1,51 +0,0 @@ -# LinuxKit - -`LinuxKit` 这个工具可以将多个 Docker 镜像组成一个最小化、可自由定制的 Linux 系统,最后的生成的系统只有几十 M 大小,可以很方便的在云端进行部署。 - -下面我们在 macOS 上通过实例,来编译并运行一个全部由 Docker 镜像组成的包含 nginx 服务的 Linux 系统。 - -## 安装 Linuxkit - -```bash -$ brew tap linuxkit/linuxkit - -$ brew install --HEAD linuxkit -``` - -## 克隆源代码 - -```bash -$ git clone -b master --depth=1 https://github.com/linuxkit/linuxkit - -$ cd linuxkit -``` - -## 编译 Linux 系统 - -LinuxKit 通过 `yaml` 文件配置。 - -我们来查看 `linuxkit.yml` 文件,了解各个字段的作用。 - -`kernel` 字段定义了内核版本。 - -`init` 字段中配置系统启动时的初始化顺序。 - -`onboot` 字段配置系统级的服务。 - -`services` 字段配置镜像启动后运行的服务。 - -`files` 字段配置制作镜像时打包入镜像中的文件。 - -```bash -$ linuxkit build linuxkit.yml -``` - -## 启动 Linux 系统 - -编译成功后,接下来启动这个 Linux 系统。 - -```bash -$ linuxkit run -publish 8080:80/tcp linuxkit -``` - -接下来在浏览器中打开 `127.0.0.1:8080` 即可看到 nginx 默认页面。 From eac2a57633befe99b9ac958516113d45ff513aa1 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 27 Aug 2020 23:09:11 +0800 Subject: [PATCH 102/201] Update vuepress nav Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 143 ++++++++++++++++++++------------------- SUMMARY.md | 2 - coreos/README.md | 2 +- image/dockerfile/copy.md | 2 + image/dockerfile/user.md | 2 +- 5 files changed, 77 insertions(+), 74 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 688907437..cd2a62e38 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -36,54 +36,55 @@ module.exports = { docsRepo: 'yeasy/docker_practice', docsDir: '/', editLinks: true, - nav: [{ - text: '安装 Docker', - link: '/install/', - }, - { - text: 'Docker 入门', - link: '/' - }, - { - text: 'Docker 实战', - link: '/cases/os/' - }, - { - text: 'CI/CD', - link: '/cases/ci/' - }, - { - text: 'Docker 仓库', - link: '/repository/' - }, - { - text: '底层实现', - link: '/underly/', - }, - { - text: 'Compose', - link: '/compose/', - }, - { - text: 'Kubernetes', - link: '/kubernetes/', - }, - { - text: "云计算", - link: "/cloud/", - }, - { - text: 'GitHub', - link: 'https://github.com/yeasy/docker_practice' - }, - // { - // text: '捐赠', - // link: '' - // }, - { - text: '腾讯云容器服务', - link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' - }, + nav: [ + { + text: '微信交流群', + link: 'https://yewm28.coding-pages.com/wechat.jpg', + }, + { + text: '小程序', + link: 'https://yewm28.coding-pages.com/49682252-3ac4c500-faec-11e8-86ab-eafe0139be6b.jpg', + }, + { + text: '安装 Docker', + link: '/install/', + }, + { + text: 'Docker 入门', + link: '/' + }, + { + text: 'Docker 实战', + link: '/cases/os/' + }, + { + text: 'CI/CD', + link: '/cases/ci/' + }, + { + text: 'Compose', + link: '/compose/', + }, + { + text: 'Kubernetes', + link: '/kubernetes/', + }, + { + text: "云计算", + link: "/cloud/", + }, + { + text: 'GitHub', + link: 'https://github.com/yeasy/docker_practice' + }, + // { + // text: '捐赠', + // link: '' + // }, + { + text: '腾讯云容器服务', + link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' + }, // { // text: '语言', // items: [{ @@ -146,20 +147,6 @@ module.exports = { 'mirror', 'experimental', ], - '/underly/': [ - 'arch', - 'namespace', - 'cgroups', - 'ufs', - 'container_format', - 'network', - ], - '/repository/': [ - 'dockerhub', - 'registry', - 'registry_auth', - 'nexus3_registry', - ], '/cases/os/': [ { title: "操作系统", @@ -264,6 +251,17 @@ module.exports = { 'container/rm', ], }, + { + title: "Docker 仓库", + collapsable: false, + children: [ + 'repository/', + 'repository/dockerhub', + 'repository/registry', + 'repository/registry_auth', + 'repository/nexus3_registry', + ], + }, { title: "数据管理", collapsable: false, @@ -323,6 +321,19 @@ module.exports = { 'security/summary', ], }, + { + title: "底层实现", + collapsable: false, + children: [ + 'underly/', + 'underly/arch', + 'underly/namespace', + 'underly/cgroups', + 'underly/ufs', + 'underly/container_format', + 'underly/network', + ], + }, { title: "Docker Buildx", collapsable: false, @@ -353,14 +364,6 @@ module.exports = { 'coreos/install', ], }, - { - title: "Docker 开源项目", - collapsable: false, - children: [ - 'opensource/', - 'opensource/linuxkit', - ], - }, 'podman/', 'appendix/faq/', { diff --git a/SUMMARY.md b/SUMMARY.md index 3fba08427..3392212d6 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -147,8 +147,6 @@ * [Travis CI](cases/ci/travis/README.md) * [在 IDE 中使用 Docker](ide/README.md) * [VS Code](ide/vsCode.md) -* [Docker 开源项目](opensource/README.md) - * [LinuxKit](opensource/linuxkit.md) * [podman - 下一代 Linux 容器工具](podman/README.md) * [附录](appendix/README.md) * [附录一:常见问题总结](appendix/faq/README.md) diff --git a/coreos/README.md b/coreos/README.md index 9fbf86091..ca63655c8 100644 --- a/coreos/README.md +++ b/coreos/README.md @@ -1,6 +1,6 @@ # Fedora CoreOS -`CoreOS` 是一个专门为安全和大规模运行容器化工作负载而构建的新 Fedora 版本,它是 Fedora Atomic Host 和 CoreOS Container Linux 的后续项目。 +`CoreOS` 是一个专门为安全和大规模运行容器化工作负载而构建的新 Fedora 版本,它是 Fedora Atomic Host 和 CoreOS Container Linux 的后继项目。 `CoreOS` 的安装文件和运行依赖非常小,它提供了精简的 Linux 系统。它使用 Linux 容器在更高的抽象层来管理你的服务,而不是通过常规的包管理工具 `yum` 或 `apt` 来安装包。 diff --git a/image/dockerfile/copy.md b/image/dockerfile/copy.md index d12b446c8..0d482335f 100644 --- a/image/dockerfile/copy.md +++ b/image/dockerfile/copy.md @@ -32,3 +32,5 @@ COPY --chown=bin files* /mydir/ COPY --chown=1 files* /mydir/ COPY --chown=10:11 files* /mydir/ ``` + +如果源路径为文件夹,复制的时候不是直接复制该文件夹,而是将文件夹中的内容复制到目标路径。 diff --git a/image/dockerfile/user.md b/image/dockerfile/user.md index 260b439b1..0fb7dabc7 100644 --- a/image/dockerfile/user.md +++ b/image/dockerfile/user.md @@ -18,7 +18,7 @@ RUN [ "redis-server" ] # 建立 redis 用户,并使用 gosu 换另一个用户执行命令 RUN groupadd -r redis && useradd -r -g redis redis # 下载 gosu -RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64" \ +RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64" \ && chmod +x /usr/local/bin/gosu \ && gosu nobody true # 设置 CMD,并以另外的用户执行 From e021b27323e34de342a3014daf2cd366308212ad Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 29 Aug 2020 15:30:32 +0800 Subject: [PATCH 103/201] registry image not include htpasswd Signed-off-by: Kang Huaishuai --- repository/registry_auth.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/registry_auth.md b/repository/registry_auth.md index 68fda836a..2776bfea6 100644 --- a/repository/registry_auth.md +++ b/repository/registry_auth.md @@ -131,7 +131,7 @@ $ mkdir auth $ docker run --rm \ --entrypoint htpasswd \ - registry \ + httpd:alpine \ -Bbn username password > auth/nginx.htpasswd ``` From 4b70a27151f2eb5bc4faeee25f2fd1abf1e9c173 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 29 Aug 2020 15:46:24 +0800 Subject: [PATCH 104/201] link-check exclude ip.cn Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index d595c3eac..335c28044 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -59,6 +59,7 @@ jobs: "x.x.x.x/base",\ "x.x.x.x:9000/minio/",\ "https://www.freedesktop.org/wiki/Software/systemd/",\ + "ip.cn",\ "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ From d1e303d139ec5449c6c6ee7c1af25ffee1b1ddc1 Mon Sep 17 00:00:00 2001 From: jackeylv Date: Fri, 4 Sep 2020 14:19:05 +0800 Subject: [PATCH 105/201] fix #461 https://github.com/yeasy/docker_practice/issues/461#issue-692771052 Signed-off-by: jackeylv --- install/debian.md | 2 +- install/raspberry-pi.md | 2 +- install/ubuntu.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/install/debian.md b/install/debian.md index 28c88a8a6..d47c991fc 100644 --- a/install/debian.md +++ b/install/debian.md @@ -49,7 +49,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-k # $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - ``` -然后,我们需要向 `source.list` 中添加 Docker CE 软件源: +然后,我们需要向 `sources.list` 中添加 Docker CE 软件源: ```bash $ sudo add-apt-repository \ diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 66ee99be3..5d0eb8531 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -40,7 +40,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/raspbian/gpg | sudo apt # $ curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo apt-key add - ``` -然后,我们需要向 `source.list` 中添加 Docker CE 软件源: +然后,我们需要向 `sources.list` 中添加 Docker CE 软件源: ```bash $ sudo add-apt-repository \ diff --git a/install/ubuntu.md b/install/ubuntu.md index bee34bbf1..0435b086c 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -51,7 +51,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-k # $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - ``` -然后,我们需要向 `source.list` 中添加 Docker 软件源 +然后,我们需要向 `sources.list` 中添加 Docker 软件源 ```bash $ sudo add-apt-repository \ From 90a73163222cc3c0447704a7c24bd3ffdfab2fb1 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 08:52:31 +0800 Subject: [PATCH 106/201] buildkit more arg --- buildx/buildkit.md | 6 ++-- buildx/multi-arch-images.md | 60 ++++++++++++++++++++++++++++++++++++- kubernetes/setup/kubeadm.md | 8 ++--- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/buildx/buildkit.md b/buildx/buildkit.md index 235e1e60c..e8300a053 100644 --- a/buildx/buildkit.md +++ b/buildx/buildkit.md @@ -4,8 +4,6 @@ **注意:如果您的镜像构建使用的是云服务商提供的镜像构建服务(腾讯云容器服务、阿里云容器服务等),由于上述服务提供商的 Docker 版本低于 18.09,BuildKit 无法使用,将造成镜像构建失败。建议使用 BuildKit 构建镜像时使用一个新的 Dockerfile 文件(例如 Dockerfile.buildkit)** -**注意:docker-compose build 命令暂时不支持 BuildKit** - 目前,Docker Hub 自动构建已经支持 buildkit,具体请参考 https://github.com/docker-practice/docker-hub-buildx ## `Dockerfile` 新增指令详解 @@ -147,6 +145,10 @@ $ ssh-add ~/.ssh/id_rsa $ docker build -t test --ssh default=$SSH_AUTH_SOCK . ``` +## docker-compose build 使用 Buildkit + +设置 `COMPOSE_DOCKER_CLI_BUILD=1` 环境变量即可使用。 + ## 官方文档 * https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md diff --git a/buildx/multi-arch-images.md b/buildx/multi-arch-images.md index 79b66aef2..4cc94839c 100644 --- a/buildx/multi-arch-images.md +++ b/buildx/multi-arch-images.md @@ -9,7 +9,7 @@ Docker for Linux 不支持构建 `arm` 架构镜像,我们可以运行一个新的容器让其支持该特性,Docker 桌面版无需进行此项设置。 ```bash -$ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3 +$ docker run --rm --privileged tonistiigi/binfmt:latest --install all ``` 由于 Docker 默认的 `builder` 实例不支持同时指定多个 `--platform`,我们必须首先创建一个新的 `builder` 实例。同时由于国内拉取镜像较缓慢,我们可以使用配置了 [镜像加速地址](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) 的 [`dockerpracticesig/buildkit:master`](https://github.com/docker-practice/buildx) 镜像替换官方镜像。 @@ -66,3 +66,61 @@ Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 aarch6 $ docker run -it --rm myusername/hello Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 Linux ``` + +## 架构相关变量 + +`Dockerfile` 支持如下架构相关的变量 + +**TARGETPLATFORM** + +构建镜像的目标平台,例如 `linux/amd64`, `linux/arm/v7`, `windows/amd64`。 + +**TARGETOS** + +`TARGETPLATFORM` 的 OS 类型,例如 `linux`, `windows` + +**TARGETARCH** + +`TARGETPLATFORM` 的架构类型,例如 `amd64`, `arm` + +**TARGETVARIANT** + +`TARGETPLATFORM` 的变种,该变量可能为空,例如 `v7` + +**BUILDPLATFORM** + +构建镜像主机平台,例如 `linux/amd64` + +**BUILDOS** + +`BUILDPLATFORM` 的 OS 类型,例如 `linux` + +**BUILDARCH** + +`BUILDPLATFORM` 的架构类型,例如 `amd64` + +**BUILDVARIANT** + +`BUILDPLATFORM` 的变种,该变量可能为空,例如 `v7` + +### 使用举例 + +例如我们要构建支持 `linux/arm/v7` 和 `linux/amd64` 两种架构的镜像。假设已经生成了两个平台对应的二进制文件: + +* bin/dist-linux-arm +* bin/dist-linux-amd64 + +那么 `Dockerfile` 可以这样书写: + +```bash +FROM scratch + +# 使用变量必须申明 +ARG TARGETOS + +ARG TARGETARCH + +COPY bin/dist-${TARGETOS}-${TARGETARCH} /dist + +ENTRYPOINT ["dist"] +``` diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md index 828d566d1..3ee8400fb 100644 --- a/kubernetes/setup/kubeadm.md +++ b/kubernetes/setup/kubeadm.md @@ -60,10 +60,10 @@ $ sysctl --system ```bash # 启用 ipvs 相关内核模块 [Service] -ExecStartPre=-modprobe ip_vs -ExecStartPre=-modprobe ip_vs_rr -ExecStartPre=-modprobe ip_vs_wrr -ExecStartPre=-modprobe ip_vs_sh +ExecStartPre=-/sbin/modprobe ip_vs +ExecStartPre=-/sbin/modprobe ip_vs_rr +ExecStartPre=-/sbin/modprobe ip_vs_wrr +ExecStartPre=-/sbin/modprobe ip_vs_sh ``` 执行以下命令应用配置。 From b0ccb74dbd27864befdc00eadae9946671555be8 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 09:15:03 +0800 Subject: [PATCH 107/201] [install] Add CentOS 8 Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 1 + SUMMARY.md | 1 + install/centos8.md | 5 +++++ 3 files changed, 7 insertions(+) create mode 100644 install/centos8.md diff --git a/.vuepress/config.js b/.vuepress/config.js index cd2a62e38..cc2ef1dc7 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -140,6 +140,7 @@ module.exports = { 'debian', 'fedora', 'centos', + 'centos8', 'raspberry-pi', 'offline', 'mac', diff --git a/SUMMARY.md b/SUMMARY.md index 3392212d6..db95cf3d6 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -15,6 +15,7 @@ * [Debian](install/debian.md) * [Fedora](install/fedora.md) * [CentOS](install/centos.md) + * [CentOS8](install/centos8.md) * [Raspberry Pi](install/raspberry-pi.md) * [Linux 离线安装](install/offline.md) * [macOS](install/mac.md) diff --git a/install/centos8.md b/install/centos8.md new file mode 100644 index 000000000..3b110d238 --- /dev/null +++ b/install/centos8.md @@ -0,0 +1,5 @@ +# CentOS8 安装 Docker CE + +当前官方版本的 Docker CE [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot。 + +[docker-docker]:https://download.docker.com/linux/centos/ From cc210f75a73369457854c27993fc92ab6a1cbf1b Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 09:30:17 +0800 Subject: [PATCH 108/201] [install] Update CentOS8 Signed-off-by: Kang Huaishuai --- install/centos8.md | 24 ++++++++++++++++++++++++ install/ubuntu.md | 1 - 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/install/centos8.md b/install/centos8.md index 3b110d238..02778ffaa 100644 --- a/install/centos8.md +++ b/install/centos8.md @@ -3,3 +3,27 @@ 当前官方版本的 Docker CE [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot。 [docker-docker]:https://download.docker.com/linux/centos/ + +## 设置 + +由于 CentOS8 防火墙使用了 `nftables`,我们可以使用如下设置使用 `iptables` + +更改 `/etc/firewalld/firewalld.conf` + +```bash +# FirewallBackend=nftables +FirewallBackend=iptables +``` + +或者执行如下命令: + +```bash +$ firewall-cmd --permanent --zone=trusted --add-interface=docker0 + +$ firewall-cmd --reload +``` + +## 参考链接 + +* https://firewalld.org/2018/07/nftables-backend +* https://github.com/moby/libnetwork/issues/2496 diff --git a/install/ubuntu.md b/install/ubuntu.md index 0435b086c..a13629b3f 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -9,7 +9,6 @@ Docker CE 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: * Ubuntu Focal 20.04 (LTS) -* Eoan 19.10 * Bionic 18.04 (LTS) * Xenial 16.04 (LTS) From c1c7a7981d827baf143708c090d8616bfcdaa917 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 09:40:55 +0800 Subject: [PATCH 109/201] Fixed 301 link Signed-off-by: Kang Huaishuai --- repository/nexus3_registry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/nexus3_registry.md b/repository/nexus3_registry.md index 5f35eddd5..44126130d 100644 --- a/repository/nexus3_registry.md +++ b/repository/nexus3_registry.md @@ -1,6 +1,6 @@ # Nexus3.x 的私有仓库 -使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/download-oss-sonatype) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 +使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/nexus/repository-oss/download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 ## 启动 Nexus 容器 From 4f7b448f0ca5808bf86dd7e6f8e4f10f5dbd643d Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 09:51:53 +0800 Subject: [PATCH 110/201] [install] remove nightly version Signed-off-by: Kang Huaishuai --- install/centos.md | 6 ------ install/debian.md | 2 +- install/fedora.md | 6 ------ install/raspberry-pi.md | 2 +- install/ubuntu.md | 2 +- 5 files changed, 3 insertions(+), 15 deletions(-) diff --git a/install/centos.md b/install/centos.md index cdf8831b2..929f8e552 100644 --- a/install/centos.md +++ b/install/centos.md @@ -58,12 +58,6 @@ $ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum. $ sudo yum-config-manager --enable docker-ce-test ``` -如果需要每日构建版本的 Docker CE 请使用以下命令: - -```bash -$ sudo yum-config-manager --enable docker-ce-nightly -``` - ### 安装 Docker CE 更新 `yum` 软件源缓存,并安装 `docker-ce`。 diff --git a/install/debian.md b/install/debian.md index d47c991fc..b66e0c259 100644 --- a/install/debian.md +++ b/install/debian.md @@ -64,7 +64,7 @@ $ sudo add-apt-repository \ # stable" ``` ->以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。 +>以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试版本的 Docker CE 请将 stable 改为 test。 ### 安装 Docker CE diff --git a/install/fedora.md b/install/fedora.md index 384dfd696..1fd500291 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -59,12 +59,6 @@ $ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum. $ sudo dnf config-manager --set-enabled docker-ce-test ``` -如果需要每日构建版本的 Docker CE 请使用以下命令: - -```bash -$ sudo dnf config-manager --set-enabled docker-ce-nightly -``` - 你也可以禁用测试版本的 Docker CE ```bash diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 5d0eb8531..c297c1254 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -56,7 +56,7 @@ $ sudo add-apt-repository \ # stable" ``` ->以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。 +>以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试版本的 Docker CE 请将 stable 改为 test。 ### 安装 Docker CE diff --git a/install/ubuntu.md b/install/ubuntu.md index a13629b3f..9e0ff1544 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -66,7 +66,7 @@ $ sudo add-apt-repository \ # stable" ``` ->以上命令会添加稳定版本的 Docker CE APT 镜像源,如果需要测试或每日构建版本的 Docker CE 请将 stable 改为 test 或者 nightly。 +>以上命令会添加稳定版本的 Docker CE APT 镜像源,如果需要测试版本的 Docker CE 请将 stable 改为 test。 ### 安装 Docker CE From 4f08e73bfe19380ea37c0c24115e5aec11ceb93a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 10:06:15 +0800 Subject: [PATCH 111/201] [install] Update CentOS8 Signed-off-by: Kang Huaishuai --- install/centos8.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/centos8.md b/install/centos8.md index 02778ffaa..5110c052a 100644 --- a/install/centos8.md +++ b/install/centos8.md @@ -1,12 +1,12 @@ # CentOS8 安装 Docker CE -当前官方版本的 Docker CE [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot。 +当前官方版本的 Docker CE [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot [docker-docker]:https://download.docker.com/linux/centos/ ## 设置 -由于 CentOS8 防火墙使用了 `nftables`,我们可以使用如下设置使用 `iptables` +由于 CentOS8 防火墙使用了 `nftables`,但 Docker CE 尚未支持 `nftables`, 我们可以使用如下设置使用 `iptables`: 更改 `/etc/firewalld/firewalld.conf` From 6fcf3028092cf936f04fc3f4eeb8e81d0cb48845 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 10:14:38 +0800 Subject: [PATCH 112/201] Update format Signed-off-by: Kang Huaishuai --- buildx/multi-arch-images.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/buildx/multi-arch-images.md b/buildx/multi-arch-images.md index 4cc94839c..8b190fbf0 100644 --- a/buildx/multi-arch-images.md +++ b/buildx/multi-arch-images.md @@ -107,12 +107,12 @@ Linux buildkitsandbox 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 例如我们要构建支持 `linux/arm/v7` 和 `linux/amd64` 两种架构的镜像。假设已经生成了两个平台对应的二进制文件: -* bin/dist-linux-arm -* bin/dist-linux-amd64 +* `bin/dist-linux-arm` +* `bin/dist-linux-amd64` 那么 `Dockerfile` 可以这样书写: -```bash +```docker FROM scratch # 使用变量必须申明 From 48785525e066b923b92ec67228170d098975bdc6 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 14:18:12 +0800 Subject: [PATCH 113/201] Fixed kubeadm error Signed-off-by: Kang Huaishuai --- kubernetes/setup/kubeadm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md index 3ee8400fb..64d314421 100644 --- a/kubernetes/setup/kubeadm.md +++ b/kubernetes/setup/kubeadm.md @@ -163,7 +163,7 @@ $ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ $ kubectl get node -o yaml | grep CIDR # 输出 - podCIDR: 10.244.0.0/24 + podCIDR: 10.244.0.0/16 podCIDRs: ``` From 5d91c5a39fc38f3be135461ec563210f45462063 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 17:43:21 +0800 Subject: [PATCH 114/201] replace ip.cn Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 - image/dockerfile/entrypoint.md | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 335c28044..d595c3eac 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -59,7 +59,6 @@ jobs: "x.x.x.x/base",\ "x.x.x.x:9000/minio/",\ "https://www.freedesktop.org/wiki/Software/systemd/",\ - "ip.cn",\ "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ diff --git a/image/dockerfile/entrypoint.md b/image/dockerfile/entrypoint.md index 3f7ebfa29..bd13ed8da 100644 --- a/image/dockerfile/entrypoint.md +++ b/image/dockerfile/entrypoint.md @@ -21,7 +21,7 @@ FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* -CMD [ "curl", "-s", "http://ip.cn" ] +CMD [ "curl", "-s", "http://myip.ipip.net" ] ``` 假如我们使用 `docker build -t myip .` 来构建镜像的话,如果我们需要查询当前公网 IP,只需要执行: @@ -38,12 +38,12 @@ $ docker run myip -i docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"-i\\\": executable file not found in $PATH\"\n". ``` -我们可以看到可执行文件找不到的报错,`executable file not found`。之前我们说过,跟在镜像名后面的是 `command`,运行时会替换 `CMD` 的默认值。因此这里的 `-i` 替换了原来的 `CMD`,而不是添加在原来的 `curl -s http://ip.cn` 后面。而 `-i` 根本不是命令,所以自然找不到。 +我们可以看到可执行文件找不到的报错,`executable file not found`。之前我们说过,跟在镜像名后面的是 `command`,运行时会替换 `CMD` 的默认值。因此这里的 `-i` 替换了原来的 `CMD`,而不是添加在原来的 `curl -s http://myip.ipip.net` 后面。而 `-i` 根本不是命令,所以自然找不到。 那么如果我们希望加入 `-i` 这参数,我们就必须重新完整的输入这个命令: ```bash -$ docker run myip curl -s http://ip.cn -i +$ docker run myip curl -s http://myip.ipip.net -i ``` 这显然不是很好的解决方案,而使用 `ENTRYPOINT` 就可以解决这个问题。现在我们重新用 `ENTRYPOINT` 来实现这个镜像: @@ -53,7 +53,7 @@ FROM ubuntu:18.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* -ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] +ENTRYPOINT [ "curl", "-s", "http://myip.ipip.net" ] ``` 这次我们再来尝试直接使用 `docker run myip -i`: @@ -109,8 +109,8 @@ CMD [ "redis-server" ] ... # allow the container to be started with `--user` if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then - chown -R redis . - exec su-exec redis "$0" "$@" + find . \! -user redis -exec chown redis '{}' + + exec gosu redis "$0" "$@" fi exec "$@" From cbaa24c48f0a41e4adaec7c128ccde6d1ba99cc4 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 20:16:04 +0800 Subject: [PATCH 115/201] Dockerfile add shell label Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 2 ++ SUMMARY.md | 2 ++ image/dockerfile/arg.md | 59 +++++++++++++++++++++++++++++++++++++ image/dockerfile/label.md | 17 +++++++++++ image/dockerfile/shell.md | 33 +++++++++++++++++++++ image/dockerfile/workdir.md | 18 +++++++++++ 6 files changed, 131 insertions(+) create mode 100644 image/dockerfile/label.md create mode 100644 image/dockerfile/shell.md diff --git a/.vuepress/config.js b/.vuepress/config.js index cc2ef1dc7..876a2442b 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -233,6 +233,8 @@ module.exports = { 'image/dockerfile/workdir', 'image/dockerfile/user', 'image/dockerfile/healthcheck', + 'image/dockerfile/label', + 'image/dockerfile/shell', 'image/dockerfile/onbuild', 'image/dockerfile/references', 'image/multistage-builds/', diff --git a/SUMMARY.md b/SUMMARY.md index db95cf3d6..2ba58f02a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -41,6 +41,8 @@ * [USER 指定当前用户](image/dockerfile/user.md) * [HEALTHCHECK 健康检查](image/dockerfile/healthcheck.md) * [ONBUILD 为他人作嫁衣裳](image/dockerfile/onbuild.md) + * [LABEL 为镜像添加元数据](image/dockerfile/label.md) + * [SHELL 指令](image/dockerfile/shell.md) * [参考文档](image/dockerfile/references.md) * [Dockerfile 多阶段构建](image/multistage-builds/README.md) * [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md) diff --git a/image/dockerfile/arg.md b/image/dockerfile/arg.md index fb7be3d80..d4b270813 100644 --- a/image/dockerfile/arg.md +++ b/image/dockerfile/arg.md @@ -7,3 +7,62 @@ `Dockerfile` 中的 `ARG` 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 `docker build` 中用 `--build-arg <参数名>=<值>` 来覆盖。 在 1.13 之前的版本,要求 `--build-arg` 中的参数名,必须在 `Dockerfile` 中用 `ARG` 定义过了,换句话说,就是 `--build-arg` 指定的参数,必须在 `Dockerfile` 中使用了。如果对应参数没有被使用,则会报错退出构建。从 1.13 开始,这种严格的限制被放开,不再报错退出,而是显示警告信息,并继续构建。这对于使用 CI 系统,用同样的构建流程构建不同的 `Dockerfile` 的时候比较有帮助,避免构建命令必须根据每个 Dockerfile 的内容修改。 + +ARG 指令有生效范围,如果在 `FROM` 指令之前指定,那么只能用于 `FROM` 指令中。 + +```docker +ARG DOCKER_USERNAME=library + +FROM ${DOCKER_USERNAME}/alpine + +RUN set -x ; echo ${DOCKER_USERNAME} +``` + +使用上述 Dockerfile 会发现无法输出 `${DOCKER_USERNAME}` 变量的值,要想正常输出,你必须在 `FROM` 之后再次指定 `ARG` + +```docker +# 只在 FROM 中生效 +ARG DOCKER_USERNAME=library + +FROM ${DOCKER_USERNAME}/alpine + +# 要想在 FROM 之后使用,必须再次指定 +ARG DOCKER_USERNAME=library + +RUN set -x ; echo ${DOCKER_USERNAME} +``` + +对于多阶段构建,尤其要注意这个问题 + +```docker +# 这个变量在每个 FROM 中都生效 +ARG DOCKER_USERNAME=library + +FROM ${DOCKER_USERNAME}/alpine + +RUN set -x ; echo 1 + +FROM ${DOCKER_USERNAME}/alpine + +RUN set -x ; echo 2 +``` + +对于上述 Dockerfile 两个 `FROM` 指令都可以使用 `${DOCKER_USERNAME}`,对于在各个阶段中使用的变量都必须在每个阶段分别指定: + +```docker +ARG DOCKER_USERNAME=library + +FROM ${DOCKER_USERNAME}/alpine + +# 在FROM 之后使用变量,必须在每个阶段分别指定 +ARG DOCKER_USERNAME=library + +RUN set -x ; echo ${DOCKER_USERNAME} + +FROM ${DOCKER_USERNAME}/alpine + +# 在FROM 之后使用变量,必须在每个阶段分别指定 +ARG DOCKER_USERNAME=library + +RUN set -x ; echo ${DOCKER_USERNAME} +``` diff --git a/image/dockerfile/label.md b/image/dockerfile/label.md new file mode 100644 index 000000000..1f816de64 --- /dev/null +++ b/image/dockerfile/label.md @@ -0,0 +1,17 @@ +# LABEL 指令 + +`LABEL` 指令用来给镜像以键值对的形式添加一些元数据(metadata)。 + +```docker +LABEL = = = ... +``` + +我们还可以用一些标签来申明镜像的作者、文档地址等: + +```docker +LABEL org.opencontainers.image.authors="yeasy" + +LABEL org.opencontainers.image.documentation="https://yeasy.gitbooks.io" +``` + +具体可以参考 https://github.com/opencontainers/image-spec/blob/master/annotations.md diff --git a/image/dockerfile/shell.md b/image/dockerfile/shell.md new file mode 100644 index 000000000..c207c39dc --- /dev/null +++ b/image/dockerfile/shell.md @@ -0,0 +1,33 @@ +# SHELL 指令 + +格式:`SHELL ["executable", "parameters"]` + +`SHELL` 指令可以指定 `RUN` `ENTRYPOINT` `CMD` 指令的 shell,Linux 中默认为 `["/bin/sh", "-c"]` + +```docker +SHELL ["/bin/sh", "-c"] + +RUN lll ; ls + +SHELL ["/bin/sh", "-cex"] + +RUN lll ; ls +``` + +两个 `RUN` 运行同一命令,第二个 `RUN` 运行的命令会打印出每条命令并当遇到错误时退出。 + +当 `ENTRYPOINT` `CMD` 以 shell 格式指定时,`SHELL` 指令所指定的 shell 也会成为这两个指令的 shell + +```docker +SHELL ["/bin/sh", "-cex"] + +# /bin/sh -cex "nginx" +ENTRYPOINT nginx +``` + +```docker +SHELL ["/bin/sh", "-cex"] + +# /bin/sh -cex "nginx" +CMD nginx +``` diff --git a/image/dockerfile/workdir.md b/image/dockerfile/workdir.md index 642281215..79ad39587 100644 --- a/image/dockerfile/workdir.md +++ b/image/dockerfile/workdir.md @@ -16,3 +16,21 @@ RUN echo "hello" > world.txt 之前说过每一个 `RUN` 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 `RUN cd /app` 的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。 因此如果需要改变以后各层的工作目录的位置,那么应该使用 `WORKDIR` 指令。 + +```docker +WORKDIR /app + +RUN echo "hello" > world.txt +``` + +如果你的 `WORKDIR` 指令使用的相对路径,那么所切换的路径与之前的 `WORKDIR` 有关: + +```docker +WORKDIR /a +WORKDIR b +WORKDIR c + +RUN pwd +``` + +`pwd` 输出的结果为 `/a/b/c`。 From 58c09788f61fb55d4c3f6ef00a467c4889c0c5d2 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Sep 2020 21:04:01 +0800 Subject: [PATCH 116/201] Add link Signed-off-by: Kang Huaishuai --- security/daemon_sec.md | 6 +++--- security/kernel_capability.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/security/daemon_sec.md b/security/daemon_sec.md index 014ba12ae..e43359ce4 100644 --- a/security/daemon_sec.md +++ b/security/daemon_sec.md @@ -7,12 +7,12 @@ 为了加强对服务端的保护,Docker 的 REST API(客户端用来跟服务端通信)在 0.5.2 之后使用本地的 Unix 套接字机制替代了原先绑定在 127.0.0.1 上的 TCP 套接字,因为后者容易遭受跨站脚本攻击。现在用户使用 Unix 权限检查来加强套接字的访问安全。 -用户仍可以利用 HTTP 提供 REST API 访问。建议使用安全机制,确保只有可信的网络或 VPN,或证书保护机制(例如受保护的 stunnel 和 ssl 认证)下的访问可以进行。此外,还可以使用 HTTPS 和证书来加强保护。 +用户仍可以利用 HTTP 提供 REST API 访问。建议使用安全机制,确保只有可信的网络或 VPN,或证书保护机制(例如受保护的 stunnel 和 ssl 认证)下的访问可以进行。此外,还可以使用 [ HTTPS 和证书](https://docs.docker.com/engine/security/https/) 来加强保护。 最近改进的 Linux 命名空间机制将可以实现使用非 root 用户来运行全功能的容器。这将从根本上解决了容器和主机之间共享文件系统而引起的安全问题。 终极目标是改进 2 个重要的安全特性: -* 将容器的 root 用户映射到本地主机上的非 root 用户,减轻容器和主机之间因权限提升而引起的安全问题; -* 允许 Docker 服务端在 [非 root 权限](https://docs.docker.com/engine/security/rootless/) 下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。 +* 将容器的 root 用户 [映射到本地主机上的非 root 用户](https://docs.docker.com/engine/security/userns-remap/),减轻容器和主机之间因权限提升而引起的安全问题; +* 允许 Docker 服务端在 [非 root 权限(rootless 模式)](https://docs.docker.com/engine/security/rootless/) 下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。 最后,建议采用专用的服务器来运行 Docker 和相关的管理服务(例如管理服务比如 ssh 监控和进程监控、管理工具 nrpe、collectd 等)。其它的业务服务都放到容器中去运行。 diff --git a/security/kernel_capability.md b/security/kernel_capability.md index 4ebc9eabf..8d48b277c 100644 --- a/security/kernel_capability.md +++ b/security/kernel_capability.md @@ -1,6 +1,6 @@ # 内核能力机制 -能力机制(Capability)是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制。 +[能力机制(Capability)](https://man7.org/linux/man-pages/man7/capabilities.7.html) 是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制。 Linux 内核自 2.2 版本起就支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。 例如,一个 Web 服务进程只需要绑定一个低于 1024 的端口的权限,并不需要 root 权限。那么它只需要被授权 `net_bind_service` 能力即可。此外,还有很多其他的类似能力来避免进程获取 root 权限。 @@ -22,5 +22,5 @@ Linux 内核自 2.2 版本起就支持能力机制,它将权限划分为更加 这样,就算攻击者在容器中取得了 root 权限,也不能获得本地主机的较高权限,能进行的破坏也有限。 -默认情况下,Docker采用白名单机制,禁用必需功能之外的其它权限。 +默认情况下,Docker采用 [白名单](https://github.com/moby/moby/blob/master/oci/caps/defaults.go) 机制,禁用必需功能之外的其它权限。 当然,用户也可以根据自身需求来为 Docker 容器启用额外的权限。 From d071ed7b997a709dd42d30a32beb03a5acdb2eb5 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 16 Sep 2020 17:40:22 +0800 Subject: [PATCH 117/201] Fixed 404 link --- kubernetes/setup/kubeadm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md index 64d314421..6d2afb87a 100644 --- a/kubernetes/setup/kubeadm.md +++ b/kubernetes/setup/kubeadm.md @@ -184,4 +184,4 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master- ## 参考文档 -* [官方文档](https://kubernetes.io/zh/docs/setup/independent/create-cluster-kubeadm/) +* [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) From 83929dd0963824dea8f57db9dfbdcde35db186db Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 16 Sep 2020 18:05:52 +0800 Subject: [PATCH 118/201] [vuepress] support dark mode, close #463 Signed-off-by: Kang Huaishuai --- .github/workflows/ci.yaml | 2 +- .vuepress/config.js | 15 +++++++++++++-- image/dockerfile/env.md | 2 +- package.json | 3 ++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cb310cb57..f841d7433 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,7 +21,7 @@ jobs: sudo rm -rf _book npm i vuepress --save-dev npm i - npm run vuepress:build + npm run vuepress:build || true echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME cp -r _images .vuepress/dist diff --git a/.vuepress/config.js b/.vuepress/config.js index 876a2442b..75ec2c5f8 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -1,4 +1,15 @@ -module.exports = { +const resolve = require("vuepress-theme-hope/resolve"); + +module.exports = resolve({ + themeConfig: { + blog: false, + comment: { + type: "disable", // 使用 Valine + appId: "...", // your appId + appKey: "...", // your appKey + }, + pageInfo: false + }, title: 'Docker 从入门到实践', base: '/', head: [['script', {}, ` @@ -401,4 +412,4 @@ module.exports = { ], }, } -} +}); diff --git a/image/dockerfile/env.md b/image/dockerfile/env.md index f3d4430cb..eba9eaed7 100644 --- a/image/dockerfile/env.md +++ b/image/dockerfile/env.md @@ -7,7 +7,7 @@ 这个指令很简单,就是设置环境变量而已,无论是后面的其它指令,如 `RUN`,还是运行时的应用,都可以直接使用这里定义的环境变量。 -```Dockerfie +```docker ENV VERSION=1.0 DEBUG=on \ NAME="Happy Feet" ``` diff --git a/package.json b/package.json index 66a88fc12..5e9a38177 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "commander": "^4.0.1", "esm": "^3.2.25", "vuepress-plugin-container": "^2.1.2", - "vuepress-plugin-sitemap": "^2.3.1" + "vuepress-plugin-sitemap": "^2.3.1", + "vuepress-theme-hope": "^0.7.3" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", From 68d85ac31ee147b121e34db35a702e4e4bd9029a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 7 Oct 2020 13:31:45 +0800 Subject: [PATCH 119/201] Update laravel, close #465 --- .../example/laravel/.dockerignore | 5 ++ .../example/laravel/Dockerfile | 20 +++---- image/multistage-builds/laravel.md | 53 +++++++++++-------- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/image/multistage-builds/example/laravel/.dockerignore b/image/multistage-builds/example/laravel/.dockerignore index fed61e775..8516a3a06 100644 --- a/image/multistage-builds/example/laravel/.dockerignore +++ b/image/multistage-builds/example/laravel/.dockerignore @@ -1,9 +1,14 @@ .idea/ .git/ + vendor/ + node_modules/ + public/js/ public/css/ +public/mix-manifest.json + yarn-error.log bootstrap/cache/* diff --git a/image/multistage-builds/example/laravel/Dockerfile b/image/multistage-builds/example/laravel/Dockerfile index 2f6913411..3f247becf 100644 --- a/image/multistage-builds/example/laravel/Dockerfile +++ b/image/multistage-builds/example/laravel/Dockerfile @@ -2,13 +2,15 @@ FROM node:alpine as frontend COPY package.json /app/ -RUN cd /app \ +RUN set -x ; cd /app \ && npm install --registry=https://registry.npm.taobao.org COPY webpack.mix.js /app/ -COPY resources/assets/ /app/resources/assets/ +COPY resources/ /app/resources/ -RUN cd /app \ +RUN set -x ; cd /app \ + && touch artisan \ + && mkdir -p public \ && npm run production FROM composer as composer @@ -16,7 +18,7 @@ FROM composer as composer COPY database/ /app/database/ COPY composer.json /app/ -RUN cd /app \ +RUN set -x ; cd /app \ && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \ && composer install \ --ignore-platform-reqs \ @@ -25,7 +27,7 @@ RUN cd /app \ --no-scripts \ --prefer-dist -FROM php:7.2-fpm-alpine as laravel +FROM php:7.4-fpm-alpine as laravel ARG LARAVEL_PATH=/app/laravel @@ -33,17 +35,17 @@ COPY --from=composer /app/vendor/ ${LARAVEL_PATH}/vendor/ COPY . ${LARAVEL_PATH} COPY --from=frontend /app/public/js/ ${LARAVEL_PATH}/public/js/ COPY --from=frontend /app/public/css/ ${LARAVEL_PATH}/public/css/ -COPY --from=frontend /app/mix-manifest.json ${LARAVEL_PATH}/mix-manifest.json +COPY --from=frontend /app/public/mix-manifest.json ${LARAVEL_PATH}/public/mix-manifest.json -RUN cd ${LARAVEL_PATH} \ - && php artisan package:discover \ +RUN set -x ; cd ${LARAVEL_PATH} \ && mkdir -p storage \ && mkdir -p storage/framework/cache \ && mkdir -p storage/framework/sessions \ && mkdir -p storage/framework/testing \ && mkdir -p storage/framework/views \ && mkdir -p storage/logs \ - && chmod -R 777 storage + && chmod -R 777 storage \ + && php artisan package:discover FROM nginx:alpine as nginx diff --git a/image/multistage-builds/laravel.md b/image/multistage-builds/laravel.md index da14fdb01..07df96cf4 100644 --- a/image/multistage-builds/laravel.md +++ b/image/multistage-builds/laravel.md @@ -1,6 +1,6 @@ # 实战多阶段构建 Laravel 镜像 -> 本节适用于 PHP 开发者阅读。 +> 本节适用于 PHP 开发者阅读。`Laravel` 基于 8.x 版本,各个版本的文件结构可能会有差异,请根据实际自行修改。 ## 准备 @@ -11,10 +11,15 @@ ```bash .idea/ .git/ + vendor/ + node_modules/ + public/js/ public/css/ +public/mix-manifest.json + yarn-error.log bootstrap/cache/* @@ -55,13 +60,15 @@ FROM node:alpine as frontend COPY package.json /app/ -RUN cd /app \ +RUN set -x ; cd /app \ && npm install --registry=https://registry.npm.taobao.org COPY webpack.mix.js /app/ -COPY resources/assets/ /app/resources/assets/ +COPY resources/ /app/resources/ -RUN cd /app \ +RUN set -x ; cd /app \ + && touch artisan \ + && mkdir -p public \ && npm run production ``` @@ -75,7 +82,7 @@ FROM composer as composer COPY database/ /app/database/ COPY composer.json composer.lock /app/ -RUN cd /app \ +RUN set -x ; cd /app \ && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \ && composer install \ --ignore-platform-reqs \ @@ -90,7 +97,7 @@ RUN cd /app \ 第三阶段对以上阶段生成的文件进行整合。 ```docker -FROM php:7.2-fpm-alpine as laravel +FROM php:7.4-fpm-alpine as laravel ARG LARAVEL_PATH=/app/laravel @@ -98,17 +105,17 @@ COPY --from=composer /app/vendor/ ${LARAVEL_PATH}/vendor/ COPY . ${LARAVEL_PATH} COPY --from=frontend /app/public/js/ ${LARAVEL_PATH}/public/js/ COPY --from=frontend /app/public/css/ ${LARAVEL_PATH}/public/css/ -COPY --from=frontend /app/mix-manifest.json ${LARAVEL_PATH}/mix-manifest.json +COPY --from=frontend /app/public/mix-manifest.json ${LARAVEL_PATH}/public/mix-manifest.json -RUN cd ${LARAVEL_PATH} \ - && php artisan package:discover \ +RUN set -x ; cd ${LARAVEL_PATH} \ && mkdir -p storage \ && mkdir -p storage/framework/cache \ && mkdir -p storage/framework/sessions \ && mkdir -p storage/framework/testing \ && mkdir -p storage/framework/views \ && mkdir -p storage/logs \ - && chmod -R 777 storage + && chmod -R 777 storage \ + && php artisan package:discover ``` ## 最后一个阶段构建 NGINX 镜像 @@ -143,13 +150,13 @@ $ docker network create laravel 启动 laravel 容器, `--name=laravel` 参数设定的名字必须与 `nginx` 配置文件中的 `fastcgi_pass laravel:9000;` 一致 ```bash -$ docker run -it --rm --name=laravel --network=laravel my/laravel +$ docker run -dit --rm --name=laravel --network=laravel my/laravel ``` 启动 nginx 容器 ```bash -$ docker run -it --rm --network=laravel -p 8080:80 my/nginx +$ docker run -dit --rm --network=laravel -p 8080:80 my/nginx ``` 浏览器访问 `127.0.0.1:8080` 可以看到 Laravel 项目首页。 @@ -160,6 +167,8 @@ $ docker run -it --rm --network=laravel -p 8080:80 my/nginx 本小节内容为了方便测试,将配置文件直接放到了镜像中,实际在使用时 **建议** 将配置文件作为 `config` 或 `secret` 挂载到容器中,请读者自行学习 `Swarm mode` 或 `Kubernetes` 的相关内容。 +由于篇幅所限本小节只是简单列出,更多内容可以参考 https://github.com/khs1994-docker/laravel-demo 项目。 + ## 附录 完整的 `Dockerfile` 文件如下。 @@ -169,13 +178,15 @@ FROM node:alpine as frontend COPY package.json /app/ -RUN cd /app \ +RUN set -x ; cd /app \ && npm install --registry=https://registry.npm.taobao.org COPY webpack.mix.js /app/ -COPY resources/assets/ /app/resources/assets/ +COPY resources/ /app/resources/ -RUN cd /app \ +RUN set -x ; cd /app \ + && touch artisan \ + && mkdir -p public \ && npm run production FROM composer as composer @@ -183,7 +194,7 @@ FROM composer as composer COPY database/ /app/database/ COPY composer.json /app/ -RUN cd /app \ +RUN set -x ; cd /app \ && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \ && composer install \ --ignore-platform-reqs \ @@ -192,7 +203,7 @@ RUN cd /app \ --no-scripts \ --prefer-dist -FROM php:7.2-fpm-alpine as laravel +FROM php:7.4-fpm-alpine as laravel ARG LARAVEL_PATH=/app/laravel @@ -200,17 +211,17 @@ COPY --from=composer /app/vendor/ ${LARAVEL_PATH}/vendor/ COPY . ${LARAVEL_PATH} COPY --from=frontend /app/public/js/ ${LARAVEL_PATH}/public/js/ COPY --from=frontend /app/public/css/ ${LARAVEL_PATH}/public/css/ -COPY --from=frontend /app/mix-manifest.json ${LARAVEL_PATH}/mix-manifest.json +COPY --from=frontend /app/public/mix-manifest.json ${LARAVEL_PATH}/public/mix-manifest.json -RUN cd ${LARAVEL_PATH} \ - && php artisan package:discover \ +RUN set -x ; cd ${LARAVEL_PATH} \ && mkdir -p storage \ && mkdir -p storage/framework/cache \ && mkdir -p storage/framework/sessions \ && mkdir -p storage/framework/testing \ && mkdir -p storage/framework/views \ && mkdir -p storage/logs \ - && chmod -R 777 storage + && chmod -R 777 storage \ + && php artisan package:discover FROM nginx:alpine as nginx From 1c932ef5678180d7d883476dd0e649b5368ada46 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 7 Oct 2020 13:44:57 +0800 Subject: [PATCH 120/201] Fixed link Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 2 ++ CHANGELOG.md | 2 +- README.md | 2 +- cases/ci/actions/README.md | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index d595c3eac..ecf487c3b 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -3,6 +3,7 @@ name: check-link on: push: pull_request: + workflow_dispatch: jobs: check-link: @@ -58,6 +59,7 @@ jobs: "union-click.jd.com",\ "x.x.x.x/base",\ "x.x.x.x:9000/minio/",\ + "yeasy.gitbooks.io",\ "https://www.freedesktop.org/wiki/Software/systemd/",\ "www.aliyun.com" \ --allow-dupe \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e04a3d6b..9a4840444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ * 1.2.0 2020-12-31 * 1.1.0 2019-12-31 - * 全面支持 v19.x 新版本 + * 全面支持 v19.03 新版本 * 增加 `BuildKit` * 增加 `docker buildx` 命令使用说明 * 增加 `docker manifest` 命令使用说明 diff --git a/README.md b/README.md index 4daed698c..9272bb7ae 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Docker — 从入门到实践 -[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.x-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] +[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.03-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] **v1.2.0** diff --git a/cases/ci/actions/README.md b/cases/ci/actions/README.md index 204865208..8b5364fbf 100644 --- a/cases/ci/actions/README.md +++ b/cases/ci/actions/README.md @@ -25,4 +25,4 @@ jobs: ## 参考资料 -* [Actions Docs](https://docs.github.com/en/actions) +* [Actions Docs](https://docs.github.com/en/free-pro-team@latest/actions) From f6ec3b23d259cb4f93b7976270e44315ade09cc8 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 10 Oct 2020 09:18:58 +0800 Subject: [PATCH 121/201] Update mirror Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 2 ++ install/mirror.md | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index ecf487c3b..8ebd2f5a0 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -40,6 +40,8 @@ jobs: "mirrors.ustc.edu.cn",\ "docs.docker.com",\ "dockerhub.azk8s.cn",\ + "reg-mirror.qiniu.com",\ + "registry.docker-cn.com",\ "mirror.ccs.tencentyun.com",\ "vuepress.mirror.docker-practice.com",\ "mc.qcloudimg.com/static/img",\ diff --git a/install/mirror.md b/install/mirror.md index 19184a333..1b592b5e4 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -2,13 +2,13 @@ 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如: +* [阿里云加速器(点击管理控制台 -> 登录账号(淘宝账号) -> 右侧镜像中心 -> 镜像加速器 -> 复制地址)](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu) * [网易云加速器 `https://hub-mirror.c.163.com`](https://www.163yun.com/help/documents/56918246390157312) * [百度云加速器 `https://mirror.baidubce.com`](https://cloud.baidu.com/doc/CCE/s/Yjxppt74z#%E4%BD%BF%E7%94%A8dockerhub%E5%8A%A0%E9%80%9F%E5%99%A8) -* [阿里云加速器(需登录账号获取)](https://cr.console.aliyun.com/cn-hangzhou/mirrors) **由于镜像服务可能出现宕机,建议同时配置多个镜像。各个镜像站测试结果请到 [docker-practice/docker-registry-cn-mirror-test](https://github.com/docker-practice/docker-registry-cn-mirror-test/actions) 查看。** -> 国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考官方文档。 +> 国内各大云服务商(腾讯云、阿里云、百度云)均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务,具体请参考本页最后一小节。 本节我们以 [网易云](https://www.163yun.com/) 镜像服务 `https://hub-mirror.c.163.com` 为例进行介绍。 @@ -85,9 +85,19 @@ Registry Mirrors: $ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/xxx ``` +## 不再提供服务的镜像 + +某些镜像不再提供服务,添加无用的镜像加速器,会拖慢镜像拉取速度,你可以从镜像配置列表中删除它们。 + +* https://dockerhub.azk8s.cn **已转为私有** +* https://reg-mirror.qiniu.com +* https://registry.docker-cn.com + +建议 **watch(页面右上角)** [镜像测试](https://github.com/docker-practice/docker-registry-cn-mirror-test) 这个 GitHub 仓库,我们会在此更新各个镜像地址的状态。 + ## 云服务商 -某些云服务商提供了仅供内部访问的镜像服务,当您的 Docker 运行在云平台时可以选择它们。 +某些云服务商提供了 **仅供内部** 访问的镜像服务,当您的 Docker 运行在云平台时可以选择它们。 * [Azure 中国镜像 `https://dockerhub.azk8s.cn`](https://github.com/Azure/container-service-for-azure-china/blob/master/aks/README.md#22-container-registry-proxy) From 4751e59a6ff580a4099e90414cc45c913e45e6b3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 12 Oct 2020 18:54:47 +0800 Subject: [PATCH 122/201] rename docker ce to docker Signed-off-by: Kang Huaishuai --- CHANGELOG.md | 4 ++-- install/README.md | 6 ++---- install/centos.md | 21 +++++++++------------ install/centos8.md | 6 +++--- install/debian.md | 18 +++++++++--------- install/fedora.md | 16 ++++++++-------- install/mac.md | 2 +- install/raspberry-pi.md | 16 ++++++++-------- install/ubuntu.md | 17 +++++++++-------- install/windows.md | 6 +++--- underly/ufs.md | 8 ++++---- 11 files changed, 58 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4840444..2b7783c63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,14 @@ * 1.2.0 2020-12-31 * 1.1.0 2019-12-31 - * 全面支持 v19.03 新版本 + * 全面支持 Docker v19.03 新版本 * 增加 `BuildKit` * 增加 `docker buildx` 命令使用说明 * 增加 `docker manifest` 命令使用说明 * 移除 `Ubuntu 14.04` `Debian 8` `Debian 7` * 1.0.0: 2018-12-31 - * 全面支持 v18.x 新版本 + * 全面支持 Docker v18.x 新版本 * 添加如何调试 Docker * 错误修正 diff --git a/install/README.md b/install/README.md index a9db78b88..cfa04d0c1 100644 --- a/install/README.md +++ b/install/README.md @@ -1,7 +1,5 @@ # 安装 Docker -Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 +Docker 分为 `stable` `test` 和 `nightly` 三个更新频道。 -Docker CE 分为 `stable` `test` 和 `nightly` 三个更新频道。 - -官方网站上有各种环境下的 [安装指南](https://docs.docker.com/install/),这里主要介绍 Docker CE 在 `Linux` 、`Windows 10` 和 `macOS` 上的安装。 +官方网站上有各种环境下的 [安装指南](https://docs.docker.com/get-docker/),这里主要介绍 Docker 在 `Linux` 、`Windows 10` 和 `macOS` 上的安装。 diff --git a/install/centos.md b/install/centos.md index 929f8e552..c5178ace7 100644 --- a/install/centos.md +++ b/install/centos.md @@ -1,4 +1,4 @@ -# CentOS 安装 Docker CE +# CentOS 安装 Docker >警告:切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker. @@ -6,7 +6,7 @@ ### 系统要求 -Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 `overlay2` 存储层驱动)无法使用,并且部分功能可能不太稳定。 +Docker 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 `overlay2` 存储层驱动)无法使用,并且部分功能可能不太稳定。 ### 卸载旧版本 @@ -30,9 +30,7 @@ $ sudo yum remove docker \ 执行以下命令安装依赖包: ```bash -$ sudo yum install -y yum-utils \ - device-mapper-persistent-data \ - lvm2 +$ sudo yum install -y yum-utils ``` 鉴于国内网络问题,强烈建议使用国内源,官方源请在注释中查看。 @@ -52,19 +50,18 @@ $ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum. # https://download.docker.com/linux/centos/docker-ce.repo ``` -如果需要测试版本的 Docker CE 请使用以下命令: +如果需要测试版本的 Docker 请使用以下命令: ```bash $ sudo yum-config-manager --enable docker-ce-test ``` -### 安装 Docker CE +### 安装 Docker 更新 `yum` 软件源缓存,并安装 `docker-ce`。 ```bash -$ sudo yum makecache fast -$ sudo yum install docker-ce +$ sudo yum install docker-ce docker-ce-cli containerd.io ``` ## 使用脚本自动安装 @@ -77,9 +74,9 @@ $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定(stable)版本安装在系统中。 -## 启动 Docker CE +## 启动 Docker ```bash $ sudo systemctl enable docker @@ -145,7 +142,7 @@ For more examples and ideas, visit: ## 添加内核参数 -如果在 CentOS 使用 Docker CE 看到下面的这些警告信息: +如果在 CentOS 使用 Docker 看到下面的这些警告信息: ```bash WARNING: bridge-nf-call-iptables is disabled diff --git a/install/centos8.md b/install/centos8.md index 5110c052a..c69d97a16 100644 --- a/install/centos8.md +++ b/install/centos8.md @@ -1,12 +1,12 @@ -# CentOS8 安装 Docker CE +# CentOS8 安装 Docker -当前官方版本的 Docker CE [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot +当前官方版本的 Docker [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot [docker-docker]:https://download.docker.com/linux/centos/ ## 设置 -由于 CentOS8 防火墙使用了 `nftables`,但 Docker CE 尚未支持 `nftables`, 我们可以使用如下设置使用 `iptables`: +由于 CentOS8 防火墙使用了 `nftables`,但 Docker 尚未支持 `nftables`, 我们可以使用如下设置使用 `iptables`: 更改 `/etc/firewalld/firewalld.conf` diff --git a/install/debian.md b/install/debian.md index b66e0c259..f5ea07541 100644 --- a/install/debian.md +++ b/install/debian.md @@ -1,4 +1,4 @@ -# Debian 安装 Docker CE +# Debian 安装 Docker >警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. @@ -6,7 +6,7 @@ ### 系统要求 -Docker CE 支持以下版本的 [Debian](https://www.debian.org/intro/about) 操作系统: +Docker 支持以下版本的 [Debian](https://www.debian.org/intro/about) 操作系统: * Buster 10 * Stretch 9 @@ -32,7 +32,7 @@ $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ - gnupg2 \ + gnupg-agent \ lsb-release \ software-properties-common ``` @@ -49,7 +49,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-k # $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - ``` -然后,我们需要向 `sources.list` 中添加 Docker CE 软件源: +然后,我们需要向 `sources.list` 中添加 Docker 软件源: ```bash $ sudo add-apt-repository \ @@ -64,16 +64,16 @@ $ sudo add-apt-repository \ # stable" ``` ->以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试版本的 Docker CE 请将 stable 改为 test。 +>以上命令会添加稳定版本的 Docker APT 源,如果需要测试版本的 Docker 请将 stable 改为 test。 -### 安装 Docker CE +### 安装 Docker 更新 apt 软件包缓存,并安装 `docker-ce`。 ```bash $ sudo apt-get update -$ sudo apt-get install docker-ce +$ sudo apt-get install docker-ce docker-ce-cli containerd.io ``` ## 使用脚本自动安装 @@ -86,9 +86,9 @@ $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定(stable)版本安装在系统中。 -## 启动 Docker CE +## 启动 Docker ```bash $ sudo systemctl enable docker diff --git a/install/fedora.md b/install/fedora.md index 1fd500291..caa3fffc7 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -1,4 +1,4 @@ -# Fedora 安装 Docker CE +# Fedora 安装 Docker >警告:切勿在没有配置 Docker dnf 源的情况下直接使用 dnf 命令安装 Docker. @@ -6,7 +6,7 @@ ### 系统要求 -Docker CE 支持以下版本的 [Fedora](https://getfedora.org/) 操作系统: +Docker 支持以下版本的 [Fedora](https://getfedora.org/) 操作系统: * 30 * 31 @@ -53,25 +53,25 @@ $ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum. # https://download.docker.com/linux/fedora/docker-ce.repo ``` -如果需要测试版本的 Docker CE 请使用以下命令: +如果需要测试版本的 Docker 请使用以下命令: ```bash $ sudo dnf config-manager --set-enabled docker-ce-test ``` -你也可以禁用测试版本的 Docker CE +你也可以禁用测试版本的 Docker ```bash $ sudo dnf config-manager --set-disabled docker-ce-test ``` -### 安装 Docker CE +### 安装 Docker 更新 `dnf` 软件源缓存,并安装 `docker-ce`。 ```bash $ sudo dnf update -$ sudo dnf install docker-ce +$ sudo dnf install docker-ce docker-ce-cli containerd.io ``` 你也可以使用以下命令安装指定版本的 Docker @@ -100,9 +100,9 @@ $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 最新稳定(stable)版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 最新稳定(stable)版本安装在系统中。 -## 启动 Docker CE +## 启动 Docker ```bash $ sudo systemctl enable docker diff --git a/install/mac.md b/install/mac.md index e84ac09a6..176bab90e 100644 --- a/install/mac.md +++ b/install/mac.md @@ -1,4 +1,4 @@ -# macOS 安装 Docker Desktop CE +# macOS 安装 Docker ## 系统要求 diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index c297c1254..55b9c93d6 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -1,12 +1,12 @@ -# 树莓派卡片电脑安装 Docker CE +# 树莓派卡片电脑安装 Docker >警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. ## 系统要求 -Docker CE 不仅支持 `x86_64` 架构的计算机,同时也支持 `ARM` 架构的计算机,本小节内容以树莓派单片电脑为例讲解 `ARM` 架构安装 Docker CE。 +Docker 不仅支持 `x86_64` 架构的计算机,同时也支持 `ARM` 架构的计算机,本小节内容以树莓派单片电脑为例讲解 `ARM` 架构安装 Docker。 -Docker CE 支持以下版本的 [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspberry-pi-os/) 操作系统: +Docker 支持以下版本的 [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspberry-pi-os/) 操作系统: * Raspberry Pi OS Buster @@ -40,7 +40,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/raspbian/gpg | sudo apt # $ curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo apt-key add - ``` -然后,我们需要向 `sources.list` 中添加 Docker CE 软件源: +然后,我们需要向 `sources.list` 中添加 Docker 软件源: ```bash $ sudo add-apt-repository \ @@ -56,9 +56,9 @@ $ sudo add-apt-repository \ # stable" ``` ->以上命令会添加稳定版本的 Docker CE APT 源,如果需要测试版本的 Docker CE 请将 stable 改为 test。 +>以上命令会添加稳定版本的 Docker APT 源,如果需要测试版本的 Docker 请将 stable 改为 test。 -### 安装 Docker CE +### 安装 Docker 更新 apt 软件包缓存,并安装 `docker-ce`。 @@ -78,9 +78,9 @@ $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定(stable)版本安装在系统中。 -## 启动 Docker CE +## 启动 Docker ```bash $ sudo systemctl enable docker diff --git a/install/ubuntu.md b/install/ubuntu.md index 9e0ff1544..1323335a0 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -1,4 +1,4 @@ -# Ubuntu 安装 Docker CE +# Ubuntu 安装 Docker >警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. @@ -6,13 +6,13 @@ ### 系统要求 -Docker CE 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: +Docker 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: * Ubuntu Focal 20.04 (LTS) * Bionic 18.04 (LTS) * Xenial 16.04 (LTS) -Docker CE 可以安装在 64 位的 x86 平台或 ARM 平台上。Ubuntu 发行版中,LTS(Long-Term-Support)长期支持版本,会获得 5 年的升级维护支持,这样的版本会更稳定,因此在生产环境中推荐使用 LTS 版本。 +Docker 可以安装在 64 位的 x86 平台或 ARM 平台上。Ubuntu 发行版中,LTS(Long-Term-Support)长期支持版本,会获得 5 年的升级维护支持,这样的版本会更稳定,因此在生产环境中推荐使用 LTS 版本。 ### 卸载旧版本 @@ -35,6 +35,7 @@ $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ + gnupg-agent \ software-properties-common ``` @@ -66,16 +67,16 @@ $ sudo add-apt-repository \ # stable" ``` ->以上命令会添加稳定版本的 Docker CE APT 镜像源,如果需要测试版本的 Docker CE 请将 stable 改为 test。 +>以上命令会添加稳定版本的 Docker APT 镜像源,如果需要测试版本的 Docker 请将 stable 改为 test。 -### 安装 Docker CE +### 安装 Docker 更新 apt 软件包缓存,并安装 `docker-ce`: ```bash $ sudo apt-get update -$ sudo apt-get install docker-ce +$ sudo apt-get install docker-ce docker-ce-cli containerd.io ``` ## 使用脚本自动安装 @@ -88,9 +89,9 @@ $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud ``` -执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的稳定(stable)版本安装在系统中。 +执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定(stable)版本安装在系统中。 -## 启动 Docker CE +## 启动 Docker ```bash $ sudo systemctl enable docker diff --git a/install/windows.md b/install/windows.md index d62c0cc94..36cbfdd3f 100644 --- a/install/windows.md +++ b/install/windows.md @@ -1,4 +1,4 @@ -# Windows 10 安装 Docker Desktop CE +# Windows 10 安装 Docker ## 系统要求 @@ -28,11 +28,11 @@ $ winget install Docker.DockerDesktopEdge ![](_images/install-win-docker-app-search.png) -Docker CE 启动之后会在 Windows 任务栏出现鲸鱼图标。 +Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。 ![](_images/install-win-taskbar-circle.png) -等待片刻,点击 Got it 开始使用 Docker CE。 +等待片刻,点击 Got it 开始使用 Docker。 ![](_images/install-win-success-popup-cloud.png) diff --git a/underly/ufs.md b/underly/ufs.md index 9b3ed1237..fb01da17d 100644 --- a/underly/ufs.md +++ b/underly/ufs.md @@ -14,9 +14,9 @@ Docker 目前支持的联合文件系统包括 `OverlayFS`, `AUFS`, `Btrfs`, `VF |Linux 发行版 | Docker 推荐使用的存储驱动 | | :-- | :-- | -|Docker CE on Ubuntu | `overlay2` (16.04 +) | -|Docker CE on Debian | `overlay2` (Debian Stretch), `aufs`, `devicemapper` | -|Docker CE on CentOS | `overlay2` | -|Docker CE on Fedora | `overlay2` | +|Docker on Ubuntu | `overlay2` (16.04 +) | +|Docker on Debian | `overlay2` (Debian Stretch), `aufs`, `devicemapper` | +|Docker on CentOS | `overlay2` | +|Docker on Fedora | `overlay2` | 在可能的情况下,[推荐](https://docs.docker.com/storage/storagedriver/select-storage-driver/) 使用 `overlay2` 存储驱动,`overlay2` 是目前 Docker 默认的存储驱动,以前则是 `aufs`。你可以通过配置来使用以上提到的其他类型的存储驱动。 From ff1f48a7931ce9489f01a7867fb2977153d9ddc1 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 13 Oct 2020 09:35:40 +0800 Subject: [PATCH 123/201] Update mirror: check docker.service first Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 - install/mirror.md | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 8ebd2f5a0..c74c0540c 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -62,7 +62,6 @@ jobs: "x.x.x.x/base",\ "x.x.x.x:9000/minio/",\ "yeasy.gitbooks.io",\ - "https://www.freedesktop.org/wiki/Software/systemd/",\ "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ diff --git a/install/mirror.md b/install/mirror.md index 1b592b5e4..1f2a999d6 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -12,9 +12,19 @@ 本节我们以 [网易云](https://www.163yun.com/) 镜像服务 `https://hub-mirror.c.163.com` 为例进行介绍。 -## Ubuntu 16.04+、Debian 8+、CentOS 7 +## Ubuntu 16.04+、Debian 8+、CentOS 7+ -对于使用 [systemd](https://www.freedesktop.org/wiki/Software/systemd/) 的系统,请在 `/etc/docker/daemon.json` 中写入如下内容(如果文件不存在请新建该文件) +目前主流 Linux 发行版均已使用 [systemd](https://systemd.io/) 进行服务管理,这里介绍如何在使用 systemd 的 Linux 发行版中配置镜像加速器。 + +请首先执行以下命令,查看是否在 `docker.service` 文件中配置过镜像地址。 + +```bash +$ systemctl cat docker | grep '\-\-registry\-mirror' +``` + +如果该命令有输出,那么请执行 `$ systemctl cat docker` 查看 `ExecStart=` 出现的位置,修改对应的文件内容去掉 `--registry-mirror` 参数及其值,并按接下来的步骤进行配置。 + +如果以上命令没有任何输出,那么就可以在 `/etc/docker/daemon.json` 中写入如下内容(如果文件不存在请新建该文件): ```json { @@ -34,8 +44,6 @@ $ sudo systemctl daemon-reload $ sudo systemctl restart docker ``` ->注意:如果您之前查看旧教程,修改了 `docker.service` 文件内容,请去掉您添加的内容(`--registry-mirror=https://hub-mirror.c.163.com`)。 - ## Windows 10 对于使用 `Windows 10` 的用户,在任务栏托盘 Docker 图标内右键菜单选择 `Settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。 From fc8b8867af17ef2b4f7884853b073c69884d0eb1 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 13 Oct 2020 22:24:30 +0800 Subject: [PATCH 124/201] [vuepress] Update config Signed-off-by: Kang Huaishuai --- .github/workflows/ci.yaml | 10 +++++-- .gitignore | 2 -- .vuepress/.gitignore | 3 ++ .vuepress/config.js | 59 +++++++++++++++++++++++++++++++-------- package.json | 11 ++++---- 5 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 .vuepress/.gitignore diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f841d7433..10afc2b61 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,7 +21,13 @@ jobs: sudo rm -rf _book npm i vuepress --save-dev npm i - npm run vuepress:build || true + + git clone https://github.com/docker-practice/.vuepress .vuepress2 + cp -r .vuepress2/. .vuepress/ + rm -rf .vuepress2 + find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" -o -path "./node_modules" -o -path "./.vuepress" -o -path "./_book" -o -path "./CHANGELOG.md" -o -path "./CONTRIBUTING.md" \) -prune -o -name "*.md" -exec sed -i 'N;2a\\n' {} \; + + npm run vuepress:build echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME cp -r _images .vuepress/dist @@ -39,7 +45,7 @@ jobs: cp -r mesos/_images .vuepress/dist/mesos cp -r underly/_images .vuepress/dist/underly - echo "include: [_images]" > .vuepress/dist/_config + echo "include: [_images]" > .vuepress/dist/_config.yml - name: Upload Vuepress dist uses: docker://pcit/pages if: github.repository == 'docker-practice/docker_practice' diff --git a/.gitignore b/.gitignore index 4d197531a..cd6ce1c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,3 @@ _book/ node_modules/ package-lock.json - -.vuepress/dist diff --git a/.vuepress/.gitignore b/.vuepress/.gitignore new file mode 100644 index 000000000..c01fe453d --- /dev/null +++ b/.vuepress/.gitignore @@ -0,0 +1,3 @@ +/* +!.gitignore +!config.js diff --git a/.vuepress/config.js b/.vuepress/config.js index 75ec2c5f8..6c5dacd1f 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -1,15 +1,6 @@ const resolve = require("vuepress-theme-hope/resolve"); module.exports = resolve({ - themeConfig: { - blog: false, - comment: { - type: "disable", // 使用 Valine - appId: "...", // your appId - appKey: "...", // your appKey - }, - pageInfo: false - }, title: 'Docker 从入门到实践', base: '/', head: [['script', {}, ` @@ -39,13 +30,57 @@ module.exports = resolve({ ] ], plugins: { - sitemap: { - hostname: 'https://vuepress.mirror.docker-practice.com' - }, + // sitemap: { + // hostname: 'https://vuepress.mirror.docker-practice.com' + // }, + // 'git-log': { + // additionalArgs: '--no-merge', + // onlyFirstAndLastCommit: true, + // }, }, themeConfig: { + blog: false, + // comment: false, + comment: { + type: "disable", // 使用 Valine + appId: "...", // your appId + appKey: "...", // your appKey + }, + pageInfo: [ + // 'Author', + 'ReadTime', + 'Word', + ], + footer: { + content: "", + display: true, + copyright: false, + }, + searchPlaceholder: 'Search', + repo: 'yeasy/docker_practice', + repoLabel: 'GitHub', + hostname: 'https://vuepress.mirror.docker-practice.com', + // author: 'yeasy', + markdown: { + // lineNumbers: true, + // sub: true, + // footnote: true + enableAll: true + }, + themeColor: { + blue: '#2196f3', + red: '#f26d6d', + green: '#3eaf7c', + orange: '#fb9b5f' + }, + + // + + showAds: true, + docsRepo: 'yeasy/docker_practice', docsDir: '/', + docsBranch: 'master', editLinks: true, nav: [ { diff --git a/package.json b/package.json index 5e9a38177..9dbf99cc1 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,11 @@ "main": "index.js", "dependencies": {}, "devDependencies": { - "chalk": "^3.0.0", - "commander": "^4.0.1", - "esm": "^3.2.25", - "vuepress-plugin-container": "^2.1.2", - "vuepress-plugin-sitemap": "^2.3.1", - "vuepress-theme-hope": "^0.7.3" + "chalk": "^2.4.2", + "commander": "^2.0.0", + "esm": "^3.0.0", + "vuepress-plugin-container": "^2.1.5", + "vuepress-theme-hope": "^0.8.0" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", From 1b2c480a55692b6f39d947f229f6dce4c2f3ce65 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 14 Oct 2020 00:28:50 +0800 Subject: [PATCH 125/201] Add vscode devcontainer Signed-off-by: Kang Huaishuai --- .devcontainer/devcontainer.json | 20 ++++++++++++++++++++ .github/workflows/check-link.yml | 4 ++-- package.json | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..2ca1d999d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,20 @@ +{ + "image": "yeasy/docker_practice:latest", + "mounts": [ + "source=dp-code-remote-cache,target=/root/.vscode-server,type=volume" + ], + "settings": { + "terminal.integrated.shell.linux": "/bin/sh" + }, + "forwardPorts": [ + 4000 + ], + "runArgs": [ + "--cap-add=SYS_ADMIN" + ], + "postStartCommand": [ + "sh", + "-cx", + "pwd ; mkdir -p /workspaces/docker_practice/node_modules; mkdir -p /workspaces/docker_practice/_book; mount --bind /srv/gitbook/node_modules /workspaces/docker_practice/node_modules ; mount --bind /mnt /workspaces/docker_practice/_book" + ] +} diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index c74c0540c..684f35778 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -1,8 +1,8 @@ name: check-link on: - push: - pull_request: + # push: + # pull_request: workflow_dispatch: jobs: diff --git a/package.json b/package.json index 9dbf99cc1..3ff639dbe 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", + "gitbook:help": "gitbook help", + "gitbook:build": "gitbook build", + "gitbook:serve": "gitbook serve", "vuepress:build": "npx vuepress build" }, "repository": { From fd85d5a0e5030cb22fc83be74dd587c630927894 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 14 Oct 2020 00:40:07 +0800 Subject: [PATCH 126/201] project docker image add bash Signed-off-by: Kang Huaishuai --- .travis/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/Dockerfile b/.travis/Dockerfile index cb4c7f36d..f0fd97dd6 100644 --- a/.travis/Dockerfile +++ b/.travis/Dockerfile @@ -9,7 +9,7 @@ COPY book.json book.json COPY docker-entrypoint.sh /usr/local/bin/ RUN set -x && apk add --no-cache \ - tzdata \ + tzdata bash \ && npm install -g gitbook-cli \ && gitbook install \ && ln -s /usr/local/bin/docker-entrypoint.sh / \ From c572a399f32832e7919d9d2c92a7909e84dbe54b Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 14 Oct 2020 11:52:48 +0800 Subject: [PATCH 127/201] [vuepress] Update config Signed-off-by: Kang Huaishuai --- .devcontainer/devcontainer.json | 2 +- .github/workflows/ci.yaml | 1 + .vuepress/config.js | 15 +++++++-------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2ca1d999d..c97bc620a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,6 +15,6 @@ "postStartCommand": [ "sh", "-cx", - "pwd ; mkdir -p /workspaces/docker_practice/node_modules; mkdir -p /workspaces/docker_practice/_book; mount --bind /srv/gitbook/node_modules /workspaces/docker_practice/node_modules ; mount --bind /mnt /workspaces/docker_practice/_book" + "pwd ; cd /workspaces/docker_practice ; mkdir -p ${PWD}/node_modules; mkdir -p ${PWD}/_book; mount --bind /srv/gitbook/node_modules ${PWD}/node_modules ; mount --bind /mnt ${PWD}/_book" ] } diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 10afc2b61..3892ff44d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,7 @@ on: push: pull_request: + workflow_dispatch: name: CI diff --git a/.vuepress/config.js b/.vuepress/config.js index 6c5dacd1f..309d176b6 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -1,5 +1,7 @@ const resolve = require("vuepress-theme-hope/resolve"); +// const { config } = require('vuepress-theme-hope') +// module.exports =config({ module.exports = resolve({ title: 'Docker 从入门到实践', base: '/', @@ -52,7 +54,7 @@ module.exports = resolve({ 'Word', ], footer: { - content: "", + content: "Powerd by Vuepress, Made with
vuepress-theme-hope", display: true, copyright: false, }, @@ -62,16 +64,13 @@ module.exports = resolve({ hostname: 'https://vuepress.mirror.docker-practice.com', // author: 'yeasy', markdown: { - // lineNumbers: true, - // sub: true, - // footnote: true - enableAll: true + lineNumbers: true, }, themeColor: { blue: '#2196f3', - red: '#f26d6d', - green: '#3eaf7c', - orange: '#fb9b5f' + // red: '#f26d6d', + // green: '#3eaf7c', + // orange: '#fb9b5f' }, // From 47ec0e2ab8c19491e2e7e99e71681a7005296534 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 14 Oct 2020 13:40:46 +0800 Subject: [PATCH 128/201] [vuepress] bump 1.6.0 Signed-off-by: Kang Huaishuai --- .github/workflows/ci.yaml | 4 +++- .vuepress/config.js | 2 +- package.json | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3892ff44d..5ba4edc3f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,7 +20,7 @@ jobs: - name: vuepress run: | sudo rm -rf _book - npm i vuepress --save-dev + # npm i vuepress --save-dev npm i git clone https://github.com/docker-practice/.vuepress .vuepress2 @@ -28,6 +28,8 @@ jobs: rm -rf .vuepress2 find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" -o -path "./node_modules" -o -path "./.vuepress" -o -path "./_book" -o -path "./CHANGELOG.md" -o -path "./CONTRIBUTING.md" \) -prune -o -name "*.md" -exec sed -i 'N;2a\\n' {} \; + npx vuepress --version + npm run vuepress:build echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME diff --git a/.vuepress/config.js b/.vuepress/config.js index 309d176b6..0cbb74ae9 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -54,7 +54,7 @@ module.exports = resolve({ 'Word', ], footer: { - content: "Powerd by Vuepress, Made with vuepress-theme-hope", + content: "Made with vuepress-theme-hope", display: true, copyright: false, }, diff --git a/package.json b/package.json index 3ff639dbe..643586228 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "chalk": "^2.4.2", "commander": "^2.0.0", "esm": "^3.0.0", + "vuepress": "1.6.0", "vuepress-plugin-container": "^2.1.5", "vuepress-theme-hope": "^0.8.0" }, From bcc901ac9fb4e68c08f2cba19afa4c9848d91a28 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 14 Oct 2020 23:30:27 +0800 Subject: [PATCH 129/201] [install] Docker 20.10 beta support CentOS 8 Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 1 - CHANGELOG.md | 1 + SUMMARY.md | 1 - install/centos.md | 28 ++++++++++++++++++++++++++-- install/centos8.md | 29 ----------------------------- install/debian.md | 3 +++ install/fedora.md | 6 +++++- install/raspberry-pi.md | 3 +++ install/ubuntu.md | 3 +++ 9 files changed, 41 insertions(+), 34 deletions(-) delete mode 100644 install/centos8.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 0cbb74ae9..23f64f788 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -185,7 +185,6 @@ module.exports = resolve({ 'debian', 'fedora', 'centos', - 'centos8', 'raspberry-pi', 'offline', 'mac', diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b7783c63..7f5260754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # 修订记录 * 1.2.0 2020-12-31 + * 全面支持 Docker v20.10 新版本 * 1.1.0 2019-12-31 * 全面支持 Docker v19.03 新版本 diff --git a/SUMMARY.md b/SUMMARY.md index 2ba58f02a..414e65c00 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -15,7 +15,6 @@ * [Debian](install/debian.md) * [Fedora](install/fedora.md) * [CentOS](install/centos.md) - * [CentOS8](install/centos8.md) * [Raspberry Pi](install/raspberry-pi.md) * [Linux 离线安装](install/offline.md) * [macOS](install/mac.md) diff --git a/install/centos.md b/install/centos.md index c5178ace7..a9b24ba36 100644 --- a/install/centos.md +++ b/install/centos.md @@ -6,7 +6,7 @@ ### 系统要求 -Docker 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 `overlay2` 存储层驱动)无法使用,并且部分功能可能不太稳定。 +Docker 支持 64 位版本 CentOS 7/8,并且要求内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 `overlay2` 存储层驱动)无法使用,并且部分功能可能不太稳定。 ### 卸载旧版本 @@ -50,7 +50,7 @@ $ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum. # https://download.docker.com/linux/centos/docker-ce.repo ``` -如果需要测试版本的 Docker 请使用以下命令: +如果需要测试版本的 Docker (**或你的系统是 CentOS 8**)请执行以下命令: ```bash $ sudo yum-config-manager --enable docker-ce-test @@ -64,11 +64,33 @@ $ sudo yum-config-manager --enable docker-ce-test $ sudo yum install docker-ce docker-ce-cli containerd.io ``` +## CentOS8 额外设置 + +由于 CentOS8 防火墙使用了 `nftables`,但 Docker 尚未支持 `nftables`, 我们可以使用如下设置使用 `iptables`: + +更改 `/etc/firewalld/firewalld.conf` + +```bash +# FirewallBackend=nftables +FirewallBackend=iptables +``` + +或者执行如下命令: + +```bash +$ firewall-cmd --permanent --zone=trusted --add-interface=docker0 + +$ firewall-cmd --reload +``` + ## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: +> 若你想安装测试版的 Docker(**或你的系统是 CentOS 8**), 请从 test.docker.com 获取脚本 + ```bash +# $ curl -fsSL test.docker.com -o get-docker.sh $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud @@ -167,3 +189,5 @@ $ sudo sysctl -p ## 参考文档 * [Docker 官方 CentOS 安装文档](https://docs.docker.com/install/linux/docker-ce/centos/)。 +* https://firewalld.org/2018/07/nftables-backend +* https://github.com/moby/libnetwork/issues/2496 diff --git a/install/centos8.md b/install/centos8.md deleted file mode 100644 index c69d97a16..000000000 --- a/install/centos8.md +++ /dev/null @@ -1,29 +0,0 @@ -# CentOS8 安装 Docker - -当前官方版本的 Docker [尚未支持][docker-docker] CentOS8,我们可以使用 Moby 项目维护者 AkihiroSuda 所构建的包,具体请参考 https://github.com/AkihiroSuda/moby-snapshot - -[docker-docker]:https://download.docker.com/linux/centos/ - -## 设置 - -由于 CentOS8 防火墙使用了 `nftables`,但 Docker 尚未支持 `nftables`, 我们可以使用如下设置使用 `iptables`: - -更改 `/etc/firewalld/firewalld.conf` - -```bash -# FirewallBackend=nftables -FirewallBackend=iptables -``` - -或者执行如下命令: - -```bash -$ firewall-cmd --permanent --zone=trusted --add-interface=docker0 - -$ firewall-cmd --reload -``` - -## 参考链接 - -* https://firewalld.org/2018/07/nftables-backend -* https://github.com/moby/libnetwork/issues/2496 diff --git a/install/debian.md b/install/debian.md index f5ea07541..b0e226c0e 100644 --- a/install/debian.md +++ b/install/debian.md @@ -80,7 +80,10 @@ $ sudo apt-get install docker-ce docker-ce-cli containerd.io 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: +> 若你想安装测试版的 Docker, 请从 test.docker.com 获取脚本 + ```bash +# $ curl -fsSL test.docker.com -o get-docker.sh $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud diff --git a/install/fedora.md b/install/fedora.md index caa3fffc7..be91d2007 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -10,6 +10,7 @@ Docker 支持以下版本的 [Fedora](https://getfedora.org/) 操作系统: * 30 * 31 +* 32 ### 卸载旧版本 @@ -84,7 +85,7 @@ docker-ce.x86_64 18.06.1.ce-3.fc28 docker-ce-stable $ sudo dnf -y install docker-ce-18.06.1.ce ``` -由于 Fedora 31 默认启用了 **Cgroupv2**,暂时 Docker 与 Cgroupv2 不兼容,请执行以下命令切换到 **Cgroupv1** 并重启计算机: +由于 Fedora 31 默认启用了 **Cgroupv2**,稳定版本的 Docker 与 Cgroupv2 不兼容,你可以安装测试版 Docker,或者执行以下命令切换到 **Cgroupv1** 并重启计算机: ```bash $ sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" @@ -94,7 +95,10 @@ $ sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: +> 若你想安装测试版的 Docker, 请从 test.docker.com 获取脚本 + ```bash +# $ curl -fsSL test.docker.com -o get-docker.sh $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 55b9c93d6..d278cef51 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -72,7 +72,10 @@ $ sudo apt-get install docker-ce 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspberry Pi OS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: +> 若你想安装测试版的 Docker, 请从 test.docker.com 获取脚本 + ```bash +# $ curl -fsSL test.docker.com -o get-docker.sh $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud diff --git a/install/ubuntu.md b/install/ubuntu.md index 1323335a0..4b14c09d2 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -83,7 +83,10 @@ $ sudo apt-get install docker-ce docker-ce-cli containerd.io 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: +> 若你想安装测试版的 Docker, 请从 test.docker.com 获取脚本 + ```bash +# $ curl -fsSL test.docker.com -o get-docker.sh $ curl -fsSL get.docker.com -o get-docker.sh $ sudo sh get-docker.sh --mirror Aliyun # $ sudo sh get-docker.sh --mirror AzureChinaCloud From 0fdc2d64a9ae54d5e023901b969bac87d4aa08af Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 14 Oct 2020 23:33:32 +0800 Subject: [PATCH 130/201] based Docker v20.10 Signed-off-by: Kang Huaishuai --- .github/ISSUE_TEMPLATE/Bug_report.md | 2 +- .github/ISSUE_TEMPLATE/Custom.md | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 8528cd1f5..d0ac6ea99 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -24,7 +24,7 @@ about: Create a report to help us improve -* [x] Edge (v19.03) +* [x] Test (v20.10) * [x] Stable (v19.03) * [x] 1.13.0 or Before diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md index 650a860b6..fa5bf1311 100644 --- a/.github/ISSUE_TEMPLATE/Custom.md +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -24,7 +24,7 @@ about: Create a issue about Docker -* [x] Edge (v19.03) +* [x] Test (v20.10) * [x] Stable (v19.03) * [x] 1.13.0 or Before diff --git a/README.md b/README.md index 9272bb7ae..4fa8d0026 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Docker — 从入门到实践 -[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v19.03-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] +[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v20.10-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] **v1.2.0** From f9182e5d191f06b7c4142b6d6a95d387055408af Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 15 Oct 2020 18:30:34 +0800 Subject: [PATCH 131/201] [vuepress] bump 1.7.0 Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 7 +++---- package.json | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 23f64f788..5cb6c3d85 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -1,8 +1,6 @@ -const resolve = require("vuepress-theme-hope/resolve"); -// const { config } = require('vuepress-theme-hope') +const { config } = require('vuepress-theme-hope') -// module.exports =config({ -module.exports = resolve({ +module.exports = config({ title: 'Docker 从入门到实践', base: '/', head: [['script', {}, ` @@ -41,6 +39,7 @@ module.exports = resolve({ // }, }, themeConfig: { + baseLang: 'zh-CN', blog: false, // comment: false, comment: { diff --git a/package.json b/package.json index 643586228..50938ea68 100644 --- a/package.json +++ b/package.json @@ -8,9 +8,9 @@ "chalk": "^2.4.2", "commander": "^2.0.0", "esm": "^3.0.0", - "vuepress": "1.6.0", + "vuepress": "1.7.0", "vuepress-plugin-container": "^2.1.5", - "vuepress-theme-hope": "^0.8.0" + "vuepress-theme-hope": "^1.0.0" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", From 8e8126756a9cfab2134b79c5050f292ada059823 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 16 Oct 2020 12:13:14 +0800 Subject: [PATCH 132/201] [vuepress] Fixed https://github.com/Mister-Hope/vuepress-theme-hope/issues/406 --- advanced_network/README.md | 2 +- cases/ci/drone/README.md | 2 +- cases/os/alpine.md | 2 +- cases/os/busybox.md | 2 +- cases/os/centos.md | 4 ++-- cases/os/debian.md | 4 ++-- cloud/alicloud.md | 2 +- cloud/aws.md | 4 ++-- cloud/tencentCloud.md | 2 +- data_management/README.md | 2 +- etcd/intro.md | 2 +- image/commit.md | 4 ++-- install/mac.md | 12 ++++++------ install/windows.md | 6 +++--- introduction/what.md | 4 ++-- kubernetes/concepts.md | 2 +- kubernetes/design.md | 4 ++-- kubernetes/intro.md | 2 +- underly/arch.md | 2 +- 19 files changed, 32 insertions(+), 32 deletions(-) diff --git a/advanced_network/README.md b/advanced_network/README.md index e21d4b3cf..52ea99073 100644 --- a/advanced_network/README.md +++ b/advanced_network/README.md @@ -10,6 +10,6 @@ 当创建一个 Docker 容器的时候,同时会创建了一对 `veth pair` 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 `eth0`;另一端在本地并被挂载到 `docker0` 网桥,名称以 `veth` 开头(例如 `vethAQI2QT`)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。 -![Docker 网络](_images/network.png) +![Docker 网络](./_images/network.png) 接下来的部分将介绍在一些场景中,Docker 所有的网络定制配置。以及通过 Linux 命令来调整、补充、甚至替换 Docker 默认的网络配置。 diff --git a/cases/ci/drone/README.md b/cases/ci/drone/README.md index 69271c39a..5055e4e6d 100644 --- a/cases/ci/drone/README.md +++ b/cases/ci/drone/README.md @@ -86,7 +86,7 @@ $ git push origin master 打开我们部署好的 `Drone` 网站或者 Drone Cloud,即可看到构建结果。 -![](_images/drone-build.png) +![](./_images/drone-build.png) 当然我们也可以把构建结果上传到 GitHub,Docker Registry,云服务商提供的对象存储,或者生产环境中。 diff --git a/cases/os/alpine.md b/cases/os/alpine.md index 0a36fc12e..28f7a2773 100644 --- a/cases/os/alpine.md +++ b/cases/os/alpine.md @@ -2,7 +2,7 @@ ## 简介 -![Alpine Linux 操作系统](_images/alpinelinux-logo.png) +![Alpine Linux 操作系统](./_images/alpinelinux-logo.png) `Alpine` 操作系统是一个面向安全的轻型 `Linux` 发行版。它不同于通常 `Linux` 发行版,`Alpine` 采用了 `musl libc` 和 `busybox` 以减小系统的体积和运行时资源消耗,但功能上比 `busybox` 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,`Alpine` 还提供了自己的包管理工具 `apk`,可以通过 `https://pkgs.alpinelinux.org/packages` 网站上查询包信息,也可以直接通过 `apk` 命令直接查询和安装各种软件。 diff --git a/cases/os/busybox.md b/cases/os/busybox.md index b3527728f..25eaa8fc1 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -2,7 +2,7 @@ ## 简介 -![Busybox - Linux 瑞士军刀](_images/busybox-logo.png) +![Busybox - Linux 瑞士军刀](./_images/busybox-logo.png) `BusyBox` 是一个集成了一百多个最常用 Linux 命令和工具(如 `cat`、`echo`、`grep`、`mount`、`telnet` 等)的精简工具箱,它只需要几 MB 的大小,很方便进行各种快速验证,被誉为“Linux 系统的瑞士军刀”。 diff --git a/cases/os/centos.md b/cases/os/centos.md index b331e0486..bc32c99f8 100644 --- a/cases/os/centos.md +++ b/cases/os/centos.md @@ -4,7 +4,7 @@ `CentOS` 和 `Fedora` 都是基于 `Redhat` 的常见 Linux 分支。`CentOS` 是目前企业级服务器的常用操作系统;`Fedora` 则主要面向个人桌面用户。 -![CentOS 操作系统](_images/centos-logo.png) +![CentOS 操作系统](./_images/centos-logo.png) CentOS(Community Enterprise Operating System,中文意思是:社区企业操作系统),它是基于 `Red Hat Enterprise Linux` 源代码编译而成。由于 `CentOS` 与 `Redhat Linux` 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 `CentOS` 来替代商业版 `Red Hat Enterprise Linux`。`CentOS` 自身不包含闭源软件。 @@ -34,7 +34,7 @@ CentOS Linux release 7.2.1511 (Core) ## Fedora 系统简介 -![Fedora 操作系统](_images/fedora-logo.png) +![Fedora 操作系统](./_images/fedora-logo.png) `Fedora` 由 `Fedora Project` 社区开发,红帽公司赞助的 `Linux` 发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。`Fedora` 的功能对于用户而言,它是一套功能完备的,可以更新的免费操作系统,而对赞助商 `Red Hat` 而言,它是许多新技术的测试平台。被认为可用的技术最终会加入到 `Red Hat Enterprise Linux` 中。 diff --git a/cases/os/debian.md b/cases/os/debian.md index b19c6d6e7..46b8e95f9 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -3,7 +3,7 @@ ## Debian 系统简介 -![Debian 操作系统](_images/debian-logo.png) +![Debian 操作系统](./_images/debian-logo.png) `Debian` 是由 `GPL` 和其他自由软件许可协议授权的自由软件组成的操作系统,由 **Debian 计划(Debian Project)** 组织维护。**Debian 计划** 是一个独立的、分散的组织,由 `3000` 人志愿者组成,接受世界多个非盈利组织的资金支持,`Software in the Public Interest` 提供支持并持有商标作为保护机构。`Debian` 以其坚守 `Unix` 和自由软件的精神,以及其给予用户的众多选择而闻名。现时 `Debian` 包括了超过 `25,000` 个软件包并支持 `12` 个计算机系统结构。 @@ -38,7 +38,7 @@ Debian GNU/Linux 8 ## Ubuntu 系统简介 -![Ubuntu 操作系统](_images/ubuntu-logo.jpg) +![Ubuntu 操作系统](./_images/ubuntu-logo.jpg) `Ubuntu` 是一个以桌面应用为主的 `GNU/Linux` 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词(官方译名“友帮拓”,另有“吾帮托”、“乌班图”、“有奔头”或“乌斑兔”等译名)。`Ubuntu` 意思是“人性”以及“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。 `Ubuntu` 基于 `Debian` 发行版和 `GNOME/Unity` 桌面环境,与 `Debian` 的不同在于它每 6 个月会发布一个新版本,每 2 年推出一个长期支持 **(Long Term Support,LTS)** 版本,一般支持 3 年时间。 diff --git a/cloud/alicloud.md b/cloud/alicloud.md index 4abbf6c10..6d8783f4e 100644 --- a/cloud/alicloud.md +++ b/cloud/alicloud.md @@ -1,6 +1,6 @@ # 阿里云 -![阿里云](_images/aliyun-logo.png) +![阿里云](./_images/aliyun-logo.png) [阿里云](https://www.aliyun.com?source=5176.11533457&userCode=8lx5zmtu&type=copy) 创立于 2009 年,是中国较早的云计算平台。阿里云致力于提供安全、可靠的计算和数据处理能力。 diff --git a/cloud/aws.md b/cloud/aws.md index aea35a170..81c03033b 100644 --- a/cloud/aws.md +++ b/cloud/aws.md @@ -1,6 +1,6 @@ # 亚马逊云 -![AWS](_images/aws-logo.jpg) +![AWS](./_images/aws-logo.jpg) [AWS](https://www.amazonaws.cn),即 Amazon Web Services,是亚马逊(Amazon)公司的 IaaS 和 PaaS 平台服务。AWS 提供了一整套基础设施和应用程序服务,使用户几乎能够在云中运行一切应用程序:从企业应用程序和大数据项目,到社交游戏和移动应用程序。AWS 面向用户提供包括弹性计算、存储、数据库、应用程序在内的一整套云计算服务,能够帮助企业降低 IT 投入成本和维护成本。 @@ -8,4 +8,4 @@ 2015 年 AWS 正式发布了 EC2 容器服务(ECS)。ECS 的目的是让 Docker 容器变的更加简单,它提供了一个集群和编排的层,用来控制主机上的容器部署,以及部署之后的集群内的容器的生命周期管理。ECS 是诸如 Docker Swarm、Kubernetes、Mesos 等工具的替代,它们工作在同一个层,除了作为一个服务来提供。这些工具和 ECS 不同的地方在于,前者需要用户自己来部署和管理,而 ECS 是“作为服务”来提供的。 -![AWS 容器服务](_images/ECS.jpg) +![AWS 容器服务](./_images/ECS.jpg) diff --git a/cloud/tencentCloud.md b/cloud/tencentCloud.md index 383aa9391..4c2f8d43a 100644 --- a/cloud/tencentCloud.md +++ b/cloud/tencentCloud.md @@ -1,6 +1,6 @@ # 腾讯云 -![腾讯云](_images/qcloud-logo.jpg) +![腾讯云](./_images/qcloud-logo.jpg) [腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=1040&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console) 在架构方面经过多年积累,并且有着多年对海量互联网服务的经验。不管是社交、游戏还是其他领域,都有多年的成熟产品来提供产品服务。腾讯在云端完成重要部署,为开发者及企业提供云服务、云数据、云运营等整体一站式服务方案。 diff --git a/data_management/README.md b/data_management/README.md index a45cd21db..532f4374e 100644 --- a/data_management/README.md +++ b/data_management/README.md @@ -1,6 +1,6 @@ # Docker 数据管理 -![](_images/types-of-mounts.png) +![](./_images/types-of-mounts.png) 这一章介绍如何在 Docker 内部以及容器之间管理数据,在容器中管理数据主要有两种方式: diff --git a/etcd/intro.md b/etcd/intro.md index 19f98b17c..23e1caa4f 100644 --- a/etcd/intro.md +++ b/etcd/intro.md @@ -1,6 +1,6 @@ # 什么是 etcd -![](_images/etcd_logo.png) +![](./_images/etcd_logo.png) `etcd` 是 `CoreOS` 团队于 2013 年 6 月发起的开源项目,它的目标是构建一个高可用的分布式键值(`key-value`)数据库,基于 `Go` 语言实现。我们知道,在分布式系统中,各种服务的配置信息的管理分享,服务的发现是一个很基本同时也是很重要的问题。`CoreOS` 项目就希望基于 `etcd` 来解决这一问题。 diff --git a/image/commit.md b/image/commit.md index 6dcc23103..19f4fdc3c 100644 --- a/image/commit.md +++ b/image/commit.md @@ -20,7 +20,7 @@ $ docker run --name webserver -d -p 80:80 nginx 直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。 -![](_images/images-mac-example-nginx.png) +![](./_images/images-mac-example-nginx.png) 现在,假设我们非常不喜欢这个欢迎页面,我们希望改成欢迎 Docker 的文字,我们可以使用 `docker exec` 命令进入容器,修改其内容。 @@ -37,7 +37,7 @@ exit 现在我们再刷新浏览器的话,会发现内容被改变了。 -![](_images/images-create-nginx-docker.png) +![](./_images/images-create-nginx-docker.png) 我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 `docker diff` 命令看到具体的改动。 diff --git a/install/mac.md b/install/mac.md index 176bab90e..c6049d432 100644 --- a/install/mac.md +++ b/install/mac.md @@ -20,25 +20,25 @@ $ brew cask install docker 如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。 -![](_images/install-mac-dmg.png) +![](./_images/install-mac-dmg.png) ## 运行 从应用中找到 Docker 图标并点击运行。 -![](_images/install-mac-apps.png) +![](./_images/install-mac-apps.png) 运行之后,会在右上角菜单栏看到多了一个鲸鱼图标,这个图标表明了 Docker 的运行状态。 -![](_images/install-mac-menubar.png) +![](./_images/install-mac-menubar.png) 第一次点击图标,可能会看到这个安装成功的界面,点击 "Got it!" 可以关闭这个窗口。 -![](_images/install-mac-success.png) +![](./_images/install-mac-success.png) 以后每次点击鲸鱼图标会弹出操作菜单。 -![](_images/install-mac-menu.png) +![](./_images/install-mac-menu.png) 启动终端后,通过命令可以检查安装后的 Docker 版本。 @@ -59,7 +59,7 @@ $ docker run -d -p 80:80 --name webserver nginx 服务运行后,可以访问 ,如果看到了 "Welcome to nginx!",就说明 Docker Desktop for Mac 安装成功了。 -![](_images/install-mac-example-nginx.png) +![](./_images/install-mac-example-nginx.png) 要停止 Nginx 服务器并删除执行下面的命令: diff --git a/install/windows.md b/install/windows.md index 36cbfdd3f..98eae7cef 100644 --- a/install/windows.md +++ b/install/windows.md @@ -26,15 +26,15 @@ $ winget install Docker.DockerDesktopEdge 在 Windows 搜索栏输入 **Docker** 点击 **Docker Desktop** 开始运行。 -![](_images/install-win-docker-app-search.png) +![](./_images/install-win-docker-app-search.png) Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。 -![](_images/install-win-taskbar-circle.png) +![](./_images/install-win-taskbar-circle.png) 等待片刻,点击 Got it 开始使用 Docker。 -![](_images/install-win-success-popup-cloud.png) +![](./_images/install-win-success-popup-cloud.png) ## 镜像加速 diff --git a/introduction/what.md b/introduction/what.md index 55cdffb68..2c4cd7da4 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -16,8 +16,8 @@ 下面的图片比较了 **Docker** 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。 -![传统虚拟化](_images/virtualization.png) +![传统虚拟化](./_images/virtualization.png) -![Docker](_images/docker.png) +![Docker](./_images/docker.png) [docker-soft]:https://en.wikipedia.org/wiki/Docker_(software) diff --git a/kubernetes/concepts.md b/kubernetes/concepts.md index 948bbcf66..99391f726 100644 --- a/kubernetes/concepts.md +++ b/kubernetes/concepts.md @@ -1,6 +1,6 @@ # 基本概念 -![](_images/kubernetes_design.jpg) +![](./_images/kubernetes_design.jpg) * 节点(`Node`):一个节点是一个运行 Kubernetes 中的主机。 * 容器组(`Pod`):一个 Pod 对应于由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。 diff --git a/kubernetes/design.md b/kubernetes/design.md index 9eeb6d03c..70bec9c3c 100644 --- a/kubernetes/design.md +++ b/kubernetes/design.md @@ -13,7 +13,7 @@ 下面这张图完整展示了 Kubernetes 的运行原理。 -![Kubernetes 架构](_images/k8s_architecture.png) +![Kubernetes 架构](./_images/k8s_architecture.png) 可见,Kubernetes 首先是一套分布式系统,由多个节点组成,节点分为两类:一类是属于管理平面的主节点/控制节点(Master Node);一类是属于运行平面的工作节点(Worker Node)。 @@ -41,4 +41,4 @@ * kubelet 是工作节点执行操作的 agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报 pod 运行状态等; * kube-proxy 是一个简单的网络访问代理,同时也是一个 Load Balancer。它负责将访问到某个服务的请求具体分配给工作节点上的 Pod(同一类标签)。 -![Proxy 代理对服务的请求](_images/kube-proxy.png) +![Proxy 代理对服务的请求](./_images/kube-proxy.png) diff --git a/kubernetes/intro.md b/kubernetes/intro.md index 6ecce9453..b80bd6b40 100644 --- a/kubernetes/intro.md +++ b/kubernetes/intro.md @@ -1,6 +1,6 @@ # 项目简介 -![](_images/kubernetes_logo.png) +![](./_images/kubernetes_logo.png) Kubernetes 是 Google 团队发起的开源项目,它的目标是管理跨多个主机的容器,提供基本的部署,维护以及应用伸缩,主要实现语言为 Go 语言。Kubernetes 是: diff --git a/underly/arch.md b/underly/arch.md index b4366dfc9..64318e499 100644 --- a/underly/arch.md +++ b/underly/arch.md @@ -4,7 +4,7 @@ Docker 采用了 `C/S` 架构,包括客户端和服务端。Docker 守护进 客户端和服务端既可以运行在一个机器上,也可通过 `socket` 或者 `RESTful API` 来进行通信。 -![Docker 基本架构](_images/docker_arch.png) +![Docker 基本架构](./_images/docker_arch.png) Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息。 From 17ad4945372b03e469d98a96eaed39c96ab2e97d Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 22 Oct 2020 08:46:09 +0800 Subject: [PATCH 133/201] remove outdated content Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 2 +- .vuepress/config.js | 2 +- install/mac.md | 2 -- package.json | 5 +++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 684f35778..911d2628f 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -1,4 +1,4 @@ -name: check-link +name: Check link on: # push: diff --git a/.vuepress/config.js b/.vuepress/config.js index 5cb6c3d85..0130ab02e 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -62,7 +62,7 @@ module.exports = config({ repoLabel: 'GitHub', hostname: 'https://vuepress.mirror.docker-practice.com', // author: 'yeasy', - markdown: { + mdEnhance: { lineNumbers: true, }, themeColor: { diff --git a/install/mac.md b/install/mac.md index c6049d432..f697c628c 100644 --- a/install/mac.md +++ b/install/mac.md @@ -47,8 +47,6 @@ $ docker --version Docker version 19.03.8, build afacb8b $ docker-compose --version docker-compose version 1.25.5, build 8a1c60f6 -$ docker-machine --version -docker-machine version 0.16.1, build cce350d7 ``` 如果 `docker version`、`docker info` 都正常的话,可以尝试运行一个 [Nginx 服务器](https://hub.docker.com/_/nginx/): diff --git a/package.json b/package.json index 50938ea68..3ce29fe81 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "chalk": "^2.4.2", "commander": "^2.0.0", "esm": "^3.0.0", - "vuepress": "1.7.0", + "vuepress": "1.7.1", "vuepress-plugin-container": "^2.1.5", "vuepress-theme-hope": "^1.0.0" }, @@ -17,7 +17,8 @@ "gitbook:help": "gitbook help", "gitbook:build": "gitbook build", "gitbook:serve": "gitbook serve", - "vuepress:build": "npx vuepress build" + "vuepress:build": "npx vuepress build", + "vuepress": "npx vuepress" }, "repository": { "type": "git", From 0b1812aac80333f546abc0511625cbd7988272cf Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 2 Nov 2020 10:33:27 +0800 Subject: [PATCH 134/201] Update fcos Signed-off-by: Kang Huaishuai --- .devcontainer/devcontainer.json | 2 ++ coreos/README.md | 2 +- coreos/intro.md | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c97bc620a..eb977b416 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,3 +1,5 @@ +// https://code.visualstudio.com/docs/remote/devcontainerjson-reference + { "image": "yeasy/docker_practice:latest", "mounts": [ diff --git a/coreos/README.md b/coreos/README.md index ca63655c8..36512e4fe 100644 --- a/coreos/README.md +++ b/coreos/README.md @@ -1,6 +1,6 @@ # Fedora CoreOS -`CoreOS` 是一个专门为安全和大规模运行容器化工作负载而构建的新 Fedora 版本,它是 Fedora Atomic Host 和 CoreOS Container Linux 的后继项目。 +`CoreOS` 是一个专门为安全和大规模运行容器化工作负载而构建的新 Fedora 版本,它继承了 Fedora Atomic Host 和 CoreOS Container Linux 的优势。 `CoreOS` 的安装文件和运行依赖非常小,它提供了精简的 Linux 系统。它使用 Linux 容器在更高的抽象层来管理你的服务,而不是通过常规的包管理工具 `yum` 或 `apt` 来安装包。 diff --git a/coreos/intro.md b/coreos/intro.md index d73998fd4..5540d942a 100644 --- a/coreos/intro.md +++ b/coreos/intro.md @@ -20,7 +20,7 @@ FCOS 使用 rpm-ostree 系统进行事务性升级。无需像 yum 升级那样 ### 容器工具 -对于诸如构建,复制和其他管理容器的任务,FCOS 用一组兼容的容器工具代替了 **Docker CLI** 工具。**podman CLI** 工具支持许多容器运行时功能,例如运行,启动,停止,列出和删除容器和镜像。**skopeo CLI** 工具可以复制,认证和签名镜像。您还可以使用 **crictl CLI** 工具来处理 CRI-O 容器引擎中的容器和镜像。 +对于诸如构建,复制和其他管理容器的任务,FCOS 用一组容器工具代替了 **Docker CLI**。**podman CLI** 工具支持许多容器运行时功能,例如运行,启动,停止,列出和删除容器和镜像。**skopeo CLI** 工具可以复制,认证和签名镜像。您还可以使用 **crictl CLI** 工具来处理 CRI-O 容器引擎中的容器和镜像。 ## 参考文档 From 00274b06152a1287c543d15e18fb8229d9306b9a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 2 Nov 2020 17:46:43 +0800 Subject: [PATCH 135/201] Update Dockerfile USER,close #473 Signed-off-by: Kang Huaishuai --- image/dockerfile/user.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/dockerfile/user.md b/image/dockerfile/user.md index 0fb7dabc7..5c60d243d 100644 --- a/image/dockerfile/user.md +++ b/image/dockerfile/user.md @@ -4,7 +4,7 @@ `USER` 指令和 `WORKDIR` 相似,都是改变环境状态并影响以后的层。`WORKDIR` 是改变工作目录,`USER` 则是改变之后层的执行 `RUN`, `CMD` 以及 `ENTRYPOINT` 这类命令的身份。 -当然,和 `WORKDIR` 一样,`USER` 只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。 +注意,`USER` 只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。 ```docker RUN groupadd -r redis && useradd -r -g redis redis From 7d51bacb1231d28185560703093f801995aa7b3a Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 2 Nov 2020 18:57:51 +0800 Subject: [PATCH 136/201] [compose] Remove outdated content Signed-off-by: Kang Huaishuai --- compose/commands.md | 4 ---- compose/demo/django/docker-compose.yml | 2 -- compose/django.md | 2 -- compose/rails.md | 2 -- 4 files changed, 10 deletions(-) diff --git a/compose/commands.md b/compose/commands.md index dda0b834f..e18e7a779 100644 --- a/compose/commands.md +++ b/compose/commands.md @@ -18,10 +18,6 @@ docker-compose [-f=...] [options] [COMMAND] [ARGS...] * `-p, --project-name NAME` 指定项目名称,默认将使用所在目录名称作为项目名。 -* `--x-networking` 使用 Docker 的可拔插网络后端特性 - -* `--x-network-driver DRIVER` 指定网络后端的驱动,默认为 `bridge` - * `--verbose` 输出更多调试信息。 * `-v, --version` 打印版本并退出。 diff --git a/compose/demo/django/docker-compose.yml b/compose/demo/django/docker-compose.yml index d3a50353b..18643f29a 100644 --- a/compose/demo/django/docker-compose.yml +++ b/compose/demo/django/docker-compose.yml @@ -11,5 +11,3 @@ services: - .:/code ports: - "8000:8000" - links: - - db diff --git a/compose/django.md b/compose/django.md index 2b5219769..b5ff327a0 100644 --- a/compose/django.md +++ b/compose/django.md @@ -43,8 +43,6 @@ services: - .:/code ports: - "8000:8000" - links: - - db ``` 查看 [`docker-compose.yml` 章节](compose_file.md) 了解更多详细的工作机制。 diff --git a/compose/rails.md b/compose/rails.md index 5222848f1..af8517b68 100644 --- a/compose/rails.md +++ b/compose/rails.md @@ -45,8 +45,6 @@ services: - .:/myapp ports: - "3000:3000" - links: - - db ``` 所有文件就绪后,我们就可以通过使用 `docker-compose run` 命令生成应用的骨架了。 From e8d45d3be972b6662549c7791ed60e5371ef0861 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 3 Nov 2020 13:04:28 +0800 Subject: [PATCH 137/201] [install] Update outdated content Signed-off-by: Kang Huaishuai --- install/_images/install-mac-success.png | Bin 60613 -> 0 bytes .../install-win-success-popup-cloud.png | Bin 170590 -> 0 bytes install/mac.md | 10 +++------- install/ubuntu.md | 2 +- install/windows.md | 4 ++-- 5 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 install/_images/install-mac-success.png delete mode 100644 install/_images/install-win-success-popup-cloud.png diff --git a/install/_images/install-mac-success.png b/install/_images/install-mac-success.png deleted file mode 100644 index 62e8b9aad181cdbda231a18cadb9437535532c48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60613 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%0A32C4_KR8 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 diff --git a/install/mac.md b/install/mac.md index f697c628c..f09fdca1c 100644 --- a/install/mac.md +++ b/install/mac.md @@ -2,7 +2,7 @@ ## 系统要求 -[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Catalina 10.13。 +[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Mojave 10.14。 ## 安装 @@ -32,15 +32,11 @@ $ brew cask install docker ![](./_images/install-mac-menubar.png) -第一次点击图标,可能会看到这个安装成功的界面,点击 "Got it!" 可以关闭这个窗口。 - -![](./_images/install-mac-success.png) - -以后每次点击鲸鱼图标会弹出操作菜单。 +每次点击鲸鱼图标会弹出操作菜单。 ![](./_images/install-mac-menu.png) -启动终端后,通过命令可以检查安装后的 Docker 版本。 +之后,你可以在终端通过命令检查安装后的 Docker 版本。 ```bash $ docker --version diff --git a/install/ubuntu.md b/install/ubuntu.md index 4b14c09d2..3242d15c2 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -8,7 +8,7 @@ Docker 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: -* Ubuntu Focal 20.04 (LTS) +* Focal 20.04 (LTS) * Bionic 18.04 (LTS) * Xenial 16.04 (LTS) diff --git a/install/windows.md b/install/windows.md index 98eae7cef..4ed0dfc20 100644 --- a/install/windows.md +++ b/install/windows.md @@ -32,9 +32,9 @@ Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。 ![](./_images/install-win-taskbar-circle.png) -等待片刻,点击 Got it 开始使用 Docker。 +等待片刻,当鲸鱼图标静止时,说明 Docker 启动成功,之后你可以打开 PowerShell 使用 Docker。 -![](./_images/install-win-success-popup-cloud.png) +> 推荐使用 [Windows Terminal](https://docs.microsoft.com/zh-cn/windows/terminal/get-started) 在终端使用 Docker。 ## 镜像加速 From 7b5a21bf6dfd676a4acb7a69e471b8990a6e5cb3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 3 Nov 2020 15:36:14 +0800 Subject: [PATCH 138/201] [install] Update debian Signed-off-by: Kang Huaishuai --- install/debian.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install/debian.md b/install/debian.md index b0e226c0e..ac9f574fc 100644 --- a/install/debian.md +++ b/install/debian.md @@ -51,6 +51,8 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-k 然后,我们需要向 `sources.list` 中添加 Docker 软件源: +> 在一些基于 Debian 的 Linux 发行版中 `$(lsb_release -cs)` 可能不会返回 Debian 的版本代号,例如 [Kail Linux](https://www.kali.org/docs/policy/kali-linux-relationship-with-debian/)、 [BunsenLabs Linux](https://www.bunsenlabs.org/)。在这些发行版中我们需要将下面命令中的 `$(lsb_release -cs)` 替换为 https://mirrors.ustc.edu.cn/docker-ce/linux/debian/dists/ 中支持的 Debian 版本代号,例如 `buster`。 + ```bash $ sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/debian \ From 2b7f954c6574ed70a91b8f663fc2ec40fccf13e3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 9 Nov 2020 12:41:02 +0800 Subject: [PATCH 139/201] [install] use aliyun mirror Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 - install/centos.md | 4 ++-- install/debian.md | 6 +++--- install/fedora.md | 4 ++-- install/raspberry-pi.md | 4 ++-- install/ubuntu.md | 4 ++-- kubernetes/setup/README.md | 2 +- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 911d2628f..6866bf657 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -37,7 +37,6 @@ jobs: "nodejs.org/dist/",\ "c.163.com/hub",\ "drone.yeasy.com",\ - "mirrors.ustc.edu.cn",\ "docs.docker.com",\ "dockerhub.azk8s.cn",\ "reg-mirror.qiniu.com",\ diff --git a/install/centos.md b/install/centos.md index a9b24ba36..683ca0919 100644 --- a/install/centos.md +++ b/install/centos.md @@ -40,9 +40,9 @@ $ sudo yum install -y yum-utils ```bash $ sudo yum-config-manager \ --add-repo \ - https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo + https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -$ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo +$ sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo # 官方源 # $ sudo yum-config-manager \ diff --git a/install/debian.md b/install/debian.md index ac9f574fc..d6fbc604e 100644 --- a/install/debian.md +++ b/install/debian.md @@ -42,7 +42,7 @@ $ sudo apt-get install \ 为了确认所下载软件包的合法性,需要添加软件源的 GPG 密钥。 ```bash -$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add - +$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | sudo apt-key add - # 官方源 @@ -51,11 +51,11 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-k 然后,我们需要向 `sources.list` 中添加 Docker 软件源: -> 在一些基于 Debian 的 Linux 发行版中 `$(lsb_release -cs)` 可能不会返回 Debian 的版本代号,例如 [Kail Linux](https://www.kali.org/docs/policy/kali-linux-relationship-with-debian/)、 [BunsenLabs Linux](https://www.bunsenlabs.org/)。在这些发行版中我们需要将下面命令中的 `$(lsb_release -cs)` 替换为 https://mirrors.ustc.edu.cn/docker-ce/linux/debian/dists/ 中支持的 Debian 版本代号,例如 `buster`。 +> 在一些基于 Debian 的 Linux 发行版中 `$(lsb_release -cs)` 可能不会返回 Debian 的版本代号,例如 [Kail Linux](https://www.kali.org/docs/policy/kali-linux-relationship-with-debian/)、 [BunsenLabs Linux](https://www.bunsenlabs.org/)。在这些发行版中我们需要将下面命令中的 `$(lsb_release -cs)` 替换为 https://mirrors.aliyun.com/docker-ce/linux/debian/dists/ 中支持的 Debian 版本代号,例如 `buster`。 ```bash $ sudo add-apt-repository \ - "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/debian \ + "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian \ $(lsb_release -cs) \ stable" diff --git a/install/fedora.md b/install/fedora.md index be91d2007..c1fba7c38 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -44,9 +44,9 @@ $ sudo dnf -y install dnf-plugins-core ```bash $ sudo dnf config-manager \ --add-repo \ - https://mirrors.ustc.edu.cn/docker-ce/linux/fedora/docker-ce.repo + https://mirrors.aliyun.com/docker-ce/linux/fedora/docker-ce.repo -$ sudo sed -i 's/download.docker.com/mirrors.ustc.edu.cn\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo +$ sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo # 官方源 # $ sudo dnf config-manager \ diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index d278cef51..be1a73d8a 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -33,7 +33,7 @@ $ sudo apt-get install \ 为了确认所下载软件包的合法性,需要添加软件源的 GPG 密钥。 ```bash -$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/raspbian/gpg | sudo apt-key add - +$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/raspbian/gpg | sudo apt-key add - # 官方源 @@ -44,7 +44,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/raspbian/gpg | sudo apt ```bash $ sudo add-apt-repository \ - "deb [arch=armhf] https://mirrors.ustc.edu.cn/docker-ce/linux/raspbian \ + "deb [arch=armhf] https://mirrors.aliyun.com/docker-ce/linux/raspbian \ $(lsb_release -cs) \ stable" diff --git a/install/ubuntu.md b/install/ubuntu.md index 3242d15c2..8ad928cf3 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -44,7 +44,7 @@ $ sudo apt-get install \ 为了确认所下载软件包的合法性,需要添加软件源的 `GPG` 密钥。 ```bash -$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add - +$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # 官方源 @@ -55,7 +55,7 @@ $ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-k ```bash $ sudo add-apt-repository \ - "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \ + "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable" diff --git a/kubernetes/setup/README.md b/kubernetes/setup/README.md index f6bc2ff90..c5d661f3a 100644 --- a/kubernetes/setup/README.md +++ b/kubernetes/setup/README.md @@ -1,6 +1,6 @@ # 部署 Kubernetes -目前,Kubernetes 支持在多种环境下使用,包括本地主机(Fedora)、云服务(Google GAE、AWS 等)。 +目前,Kubernetes 支持在多种环境下使用,包括本地主机(Ubuntu、Debian、Fedora 等)、云服务([腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61)、[阿里云](https://www.aliyun.com/product/kubernetes?source=5176.11533457&userCode=8lx5zmtu&type=copy)、[百度云](https://cloud.baidu.com/product/cce.html) 等)。 你可以使用以下几种方式部署 Kubernetes: From da09321b0eb1fefa19e9f4636ced90126eac3460 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 21 Nov 2020 20:43:00 +0800 Subject: [PATCH 140/201] close #478 Signed-off-by: Kang Huaishuai --- install/windows.md | 5 ++++- kubernetes/setup/README.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/install/windows.md b/install/windows.md index 4ed0dfc20..9ad6a3263 100644 --- a/install/windows.md +++ b/install/windows.md @@ -22,6 +22,10 @@ $ winget install Docker.DockerDesktop $ winget install Docker.DockerDesktopEdge ``` +## 在 WSL2 运行 Docker + +若你的 Windows 版本为 Windows 10 专业版或家庭版 v1903 及以上版本可以使用 WSL2 运行 Docker,具体请查看 [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl/)。 + ## 运行 在 Windows 搜索栏输入 **Docker** 点击 **Docker Desktop** 开始运行。 @@ -43,5 +47,4 @@ Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。 ## 参考链接 * [官方文档](https://docs.docker.com/docker-for-windows/install/) -* [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl/) * [WSL 2 Support is coming to Windows 10 Versions 1903 and 1909](https://devblogs.microsoft.com/commandline/wsl-2-support-is-coming-to-windows-10-versions-1903-and-1909/) diff --git a/kubernetes/setup/README.md b/kubernetes/setup/README.md index c5d661f3a..4275d0da1 100644 --- a/kubernetes/setup/README.md +++ b/kubernetes/setup/README.md @@ -1,6 +1,6 @@ # 部署 Kubernetes -目前,Kubernetes 支持在多种环境下使用,包括本地主机(Ubuntu、Debian、Fedora 等)、云服务([腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61)、[阿里云](https://www.aliyun.com/product/kubernetes?source=5176.11533457&userCode=8lx5zmtu&type=copy)、[百度云](https://cloud.baidu.com/product/cce.html) 等)。 +目前,Kubernetes 支持在多种环境下使用,包括本地主机(Ubuntu、Debian、CentOS、Fedora 等)、云服务([腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61)、[阿里云](https://www.aliyun.com/product/kubernetes?source=5176.11533457&userCode=8lx5zmtu&type=copy)、[百度云](https://cloud.baidu.com/product/cce.html) 等)。 你可以使用以下几种方式部署 Kubernetes: From 9d62668fcf6bcfa1e0dadf068b32244b933a2f87 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 9 Dec 2020 23:49:26 +0800 Subject: [PATCH 141/201] close #479 Signed-off-by: Kang Huaishuai --- compose/demo/django/docker-compose.yml | 2 ++ compose/django.md | 3 +++ 2 files changed, 5 insertions(+) diff --git a/compose/demo/django/docker-compose.yml b/compose/demo/django/docker-compose.yml index 18643f29a..861980abd 100644 --- a/compose/demo/django/docker-compose.yml +++ b/compose/demo/django/docker-compose.yml @@ -3,6 +3,8 @@ services: db: image: postgres + environment: + POSTGRES_PASSWORD: 'postgres' web: build: . diff --git a/compose/django.md b/compose/django.md index b5ff327a0..16a588f5e 100644 --- a/compose/django.md +++ b/compose/django.md @@ -35,6 +35,8 @@ services: db: image: postgres + environment: + POSTGRES_PASSWORD: 'postgres' web: build: . @@ -78,6 +80,7 @@ DATABASES = { 'USER': 'postgres', 'HOST': 'db', 'PORT': 5432, + 'PASSWORD': 'postgres', } } ``` From da10b3a7a1c6e0b98a8cf3ed036188d8a0a4398e Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 11 Dec 2020 22:00:57 +0800 Subject: [PATCH 142/201] remove docker desktop edge channel Signed-off-by: Kang Huaishuai --- install/mac.md | 2 +- install/windows.md | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/install/mac.md b/install/mac.md index f09fdca1c..d0e8fb986 100644 --- a/install/mac.md +++ b/install/mac.md @@ -16,7 +16,7 @@ $ brew cask install docker ### 手动下载安装 -如果需要手动下载,请点击以下链接下载 [Stable](https://download.docker.com/mac/stable/Docker.dmg) 或 [Edge](https://download.docker.com/mac/edge/Docker.dmg) 版本的 Docker Desktop for Mac。 +如果需要手动下载,请点击以下 [链接](https://desktop.docker.com/mac/stable/Docker.dmg) 下载 Docker Desktop for Mac。 如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。 diff --git a/install/windows.md b/install/windows.md index 9ad6a3263..70fefb8be 100644 --- a/install/windows.md +++ b/install/windows.md @@ -8,18 +8,14 @@ **手动下载安装** -点击以下链接下载 [Stable](https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe) 或 [Edge](https://download.docker.com/win/edge/Docker%20Desktop%20Installer.exe) 版本的 Docker Desktop for Windows。 +点击以下 [链接](https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe) 下载 Docker Desktop for Windows。 下载好之后双击 `Docker Desktop Installer.exe` 开始安装。 **使用 [winget](https://docs.microsoft.com/zh-cn/windows/package-manager/) 安装** ```powershell -# stable $ winget install Docker.DockerDesktop - -# edge -$ winget install Docker.DockerDesktopEdge ``` ## 在 WSL2 运行 Docker From 47e83e7aa3c9f730d02a14657744d9f6a24fd537 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 20 Dec 2020 22:10:25 +0800 Subject: [PATCH 143/201] docker v20.10.0 released Signed-off-by: Kang Huaishuai --- .github/ISSUE_TEMPLATE/Bug_report.md | 6 +++--- .github/ISSUE_TEMPLATE/Custom.md | 6 +++--- CHANGELOG.md | 5 ++++- README.md | 2 +- install/centos.md | 4 ++-- install/fedora.md | 6 ------ install/mac.md | 4 +--- manifest | 2 +- 8 files changed, 15 insertions(+), 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index d0ac6ea99..4db514ec7 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -21,11 +21,11 @@ about: Create a report to help us improve * [x] Others (Pls describe below) ### Docker Version - - + + * [x] Test (v20.10) -* [x] Stable (v19.03) +* [x] Stable (v20.10) * [x] 1.13.0 or Before ### Problem Description diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md index fa5bf1311..6db0f8f22 100644 --- a/.github/ISSUE_TEMPLATE/Custom.md +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -21,11 +21,11 @@ about: Create a issue about Docker * [x] Others (Pls describe below) ### Docker Version - - + + * [x] Test (v20.10) -* [x] Stable (v19.03) +* [x] Stable (v20.10) * [x] 1.13.0 or Before ### Problem Description diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f5260754..cfd3cfc49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,11 @@ # 修订记录 -* 1.2.0 2020-12-31 +* 1.3.0 2021-YY-DD * 全面支持 Docker v20.10 新版本 +* 1.2.0 2020-12-20 + * 错误修复 + * 1.1.0 2019-12-31 * 全面支持 Docker v19.03 新版本 * 增加 `BuildKit` diff --git a/README.md b/README.md index 4fa8d0026..ffe37c571 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![](https://travis-ci.org/yeasy/docker_practice.svg?branch=master)](https://travis-ci.org/yeasy/docker_practice) [![](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![](https://img.shields.io/badge/Based-Docker%20CE%20v20.10-blue.svg)](https://github.com/docker/docker-ce) [![](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] -**v1.2.0** +**v1.3.0** | 语言 | 构建状态 | - | | :------------- | :------------- | :--- | diff --git a/install/centos.md b/install/centos.md index 683ca0919..e424f4b3b 100644 --- a/install/centos.md +++ b/install/centos.md @@ -50,7 +50,7 @@ $ sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.r # https://download.docker.com/linux/centos/docker-ce.repo ``` -如果需要测试版本的 Docker (**或你的系统是 CentOS 8**)请执行以下命令: +如果需要测试版本的 Docker 请执行以下命令: ```bash $ sudo yum-config-manager --enable docker-ce-test @@ -87,7 +87,7 @@ $ firewall-cmd --reload 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: -> 若你想安装测试版的 Docker(**或你的系统是 CentOS 8**), 请从 test.docker.com 获取脚本 +> 若你想安装测试版的 Docker, 请从 test.docker.com 获取脚本 ```bash # $ curl -fsSL test.docker.com -o get-docker.sh diff --git a/install/fedora.md b/install/fedora.md index c1fba7c38..fc72d6564 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -85,12 +85,6 @@ docker-ce.x86_64 18.06.1.ce-3.fc28 docker-ce-stable $ sudo dnf -y install docker-ce-18.06.1.ce ``` -由于 Fedora 31 默认启用了 **Cgroupv2**,稳定版本的 Docker 与 Cgroupv2 不兼容,你可以安装测试版 Docker,或者执行以下命令切换到 **Cgroupv1** 并重启计算机: - -```bash -$ sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" -``` - ## 使用脚本自动安装 在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装: diff --git a/install/mac.md b/install/mac.md index d0e8fb986..3ceefb0f3 100644 --- a/install/mac.md +++ b/install/mac.md @@ -40,9 +40,7 @@ $ brew cask install docker ```bash $ docker --version -Docker version 19.03.8, build afacb8b -$ docker-compose --version -docker-compose version 1.25.5, build 8a1c60f6 +Docker version 20.10.0, build 7287ab3 ``` 如果 `docker version`、`docker info` 都正常的话,可以尝试运行一个 [Nginx 服务器](https://hub.docker.com/_/nginx/): diff --git a/manifest b/manifest index dafda1705..3edf306bf 100644 --- a/manifest +++ b/manifest @@ -1,4 +1,4 @@ -DOCKER_VERSION=19.03.8 +DOCKER_VERSION=20.10.0 DOCKER_COMPOSE_VERSION=1.25.5 DOCKER_MACHINE_VERSION=0.16.1 ETCD_VERSION=3.4.0 From cc726421c85b9e872e64231c23765934b05de39e Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 20 Dec 2020 22:18:08 +0800 Subject: [PATCH 144/201] Update compose version Signed-off-by: Kang Huaishuai --- compose/install.md | 11 +++++++---- etcd/install.md | 4 ++++ manifest | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compose/install.md b/compose/install.md index 92ae6fc3d..468a1a5ee 100644 --- a/compose/install.md +++ b/compose/install.md @@ -9,7 +9,7 @@ ```bash $ docker-compose --version -docker-compose version 1.25.5, build 4667896b +docker-compose version 1.27.4, build 40524192 ``` Linux 系统请使用以下介绍的方法安装。 @@ -21,7 +21,10 @@ Linux 系统请使用以下介绍的方法安装。 例如,在 Linux 64 位系统上直接下载对应的二进制包。 ```bash -$ sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose +$ sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose + +# 国内用户可以使用以下方式加快下载 +$ sudo curl -L https://download.fastgit.org/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose ``` @@ -42,7 +45,7 @@ $ sudo pip install -U docker-compose ```bash Collecting docker-compose - Downloading docker-compose-1.25.5.tar.gz (149kB): 149kB downloaded + Downloading docker-compose-1.27.4.tar.gz (149kB): 149kB downloaded ... Successfully installed docker-compose cached-property requests texttable websocket-client docker-py dockerpty six enum34 backports.ssl-match-hostname ipaddress ``` @@ -50,7 +53,7 @@ Successfully installed docker-compose cached-property requests texttable websock ## bash 补全命令 ```bash -$ curl -L https://raw.githubusercontent.com/docker/compose/1.25.5/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose +$ curl -L https://raw.githubusercontent.com/docker/compose/1.27.4/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose ``` ## 卸载 diff --git a/etcd/install.md b/etcd/install.md index d188f5efe..5366f1ec2 100644 --- a/etcd/install.md +++ b/etcd/install.md @@ -12,6 +12,10 @@ ```bash $ curl -L https://github.com/etcd-io/etcd/releases/download/v3.4.0/etcd-v3.4.0-linux-amd64.tar.gz -o etcd-v3.4.0-linux-amd64.tar.gz + +# 国内用户可以使用以下方式加快下载 +$ curl -L https://download.fastgit.org/etcd-io/etcd/releases/download/v3.4.0/etcd-v3.4.0-linux-amd64.tar.gz -o etcd-v3.4.0-linux-amd64.tar.gz + $ tar xzvf etcd-v3.4.0-linux-amd64.tar.gz $ cd etcd-v3.4.0-linux-amd64 ``` diff --git a/manifest b/manifest index 3edf306bf..107f15ce2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ DOCKER_VERSION=20.10.0 -DOCKER_COMPOSE_VERSION=1.25.5 +DOCKER_COMPOSE_VERSION=1.27.4 DOCKER_MACHINE_VERSION=0.16.1 ETCD_VERSION=3.4.0 KUBERNETES_VERSION=1.14.3 From fb162df03313133f7ccd159d491ee63a62d11b54 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 20 Dec 2020 22:32:04 +0800 Subject: [PATCH 145/201] remove project travis ci Signed-off-by: Kang Huaishuai --- .github/CODEOWNERS | 1 - .github/workflows/ci.yaml | 48 ++++++++++++++++++++++++++-- .travis.yml | 65 -------------------------------------- .travis/id_rsa.enc | Bin 1680 -> 0 bytes README.md | 11 +++---- docker-compose.yml | 2 +- 6 files changed, 51 insertions(+), 76 deletions(-) delete mode 100644 .travis.yml delete mode 100644 .travis/id_rsa.enc diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fb7faa903..bf8cf1de4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,7 +28,6 @@ /.editorconfig/ @khs1994 /.gitattributes @khs1994 /.gitignore @khs1994 -/.travis.yml @khs1994 /_config.yml @yeasy @khs1994 /book.json @yeasy @khs1994 /CHANGELOG.md @yeasy @khs1994 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5ba4edc3f..445529d6b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,16 +7,58 @@ name: CI jobs: build: - name: Build GitBook + name: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@master with: fetch-depth: 2 - - name: Build + - name: Build Gitbook uses: docker://yeasy/docker_practice with: args: build + - name: Build Gitbook Docker Image + if: github.repository == 'docker-practice/docker_practice' + run: | + sudo chmod -R 777 _book + echo "FROM nginx:alpine" >> Dockerfile + echo "COPY _book /usr/share/nginx/html" >> Dockerfile + echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile + echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile + + export VCS_REF=`git rev-parse --short HEAD` + + docker build \ + -t dockerpracticesig/docker_practice \ + -t dockerpracticesig/docker_practice:gitbook \ + --label org.opencontainers.image.revision=$VCS_REF \ + --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ + --label maintainer="https://github.com/docker-practice" \ + . + + docker run -d --rm -p 4000:80 dockerpracticesig/docker_practice + + sleep 5 + curl 127.0.0.1:4000 + + echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + docker push dockerpracticesig/docker_practice + docker push dockerpracticesig/docker_practice:gitbook + env: + DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} + DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} + - name: Upload Gitbook dist + uses: docker://pcit/pages + if: github.repository == 'docker-practice/docker_practice' + env: + PCIT_EMAIL: khs1994@khs1994.com + PCIT_GIT_TOKEN: ${{ secrets.PCIT_GIT_TOKEN }} + PCIT_GIT_URL: github.com/docker-practice/zh-cn + PCIT_KEEP_HISTORY: "true" + PCIT_LOCAL_DIR: _book + PCIT_MESSAGE: Build from yeasy/docker_practice@${{github.sha}} + PCIT_TARGET_BRANCH: master + PCIT_USERNAME: khs1994 - name: vuepress run: | sudo rm -rf _book @@ -73,7 +115,7 @@ jobs: PCIT_GIT_URL: e.coding.net/dpsigs/docker_practice PCIT_KEEP_HISTORY: "true" PCIT_LOCAL_DIR: .vuepress/dist - PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT + PCIT_MESSAGE: Build from yeasy/docker_practice@${{github.sha}} PCIT_TARGET_BRANCH: master PCIT_USERNAME: ptt0xjqzbke3 - name: Build vuepress docker image diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3f12f43f0..000000000 --- a/.travis.yml +++ /dev/null @@ -1,65 +0,0 @@ -language: bash - -services: -- docker - -before_install: -- openssl aes-256-cbc -K $encrypted_6cc8cff04075_key -iv $encrypted_6cc8cff04075_iv - -in .travis/id_rsa.enc -out ~/.ssh/id_rsa -d -- chmod 600 ~/.ssh/id_rsa -- export TZ='Asia/Shanghai' -- date -- git config --global user.name "khs1994" -- git config --global user.email "khs1994@khs1994.com" - -script: -- docker run -it --rm -v $PWD:/srv/gitbook-src yeasy/docker_practice build - -after_success: -- sudo chmod -R 777 _book - -- echo "FROM nginx:alpine" >> Dockerfile -- echo "COPY _book /usr/share/nginx/html" >> Dockerfile -- echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile -- echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile - -- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin -- export VCS_REF=`git rev-parse --short HEAD` -- | - docker build \ - -t dockerpracticesig/docker_practice \ - -t dockerpracticesig/docker_practice:gitbook \ - --label org.opencontainers.image.revision=$VCS_REF \ - --label org.opencontainers.image.source="https://github.com/yeasy/docker_practice" \ - --label maintainer="https://github.com/docker-practice" \ - . - -- docker run -dit --rm -p 4000:80 dockerpracticesig/docker_practice - -- sleep 5 -- curl 127.0.0.1:4000 - -- docker push dockerpracticesig/docker_practice -- docker push dockerpracticesig/docker_practice:gitbook - -- cd _book -- rm -rf .github/workflows -- git init -- git remote add origin "$DEPLOY_REPO" -- git add . -- COMMIT=`date "+%F %T"` -- git commit -m "Travis CI Site updated $COMMIT yeasy/docker_practice@${TRAVIS_COMMIT}" -- git push -f origin master:"$DEPLOY_BRANCH" - -env: - global: - - DEPLOY_BRANCH: master - - DEPLOY_REPO: git@github.com:docker-practice/zh-cn.git - -addons: - ssh_known_hosts: - - github.com - -branches: - only: - - master diff --git a/.travis/id_rsa.enc b/.travis/id_rsa.enc deleted file mode 100644 index 5e4575408efe2d32cd4f1d6d11987f2b915b9d17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1680 zcmV;B25{o1;yEeP;f?g$hIj7}{4s+oxh`2aC%pR6)~+8-IL zTh6{Zsg6kUu`cG5%3?hJKM6dzaFWKY{oZK?Q?1%V5PfD3$bwi(CXIz~$BZIlW!};> zc`VPisFqU!QE&ARJ~9;c7DK}TA8XtLj7Hm$?b_d!@d2fh(V6wFjP96)Xg(A@A+XAT z=fBeo*6#}{PwtWou@vzLR2O}ozfo`%*@2osnn=3@YAy;3&GflKL_tso=zGskoBdq2 ziUeWh1+bC4C?5a0{nZNDfF-ZR`5Sd1-BI$!a0sN@sBdjYZq1A8!ih9&0~N-vQGv+o z^Hvkeq3m46H_7W~NetCt0e;z9Xgfzy2Z!O;KwRN0B4QAviB-fdA4tKL1O#)bIfw@b z=gIP#(N>wRykihK95X`($?l_9o8W+|_L_};g*dm+4cp#)(@^~Dqb+RClh4Q<$PF|Y z97@JL92kmDHV?67>jqYpughHjKrI0>>3?@SFj0QxYdtU#5savW@|_Y}Gi&N5ONu zVRke^?6XJTs~<(lwccQ6ng}Y_*xxXCDYJwfELZ#!wTi2L4kfb_xBgn37ox((1}%D1 z-wRPT-GT&`xM$Z(Jl4)%$BLOs-Fpt}T!m4J%4=BrjUO4!EU`6L=G|5w*e2UsIcQe$ z&#xtn&2BBTd9vbT)wWSNTe>-JEW@PwOU0X|i>f|^h`I!3mZ2T+##k)ZW%a}0#B9%R zE;defMGHKQD(?Cd)id%gDv`1YYJr2eBLHLIhA}JN2}z_;1T`Is4Cj2AucmCKhPOs! zAI19KMN)PAQn5DP-)5ryZb-cjIFCF^B=$g~)^IQ;EgR>oh)4vDh;v%JZkKrPXB@nq zW*>ceDNYXR=zCdkt{m>E%w3gxdFxWMCB1@7Th9YPqv}o9H%| zdBRm0#B!krZ?KIr#CUsC4;GBr&5-!t5Bg@Q<*XKvLFZl2GVBt@ef>6Z_`A=6*hJN zI-n*I4u^vKIY{1R?+90h^H`VvN+^TjunuWlA97VwWMqi*#@jO)dSqMEb9VPvQlF&c zMxd%`s(Gf194Qod*l&0#pnRyw+KKf&F|P5X2;K4_#c^y_(WUX%jX}*>pvvoYEU*n$ znHIYLl8i$9|5*;9X$4cVpfr{DcOBRlImj%mz~yO_UWK#KeD8J={`y>}XO71L_gtJ( zRngE9Uq3ged$pSe*MDht9|B!AP~)b~G0DgUmN{wEW2G2_DIwE)~MQ z8(iFyF{y)L(M}g+FC9;DY{ceqB?ccH8)1v+unov=1+~mS`8~4D(BQiOPp;JjxP)idA+Ib1~!S4vf!U@z%qbB%t(z-(X%D)1lQ{l|XJHD0X|n z)j)b@m6o+L;1(Nu8G;puO^n>y%leG|Sz$khy2iH3_5F@cHZoKmi9I)s#^lFT8Z$h` aRZdWiv9vTmf{BX+fd@SKrMR~Cy Date: Sun, 20 Dec 2020 22:58:09 +0800 Subject: [PATCH 146/201] remove mesos Signed-off-by: Kang Huaishuai --- .github/workflows/ci.yaml | 1 - SUMMARY.md | 8 - mesos/README.md | 6 - mesos/_images/marathon.png | Bin 13638 -> 0 bytes mesos/_images/marathon_basic0.png | Bin 27087 -> 0 bytes mesos/_images/mesos-architecture.png | Bin 46092 -> 0 bytes mesos/_images/mesos.png | Bin 28889 -> 0 bytes mesos/architecture.md | 83 ------ mesos/configuration.md | 172 ------------ mesos/framework.md | 89 ------ mesos/installation.md | 387 --------------------------- mesos/intro.md | 20 -- mesos/monitor.md | 110 -------- mesos/summary.md | 7 - 14 files changed, 883 deletions(-) delete mode 100644 mesos/README.md delete mode 100644 mesos/_images/marathon.png delete mode 100644 mesos/_images/marathon_basic0.png delete mode 100644 mesos/_images/mesos-architecture.png delete mode 100644 mesos/_images/mesos.png delete mode 100644 mesos/architecture.md delete mode 100644 mesos/configuration.md delete mode 100644 mesos/framework.md delete mode 100644 mesos/installation.md delete mode 100644 mesos/intro.md delete mode 100644 mesos/monitor.md delete mode 100644 mesos/summary.md diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 445529d6b..08065784d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -87,7 +87,6 @@ jobs: cp -r install/_images .vuepress/dist/install cp -r introduction/_images .vuepress/dist/introduction cp -r kubernetes/_images .vuepress/dist/kubernetes - cp -r mesos/_images .vuepress/dist/mesos cp -r underly/_images .vuepress/dist/underly echo "include: [_images]" > .vuepress/dist/_config.yml diff --git a/SUMMARY.md b/SUMMARY.md index 414e65c00..e3ef168dd 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -170,14 +170,6 @@ * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) * [归档](archive/README.md) - * [Mesos - 优秀的集群资源调度平台](mesos/README.md) - * [Mesos 简介](mesos/intro.md) - * [安装与使用](mesos/installation.md) - * [原理与架构](mesos/architecture.md) - * [Mesos 配置项解析](mesos/configuration.md) - * [日志与监控](mesos/monitor.md) - * [常见应用框架](mesos/framework.md) - * [本章小结](mesos/summary.md) * [Docker Machine](machine/README.md) * [安装](machine/install.md) * [使用](machine/usage.md) diff --git a/mesos/README.md b/mesos/README.md deleted file mode 100644 index ec9b7f4e1..000000000 --- a/mesos/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Mesos - 优秀的集群资源调度平台 -Mesos 项目是源自 UC Berkeley 的对集群资源进行抽象和管理的开源项目,类似于操作系统内核,用户可以使用它很容易地实现分布式应用的自动化调度。 - -同时,Mesos 自身也很好地结合和主持了 Docker 等相关容器技术,基于 Mesos 已有的大量应用框架,可以实现用户应用的快速上线。 - -本章将介绍 Mesos 项目的安装、使用、配置以及核心的原理知识。 \ No newline at end of file diff --git a/mesos/_images/marathon.png b/mesos/_images/marathon.png deleted file mode 100644 index 130c6649f0d0a3b3ed1552ef05d0c1af194bb8a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13638 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 diff --git a/mesos/_images/marathon_basic0.png b/mesos/_images/marathon_basic0.png deleted file mode 100644 index 2b8f920a0605a322030c565002425ff75baf1051..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27087 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 HO~`)%avHv` diff --git a/mesos/architecture.md b/mesos/architecture.md deleted file mode 100644 index 22b1d8538..000000000 --- a/mesos/architecture.md +++ /dev/null @@ -1,83 +0,0 @@ -## 原理与架构 - -首先,再次需要强调 Mesos 自身只是一个资源调度框架,并非一整套完整的应用管理平台,所以只有 Mesos 自己是不能干活的。但是基于 Mesos,可以比较容易地为各种应用管理框架或者中间件平台(作为 Mesos 的应用)提供分布式运行能力;同时多个框架也可以同时运行在一个 Mesos 集群中,提高整体的资源使用效率。 - -Mesos 对自己定位范围的划分,使得它要完成的任务很明确,其它任务框架也可以很容易的与它进行整合。 - -### 架构 -下面这张基本架构图来自 Mesos 官方。 - -![mesos 的基本架构](_images/mesos-architecture.png) - -可以看出,Mesos 采用了经典的主-从(master-slave)架构,其中主节点(管理节点)可以使用 zookeeper 来做 HA。 - -Mesos master 服务将运行在主节点上,Mesos slave 服务则需要运行在各个计算任务节点上。 - -负责完成具体任务的应用框架们,跟 Mesos master 进行交互,来申请资源。 - -### 基本单元 -Mesos 中有三个基本的组件:管理服务(master)、任务服务(slave)以及应用框架(framework)。 - -#### 管理服务 - master -跟大部分分布式系统中类似,主节点起到管理作用,将看到全局的信息,负责不同应用框架之间的资源调度和逻辑控制。应用框架需要注册到管理服务上才能被使用。 - -用户和应用需要通过主节点提供的 API 来获取集群状态和操作集群资源。 - -#### 任务服务 - slave -负责汇报本从节点上的资源状态(空闲资源、运行状态等等)给主节点,并负责隔离本地资源来执行主节点分配的具体任务。 - -隔离机制目前包括各种容器机制,包括 LXC、Docker 等。 - -#### 应用框架 - framework -应用框架是实际干活的,包括两个主要组件: - -* 调度器(scheduler):注册到主节点,等待分配资源; -* 执行器(executor):在从节点上执行框架指定的任务(框架也可以使用 Mesos 自带的执行器,包括 shell 脚本执行器和 Docker 执行器)。 - -应用框架可以分两种:一种是对资源的需求是会扩展的(比如 Hadoop、Spark 等),申请后还可能调整;一种是对资源需求大小是固定的(MPI 等),一次申请即可。 - -### 调度 -对于一个资源调度框架来说,最核心的就是调度机制,怎么能快速高效地完成对某个应用框架资源的分配,是核心竞争力所在。最理想情况下(大部分时候都无法实现),最好是能猜到应用们的实际需求,实现最大化的资源使用率。 - -Mesos 为了实现尽量优化的调度,采取了两层(two-layer)的调度算法。 - -#### 算法基本过程 -调度的基本思路很简单,master 先全局调度一大块资源给某个 framework,framework 自己再实现内部的细粒度调度,决定哪个任务用多少资源。两层调度简化了 Mesos master 自身的调度过程,通过将复杂的细粒度调度交由 framework 实现,避免了 Mesos master 成为性能瓶颈。 - -调度机制支持插件机制来实现不同的策略。默认是 Dominant Resource Fairness(DRF)。 - -*注:DRF 算法细节可以参考论文《Dominant Resource Fairness: Fair Allocation of Multiple Resource Types》。其核心思想是对不同类型资源的多个请求,计算请求的主资源类型,然后根据主资源进行公平分配。* - -#### 调度过程 -调度通过 offer 发送的方式进行交互。一个 offer 是一组资源,例如 `<1 CPU, 2 GB Mem>`。 - -基本调度过程如下: - -* 首先,slave 节点会周期性汇报自己可用的资源给 master; -* 某个时候,master 收到应用框架发来的资源请求,根据调度策略,计算出来一个资源 offer 给 framework; -* framework 收到 offer 后可以决定要不要,如果接受的话,返回一个描述,说明自己希望如何使用和分配这些资源来运行某些任务(可以说明只希望使用部分资源,则多出来的会被 master 收回); -* 最后,master 则根据 framework 答复的具体分配情况发送给 slave,以使用 framework 的 executor 来按照分配的资源策略执行任务。 - -具体给出一个例子,某从节点向主节点汇报自己有 `<4 CPU, 8 GB Mem>` 的空闲资源,同时,主节点看到某个应用框架请求 `<3 CPU, 6 GB Mem>`,就创建一个 offer `` 把满足的资源发给应用框架。应用框架(的调度器)收到 offer 后觉得可以接受,就回复主节点,并告诉主节点希望运行两个任务:一个占用 `<1 CPU, 2 GB Mem>`,一个占用 一个占用 `<2 CPU, 4 GB Mem>`。主节点收到任务信息后分配任务到从节点上进行运行(实际上是应用框架的执行器来负责执行任务)。任务运行结束后资源可以被释放出来。 - -剩余的资源还可以继续分配给其他应用框架或任务。 - -应用框架在收到 offer 后,如果 offer 不满足自己的偏好(例如希望继续使用上次的 slave 节点),则可以选择拒绝 offer,等待 master 发送新的 offer 过来。另外,可以通过过滤器机制来加快资源的分配过程。 - -#### 过滤器 -framework 可以通过过滤器机制告诉 master 它的资源偏好,比如希望分配过来的 offer 有哪个资源,或者至少有多少资源等。 - -过滤器可以避免某些应用资源长期分配不到所需要的资源的情况,加速整个资源分配的交互过程。 - -#### 回收机制 -为了避免某些任务长期占用集群中资源,Mesos 也支持回收机制。 - -主节点可以定期回收计算节点上的任务所占用的资源,可以动态调整长期任务和短期任务的分布。 - -### HA - -从架构上看,最为核心的节点是 master 节点。除了使用 ZooKeeper 来解决单点失效问题之外,Mesos 的 master 节点自身还提供了很高的鲁棒性。 - -Mesos master 节点在重启后,可以动态通过 slave 和 framework 发来的消息重建内部状态,虽然可能导致一定的时延,但这避免了传统控制节点对数据库的依赖。 - -当然,为了减少 master 节点的负载过大,在集群中 slave 节点数目较多的时候,要避免把各种通知的周期配置的过短。实践中,可以通过部署多个 Mesos 集群来保持单个集群的规模不要过大。 diff --git a/mesos/configuration.md b/mesos/configuration.md deleted file mode 100644 index bacec5daa..000000000 --- a/mesos/configuration.md +++ /dev/null @@ -1,172 +0,0 @@ -## Mesos 配置项解析 - -Mesos 支持在运行时通过命令行参数形式提供的配置项。如果是通过系统服务方式启动,也支持以配置文件或环境变量方式给出。当然,实际上最终是提取为命令行参数传递给启动命令。 - -Mesos 的配置项分为三种类型:通用项(master 和 slave 都支持),只有 master 支持的,以及只有 slave 支持的。 - -Mesos 配置项比较多,下面对一些重点配置进行描述。少数为必备项,意味着必须给出配置值;另外一些是可选配置,自己带有默认值。 - -### 通用项 -通用项数量不多,主要涉及到服务绑定地址和日志信息等,包括: - -* `--advertise_ip=VALUE` 可以通过该地址访问到服务,比如应用框架访问到 master 节点; -* `--advertise_port=VALUE` 可以通过该端口访问到服务; -* `--external_log_file=VALUE` 指定存储日志的外部文件,可通过 Web 界面查看; -* `--firewall_rules=VALUE` endpoint 防火墙规则,`VALUE` 可以是 JSON 格式或者存有 JSON 格式的文件路径; -* `--ip=VALUE` 服务绑定到的IP 地址,用来监听外面过来的请求; -* `--log_dir=VALUE` 日志文件路径,如果为空(默认值)则不存储日志到本地; -* `--logbufsecs=VALUE` buffer 多少秒的日志,然后写入本地; -* `--logging_level=VALUE` 日志记录的最低级别; -* `--port=VALUE` 绑定监听的端口,master 默认是 5050,slave 默认是 5051。 - -### master 专属配置项 -这些配置项是针对主节点上的 Mesos master 服务的,围绕高可用、注册信息、对应用框架的资源管理等。用户应该根据本地主节点资源情况来合理的配置这些选项。 - -用户可以通过 `mesos-master --help` 命令来获取所有支持的配置项信息。 - -必须指定的配置项有三个: - -* `--quorum=VALUE` 必备项,使用基于 replicated-Log 的注册表(即利用 ZooKeeper 实现 HA)时,参与投票时的最少节点个数; -* `--work_dir=VALUE` 必备项,注册表持久化信息存储位置; -* `--zk=VALUE` 如果主节点为 HA 模式,此为必备项,指定 ZooKeepr 的服务地址,支持多个地址,之间用逗号隔离,例如 `zk://username:password@host1:port1,host2:port2,.../path`。还可以为存有路径信息的文件路径。 - - -可选的配置项有: - -* `--acls=VALUE` ACL 规则或所在文件; -* `--allocation_interval=VALUE` 执行 allocation 的间隔,默认为 1sec; -* `--allocator=VALUE` 分配机制,默认为 HierarchicalDRF; -* `--[no-]authenticate` 是否允许非认证过的 framework 注册; -* `--[no-]authenticate_slaves` 是否允许非认证过的 slaves 注册; -* `--authenticators=VALUE` 对 framework 或 salves 进行认证时的实现机制; -* `--cluster=VALUE` 集群别名,显示在 Web 界面上供用户识别的; -* `--credentials=VALUE` 存储加密后凭证的文件的路径; -* `--external_log_file=VALUE` 采用外部的日志文件; -* `--framework_sorter=VALUE` 给定 framework 之间的资源分配策略; -* `--hooks=VALUE` master 中安装的 hook 模块; -* `--hostname=VALUE` master 节点使用的主机名,不配置则从系统中获取; -* `--[no-]log_auto_initialize` 是否自动初始化注册表需要的 replicated 日志; -* `--modules=VALUE` 要加载的模块,支持文件路径或者 JSON; -* `--offer_timeout=VALUE` offer 撤销的超时; -* `--rate_limits=VALUE` framework 的速率限制,即 query per second (qps); -* `--recovery_slave_removal_limit=VALUE` 限制注册表恢复后可以移除或停止的 slave 数目,超出后 master 会失败,默认是 100%; -* `--slave_removal_rate_limit=VALUE slave` 没有完成健康度检查时候被移除的速率上限,例如 1/10mins 代表每十分钟最多有一个; -* `--registry=VALUE` 注册表信息的持久化策略,默认为 `replicated_log` 存放本地,还可以为 `in_memory` 放在内存中; -* `--registry_fetch_timeout=VALUE` 访问注册表失败超时; -* `--registry_store_timeout=VALUE` 存储注册表失败超时; -* `--[no-]registry_strict` 是否按照注册表中持久化信息执行操作,默认为 false; -* `--roles=VALUE` 集群中 framework 可以所属的分配角色; -* `--[no-]root_submissions` root 是否可以提交 framework,默认为 true; -* `--slave_reregister_timeout=VALUE` 新的 lead master 节点选举出来后,多久之内所有的 slave 需要注册,超时的 salve 将被移除并关闭,默认为 10mins; -* `--user_sorter=VALUE` 在用户之间分配资源的策略,默认为 drf; -* `--webui_dir=VALUE` webui 实现的文件目录所在,默认为 `/usr/local/share/mesos/webui`; -* `--weights=VALUE` 各个角色的权重; -* `--whitelist=VALUE` 文件路径,包括发送 offer 的 slave 名单,默认为 None; -* `--zk_session_timeout=VALUE` session 超时,默认为 10secs; -* `--max_executors_per_slave=VALUE` 配置了 `--with-network-isolator` 时可用,限制每个 slave 同时执行任务个数。 - -下面给出一个由三个节点组成的 master 集群典型配置,工作目录指定为 `/tmp/mesos`,集群名称为 `mesos_cluster`。 - -```sh -mesos-master \ ---zk=zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos \ ---quorum=2 \ ---work_dir=/tmp/mesos \ ---cluster=mesos_cluster -``` - - -### slave 专属配置项 -slave 节点支持的配置项是最多的,因为它所完成的事情也最复杂。这些配置项既包括跟主节点打交道的一些参数,也包括对本地资源的配置,包括隔离机制、本地任务的资源限制等。 - -用户可以通过 `mesos-slave --help` 命令来获取所有支持的配置项信息。 - -必备项就一个: - -* `--master=VALUE` 必备项,master 所在地址,或对应 ZooKeeper 服务地址,或文件路径,可以是列表。 - -以下为可选配置项: - -* `--attributes=VALUE` 机器属性; -* `--authenticatee=VALUE` 跟 master 进行认证时候的认证机制; -* `--[no-]cgroups_enable_cfs` 采用 CFS 进行带宽限制时候对 CPU 资源进行限制,默认为 false; -* `--cgroups_hierarchy=VALUE` cgroups 的目录根位置,默认为 `/sys/fs/cgroup`; -* `--[no-]cgroups_limit_swap` 限制内存和 swap,默认为 false,只限制内存; -* `--cgroups_root=VALUE` 根 cgroups 的名称,默认为 mesos; -* `--container_disk_watch_interval=VALUE` 为容器进行硬盘配额查询的时间间隔; -* `--containerizer_path=VALUE` 采用外部隔离机制(`--isolation=external`)时候,外部容器机制执行文件路径; -* `--containerizers=VALUE` 可用的容器实现机制,包括 mesos、external、docker; -* `--credential=VALUE` 加密后凭证,或者所在文件路径; -* `--default_container_image=VALUE` 采用外部容器机制时,任务缺省使用的镜像; -* `--default_container_info=VALUE` 容器信息的缺省值; -* `--default_role=VALUE` 资源缺省分配的角色; -* `--disk_watch_interval=VALUE` 硬盘使用情况的周期性检查间隔,默认为 1mins; -* `--docker=VALUE` docker 执行文件的路径; -* `--docker_remove_delay=VALUE` 删除容器之前的等待时间,默认为 6hrs; -* `--[no-]docker_kill_orphans` 清除孤儿容器,默认为 true; -* `--docker_sock=VALUE` docker sock 地址,默认为 `/var/run/docker.sock`; -* `--docker_mesos_image=VALUE` 运行 slave 的 docker 镜像,如果被配置,docker 会假定 slave 运行在一个 docker 容器里; -* `--docker_sandbox_directory=VALUE` sandbox 映射到容器里的哪个路径; -* `--docker_stop_timeout=VALUE` 停止实例后等待多久执行 kill 操作,默认为 0secs; -* `--[no-]enforce_container_disk_quota` 是否启用容器配额限制,默认为 false; -* `--executor_registration_timeout=VALUE` 执行应用最多可以等多久再注册到 slave,否则停止它,默认为 1mins; -* `--executor_shutdown_grace_period=VALUE` 执行应用停止后,等待多久,默认为 5secs; -* `--external_log_file=VALUE` 外部日志文件; -* `--fetcher_cache_size=VALUE` fetcher 的 cache 大小,默认为 2 GB; -* `--fetcher_cache_dir=VALUE` fetcher cache 文件存放目录,默认为 /tmp/mesos/fetch; -* `--frameworks_home=VALUE` 执行应用前添加的相对路径,默认为空; -* `--gc_delay=VALUE` 多久清理一次执行应用目录,默认为 1weeks; -* `--gc_disk_headroom=VALUE` 调整计算最大执行应用目录年龄的硬盘留空量,默认为 0.1; -* `--hadoop_home=VALUE` hadoop 安装目录,默认为空,会自动查找 HADOOP_HOME 或者从系统路径中查找; -* `--hooks=VALUE` 安装在 master 中的 hook 模块列表; -* `--hostname=VALUE` slave 节点使用的主机名; -* `--isolation=VALUE` 隔离机制,例如 `posix/cpu,posix/mem`(默认)或者 `cgroups/cpu,cgroups/mem`、`external` 等; -* `--launcher_dir=VALUE` mesos 可执行文件的路径,默认为 `/usr/local/lib/mesos`; -* `--image_providers=VALUE` 支持的容器镜像机制,例如 'APPC,DOCKER'; -* `--oversubscribed_resources_interval=VALUE` slave 节点定期汇报超配资源状态的周期; -* `--modules=VALUE` 要加载的模块,支持文件路径或者 JSON; -* `--perf_duration=VALUE` perf 采样时长,必须小于 perf_interval,默认为 10secs; -* `--perf_events=VALUE` perf 采样的事件; -* `--perf_interval=VALUE` perf 采样的时间间隔; -* `--qos_controller=VALUE` 超配机制中保障 QoS 的控制器名; -* `--qos_correction_interval_min=VALUE` Qos 控制器纠正超配资源的最小间隔,默认为 0secs; -* `--recover=VALUE` 回复后是否重连旧的执行应用,reconnect(默认值)是重连,cleanup 清除旧的执行器并退出; -* `--recovery_timeout=VALUE` slave 恢复时的超时,太久则所有相关的执行应用将自行退出,默认为 15mins; -* `--registration_backoff_factor=VALUE` 跟 master 进行注册时候的重试时间间隔算法的因子,默认为 1secs,采用随机指数算法,最长 1mins; -* `--resource_monitoring_interval=VALUE` 周期性监测执行应用资源使用情况的间隔,默认为 1secs; -* `--resources=VALUE` 每个 slave 可用的资源,比如主机端口默认为 [31000, 32000]; -* `--[no-]revocable_cpu_low_priority` 运行在可撤销 CPU 上容器将拥有较低优先级,默认为 true。 -* `--slave_subsystems=VALUE` slave 运行在哪些 cgroup 子系统中,包括 memory,cpuacct 等,缺省为空; -* `--[no-]strict` 是否认为所有错误都不可忽略,默认为 true; -* `--[no-]switch_user` 用提交任务的用户身份来运行,默认为 true; -* `--work_dir=VALUE` framework 的工作目录,默认为 /tmp/mesos。 - -下面这些选项需要配置 `--with-network-isolator` 一起使用(编译时需要启用 ` --with-network-isolator` 参数)。 - -* `--ephemeral_ports_per_container=VALUE` 分配给一个容器的临时端口的最大数目,需要为 2 的整数幂(默认为 1024); -* `--eth0_name=VALUE` public 网络的接口名称,如果不指定,根据主机路由进行猜测; -* `--lo_name=VALUE` loopback 网卡名称; -* `--egress_rate_limit_per_container=VALUE` 每个容器的输出流量限制速率限制(采用 fq_codel 算法来限速),单位是字节每秒; -* `--[no-]-egress_unique_flow_per_container` 是否把不同容器的流量当作彼此不同的流,避免彼此影响(默认为 false); -* `--[no-]network_enable_socket_statistics` 是否采集每个容器的 socket 统计信息,默认为 false。 - -下面给出一个典型的 slave 配置,容器为 Docker,监听在 `10.0.0.10` 地址;节点上限制 16 个 CPU、64 GB 内存,容器的非临时端口范围指定为 [31000-32000],临时端口范围指定为 [32768-57344];每个容器临时端口最多为 512 个,并且外出流量限速为 50 MB/s。 - -```sh -mesos-slave \ ---master=zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos \ ---containerizers=docker \ ---ip=10.0.0.10 \ ---isolation=cgroups/cpu,cgroups/mem,network/port_mapping \ ---resources=cpus:16;mem:64000;ports:[31000-32000];ephemeral_ports:[32768-57344] \ ---ephemeral_ports_per_container=512 \ ---egress_rate_limit_per_container=50000KB \ ---egress_unique_flow_per_container -``` - -为了避免主机分配的临时端口跟我们指定的临时端口范围冲突,需要在主机节点上进行配置。 -```sh -$ echo "57345 61000" > /proc/sys/net/ipv4/ip_local_port_range -``` - -*注:非临时端口是 Mesos 分配给框架,绑定到任务使用的,端口号往往有明确意义;临时端口是系统分配的,往往不太关心具体端口号。* diff --git a/mesos/framework.md b/mesos/framework.md deleted file mode 100644 index 2430d4a10..000000000 --- a/mesos/framework.md +++ /dev/null @@ -1,89 +0,0 @@ -## 常见应用框架 - -应用框架是实际干活的,可以理解为 Mesos 之上跑的 `应用`。应用框架注册到 Mesos master 服务上即可使用。 - -用户大部分时候,只需要跟应用框架打交道。因此,选择合适的应用框架十分关键。 - -Mesos 目前支持的应用框架分为四大类:长期运行任务(以及 PaaS)、大数据处理、批量调度、数据存储。 - -随着 Mesos 自身的发展,越来越多的框架开始支持 Mesos,下面总结了目前常用的一些框架。 - -### 长期运行的服务 - -#### [Aurora](http://aurora.incubator.apache.org) - -利用 Mesos 调度安排的任务,保证任务一直在运行。 - -提供 REST 接口,客户端和 webUI(8081 端口) - -#### [Marathon](https://github.com/mesosphere/marathon) - -一个私有 PaaS 平台,保证运行的应用不被中断。 - -如果任务停止了,会自动重启一个新的相同任务。 - -支持任务为任意 bash 命令,以及容器。 - -提供 REST 接口,客户端和 webUI(8080 端口) - -#### [Singularity](https://github.com/HubSpot/Singularity) - -一个私有 PaaS 平台。 - -调度器,运行长期的任务和一次性任务。 - -提供 REST 接口,客户端和 webUI(7099、8080 端口),支持容器。 - -### 大数据处理 -#### [Cray Chapel](https://github.com/nqn/mesos-chapel) - -支持 Chapel 并行编程语言的运行框架。 - -#### [Dpark](https://github.com/douban/dpark) - -Spark 的 Python 实现。 - -#### [Hadoop](https://github.com/mesos/hadoop) - -经典的 map-reduce 模型的实现。 - -#### [Spark](http://spark.apache.org) - -跟 Hadoop 类似,但处理迭代类型任务会更好的使用内存做中间状态缓存,速度要快一些。 - -#### [Storm](https://github.com/mesos/storm) - -分布式流计算,可以实时处理数据流。 - -### 批量调度 -#### [Chronos](https://github.com/airbnb/chronos) - -Cron 的分布式实现,负责任务调度,支持容错。 - -#### [Jenkins](https://github.com/jenkinsci/mesos-plugin) - -大名鼎鼎的 CI 引擎。使用 mesos-jenkins 插件,可以将 jenkins 的任务被 Mesos 集群来动态调度执行。 - -#### [JobServer](http://www.grandlogic.com/content/html_docs/jobserver.html) - -基于 Java 的调度任务和数据处理引擎。 - -#### [GoDocker](https://bitbucket.org/osallou/go-docker) - -基于 Docker 容器的集群维护工具。提供用户接口,除了支持 Mesos,还支持 Kubernetes、Swarm 等。 - -### 数据存储 - -#### [ElasticSearch](https://github.com/mesos/elasticsearch) - -功能十分强大的分布式数据搜索引擎。 - -一方面通过分布式集群实现可靠的数据库,一方面提供灵活的 API,对数据进行整合和分析。ElasticSearch + LogStash + Kibana 目前合成为 ELK 工具栈。 - -#### [Hypertable](https://code.google.com/p/hypertable) - -高性能的分布式数据库,支持结构化或者非结构化的数据存储。 - -#### [Tachyon](http://tachyon-project.org/) - -内存为中心的分布式存储系统,利用内存访问的高速提供高性能。 diff --git a/mesos/installation.md b/mesos/installation.md deleted file mode 100644 index 0a60a1857..000000000 --- a/mesos/installation.md +++ /dev/null @@ -1,387 +0,0 @@ -## Mesos 安装与使用 -以 Mesos 结合 Marathon 应用框架为例,来看下如何快速搭建一套 Mesos 平台。 - -Marathon 是可以跟 Mesos 一起协作的一个 framework,基于 Scala 实现,可以实现保持应用的持续运行。 - -另外,Mesos 默认利用 ZooKeeper 来进行多个主节点之间的选举,以及从节点发现主节点的过程。一般在生产环境中,需要启动多个 Mesos master 服务(推荐 3 或 5 个),并且推荐使用 supervisord 等进程管理器来自动保持服务的运行。 - -ZooKeeper 是一个分布式集群中信息同步的工具,通过自动在多个节点中选举 `leader`,保障多个节点之间的某些信息保持一致性。 - -### 安装 -安装主要需要 mesos、zookeeper 和 marathon 三个软件包。 - -Mesos 也采用了经典的主-从结构,一般包括若干主节点和大量从节点。其中,mesos master 服务和 zookeeper 需要部署到所有的主节点,mesos slave 服务需要部署到所有从节点。marathon 可以部署到主节点。 - -安装可以通过源码编译、软件源或者 Docker 镜像方式进行,下面分别进行介绍。 - -#### 源码编译 - -源码编译方式可以保障获取到最新版本,但编译过程比较费时间。 - -首先,从 apache.org 开源网站下载最新的源码。 - -```sh -$ git clone https://git-wip-us.apache.org/repos/asf/mesos.git -``` - -其中,主要代码在 `src` 目录下,应用框架代码在 `frameworks` 目录下,文档在 `docs` 目录下,`include ` 中包括了跟 Mesos 打交道使用的一些 API 定义头文件。 - -安装依赖,主要包括 Java 运行环境、Linux 上的自动编译环境等。 - -```sh -$ sudo apt-get update -$ sudo apt-get install -y openjdk-8-jdk autoconf libtool \ -build-essential python-dev python-boto libcurl4-nss-dev \ -libsasl2-dev maven libapr1-dev libsvn-dev -``` - -后面就是常规 C++ 项目的方法,configure 之后利用 Makefile 进行编译和安装。 - -```sh -$ cd mesos -$ ./bootstrap -$ mkdir build -$ cd build && ../configure --with-network-isolator -$ make -$ make check && sudo make install -``` - -#### 软件源安装 - -通过软件源方式进行安装相对会省时间,但往往不是最新版本。 - -这里以 Ubuntu 系统为例,首先添加软件源地址。 - -```sh -$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E56151BF -$ DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]') -$ CODENAME=$(lsb_release -cs) -$ echo "deb http://repos.mesosphere.io/${DISTRO} ${CODENAME} main" | \ -sudo tee /etc/apt/sources.list.d/mesosphere.list -``` - -刷新本地软件仓库信息并安装 zookeeper、mesos、marathon 三个软件包。 - -```sh -$ sudo apt-get -y update && sudo apt-get -y install zookeeper mesos marathon -``` - -注意,Marathon 最新版本需要 jdk 1.8+ 的支持。如果系统中有多个 Java 版本,需要检查配置默认的 JDK 版本符合要求。 - -```sh -$ sudo update-alternatives --config java -``` - -安装 Mesos 成功后,会在 `/usr/sbin/` 下面发现 `mesos-master` 和 `mesos-slave` 两个二进制文件,分别对应主节点上需要运行的管理服务和从节点上需要运行的任务服务。 - -用户可以手动运行二进制文件启动服务,也可以通过 `service` 命令来方便进行管理。 - -例如,在主节点上重启 Mesos 管理服务: - -```sh -$ sudo service mesos-master restart -``` - -通过 `service` 命令来管理,实际上是通过调用 `/usr/bin/mesos-init-wrapper` 脚本文件进行处理。 - -#### [基于 Docker](https://github.com/sekka1/mesosphere-docker) - -需要如下三个镜像。 - -* ZooKeeper:https://registry.hub.docker.com/u/garland/zookeeper/ -* Mesos:https://registry.hub.docker.com/u/garland/mesosphere-docker-mesos-master/ -* Marathon:https://registry.hub.docker.com/u/garland/mesosphere-docker-marathon/ - -其中 mesos-master 镜像在后面将分别作为 master 和 slave 角色进行使用。 - -首先,拉取三个镜像。 - -```sh -$ docker pull garland/zookeeper -$ docker pull garland/mesosphere-docker-mesos-master -$ docker pull garland/mesosphere-docker-marathon -``` - -导出主节点机器的地址到环境变量。 - -```sh -$ HOST_IP=10.0.0.2 -``` - -在主节点上启动 Zookeepr 容器。 - -```sh -docker run -d \ --p 2181:2181 \ --p 2888:2888 \ --p 3888:3888 \ -garland/zookeeper -``` - -在主节点上启动 Mesos Master 服务容器。 - -```sh -docker run --net="host" \ --p 5050:5050 \ --e "MESOS_HOSTNAME=${HOST_IP}" \ --e "MESOS_IP=${HOST_IP}" \ --e "MESOS_ZK=zk://${HOST_IP}:2181/mesos" \ --e "MESOS_PORT=5050" \ --e "MESOS_LOG_DIR=/var/log/mesos" \ --e "MESOS_QUORUM=1" \ --e "MESOS_REGISTRY=in_memory" \ --e "MESOS_WORK_DIR=/var/lib/mesos" \ --d \ -garland/mesosphere-docker-mesos-master -``` - -在主节点上启动 Marathon。 - -```sh -docker run \ --d \ --p 8080:8080 \ -garland/mesosphere-docker-marathon --master zk://${HOST_IP}:2181/mesos --zk zk://${HOST_IP}:2181/marathon -``` - -在从节点上启动 Mesos slave 容器。 - -```sh -docker run -d \ ---name mesos_slave_1 \ ---entrypoint="mesos-slave" \ --e "MESOS_MASTER=zk://${HOST_IP}:2181/mesos" \ --e "MESOS_LOG_DIR=/var/log/mesos" \ --e "MESOS_LOGGING_LEVEL=INFO" \ -garland/mesosphere-docker-mesos-master:latest -``` - -接下来,可以通过访问本地 8080 端口来使用 Marathon 启动任务了。 - - -### 配置说明 - -下面以本地通过软件源方式安装为例,解释如何修改各个配置文件。 - -#### ZooKeepr - -ZooKeepr 是一个分布式应用的协调工具,用来管理多个主节点的选举和冗余,监听在 2181 端口。推荐至少布置三个主节点来被 ZooKeeper 维护。 - -配置文件默认都在 `/etc/zookeeper/conf/` 目录下。比较关键的配置文件有两个:`myid` 和 `zoo.cfg`。 - -myid 文件会记录加入 ZooKeeper 集群的节点的序号(1-255之间)。`/var/lib/zookeeper/myid` 文件其实也是软连接到了该文件。 - -比如配置某节点序号为 1,则需要在该节点上执行: - -```sh -$ echo 1 | sudo dd of=/etc/zookeeper/conf/myid -``` - -节点序号在 ZooKeeper 集群中必须唯一,不能出现多个拥有相同序号的节点。 - -另外,需要修改 zoo.cfg 文件,该文件是主配置文件,主要需要添加上加入 ZooKeeper 集群的机器的序号和对应监听地址。 - -例如,现在 ZooKeeper 集群中有三个节点,地址分别为 `10.0.0.2`、`10.0.0.3`、`10.0.0.4`,序号分别配置为 `2`、`3`、`4`。 - -则配置如下的三行: - -```sh -server.2=10.0.0.2:2888:3888 -server.3=10.0.0.3:2888:3888 -server.4=10.0.0.4:2888:3888 -``` - -其中第一个端口 2888 负责从节点连接到主节点的;第二个端口 3888 则负责主节点进行选举时候通信。 - -也可以用主机名形式,则需要各个节点 `/etc/hosts` 文件中都记录地址到主机名对应的映射关系。 - -完成配置后,启动 ZooKeeper 服务。 - -```sh -$ sudo service zookeeper start -``` - -#### Mesos - -Mesos 的默认配置目录有三个: - -* /etc/mesos/:主节点和从节点都会读取的配置文件,最关键的是 zk 文件存放主节点的信息; -* /etc/mesos-master/:只有主节点会读取的配置,等价于启动 mesos-master 命令时候的默认选项; -* /etc/mesos-slave/:只有从节点会读取的配置,等价于启动 mesos-master 命令时候的默认选项。 - -最关键的是需要在所有节点上修改 `/etc/mesos/zk`,写入主节点集群的 ZooKeeper 地址列表,例如: - -```sh -zk://10.0.0.2:2181,10.0.0.3:2181,10.0.0.4:2181/mesos -``` - -此外,`/etc/default/mesos`、`/etc/default/mesos-master`、`/etc/default/mesos-slave` 这三个文件中可以存放一些环境变量定义,Mesos 服务启动之前,会将这些环境变量导入进来作为启动参数。格式为 `MESOS_OPTION_NAME`。 - -下面分别说明在主节点和从节点上的配置。 - -##### 主节点 - -一般只需要关注 `/etc/mesos-master/` 目录下的文件。默认情况下目录下为空。 - -该目录下文件命名和内容需要跟 mesos-master 支持的命令行选项一一对应。可以通过 `mesos-master --help` 命令查看支持的选项。 - -例如某个文件 `key` 中内容为 `value`,则在 mesos-master 服务启动的时候,会自动添加参数 `--key=value` 给二进制命令。 - -例如,mesos-master 服务默认监听在 loopback 端口,即 `127.0.0.1:5050`,我们需要修改主节点监听的地址,则可以创建 /etc/mesos-master/ip 文件,在其中写入主节点监听的外部地址。 - -为了正常启动 mesos-master 服务,还需要指定 `work_dir` 参数(表示应用框架的工作目录)的值,可以通过创建 /etc/mesos-master/work_dir 文件,在其中写入目录,例如 ` /var/lib/mesos`。工作目录下会生成一个 `replicated_log` 目录,会存有各种同步状态的持久化信息。 - -以及指定 quorum 参数的值,该参数用来表示 ZooKeeper 集群中要求最少参加表决的节点数目。一般设置为比 ZooKeeper 集群中节点个数的半数多一些(比如三个节点的话,可以配置为 `2`)。 - -此外,要修改 Mesos 集群的名称,可以创建 `/etc/mesos-master/cluster` 文件,在其中写入集群的别名,例如 `MesosCluster`。 - -总结下,建议在 `/etc/mesos-master` 目录下,配置至少四个参数文件:`ip`、`quorum`、`work_dir`、`cluster`。 - -修改配置之后,需要启动服务即可生效。 -```sh -$ sudo service mesos-master start -``` - -更多选项可以参考后面的配置项解析章节。 - -主节点服务启动后,则可以在从节点上启动 mesos-slave 服务来加入主节点的管理。 - -##### 从节点 -一般只需要关注 `/etc/mesos-slave/` 目录下的文件。默认情况下目录下为空。 - -文件命名和内容也是跟主节点类似,对应二进制文件支持的命令行参数。 - -建议在从节点上,创建 `/etc/mesos-slave/ip` 文件,在其中写入跟主节点通信的地址。 - -修改配置之后,也需要重新启动服务。 - -```sh -$ sudo service mesos-slave start -``` - -更多选项可以参考后面的配置项解析章节。 - -#### Marathon -Marathon 作为 Mesos 的一个应用框架,配置要更为简单,必需的配置项有 `--master` 和 `--zk`。 - -安装完成后,会在 /usr/bin 下多一个 marathon shell 脚本,为启动 marathon 时候执行的命令。 - -配置目录为 `/etc/marathon/conf`(需要手动创建),此外默认配置文件在 `/etc/default/marathon`。 - -我们手动创建配置目录,并添加配置项(文件命名和内容跟 Mesos 风格一致),让 Marathon 能连接到已创建的 Mesos 集群中。 - -```sh -$ sudo mkdir -p /etc/marathon/conf -$ sudo cp /etc/mesos/zk /etc/marathon/conf/master -``` - -同时,让 Marathon 也将自身的状态信息保存到 ZooKeeper 中。创建 `/etc/marathon/conf/zk` 文件,添加 ZooKeeper 地址和路径。 - -```sh -zk://10.0.0.2:2181,10.0.0.2:2181,10.0.0.2:2181/marathon -``` - -启动 marathon 服务。 - -```sh -$ sudo service marathon start -``` - -### 访问 Mesos 图形界面 - -Mesos 自带了 Web 图形界面,可以方便用户查看集群状态。 - -用户在 Mesos 主节点服务和从节点服务都启动后,可以通过浏览器访问主节点 5050 端口,看到类似如下界面,已经有两个 slave 节点加入了。 - -![mesos 界面查看加入的 slave 节点](_images/mesos.png) - -通过 Slaves 标签页能看到加入集群的从节点的信息。 - -如果没有启动 Marathon 服务,在 Frameworks 标签页下将看不到任何内容。 - -### 访问 Marathon 图形界面 - -Marathon 服务启动成功后,在 Mesos 的 web 界面的 Frameworks 标签页下面将能看到名称为 marathon 的框架出现。 - -同时可以通过浏览器访问 8080 端口,看到 Marathon 自己的管理界面。 - -![marathon 图形管理界面](_images/marathon.png) - -此时,可以通过界面或者 REST API 来创建一个应用,Marathon 会保持该应用的持续运行。 - -![marathon 查看任务支持的参数](_images/marathon_basic0.png) - -通过界面方式可以看到各任务支持的参数(包括资源、命令、环境变量、健康检查等),同时可以很容易地修改任务运行实例数进行扩展,非常适合进行测试。 - -如果要更自动化地使用 Marathon,则需要通过它的 REST API 进行操作。 - -一般的,启动新任务需要先创建一个定义模板(JSON 格式),然后发到指定的 API。 - -例如,示例任务 basic-0 的定义模板为: - -```json -{ - "id": "basic-0", - "cmd": "while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done", - "cpus": 0.1, - "mem": 10.0, - "instances": 1 -} -``` - -该任务申请资源为 0.1 个单核 CPU 资源和 10 MB 的内存资源,具体命令为每隔五秒钟用 shell 打印一句 `Hello Marathon`。 - -可以通过如下命令发出 basic-0 任务到 Marathon 框架,框架会分配任务到某个满足条件的从节点上,成功会返回一个 json 对象,描述任务的详细信息。 - -```sh -$ curl -X POST http://marathon_host:8080/v2/apps -d @basic-0.json -H "Content-type: application/json" -{"id":"/basic-0","cmd":"while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done","args":null,"user":null,"env":{},"instances":1,"cpus":0.1,"mem":10,"disk":0,"executor":"","constraints":[],"uris":[],"storeUrls":[],"ports":[0],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":null,"healthChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"labels":{},"acceptedResourceRoles":null,"version":"2015-12-28T05:33:05.805Z","tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"3ec3fbd5-11e4-479f-bd17-813d33e43e0c"}],"tasks":[]}% -``` - -Marathon 的更多 REST API 可以参考本地自带的文档:`http://marathon_host:8080/api-console/index.html`。 - -此时,如果运行任务的从节点出现故障,任务会自动在其它可用的从节点上启动。 - -此外,目前也已经支持基于 Docker 容器的任务。需要先在 Mesos slave 节点上为 slave 服务配置 `--containerizers=docker,mesos` 参数。 - -例如如下面的示例任务: - -```json -{ - "id": "basic-3", - "cmd": "python3 -m http.server 8080", - "cpus": 0.5, - "mem": 32.0, - "container": { - "type": "DOCKER", - "volumes": [], - "docker": { - "image": "python:3", - "network": "BRIDGE", - "portMappings": [ - { - "containerPort": 8080, - "hostPort": 31000, - "servicePort": 0, - "protocol": "tcp" - } - ], - "privileged": false, - "parameters": [], - "forcePullImage": true - } - } -} -``` - -该任务启动一个 `python:3` 容器,执行 `python3 -m http.server 8080` 命令,作为一个简单的 web 服务,实际端口会映射到宿主机的 31000 端口。 - -注意区分 hostPort 和 servicePort,前者代表任务映射到的本地可用端口(可用范围由 Mesos slave 汇报,默认为 31000 ~ 32000);后者作为服务管理的端口,可以被用作一些服务发行机制使用进行转发,在整个 Marathon 集群中是唯一的。 - -任务执行后,也可以在对应 slave 节点上通过 Docker 命令查看容器运行情况,容器将以 `mesos-SLAVE_ID` 开头。 - -```sh -$ docker container ls -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -1226b4ec8d7d python:3 "/bin/sh -c 'python3 " 3 days ago Up 3 days 0.0.0.0:10000->8080/tcp mesos-06db0fba-49dc-4d28-ad87-6c2d5a020866-S10.b581149e-2c43-46a2-b652-1a0bc10204b3 -``` diff --git a/mesos/intro.md b/mesos/intro.md deleted file mode 100644 index a33a5b769..000000000 --- a/mesos/intro.md +++ /dev/null @@ -1,20 +0,0 @@ -## 简介 -Mesos 最初由 UC Berkeley 的 AMP 实验室于 2009 年发起,遵循 Apache 协议,目前已经成立了 Mesosphere 公司进行运营。Mesos 可以将整个数据中心的资源(包括 CPU、内存、存储、网络等)进行抽象和调度,使得多个应用同时运行在集群中分享资源,并无需关心资源的物理分布情况。 - -如果把数据中心中的集群资源看做一台服务器,那么 Mesos 要做的事情,其实就是今天操作系统内核的职责:抽象资源 + 调度任务。Mesos 项目是 Mesosphere 公司 Datacenter Operating System (DCOS) 产品的核心部件。 - -Mesos 项目主要由 C++ 语言编写,项目官方地址为 [https://mesos.apache.org](https://mesos.apache.org),代码仍在快速演化中,已经发布了正式版 1.0.0 版本。 - -Mesos 拥有许多引人注目的特性,包括: -* 支持数万个节点的大规模场景(Apple、Twitter、eBay 等公司实践); -* 支持多种应用框架,包括 Marathon、Singularity、Aurora 等; -* 支持 HA(基于 ZooKeeper 实现); -* 支持 Docker、LXC 等容器机制进行任务隔离; -* 提供了多个流行语言的 API,包括 Python、Java、C++ 等; -* 自带了简洁易用的 WebUI,方便用户直接进行操作。 - -值得注意的是,Mesos 自身只是一个资源抽象的平台,要使用它往往需要结合运行其上的分布式应用(在 Mesos 中被称作框架,framework),比如 Hadoop、Spark 等可以进行分布式计算的大数据处理应用;比如 Marathon 可以实现 PaaS,快速部署应用并自动保持运行;比如 ElasticSearch 可以索引海量数据,提供灵活的整合和查询能力…… - -大部分时候,用户只需要跟这些框架打交道即可,完全无需关心底下的资源调度情况,因为 Mesos 已经自动帮你实现了。这大大方便了上层应用的开发和运维。 - -当然,用户也可以基于 Mesos 打造自己的分布式应用框架。 diff --git a/mesos/monitor.md b/mesos/monitor.md deleted file mode 100644 index 641b38db0..000000000 --- a/mesos/monitor.md +++ /dev/null @@ -1,110 +0,0 @@ -## 日志与监控 - -Mesos 自身提供了强大的日志和监控功能,某些应用框架也提供了针对框架中任务的监控能力。通过这些接口,用户可以实时获知集群的各种状态。 - -### 日志配置 -日志文件默认在 `/var/log/mesos` 目录下,根据日志等级带有不同后缀。 - -用户可以通过日志来调试使用中碰到的问题。 - -一般的,推荐使用 `--log_dir` 选项来指定日志存放路径,并通过日志分析引擎来进行监控。 - - -### 监控 - -Mesos 提供了方便的监控接口,供用户查看集群中各个节点的状态。 - -#### 主节点 -通过 `http://MASTER_NODE:5050/metrics/snapshot` 地址可以获取到 Mesos 主节点的各种状态统计信息,包括资源(CPU、硬盘、内存)使用、系统状态、从节点、应用框架、任务状态等。 - -例如查看主节点 `10.0.0.2` 的状态信息,并用 jq 来解析返回的 json 对象。 - -```sh -$ curl -s http://10.0.0.2:5050/metrics/snapshot |jq . -{ - "system/mem_total_bytes": 4144713728, - "system/mem_free_bytes": 153071616, - "system/load_5min": 0.37, - "system/load_1min": 0.6, - "system/load_15min": 0.29, - "system/cpus_total": 4, - "registrar/state_store_ms/p9999": 45.4096616192, - "registrar/state_store_ms/p999": 45.399272192, - "registrar/state_store_ms/p99": 45.29537792, - "registrar/state_store_ms/p95": 44.8336256, - "registrar/state_store_ms/p90": 44.2564352, - "registrar/state_store_ms/p50": 34.362368, - ... - "master/recovery_slave_removals": 1, - "master/slave_registrations": 0, - "master/slave_removals": 0, - "master/slave_removals/reason_registered": 0, - "master/slave_removals/reason_unhealthy": 0, - "master/slave_removals/reason_unregistered": 0, - "master/slave_reregistrations": 2, - "master/slave_shutdowns_canceled": 0, - "master/slave_shutdowns_completed": 1, - "master/slave_shutdowns_scheduled": 1 -} -``` - -#### 从节点 - -通过 `http://SLAVE_NODE:5051/metrics/snapshot` 地址可以获取到 Mesos 从节点的各种状态统计信息,包括资源、系统状态、各种消息状态等。 - -例如查看从节点 `10.0.0.10` 的状态信息。 - -```sh -$ curl -s http://10.0.0.10:5051/metrics/snapshot |jq . -{ - "system/mem_total_bytes": 16827785216, - "system/mem_free_bytes": 3377315840, - "system/load_5min": 0.11, - "system/load_1min": 0.16, - "system/load_15min": 0.13, - "system/cpus_total": 8, - "slave/valid_status_updates": 11, - "slave/valid_framework_messages": 0, - "slave/uptime_secs": 954125.458927872, - "slave/tasks_starting": 0, - "slave/tasks_staging": 0, - "slave/tasks_running": 1, - "slave/tasks_lost": 0, - "slave/tasks_killed": 2, - "slave/tasks_finished": 0, - "slave/executors_preempted": 0, - "slave/executor_directory_max_allowed_age_secs": 403050.709525191, - "slave/disk_used": 0, - "slave/disk_total": 88929, - "slave/disk_revocable_used": 0, - "slave/disk_revocable_total": 0, - "slave/disk_revocable_percent": 0, - "slave/disk_percent": 0, - "containerizer/mesos/container_destroy_errors": 0, - "slave/container_launch_errors": 6, - "slave/cpus_percent": 0.025, - "slave/cpus_revocable_percent": 0, - "slave/cpus_revocable_total": 0, - "slave/cpus_revocable_used": 0, - "slave/cpus_total": 8, - "slave/cpus_used": 0.2, - "slave/executors_registering": 0, - "slave/executors_running": 1, - "slave/executors_terminated": 8, - "slave/executors_terminating": 0, - "slave/frameworks_active": 1, - "slave/invalid_framework_messages": 0, - "slave/invalid_status_updates": 0, - "slave/mem_percent": 0.00279552715654952, - "slave/mem_revocable_percent": 0, - "slave/mem_revocable_total": 0, - "slave/mem_revocable_used": 0, - "slave/mem_total": 15024, - "slave/mem_used": 42, - "slave/recovery_errors": 0, - "slave/registered": 1, - "slave/tasks_failed": 6 -} -``` - -另外,通过 `http://MASTER_NODE:5050/monitor/statistics.json` 地址可以看到该从节点上容器网络相关的统计数据,包括进出流量、丢包数、队列情况等。获取方法同上,在此不再演示。 \ No newline at end of file diff --git a/mesos/summary.md b/mesos/summary.md deleted file mode 100644 index 53d589162..000000000 --- a/mesos/summary.md +++ /dev/null @@ -1,7 +0,0 @@ -## 本章小结 - -本章讲解了 Mesos 的安装使用、基本原理和架构,以及支持 Mesos 的重要应用框架。Mesos 最初设计为资源调度器,然而其灵活的设计和对上层框架的优秀支持,使得它可以很好的支持大规模的分布式应用场景。结合 Docker,Mesos 可以很容易部署一套私有的容器云。 - -除了核心功能之外,Mesos 在设计上有许多值得借鉴之处,比如它清晰的定位、简洁的架构、细致的参数、高度容错的可靠,还有对限速、监控等的支持等。 - -Mesos 作为一套成熟的开源项目,可以很好的被应用和集成到生产环境中。但它的定位集中在资源调度,往往需要结合应用框架或二次开发。 \ No newline at end of file From aa3d56fce9e0746cf399483faf5c39a74b873aa2 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 20 Dec 2020 23:22:30 +0800 Subject: [PATCH 147/201] remove travis ci Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 - .github/workflows/ci.yaml | 2 +- .vuepress/config.js | 1 - SUMMARY.md | 1 - cases/ci/travis/README.md | 47 -------------------------------- cases/ci/travis/demo/.travis.yml | 16 ----------- cases/ci/travis/demo/Dockerfile | 3 -- 7 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 cases/ci/travis/README.md delete mode 100644 cases/ci/travis/demo/.travis.yml delete mode 100644 cases/ci/travis/demo/Dockerfile diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 6866bf657..6250589c9 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -51,7 +51,6 @@ jobs: "security.ubuntu.com/ubuntu",\ "nginx.com",\ "img.shields.io/github/release/yeasy/docker_practice",\ - "travis-ci.org/yeasy/docker_practice.svg",\ "launchpad.net",\ "www.w3.org/1999",\ "chat.freenode.net",\ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 08065784d..45819dfed 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -99,7 +99,7 @@ jobs: PCIT_GIT_URL: github.com/docker-practice/vuepress PCIT_KEEP_HISTORY: "true" PCIT_LOCAL_DIR: .vuepress/dist - PCIT_MESSAGE: Sync from yeasy/docker_practice@${{github.sha}} by PCIT + PCIT_MESSAGE: Build from yeasy/docker_practice@${{github.sha}} PCIT_TARGET_BRANCH: master PCIT_USERNAME: khs1994 - name: Set coding.net CNAME diff --git a/.vuepress/config.js b/.vuepress/config.js index 0130ab02e..5ffa543ce 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -222,7 +222,6 @@ module.exports = config({ 'drone/install' ] }, - 'travis/' ], '/': [ '/', diff --git a/SUMMARY.md b/SUMMARY.md index e3ef168dd..9cecb27e9 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -146,7 +146,6 @@ * [GitHub Actions](cases/ci/actions/README.md) * [Drone](cases/ci/drone/README.md) * [部署 Drone](cases/ci/drone/install.md) - * [Travis CI](cases/ci/travis/README.md) * [在 IDE 中使用 Docker](ide/README.md) * [VS Code](ide/vsCode.md) * [podman - 下一代 Linux 容器工具](podman/README.md) diff --git a/cases/ci/travis/README.md b/cases/ci/travis/README.md deleted file mode 100644 index 792a5cee1..000000000 --- a/cases/ci/travis/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# 在 Travis CI 中使用 Docker - -当代码提交到 GitHub 时,[Travis CI](https://travis-ci.com/) 会根据项目根目录 `.travis.yml` 文件设置的指令,执行一系列操作。 - -本小节介绍如何在 Travis CI 中使用 Docker 进行持续集成/持续部署(CI/CD)。这里以当代码提交到 GitHub 时自动构建 Docker 镜像并推送到 Docker Hub 为例进行介绍。 - -## 准备 - -首先登录 https://travis-ci.com/account/repositories 选择 GitHub 仓库,按照指引安装 GitHub App 来启用 GitHub 仓库构建。 - -在项目根目录新建一个 `Dockerfile` 文件。 - -```docker -FROM alpine - -RUN echo "Hello World" -``` - -新建 Travis CI 配置文件 `.travis.yml` 文件。 - -```yml -language: bash - -dist: xenial - -services: - - docker - -before_script: - # 登录到 docker hub - - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - -script: - # 这里编写测试代码的命令 - - echo "test code" - -after_success: - # 当代码测试通过后执行的命令 - - docker build -t username/alpine . - - docker push username/alpine -``` - -> 请提前在 Travis CI 仓库设置页面配置 `DOCKER_PASSWORD` `DOCKER_USERNAME` 变量 - -## 查看结果 - -将项目推送到 GitHub,登录 [Travis CI](https://travis-ci.com/) 查看构建详情。 diff --git a/cases/ci/travis/demo/.travis.yml b/cases/ci/travis/demo/.travis.yml deleted file mode 100644 index a17054737..000000000 --- a/cases/ci/travis/demo/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: bash - -dist: xenial - -services: - - docker - -before_script: - - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - -script: - - echo "test code" - -after_success: - - docker build -t username/alpine . - - docker push username/alpine diff --git a/cases/ci/travis/demo/Dockerfile b/cases/ci/travis/demo/Dockerfile deleted file mode 100644 index a58cc938c..000000000 --- a/cases/ci/travis/demo/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine - -RUN echo "Hello World" From d4145058352befe6027a901a1891e7469267b3e0 Mon Sep 17 00:00:00 2001 From: WC <34792731+GFZRZK@users.noreply.github.com> Date: Mon, 11 Jan 2021 18:14:38 +0800 Subject: [PATCH 148/201] fix wrong cmd fix wrong cmd --- appendix/debug.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appendix/debug.md b/appendix/debug.md index 9fce8d7f3..90e06cd6d 100644 --- a/appendix/debug.md +++ b/appendix/debug.md @@ -21,8 +21,8 @@ $ sudo kill -SIGHUP $(pidof dockerd) ## 检查内核日志 ```bash -$ sudo dmesag |grep dockerd -$ sudo dmesag |grep runc +$ sudo dmesg |grep dockerd +$ sudo dmesg |grep runc ``` ## Docker 不响应时处理 From 6265d0274b86a364a8a39cc1b25405592e326812 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Wed, 3 Mar 2021 00:11:07 +0800 Subject: [PATCH 149/201] [vuepress] Update version Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 1 + .github/workflows/ci.yaml | 2 +- .vuepress/config.js | 10 +++++----- cases/ci/actions/README.md | 2 +- install/raspberry-pi.md | 2 +- package.json | 2 +- repository/nexus3_registry.md | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 6250589c9..e0fff2978 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -60,6 +60,7 @@ jobs: "x.x.x.x/base",\ "x.x.x.x:9000/minio/",\ "yeasy.gitbooks.io",\ + "download.fastgit.org",\ "www.aliyun.com" \ --allow-dupe \ --skip-save-results \ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 45819dfed..80f68850c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -122,7 +122,7 @@ jobs: run: | sudo rm -rf .vuepress/dist/.git - echo "FROM nginx:alpine" >> Dockerfile + echo "FROM nginx:alpine" > Dockerfile echo "COPY .vuepress/dist /usr/share/nginx/html" >> Dockerfile echo "COPY .docker/docker-entrypoint.sh /" >> Dockerfile echo "ENTRYPOINT [\"/docker-entrypoint.sh\"]" >> Dockerfile diff --git a/.vuepress/config.js b/.vuepress/config.js index 5ffa543ce..330dc1a1b 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -48,9 +48,9 @@ module.exports = config({ appKey: "...", // your appKey }, pageInfo: [ - // 'Author', - 'ReadTime', - 'Word', + // 'author', + 'reading-time', + 'word', ], footer: { content: "Made with vuepress-theme-hope", @@ -126,8 +126,8 @@ module.exports = config({ // link: '' // }, { - text: '腾讯云容器服务', - link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61' + text: '腾讯云2021新春采购节', + link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10488&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=activity' }, // { // text: '语言', diff --git a/cases/ci/actions/README.md b/cases/ci/actions/README.md index 8b5364fbf..204865208 100644 --- a/cases/ci/actions/README.md +++ b/cases/ci/actions/README.md @@ -25,4 +25,4 @@ jobs: ## 参考资料 -* [Actions Docs](https://docs.github.com/en/free-pro-team@latest/actions) +* [Actions Docs](https://docs.github.com/en/actions) diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index be1a73d8a..772670460 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -6,7 +6,7 @@ Docker 不仅支持 `x86_64` 架构的计算机,同时也支持 `ARM` 架构的计算机,本小节内容以树莓派单片电脑为例讲解 `ARM` 架构安装 Docker。 -Docker 支持以下版本的 [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspberry-pi-os/) 操作系统: +Docker 支持以下版本的 [Raspberry Pi OS](https://www.raspberrypi.org/software/operating-systems/) 操作系统: * Raspberry Pi OS Buster diff --git a/package.json b/package.json index 3ce29fe81..e7d5fb064 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "chalk": "^2.4.2", "commander": "^2.0.0", "esm": "^3.0.0", - "vuepress": "1.7.1", + "vuepress": "1.8.2", "vuepress-plugin-container": "^2.1.5", "vuepress-theme-hope": "^1.0.0" }, diff --git a/repository/nexus3_registry.md b/repository/nexus3_registry.md index 44126130d..619c63a4a 100644 --- a/repository/nexus3_registry.md +++ b/repository/nexus3_registry.md @@ -1,6 +1,6 @@ # Nexus3.x 的私有仓库 -使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/nexus/repository-oss/download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 +使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/nexus/repository-oss-download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 ## 启动 Nexus 容器 From 5ebd6fb6f8393abbaac1cd12a82700ca8e89b152 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 6 Mar 2021 11:00:31 +0800 Subject: [PATCH 150/201] Update brew command, fixed #484 Signed-off-by: Kang Huaishuai --- install/mac.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/mac.md b/install/mac.md index 3ceefb0f3..9685c14ad 100644 --- a/install/mac.md +++ b/install/mac.md @@ -11,7 +11,7 @@ [Homebrew](https://brew.sh/) 的 [Cask](https://github.com/Homebrew/homebrew-cask) 已经支持 Docker Desktop for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装: ```bash -$ brew cask install docker +$ brew install --cask docker ``` ### 手动下载安装 From ea00e0d82a9af8b2c92e9fd54b1054964ea4077d Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 7 Mar 2021 15:29:05 +0800 Subject: [PATCH 151/201] Update format Signed-off-by: Kang Huaishuai --- .github/workflows/ci.yaml | 15 +++++++++++++-- advanced_network/access_control.md | 1 + advanced_network/example.md | 1 + basic_concept/README.md | 1 + cases/os/debian.md | 1 + container/README.md | 1 + image/dockerfile/add.md | 2 +- image/dockerfile/arg.md | 2 +- image/dockerfile/cmd.md | 2 +- image/dockerfile/copy.md | 2 +- image/dockerfile/entrypoint.md | 2 +- image/dockerfile/env.md | 2 +- image/dockerfile/expose.md | 2 +- image/dockerfile/healthcheck.md | 2 +- image/dockerfile/onbuild.md | 2 +- image/dockerfile/references.md | 2 +- image/dockerfile/user.md | 2 +- image/dockerfile/volume.md | 2 +- image/dockerfile/workdir.md | 2 +- introduction/README.md | 1 + security/README.md | 1 + security/control_group.md | 1 + security/daemon_sec.md | 1 + security/kernel_ns.md | 1 + security/other_feature.md | 1 + security/summary.md | 1 + underly/namespace.md | 1 + 27 files changed, 39 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 80f68850c..68724f463 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,6 +5,10 @@ on: name: CI +defaults: + run: + shell: bash --noprofile --norc -exo pipefail {0} + jobs: build: name: Build @@ -39,7 +43,10 @@ jobs: docker run -d --rm -p 4000:80 dockerpracticesig/docker_practice sleep 5 + + echo "::group::Test" curl 127.0.0.1:4000 + echo "::endgroup::" echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin docker push dockerpracticesig/docker_practice @@ -139,9 +146,13 @@ jobs: docker push dockerpracticesig/docker_practice:vuepress - docker run -it --rm -d -p 4000:80 dockerpracticesig/docker_practice:vuepress + docker run -it --rm -d -p 4001:80 dockerpracticesig/docker_practice:vuepress - curl 127.0.0.1:4000 + sleep 5 + + echo "::group::Test" + curl 127.0.0.1:4001 + echo "::endgroup::" env: DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} diff --git a/advanced_network/access_control.md b/advanced_network/access_control.md index c382b5d7b..c99fb7787 100644 --- a/advanced_network/access_control.md +++ b/advanced_network/access_control.md @@ -1,4 +1,5 @@ # 容器访问控制 + 容器的访问控制,主要通过 Linux 上的 `iptables` 防火墙来进行管理和实现。`iptables` 是 Linux 上默认的防火墙软件,在大部分发行版中都自带。 ## 容器访问外部网络 diff --git a/advanced_network/example.md b/advanced_network/example.md index f7ca843b1..e8bf80214 100644 --- a/advanced_network/example.md +++ b/advanced_network/example.md @@ -1,4 +1,5 @@ # 工具和示例 + 在介绍自定义网络拓扑之前,你可能会对一些外部工具和例子感兴趣: ## pipework diff --git a/basic_concept/README.md b/basic_concept/README.md index dec8e471b..82c417e95 100644 --- a/basic_concept/README.md +++ b/basic_concept/README.md @@ -1,4 +1,5 @@ # 基本概念 + Docker 包括三个基本概念 * 镜像(`Image`) * 容器(`Container`) diff --git a/cases/os/debian.md b/cases/os/debian.md index 46b8e95f9..df640c147 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -1,4 +1,5 @@ # Debian/Ubuntu + `Debian` 和 `Ubuntu` 都是目前较为流行的 **Debian 系** 的服务器操作系统,十分适合研发场景。`Docker Hub` 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。 ## Debian 系统简介 diff --git a/container/README.md b/container/README.md index 5d571a9de..a7bfeffa0 100644 --- a/container/README.md +++ b/container/README.md @@ -1,4 +1,5 @@ # 操作 Docker 容器 + 容器是 Docker 又一核心概念。 简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。 diff --git a/image/dockerfile/add.md b/image/dockerfile/add.md index 5d9f18f25..4970b1034 100644 --- a/image/dockerfile/add.md +++ b/image/dockerfile/add.md @@ -1,4 +1,4 @@ -### ADD 更高级的复制文件 +# ADD 更高级的复制文件 `ADD` 指令和 `COPY` 的格式和性质基本一致。但是在 `COPY` 基础上增加了一些功能。 diff --git a/image/dockerfile/arg.md b/image/dockerfile/arg.md index d4b270813..8f5604b58 100644 --- a/image/dockerfile/arg.md +++ b/image/dockerfile/arg.md @@ -1,4 +1,4 @@ -### ARG 构建参数 +# ARG 构建参数 格式:`ARG <参数名>[=<默认值>]` diff --git a/image/dockerfile/cmd.md b/image/dockerfile/cmd.md index 9877c00e5..b4354ff9e 100644 --- a/image/dockerfile/cmd.md +++ b/image/dockerfile/cmd.md @@ -1,4 +1,4 @@ -### CMD 容器启动命令 +# CMD 容器启动命令 `CMD` 指令的格式和 `RUN` 相似,也是两种格式: diff --git a/image/dockerfile/copy.md b/image/dockerfile/copy.md index 0d482335f..1f03fe9e1 100644 --- a/image/dockerfile/copy.md +++ b/image/dockerfile/copy.md @@ -1,4 +1,4 @@ -### COPY 复制文件 +# COPY 复制文件 格式: diff --git a/image/dockerfile/entrypoint.md b/image/dockerfile/entrypoint.md index bd13ed8da..d7b6e065e 100644 --- a/image/dockerfile/entrypoint.md +++ b/image/dockerfile/entrypoint.md @@ -1,4 +1,4 @@ -### ENTRYPOINT 入口点 +# ENTRYPOINT 入口点 `ENTRYPOINT` 的格式和 `RUN` 指令格式一样,分为 `exec` 格式和 `shell` 格式。 diff --git a/image/dockerfile/env.md b/image/dockerfile/env.md index eba9eaed7..ca3936228 100644 --- a/image/dockerfile/env.md +++ b/image/dockerfile/env.md @@ -1,4 +1,4 @@ -### ENV 设置环境变量 +# ENV 设置环境变量 格式有两种: diff --git a/image/dockerfile/expose.md b/image/dockerfile/expose.md index eb707b039..a2b00b90e 100644 --- a/image/dockerfile/expose.md +++ b/image/dockerfile/expose.md @@ -1,4 +1,4 @@ -### EXPOSE 声明端口 +# EXPOSE 声明端口 格式为 `EXPOSE <端口1> [<端口2>...]`。 diff --git a/image/dockerfile/healthcheck.md b/image/dockerfile/healthcheck.md index 78a83a6db..2684347dd 100644 --- a/image/dockerfile/healthcheck.md +++ b/image/dockerfile/healthcheck.md @@ -1,4 +1,4 @@ -### HEALTHCHECK 健康检查 +# HEALTHCHECK 健康检查 格式: diff --git a/image/dockerfile/onbuild.md b/image/dockerfile/onbuild.md index dbe1384a0..50aa80325 100644 --- a/image/dockerfile/onbuild.md +++ b/image/dockerfile/onbuild.md @@ -1,4 +1,4 @@ -### ONBUILD 为他人做嫁衣裳 +# ONBUILD 为他人做嫁衣裳 格式:`ONBUILD <其它指令>`。 diff --git a/image/dockerfile/references.md b/image/dockerfile/references.md index f726792d3..96969eaf9 100644 --- a/image/dockerfile/references.md +++ b/image/dockerfile/references.md @@ -1,4 +1,4 @@ -### 参考文档 +# 参考文档 * `Dockerfie` 官方文档:https://docs.docker.com/engine/reference/builder/ diff --git a/image/dockerfile/user.md b/image/dockerfile/user.md index 5c60d243d..272c4f5af 100644 --- a/image/dockerfile/user.md +++ b/image/dockerfile/user.md @@ -1,4 +1,4 @@ -### USER 指定当前用户 +# USER 指定当前用户 格式:`USER <用户名>[:<用户组>]` diff --git a/image/dockerfile/volume.md b/image/dockerfile/volume.md index d27172f6a..f534d3a2a 100644 --- a/image/dockerfile/volume.md +++ b/image/dockerfile/volume.md @@ -1,4 +1,4 @@ -### VOLUME 定义匿名卷 +# VOLUME 定义匿名卷 格式为: diff --git a/image/dockerfile/workdir.md b/image/dockerfile/workdir.md index 79ad39587..339540374 100644 --- a/image/dockerfile/workdir.md +++ b/image/dockerfile/workdir.md @@ -1,4 +1,4 @@ -### WORKDIR 指定工作目录 +# WORKDIR 指定工作目录 格式为 `WORKDIR <工作目录路径>`。 diff --git a/introduction/README.md b/introduction/README.md index 2907907a5..61aec6ab7 100644 --- a/introduction/README.md +++ b/introduction/README.md @@ -1,4 +1,5 @@ # 简介 + 本章将带领你进入 **Docker** 的世界。 什么是 **Docker**? diff --git a/security/README.md b/security/README.md index fab030317..c183e6a63 100644 --- a/security/README.md +++ b/security/README.md @@ -1,4 +1,5 @@ # 安全 + 评估 Docker 的安全性时,主要考虑三个方面: * 由内核的命名空间和控制组机制提供的容器内在安全 diff --git a/security/control_group.md b/security/control_group.md index cd2bd39ed..338f5f958 100644 --- a/security/control_group.md +++ b/security/control_group.md @@ -1,4 +1,5 @@ # 控制组 + 控制组是 Linux 容器机制的另外一个关键组件,负责实现资源的审计和限制。 它提供了很多有用的特性;以及确保各个容器可以公平地分享主机的内存、CPU、磁盘 IO 等资源;当然,更重要的是,控制组确保了当容器内的资源使用产生压力时不会连累主机系统。 diff --git a/security/daemon_sec.md b/security/daemon_sec.md index e43359ce4..81c862700 100644 --- a/security/daemon_sec.md +++ b/security/daemon_sec.md @@ -1,4 +1,5 @@ # Docker服务端的防护 + 运行一个容器或应用程序的核心是通过 Docker 服务端。Docker 服务的运行目前需要 root 权限,因此其安全性十分关键。 首先,确保只有可信的用户才可以访问 Docker 服务。Docker 允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限,这就容易让容器突破资源限制。例如,恶意用户启动容器的时候将主机的根目录`/`映射到容器的 `/host` 目录中,那么容器理论上就可以对主机的文件系统进行任意修改了。这听起来很疯狂?但是事实上几乎所有虚拟化系统都允许类似的资源共享,而没法禁止用户共享主机根文件系统到虚拟机系统。 diff --git a/security/kernel_ns.md b/security/kernel_ns.md index 18e070b1a..b14e4c27e 100644 --- a/security/kernel_ns.md +++ b/security/kernel_ns.md @@ -1,4 +1,5 @@ # 内核命名空间 + Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。当用 `docker run` 启动一个容器时,在后台 Docker 为容器创建了一个独立的命名空间和控制组集合。 命名空间提供了最基础也是最直接的隔离,在容器中运行的进程不会被运行在主机上的进程和其它容器发现和作用。 diff --git a/security/other_feature.md b/security/other_feature.md index 95cd6a71d..2486cfe57 100644 --- a/security/other_feature.md +++ b/security/other_feature.md @@ -1,4 +1,5 @@ # 其它安全特性 + 除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, Seccomp, SELinux, GRSEC 等。 Docker 当前默认只启用了能力机制。用户可以采用多种方案来加强 Docker 主机的安全,例如: diff --git a/security/summary.md b/security/summary.md index 3ec846730..ac789925d 100644 --- a/security/summary.md +++ b/security/summary.md @@ -1,4 +1,5 @@ # 总结 + 总体来看,Docker 容器还是十分安全的,特别是在容器内不使用 root 权限来运行进程的话。 另外,用户可以使用现有工具,比如 [Apparmor](https://docs.docker.com/engine/security/apparmor/), [Seccomp](https://docs.docker.com/engine/security/seccomp/), SELinux, GRSEC 来增强安全性;甚至自己在内核中实现更复杂的安全机制。 diff --git a/underly/namespace.md b/underly/namespace.md index ec66db213..ef81aae11 100644 --- a/underly/namespace.md +++ b/underly/namespace.md @@ -1,4 +1,5 @@ # 命名空间 + 命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。 ## pid 命名空间 From ce48a157d5e5de79ca95c034477d64603c366343 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 7 Mar 2021 22:36:48 +0800 Subject: [PATCH 152/201] Update registry * remove dtr * add ghcr.io Signed-off-by: Kang Huaishuai --- basic_concept/repository.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/basic_concept/repository.md b/basic_concept/repository.md index c7c8d03c8..69175628d 100644 --- a/basic_concept/repository.md +++ b/basic_concept/repository.md @@ -14,16 +14,16 @@ Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 -最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的官方镜像。除此以外,还有 Red Hat 的 [Quay.io](https://quay.io/repository/);Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务。 +最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的 [官方镜像](https://hub.docker.com/search?q=&type=image&image_filter=official)。除此以外,还有 Red Hat 的 [Quay.io](https://quay.io/repository/);Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务;代码托管平台 [GitHub](https://github.com) 推出的 [ghcr.io](https://docs.github.com/cn/packages/guides/about-github-container-registry)。 -由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为 **加速器**。常见的有 [阿里云加速器](https://cr.console.aliyun.com/#/accelerator)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 +由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为 **加速器**。常见的有 [阿里云加速器](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 -国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://cr.console.aliyun.com) 等。 +国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 [网易云镜像服务](https://c.163.com/hub#/m/library/)、[DaoCloud 镜像市场](https://hub.daocloud.io/)、[阿里云镜像库](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu) 等。 ## 私有 Docker Registry 除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 [Docker Registry](https://hub.docker.com/_/registry/) 镜像,可以直接使用做为私有 Registry 服务。在 [私有仓库](../repository/registry.md) 一节中,会有进一步的搭建私有 Registry 服务的讲解。 -开源的 Docker Registry 镜像只提供了 [Docker Registry API](https://docs.docker.com/registry/spec/api/) 的服务端实现,足以支持 `docker` 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本 [Docker Trusted Registry](https://docs.docker.com/datacenter/dtr/2.0/) 中,提供了这些高级功能。 +开源的 Docker Registry 镜像只提供了 [Docker Registry API](https://docs.docker.com/registry/spec/api/) 的服务端实现,足以支持 `docker` 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。 除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,[Harbor](https://github.com/goharbor/harbor) 和 [Sonatype Nexus](../repository/nexus3_registry.md)。 From 8dd3141c573df28caaf2eecd21fedcf0f377d7ac Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 7 Mar 2021 23:51:02 +0800 Subject: [PATCH 153/201] Update format Signed-off-by: Kang Huaishuai --- basic_concept/README.md | 10 +++++----- basic_concept/image.md | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/basic_concept/README.md b/basic_concept/README.md index 82c417e95..b7b39e950 100644 --- a/basic_concept/README.md +++ b/basic_concept/README.md @@ -1,8 +1,8 @@ # 基本概念 -Docker 包括三个基本概念 -* 镜像(`Image`) -* 容器(`Container`) -* 仓库(`Repository`) +**Docker** 包括三个基本概念 +* **镜像**(`Image`) +* **容器**(`Container`) +* **仓库**(`Repository`) -理解了这三个概念,就理解了 Docker 的整个生命周期。 +理解了这三个概念,就理解了 **Docker** 的整个生命周期。 diff --git a/basic_concept/image.md b/basic_concept/image.md index 5718a1556..d34fadb49 100644 --- a/basic_concept/image.md +++ b/basic_concept/image.md @@ -1,12 +1,12 @@ # Docker 镜像 -我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 `root` 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 `root` 文件系统。比如官方镜像 `ubuntu:18.04` 就包含了完整的一套 Ubuntu 18.04 最小系统的 `root` 文件系统。 +我们都知道,操作系统分为 **内核** 和 **用户空间**。对于 `Linux` 而言,内核启动后,会挂载 `root` 文件系统为其提供用户空间支持。而 **Docker 镜像**(`Image`),就相当于是一个 `root` 文件系统。比如官方镜像 `ubuntu:18.04` 就包含了完整的一套 Ubuntu 18.04 最小系统的 `root` 文件系统。 -Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 +**Docker 镜像** 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 **不包含** 任何动态数据,其内容在构建之后也不会被改变。 ## 分层存储 -因为镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。 +因为镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 `ISO` 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。 镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。 From 0a87d2a643fc53a0d04979ec8ab64e2f46d9c319 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 7 Mar 2021 23:54:43 +0800 Subject: [PATCH 154/201] Update container markdown format Signed-off-by: Kang Huaishuai --- container/attach_exec.md | 2 +- container/rm.md | 2 +- container/run.md | 4 ++-- container/stop.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/container/attach_exec.md b/container/attach_exec.md index 3c342cdce..aca5d99a2 100644 --- a/container/attach_exec.md +++ b/container/attach_exec.md @@ -24,7 +24,7 @@ root@243c32535da7:/# ## `exec` 命令 -### -i -t 参数 +### `-i` `-t` 参数 `docker exec` 后边可以跟多个参数,这里主要说明 `-i` `-t` 参数。 diff --git a/container/rm.md b/container/rm.md index 5fce0fe17..aa1958c5b 100644 --- a/container/rm.md +++ b/container/rm.md @@ -3,7 +3,7 @@ 可以使用 `docker container rm` 来删除一个处于终止状态的容器。例如 ```bash -$ docker container rm trusting_newton +$ docker container rm trusting_newton trusting_newton ``` diff --git a/container/run.md b/container/run.md index a58697e5f..d4033e8f6 100644 --- a/container/run.md +++ b/container/run.md @@ -1,6 +1,6 @@ # 启动容器 -启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(`stopped`)的容器重新启动。 +启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(`exited`)的容器重新启动。 因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。 @@ -37,7 +37,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr 当利用 `docker run` 来创建容器时,Docker 在后台运行的标准操作包括: -* 检查本地是否存在指定的镜像,不存在就从公有仓库下载 +* 检查本地是否存在指定的镜像,不存在就从 [`registry`](../repository/README.md) 下载 * 利用镜像创建并启动一个容器 * 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层 * 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 diff --git a/container/stop.md b/container/stop.md index 1c00fe4d8..4852848b4 100644 --- a/container/stop.md +++ b/container/stop.md @@ -9,7 +9,7 @@ 终止状态的容器可以用 `docker container ls -a` 命令看到。例如 ```bash -docker container ls -a +$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba267838cc1b ubuntu:18.04 "/bin/bash" 30 minutes ago Exited (0) About a minute ago trusting_newton ``` From 6f810c89f3b2fdb2e6b4d22c5cae4dc3b245ecbb Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 7 Mar 2021 23:56:19 +0800 Subject: [PATCH 155/201] Update cmd result Signed-off-by: Kang Huaishuai --- cases/os/busybox.md | 9 ++++----- image/list.md | 30 ++++++++++++++---------------- image/pull.md | 11 +++++------ introduction/what.md | 2 +- repository/dockerhub.md | 19 ++++++++++--------- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/cases/os/busybox.md b/cases/os/busybox.md index 25eaa8fc1..ddf59229e 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -28,12 +28,11 @@ azukiapp/busybox This image is meant to be used as the base... ```bash $ docker pull busybox:latest -busybox:latest: The image you are pulling has been verified -e433a6c5b276: Pull complete -e72ac664f4f0: Pull complete -511136ea3c5a: Pull complete -df7546f9f060: Pull complete +latest: Pulling from library/busybox +5c4213be9af9: Pull complete +Digest: sha256:c6b45a95f932202dbb27c31333c4789f45184a744060f6e569cc9d2bf1b9ad6f Status: Downloaded newer image for busybox:latest +docker.io/library/busybox:latest ``` 下载后,可以看到 `busybox` 镜像只有 **2.433 MB**: diff --git a/image/list.md b/image/list.md index 84efdf09d..d43d9eda1 100644 --- a/image/list.md +++ b/image/list.md @@ -9,21 +9,21 @@ redis latest 5f515359c7f8 5 days ago nginx latest 05a60462f8ba 5 days ago 181 MB mongo 3.2 fe9198c04d62 5 days ago 342 MB 00285df0df87 5 days ago 342 MB -ubuntu 18.04 f753707788c5 4 weeks ago 127 MB -ubuntu latest f753707788c5 4 weeks ago 127 MB +ubuntu 18.04 329ed837d508 3 days ago 63.3MB +ubuntu bionic 329ed837d508 3 days ago 63.3MB ``` 列表包含了 `仓库名`、`标签`、`镜像 ID`、`创建时间` 以及 `所占用的空间`。 -其中仓库名、标签在之前的基础概念章节已经介绍过了。**镜像 ID** 则是镜像的唯一标识,一个镜像可以对应多个 **标签**。因此,在上面的例子中,我们可以看到 `ubuntu:18.04` 和 `ubuntu:latest` 拥有相同的 ID,因为它们对应的是同一个镜像。 +其中仓库名、标签在之前的基础概念章节已经介绍过了。**镜像 ID** 则是镜像的唯一标识,一个镜像可以对应多个 **标签**。因此,在上面的例子中,我们可以看到 `ubuntu:18.04` 和 `ubuntu:bionic` 拥有相同的 ID,因为它们对应的是同一个镜像。 ## 镜像体积 -如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,`ubuntu:18.04` 镜像大小,在这里是 `127 MB`,但是在 [Docker Hub](https://hub.docker.com/_/ubuntu?tab=tags) 显示的却是 `50 MB`。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 `docker image ls` 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。 +如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,`ubuntu:18.04` 镜像大小,在这里是 `63.3MB`,但是在 [Docker Hub](https://hub.docker.com/layers/ubuntu/library/ubuntu/bionic/images/sha256-32776cc92b5810ce72e77aca1d949de1f348e1d281d3f00ebcc22a3adcdc9f42?context=explore) 显示的却是 `25.47 MB`。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 `docker image ls` 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。 另外一个需要注意的问题是,`docker image ls` 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。 -你可以通过以下命令来便捷的查看镜像、容器、数据卷所占用的空间。 +你可以通过 `docker system df` 命令来便捷的查看镜像、容器、数据卷所占用的空间。 ```bash $ docker system df @@ -76,8 +76,8 @@ $ docker image ls -a ```bash $ docker image ls ubuntu REPOSITORY TAG IMAGE ID CREATED SIZE -ubuntu 18.04 f753707788c5 4 weeks ago 127 MB -ubuntu latest f753707788c5 4 weeks ago 127 MB +ubuntu 18.04 329ed837d508 3 days ago 63.3MB +ubuntu bionic 329ed837d508 3 days ago 63.3MB ``` 列出特定的某个镜像,也就是说指定仓库名和标签 @@ -85,7 +85,7 @@ ubuntu latest f753707788c5 4 weeks ago ```bash $ docker image ls ubuntu:18.04 REPOSITORY TAG IMAGE ID CREATED SIZE -ubuntu 18.04 f753707788c5 4 weeks ago 127 MB +ubuntu 18.04 329ed837d508 3 days ago 63.3MB ``` 除此以外,`docker image ls` 还支持强大的过滤器参数 `--filter`,或者简写 `-f`。之前我们已经看到了使用过滤器来列出虚悬镜像的用法,它还有更多的用法。比如,我们希望看到在 `mongo:3.2` 之后建立的镜像,可以用下面的命令: @@ -116,9 +116,8 @@ $ docker image ls -q 05a60462f8ba fe9198c04d62 00285df0df87 -f753707788c5 -f753707788c5 -1e0c3dd64ccd +329ed837d508 +329ed837d508 ``` `--filter` 配合 `-q` 产生出指定范围的 ID 列表,然后送给另一个 `docker` 命令作为参数,从而针对这组实体成批的进行某种操作的做法在 Docker 命令行使用过程中非常常见,不仅仅是镜像,将来我们会在各个命令中看到这类搭配以完成很强大的功能。因此每次在文档看到过滤器后,可以多注意一下它们的用法。 @@ -133,9 +132,8 @@ $ docker image ls --format "{{.ID}}: {{.Repository}}" 05a60462f8ba: nginx fe9198c04d62: mongo 00285df0df87: -f753707788c5: ubuntu -f753707788c5: ubuntu -1e0c3dd64ccd: ubuntu +329ed837d508: ubuntu +329ed837d508: ubuntu ``` 或者打算以表格等距显示,并且有标题行,和默认一样,不过自己定义列: @@ -147,6 +145,6 @@ IMAGE ID REPOSITORY TAG 05a60462f8ba nginx latest fe9198c04d62 mongo 3.2 00285df0df87 -f753707788c5 ubuntu 18.04 -f753707788c5 ubuntu latest +329ed837d508 ubuntu 18.04 +329ed837d508 ubuntu bionic ``` diff --git a/image/pull.md b/image/pull.md index 63520a712..2aa9fb982 100644 --- a/image/pull.md +++ b/image/pull.md @@ -18,13 +18,12 @@ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] ```bash $ docker pull ubuntu:18.04 18.04: Pulling from library/ubuntu -bf5d46315322: Pull complete -9f13e0ac480c: Pull complete -e8988b5b3097: Pull complete -40af181810e7: Pull complete -e6f7c7e5c03e: Pull complete -Digest: sha256:147913621d9cdea08853f6ba9116c2e27a3ceffecf3b492983ae97c3d643fbbe +92dc2a97ff99: Pull complete +be13a9d27eb8: Pull complete +c8299583700a: Pull complete +Digest: sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26 Status: Downloaded newer image for ubuntu:18.04 +docker.io/library/ubuntu:18.04 ``` 上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 `ubuntu:18.04`,因此将会获取官方镜像 `library/ubuntu` 仓库中标签为 `18.04` 的镜像。 diff --git a/introduction/what.md b/introduction/what.md index 2c4cd7da4..19241e7c4 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -4,7 +4,7 @@ **Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 7 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 -**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [OverlayFS](https://docs.docker.com/storage/storagedriver/overlayfs-driver/) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 0.7 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 +**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [OverlayFS](https://docs.docker.com/storage/storagedriver/overlayfs-driver/) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 `0.7` 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 `1.11` 版本开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 ![Docker 架构](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/media/docker-on-linux.png) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 1ea7bdddc..8025987c9 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -28,7 +28,7 @@ saltstack/centos-6-minimal tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 instead. ... 5 [OK] ``` -可以看到返回了很多包含关键字的镜像,其中包括镜像名字、描述、收藏数(表示该镜像的受关注程度)、是否官方创建(OFFICIAL)、是否自动构建 (AUTOMATED)。 +可以看到返回了很多包含关键字的镜像,其中包括镜像名字、描述、收藏数(表示该镜像的受关注程度)、是否官方创建(`OFFICIAL`)、是否自动构建 (`AUTOMATED`)。 根据是否是官方提供,可将镜像分为两类。 @@ -42,11 +42,12 @@ tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 ```bash $ docker pull centos -Pulling repository centos -0b443ba03958: Download complete -539c0211cd76: Download complete -511136ea3c5a: Download complete -7064731afe90: Download complete +Using default tag: latest +latest: Pulling from library/centos +7a0437f04f83: Pull complete +Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1 +Status: Downloaded newer image for centos:latest +docker.io/library/centos:latest ``` ## 推送镜像 @@ -74,17 +75,17 @@ username/ubuntu ## 自动构建 -自动构建(Automated Builds)功能对于需要经常升级镜像内程序来说,十分方便。 +自动构建(`Automated Builds`)功能对于需要经常升级镜像内程序来说,十分方便。 有时候,用户构建了镜像,安装了某个软件,当软件发布新版本则需要手动更新镜像。 -而自动构建允许用户通过 Docker Hub 指定跟踪一个目标网站(支持 [GitHub](https://github.com) 或 [BitBucket](https://bitbucket.org))上的项目,一旦项目发生新的提交 (commit)或者创建了新的标签(tag),Docker Hub 会自动构建镜像并推送到 Docker Hub 中。 +而自动构建允许用户通过 Docker Hub 指定跟踪一个目标网站(支持 [GitHub](https://github.com) 或 [BitBucket](https://bitbucket.org))上的项目,一旦项目发生新的提交 (`commit`)或者创建了新的标签(`tag`),Docker Hub 会自动构建镜像并推送到 Docker Hub 中。 要配置自动构建,包括如下的步骤: * 登录 Docker Hub; -* 在 Docker Hub 点击右上角头像,在账号设置(Account Settings)中关联(Linked Accounts)目标网站; +* 在 Docker Hub 点击右上角头像,在账号设置(`Account Settings`)中关联(`Linked Accounts`)目标网站; * 在 Docker Hub 中新建或选择已有的仓库,在 `Builds` 选项卡中选择 `Configure Automated Builds`; From 7afb8991d30a3e1645a8a567703fa0a65dfd33b1 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 11 Mar 2021 21:27:50 +0800 Subject: [PATCH 156/201] Update install Signed-off-by: Kang Huaishuai --- install/debian.md | 29 ++++++++++++++--------------- install/ubuntu.md | 29 ++++++++++++++--------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/install/debian.md b/install/debian.md index d6fbc604e..5b433968a 100644 --- a/install/debian.md +++ b/install/debian.md @@ -8,8 +8,8 @@ Docker 支持以下版本的 [Debian](https://www.debian.org/intro/about) 操作系统: -* Buster 10 -* Stretch 9 +* Debian Buster 10 +* Debian Stretch 9 ### 卸载旧版本 @@ -32,9 +32,8 @@ $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ - gnupg-agent \ - lsb-release \ - software-properties-common + gnupg \ + lsb-release ``` 鉴于国内网络问题,强烈建议使用国内源,官方源请在注释中查看。 @@ -42,11 +41,11 @@ $ sudo apt-get install \ 为了确认所下载软件包的合法性,需要添加软件源的 GPG 密钥。 ```bash -$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | sudo apt-key add - +$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 官方源 -# $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - +# $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg ``` 然后,我们需要向 `sources.list` 中添加 Docker 软件源: @@ -54,16 +53,16 @@ $ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | sudo apt-ke > 在一些基于 Debian 的 Linux 发行版中 `$(lsb_release -cs)` 可能不会返回 Debian 的版本代号,例如 [Kail Linux](https://www.kali.org/docs/policy/kali-linux-relationship-with-debian/)、 [BunsenLabs Linux](https://www.bunsenlabs.org/)。在这些发行版中我们需要将下面命令中的 `$(lsb_release -cs)` 替换为 https://mirrors.aliyun.com/docker-ce/linux/debian/dists/ 中支持的 Debian 版本代号,例如 `buster`。 ```bash -$ sudo add-apt-repository \ - "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian \ - $(lsb_release -cs) \ - stable" +$ echo \ + "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + # 官方源 -# $ sudo add-apt-repository \ -# "deb [arch=amd64] https://download.docker.com/linux/debian \ -# $(lsb_release -cs) \ -# stable" +# $ echo \ +# "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://https://download.docker.com/linux/debian \ +# $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + ``` >以上命令会添加稳定版本的 Docker APT 源,如果需要测试版本的 Docker 请将 stable 改为 test。 diff --git a/install/ubuntu.md b/install/ubuntu.md index 8ad928cf3..717ba1edf 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -8,9 +8,10 @@ Docker 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: -* Focal 20.04 (LTS) -* Bionic 18.04 (LTS) -* Xenial 16.04 (LTS) +* Ubuntu Groovy 20.10 +* Ubuntu Focal 20.04 (LTS) +* Ubuntu Bionic 18.04 (LTS) +* Ubuntu Xenial 16.04 (LTS) Docker 可以安装在 64 位的 x86 平台或 ARM 平台上。Ubuntu 发行版中,LTS(Long-Term-Support)长期支持版本,会获得 5 年的升级维护支持,这样的版本会更稳定,因此在生产环境中推荐使用 LTS 版本。 @@ -35,8 +36,8 @@ $ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ - gnupg-agent \ - software-properties-common + gnupg \ + lsb-release ``` 鉴于国内网络问题,强烈建议使用国内源,官方源请在注释中查看。 @@ -44,27 +45,25 @@ $ sudo apt-get install \ 为了确认所下载软件包的合法性,需要添加软件源的 `GPG` 密钥。 ```bash -$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - +$ curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 官方源 -# $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +# $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg ``` 然后,我们需要向 `sources.list` 中添加 Docker 软件源 ```bash -$ sudo add-apt-repository \ - "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ - $(lsb_release -cs) \ - stable" +$ echo \ + "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 官方源 -# $ sudo add-apt-repository \ -# "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ -# $(lsb_release -cs) \ -# stable" +# $ echo \ +# "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ +# $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ``` >以上命令会添加稳定版本的 Docker APT 镜像源,如果需要测试版本的 Docker 请将 stable 改为 test。 From bc43b30964245cbfb96464c24f75f62288597a96 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 11 Mar 2021 23:09:37 +0800 Subject: [PATCH 157/201] Update image --- image/build.md | 2 +- image/demo/multistage-builds/Dockerfile | 2 +- image/demo/multistage-builds/Dockerfile.build | 2 +- image/demo/multistage-builds/Dockerfile.one | 2 +- image/dockerfile/arg.md | 2 +- image/dockerfile/expose.md | 2 +- image/dockerfile/volume.md | 4 ++-- image/dockerfile/workdir.md | 2 +- image/manifest.md | 6 +++--- image/multistage-builds/README.md | 8 ++++---- image/pull.md | 6 +++--- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/image/build.md b/image/build.md index 37f640103..3d29ad98d 100644 --- a/image/build.md +++ b/image/build.md @@ -40,7 +40,7 @@ FROM scratch 如果你以 `scratch` 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。 -不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,比如 [`swarm`](https://hub.docker.com/_/swarm/)、[`etcd`](https://quay.io/repository/coreos/etcd)。对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 `FROM scratch` 会让镜像体积更加小巧。使用 [Go 语言](https://golang.org/) 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。 +不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 `FROM scratch` 会让镜像体积更加小巧。使用 [Go 语言](https://golang.google.cn/) 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。 ## RUN 执行命令 diff --git a/image/demo/multistage-builds/Dockerfile b/image/demo/multistage-builds/Dockerfile index 1475e9e4b..d1492bc8d 100644 --- a/image/demo/multistage-builds/Dockerfile +++ b/image/demo/multistage-builds/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.9-alpine as builder +FROM golang:alpine as builder RUN apk --no-cache add git diff --git a/image/demo/multistage-builds/Dockerfile.build b/image/demo/multistage-builds/Dockerfile.build index 60e97bac6..48d620abe 100644 --- a/image/demo/multistage-builds/Dockerfile.build +++ b/image/demo/multistage-builds/Dockerfile.build @@ -1,4 +1,4 @@ -FROM golang:1.9-alpine +FROM golang:alpine RUN apk --no-cache add git diff --git a/image/demo/multistage-builds/Dockerfile.one b/image/demo/multistage-builds/Dockerfile.one index 79694e3c6..ed996af45 100644 --- a/image/demo/multistage-builds/Dockerfile.one +++ b/image/demo/multistage-builds/Dockerfile.one @@ -1,4 +1,4 @@ -FROM golang:1.9-alpine +FROM golang:alpine RUN apk --no-cache add git ca-certificates diff --git a/image/dockerfile/arg.md b/image/dockerfile/arg.md index 8f5604b58..8ec413fe0 100644 --- a/image/dockerfile/arg.md +++ b/image/dockerfile/arg.md @@ -6,7 +6,7 @@ `Dockerfile` 中的 `ARG` 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 `docker build` 中用 `--build-arg <参数名>=<值>` 来覆盖。 -在 1.13 之前的版本,要求 `--build-arg` 中的参数名,必须在 `Dockerfile` 中用 `ARG` 定义过了,换句话说,就是 `--build-arg` 指定的参数,必须在 `Dockerfile` 中使用了。如果对应参数没有被使用,则会报错退出构建。从 1.13 开始,这种严格的限制被放开,不再报错退出,而是显示警告信息,并继续构建。这对于使用 CI 系统,用同样的构建流程构建不同的 `Dockerfile` 的时候比较有帮助,避免构建命令必须根据每个 Dockerfile 的内容修改。 +灵活的使用 `ARG` 指令,能够在不修改 Dockerfile 的情况下,构建出不同的镜像。 ARG 指令有生效范围,如果在 `FROM` 指令之前指定,那么只能用于 `FROM` 指令中。 diff --git a/image/dockerfile/expose.md b/image/dockerfile/expose.md index a2b00b90e..48005f9d7 100644 --- a/image/dockerfile/expose.md +++ b/image/dockerfile/expose.md @@ -2,6 +2,6 @@ 格式为 `EXPOSE <端口1> [<端口2>...]`。 -`EXPOSE` 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 `docker run -P` 时,会自动随机映射 `EXPOSE` 的端口。 +`EXPOSE` 指令是声明容器运行时提供服务的端口,这只是一个声明,在容器运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 `docker run -P` 时,会自动随机映射 `EXPOSE` 的端口。 要将 `EXPOSE` 和在运行时使用 `-p <宿主端口>:<容器端口>` 区分开来。`-p`,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 `EXPOSE` 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。 diff --git a/image/dockerfile/volume.md b/image/dockerfile/volume.md index f534d3a2a..0e8731c05 100644 --- a/image/dockerfile/volume.md +++ b/image/dockerfile/volume.md @@ -11,10 +11,10 @@ VOLUME /data ``` -这里的 `/data` 目录就会在运行时自动挂载为匿名卷,任何向 `/data` 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如: +这里的 `/data` 目录就会在容器运行时自动挂载为匿名卷,任何向 `/data` 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行容器时可以覆盖这个挂载设置。比如: ```bash -docker run -d -v mydata:/data xxxx +$ docker run -d -v mydata:/data xxxx ``` 在这行命令中,就使用了 `mydata` 这个命名卷挂载到了 `/data` 这个位置,替代了 `Dockerfile` 中定义的匿名卷的挂载配置。 diff --git a/image/dockerfile/workdir.md b/image/dockerfile/workdir.md index 339540374..b8bae25d5 100644 --- a/image/dockerfile/workdir.md +++ b/image/dockerfile/workdir.md @@ -33,4 +33,4 @@ WORKDIR c RUN pwd ``` -`pwd` 输出的结果为 `/a/b/c`。 +`RUN pwd` 的工作目录为 `/a/b/c`。 diff --git a/image/manifest.md b/image/manifest.md index 382e6c338..2e25797c4 100644 --- a/image/manifest.md +++ b/image/manifest.md @@ -24,11 +24,11 @@ $ docker run -it --rm username/test 这样做显得很繁琐,那么有没有一种方法让 Docker 引擎根据系统架构自动拉取对应的镜像呢? -我们发现在 `Linux x86_64` 和 `Linux arm64v8` 架构的计算机中执行 `$ docker run golang:alpine go version` 时我们发现可以正确的运行。 +我们发现在 `Linux x86_64` 和 `Linux arm64v8` 架构的计算机中分别使用 `golang:alpine` 镜像运行容器 `$ docker run golang:alpine go version` 时,容器能够正常的运行。 这是什么原因呢? -原因就是 `golang:alpine` 官方镜像有一个 [`manifest` 列表](https://docs.docker.com/registry/spec/manifest-v2-2/)。 +原因就是 `golang:alpine` 官方镜像有一个 [`manifest` 列表 (`manifest list`)](https://docs.docker.com/registry/spec/manifest-v2-2/)。 当用户获取一个镜像时,Docker 引擎会首先查找该镜像是否有 `manifest` 列表,如果有的话 Docker 引擎会按照 Docker 运行环境(系统及架构)查找出对应镜像(例如 `golang:alpine`)。如果没有的话会直接获取镜像(例如上例中我们构建的 `username/test`)。 @@ -122,7 +122,7 @@ $ docker manifest create username/test \ username/arm64v8-test ``` -当要修改一个 `manifest` 列表时,可以加入 `-a,--amend` 参数。 +当要修改一个 `manifest` 列表时,可以加入 `-a` 或 `--amend` 参数。 ## 设置 `manifest` 列表 diff --git a/image/multistage-builds/README.md b/image/multistage-builds/README.md index f924cd2d7..9d55980a9 100644 --- a/image/multistage-builds/README.md +++ b/image/multistage-builds/README.md @@ -27,7 +27,7 @@ func main(){ 编写 `Dockerfile.one` 文件 ```docker -FROM golang:1.9-alpine +FROM golang:alpine RUN apk --no-cache add git ca-certificates @@ -57,7 +57,7 @@ $ docker build -t go/helloworld:1 -f Dockerfile.one . 例如,编写 `Dockerfile.build` 文件 ```docker -FROM golang:1.9-alpine +FROM golang:alpine RUN apk --no-cache add git @@ -126,7 +126,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB 例如,编写 `Dockerfile` 文件 ```docker -FROM golang:1.9-alpine as builder +FROM golang:alpine as builder RUN apk --no-cache add git @@ -173,7 +173,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB 我们可以使用 `as` 来为某一阶段命名,例如 ```docker -FROM golang:1.9-alpine as builder +FROM golang:alpine as builder ``` 例如当我们只想构建 `builder` 阶段的镜像时,增加 `--target=builder` 参数即可 diff --git a/image/pull.md b/image/pull.md index 2aa9fb982..f9d29a412 100644 --- a/image/pull.md +++ b/image/pull.md @@ -5,12 +5,12 @@ 从 Docker 镜像仓库获取镜像的命令是 `docker pull`。其命令格式为: ```bash -docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] +$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] ``` 具体的选项可以通过 `docker pull --help` 命令看到,这里我们说一下镜像名称的格式。 -* Docker 镜像仓库地址:地址的格式一般是 `<域名/IP>[:端口号]`。默认地址是 Docker Hub(docker.io)。 +* Docker 镜像仓库地址:地址的格式一般是 `<域名/IP>[:端口号]`。默认地址是 Docker Hub(`docker.io`)。 * 仓库名:如之前所说,这里的仓库名是两段式名称,即 `<用户名>/<软件名>`。对于 Docker Hub,如果不给出用户名,则默认为 `library`,也就是官方镜像。 比如: @@ -26,7 +26,7 @@ Status: Downloaded newer image for ubuntu:18.04 docker.io/library/ubuntu:18.04 ``` -上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 `ubuntu:18.04`,因此将会获取官方镜像 `library/ubuntu` 仓库中标签为 `18.04` 的镜像。 +上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub (`docker.io`)获取镜像。而镜像名称是 `ubuntu:18.04`,因此将会获取官方镜像 `library/ubuntu` 仓库中标签为 `18.04` 的镜像。`docker pull` 命令的输出结果最后一行给出了镜像的完整名称,即: `docker.io/library/ubuntu:18.04`。 从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 `sha256` 的摘要,以确保下载一致性。 From aa08e3200357a502947db6a5dabd629ae0dffe60 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 12 Mar 2021 00:12:47 +0800 Subject: [PATCH 158/201] Update repository Signed-off-by: Kang Huaishuai --- repository/dockerhub.md | 14 +++++------ repository/nexus3_registry.md | 47 ++++++++++++++++++++++++++--------- repository/registry.md | 4 +-- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 8025987c9..6983c8277 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -20,12 +20,12 @@ ```bash $ docker search centos -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -centos The official build of CentOS. 465 [OK] -tianon/centos CentOS 5 and 6, created using rinse instea... 28 -blalor/centos Bare-bones base CentOS 6.5 image 6 [OK] -saltstack/centos-6-minimal 6 [OK] -tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 instead. ... 5 [OK] +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +centos The official build of CentOS. 6449 [OK] +ansible/centos7-ansible Ansible on Centos7 132 [OK] +consol/centos-xfce-vnc Centos container with "headless" VNC session… 126 [OK] +jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 117 [OK] +centos/systemd systemd enabled base container. 96 [OK] ``` 可以看到返回了很多包含关键字的镜像,其中包括镜像名字、描述、收藏数(表示该镜像的受关注程度)、是否官方创建(`OFFICIAL`)、是否自动构建 (`AUTOMATED`)。 @@ -34,7 +34,7 @@ tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 一种是类似 `centos` 这样的镜像,被称为基础镜像或根镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。 -还有一种类型,比如 `tianon/centos` 镜像,它是由 Docker Hub 的注册用户创建并维护的,往往带有用户名称前缀。可以通过前缀 `username/` 来指定使用某个用户提供的镜像,比如 tianon 用户。 +还有一种类型,比如 `ansible/centos7-ansible` 镜像,它是由 Docker Hub 的注册用户创建并维护的,往往带有用户名称前缀。可以通过前缀 `username/` 来指定使用某个用户提供的镜像,比如 ansible 用户。 另外,在查找的时候通过 `--filter=stars=N` 参数可以指定仅显示收藏数量为 `N` 以上的镜像。 diff --git a/repository/nexus3_registry.md b/repository/nexus3_registry.md index 619c63a4a..65184cbbf 100644 --- a/repository/nexus3_registry.md +++ b/repository/nexus3_registry.md @@ -1,6 +1,6 @@ # Nexus3.x 的私有仓库 -使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。在企业中把内部的一些工具包放入 Nexus 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/nexus/repository-oss-download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 +使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry。在企业中把内部的一些工具包放入 `Nexus` 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/nexus/repository-oss-download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 ## 启动 Nexus 容器 @@ -11,20 +11,43 @@ $ docker run -d --name nexus3 --restart=always \ sonatype/nexus3 ``` -等待 3-5 分钟,如果 `nexus3` 容器没有异常退出,那么你可以使用浏览器打开 `http://YourIP:8081` 访问 Nexus 了。 +首次运行需等待 3-5 分钟,你可以使用 `docker logs nexus3 -f` 查看日志: -第一次启动 Nexus 的默认帐号是 `admin` 密码是 `admin123` 登录以后点击页面上方的齿轮按钮进行设置。 +```bash +$ docker logs nexus3 -f + +2021-03-11 15:31:21,990+0000 INFO [jetty-main-1] *SYSTEM org.sonatype.nexus.bootstrap.jetty.JettyServer - +------------------------------------------------- + +Started Sonatype Nexus OSS 3.30.0-01 + +------------------------------------------------- + +``` + +如果你看到以上内容,说明 `Nexus` 已经启动成功,你可以使用浏览器打开 `http://YourIP:8081` 访问 `Nexus` 了。 + +首次运行请通过以下命令获取初始密码: + +```bash +$ docker exec nexus3 cat /nexus-data/admin.password + +9266139e-41a2-4abb-92ec-e4142a3532cb +``` + +首次启动 Nexus 的默认帐号是 `admin` ,密码则是上边命令获取到的,点击右上角登录,首次登录需更改初始密码。 + +登录之后可以点击页面上方的齿轮按钮按照下面的方法进行设置。 ## 创建仓库 创建一个私有仓库的方法: `Repository->Repositories` 点击右边菜单 `Create repository` 选择 `docker (hosted)` -* Name: 仓库的名称 -* HTTP: 仓库单独的访问端口 -* Enable Docker V1 API: 如果需要同时支持 V1 版本请勾选此项(不建议勾选)。 -* Hosted -> Deployment pollcy: 请选择 Allow redeploy 否则无法上传 Docker 镜像。 +* **Name**: 仓库的名称 +* **HTTP**: 仓库单独的访问端口(例如:**5001**) +* **Hosted -> Deployment pollcy**: 请选择 **Allow redeploy** 否则无法上传 Docker 镜像。 -其它的仓库创建方法请各位自己摸索,还可以创建一个 docker (proxy) 类型的仓库链接到 DockerHub 上。再创建一个 docker (group) 类型的仓库把刚才的 hosted 与 proxy 添加在一起。主机在访问的时候默认下载私有仓库中的镜像,如果没有将链接到 DockerHub 中下载并缓存到 Nexus 中。 +其它的仓库创建方法请各位自己摸索,还可以创建一个 `docker (proxy)` 类型的仓库链接到 DockerHub 上。再创建一个 `docker (group)` 类型的仓库把刚才的 `hosted` 与 `proxy` 添加在一起。主机在访问的时候默认下载私有仓库中的镜像,如果没有将链接到 DockerHub 中下载并缓存到 Nexus 中。 ## 添加访问权限 @@ -43,7 +66,7 @@ NGINX 示例配置如下 ```nginx upstream register { - server "YourHostName OR IP":5001; #端口为上面添加的私有镜像仓库是设置的 HTTP 选项的端口号 + server "YourHostName OR IP":5001; #端口为上面添加私有镜像仓库时设置的 HTTP 选项的端口号 check interval=3000 rise=2 fall=10 timeout=1000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_4xx; @@ -91,9 +114,9 @@ server { ## Docker 主机访问镜像仓库 -如果不启用 SSL 加密可以通过前面章节的方法添加信任地址到 Docker 的配置文件中然后重启 Docker +如果不启用 SSL 加密可以通过 [前面章节](./registry.md) 的方法添加非 https 仓库地址到 Docker 的配置文件中然后重启 Docker。 -使用 SSL 加密以后程序需要访问就不能采用修改配置的访问了。具体方法如下: +使用 SSL 加密以后程序需要访问就不能采用修改配置的方式了。具体方法如下: ```bash $ openssl s_client -showcerts -connect YourDomainName OR HostIP:443 /dev/null|openssl x509 -outform PEM >ca.crt @@ -101,4 +124,4 @@ $ cat ca.crt | sudo tee -a /etc/ssl/certs/ca-certificates.crt $ systemctl restart docker ``` -使用 `docker login YourDomainName OR HostIP` 进行测试,用户名密码填写上面 Nexus 中生成的。 +使用 `docker login YourDomainName OR HostIP` 进行测试,用户名密码填写上面 Nexus 中设置的。 diff --git a/repository/registry.md b/repository/registry.md index cb0179a2a..abba1830e 100644 --- a/repository/registry.md +++ b/repository/registry.md @@ -10,7 +10,7 @@ ### 容器运行 -你可以通过获取官方 `registry` 镜像来运行。 +你可以使用官方 `registry` 镜像来运行。 ```bash $ docker run -d -p 5000:5000 --restart=always --name registry registry @@ -91,7 +91,7 @@ REPOSITORY TAG IMAGE ID CREAT 127.0.0.1:5000/ubuntu:latest latest ba5877dc9bec 6 weeks ago 192.7 MB ``` -## 注意事项 +## 配置非 https 仓库地址 如果你不想使用 `127.0.0.1:5000` 作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。你就得把例如 `192.168.199.100:5000` 这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。 From 9fe6c356f056a974c3cc4c479dbdb7f4afe5b28d Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 12 Mar 2021 00:15:47 +0800 Subject: [PATCH 159/201] Remove us-en url Signed-off-by: Kang Huaishuai --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index e00079011..103738770 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ | 语言 | - | | :------------- | :--- | | [简体中文](https://github.com/yeasy/docker_practice) | [阅读](https://vuepress.mirror.docker-practice.com/) | -| [us-en](https://github.com/yeasy/docker_practice/tree/english) | [阅读](https://docker_practice.gitee.io/us-en) | [Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松! From 1e577a8c6fbb873dcf829c0c4ed34efc2f04d1e6 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 14 Mar 2021 21:42:50 +0800 Subject: [PATCH 160/201] Update hello-world example Signed-off-by: Kang Huaishuai --- install/centos.md | 6 +++--- install/debian.md | 6 +++--- install/fedora.md | 6 +++--- install/raspberry-pi.md | 8 ++++---- install/ubuntu.md | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/install/centos.md b/install/centos.md index e424f4b3b..690cb9995 100644 --- a/install/centos.md +++ b/install/centos.md @@ -126,12 +126,12 @@ $ sudo usermod -aG docker $USER ## 测试 Docker 是否安装正确 ```bash -$ docker run hello-world +$ docker run --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world -d1725b59e92d: Pull complete -Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 +b8dfde127a29: Pull complete +Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24 Status: Downloaded newer image for hello-world:latest Hello from Docker! diff --git a/install/debian.md b/install/debian.md index 5b433968a..a61753f8b 100644 --- a/install/debian.md +++ b/install/debian.md @@ -120,12 +120,12 @@ $ sudo usermod -aG docker $USER ## 测试 Docker 是否安装正确 ```bash -$ docker run hello-world +$ docker run --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world -d1725b59e92d: Pull complete -Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 +b8dfde127a29: Pull complete +Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24 Status: Downloaded newer image for hello-world:latest Hello from Docker! diff --git a/install/fedora.md b/install/fedora.md index fc72d6564..2a07e0bf3 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -128,12 +128,12 @@ $ sudo usermod -aG docker $USER ## 测试 Docker 是否安装正确 ```bash -$ docker run hello-world +$ docker run --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world -d1725b59e92d: Pull complete -Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 +b8dfde127a29: Pull complete +Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24 Status: Downloaded newer image for hello-world:latest Hello from Docker! diff --git a/install/raspberry-pi.md b/install/raspberry-pi.md index 772670460..ccbd2c0e3 100644 --- a/install/raspberry-pi.md +++ b/install/raspberry-pi.md @@ -111,12 +111,12 @@ $ sudo usermod -aG docker $USER ## 测试 Docker 是否安装正确 ```bash -$ docker run arm32v7/hello-world +$ docker run --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world -d1725b59e92d: Pull complete -Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 +4ee5c797bcd7: Pull complete +Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24 Status: Downloaded newer image for hello-world:latest Hello from Docker! @@ -125,7 +125,7 @@ This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. - (amd64) + (arm32v7) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it diff --git a/install/ubuntu.md b/install/ubuntu.md index 717ba1edf..60af93e4c 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -121,12 +121,12 @@ $ sudo usermod -aG docker $USER ## 测试 Docker 是否安装正确 ```bash -$ docker run hello-world +$ docker run --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world -d1725b59e92d: Pull complete -Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788 +b8dfde127a29: Pull complete +Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24 Status: Downloaded newer image for hello-world:latest Hello from Docker! From da614e84417bfb21504c9405517fef40856f47c0 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 20 Mar 2021 11:22:13 +0800 Subject: [PATCH 161/201] Update link Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 6 +++--- README.md | 4 ++-- appendix/repo/nginx.md | 5 +++-- appendix/repo/nodejs.md | 2 +- container/run.md | 4 ++-- introduction/what.md | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 330dc1a1b..59d833c0c 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -83,11 +83,11 @@ module.exports = config({ nav: [ { text: '微信交流群', - link: 'https://yewm28.coding-pages.com/wechat.jpg', + link: 'https://docker_practice.gitee.io/pic/dpsig-wechat.jpg', }, { text: '小程序', - link: 'https://yewm28.coding-pages.com/49682252-3ac4c500-faec-11e8-86ab-eafe0139be6b.jpg', + link: 'https://docker_practice.gitee.io/pic/dp-wechat-miniprogram.jpg', }, { text: '安装 Docker', @@ -261,7 +261,7 @@ module.exports = config({ }, { title: 'Dockerfile', - collapsable: false, + collapsable: true, children: [ "image/dockerfile/", 'image/dockerfile/copy', diff --git a/README.md b/README.md index 103738770..4c175876e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 ## 微信小程序

- +

微信扫码 随时随地阅读~

@@ -33,7 +33,7 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 ## 技术交流

- +

微信扫码 加入群聊~ 或者微信添加 dpsigs 邀请入群

diff --git a/appendix/repo/nginx.md b/appendix/repo/nginx.md index 8abac44e7..84a3396b0 100644 --- a/appendix/repo/nginx.md +++ b/appendix/repo/nginx.md @@ -16,7 +16,7 @@ $ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d ngin 用户也可以不使用这种映射方式,通过利用 Dockerfile 来直接将静态页面内容放到镜像中,内容为 -```bash +```docker FROM nginx COPY static-html-directory /usr/share/nginx/html ``` @@ -39,7 +39,8 @@ Nginx的默认配置文件路径为 `/etc/nginx/nginx.conf`,可以通过映射 ```bash $ docker run -d \ --name some-nginx \ - -v /some/nginx.conf:/etc/nginx/nginx.conf:ro \ + -p 8080:80 \ + -v /path/nginx.conf:/etc/nginx/nginx.conf:ro \ nginx ``` diff --git a/appendix/repo/nodejs.md b/appendix/repo/nodejs.md index d44563aa6..9af57c173 100644 --- a/appendix/repo/nodejs.md +++ b/appendix/repo/nodejs.md @@ -10,7 +10,7 @@ 在项目中创建一个 Dockerfile。 -```bash +```docker FROM node:12 # replace this with your application's default port EXPOSE 8888 diff --git a/container/run.md b/container/run.md index d4033e8f6..5f7802fd5 100644 --- a/container/run.md +++ b/container/run.md @@ -37,7 +37,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr 当利用 `docker run` 来创建容器时,Docker 在后台运行的标准操作包括: -* 检查本地是否存在指定的镜像,不存在就从 [`registry`](../repository/README.md) 下载 +* 检查本地是否存在指定的镜像,不存在就从 [registry](../repository/README.md) 下载 * 利用镜像创建并启动一个容器 * 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层 * 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 @@ -47,7 +47,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr ## 启动已终止容器 -可以利用 `docker container start` 命令,直接将一个已经终止的容器启动运行。 +可以利用 `docker container start` 命令,直接将一个已经终止(`exited`)的容器启动运行。 容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 `ps` 或 `top` 来查看进程信息。 diff --git a/introduction/what.md b/introduction/what.md index 19241e7c4..534739fa7 100644 --- a/introduction/what.md +++ b/introduction/what.md @@ -4,7 +4,7 @@ **Docker** 自开源后受到广泛的关注和讨论,至今其 [GitHub 项目](https://github.com/moby/moby) 已经超过 5 万 7 千个星标和一万多个 `fork`。甚至由于 `Docker` 项目的火爆,在 `2013` 年底,[dotCloud 公司决定改名为 Docker](https://www.docker.com/blog/dotcloud-is-becoming-docker-inc/)。`Docker` 最初是在 `Ubuntu 12.04` 上开发实现的;`Red Hat` 则从 `RHEL 6.5` 开始对 `Docker` 进行支持;`Google` 也在其 `PaaS` 产品中广泛应用 `Docker`。 -**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.org/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [OverlayFS](https://docs.docker.com/storage/storagedriver/overlayfs-driver/) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 `0.7` 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 `1.11` 版本开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 +**Docker** 使用 `Google` 公司推出的 [Go 语言](https://golang.google.cn/) 进行开发实现,基于 `Linux` 内核的 [cgroup](https://zh.wikipedia.org/wiki/Cgroups),[namespace](https://en.wikipedia.org/wiki/Linux_namespaces),以及 [OverlayFS](https://docs.docker.com/storage/storagedriver/overlayfs-driver/) 类的 [Union FS](https://en.wikipedia.org/wiki/Union_mount) 等技术,对进程进行封装隔离,属于 [操作系统层面的虚拟化技术](https://en.wikipedia.org/wiki/Operating-system-level_virtualization)。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 [LXC](https://linuxcontainers.org/lxc/introduction/),从 `0.7` 版本以后开始去除 `LXC`,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 `1.11` 版本开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。 ![Docker 架构](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/media/docker-on-linux.png) From 6cfc12eece8e58f10fc24674b85aedcff9e0ec74 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 18 Apr 2021 18:58:58 +0800 Subject: [PATCH 162/201] cli experimental is deprecated on 20.10 Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 28 ++++++++++++++-------------- README.md | 2 +- buildx/buildx.md | 4 ---- image/manifest.md | 2 -- install/experimental.md | 30 +++--------------------------- install/mac.md | 4 +++- install/windows.md | 2 +- 7 files changed, 22 insertions(+), 50 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 59d833c0c..19a29bd92 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -126,8 +126,8 @@ module.exports = config({ // link: '' // }, { - text: '腾讯云2021新春采购节', - link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10488&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=activity' + text: '云服务器特惠', + link: 'https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console' }, // { // text: '语言', @@ -151,7 +151,7 @@ module.exports = config({ 'design', { title: "部署 Kubernetes", - collapsable: false, + collapsable: true, children: [ "setup/", "setup/kubeadm", @@ -162,7 +162,7 @@ module.exports = config({ }, { title: "Kubernetes 命令行 kubectl", - collapsable: false, + collapsable: true, children: [ 'kubectl/' ] @@ -185,7 +185,7 @@ module.exports = config({ 'fedora', 'centos', 'raspberry-pi', - 'offline', + // 'offline', 'mac', 'windows', 'mirror', @@ -216,7 +216,7 @@ module.exports = config({ 'actions/', { title: "Drone", - collapsable: false, + collapsable: true, children: [ 'drone/', 'drone/install' @@ -327,7 +327,7 @@ module.exports = config({ }, { title: "高级网络配置", - collapsable: false, + collapsable: true, children: [ 'advanced_network/', 'advanced_network/quick_guide', @@ -341,7 +341,7 @@ module.exports = config({ }, { title: "Swarm mode", - collapsable: false, + collapsable: true, children: [ 'swarm_mode/', 'swarm_mode/overview', @@ -355,7 +355,7 @@ module.exports = config({ }, { title: "安全", - collapsable: false, + collapsable: true, children: [ 'security/', 'security/kernel_ns', @@ -368,7 +368,7 @@ module.exports = config({ }, { title: "底层实现", - collapsable: false, + collapsable: true, children: [ 'underly/', 'underly/arch', @@ -391,7 +391,7 @@ module.exports = config({ }, { title: "Etcd", - collapsable: false, + collapsable: true, children: [ 'etcd/', 'etcd/intro', @@ -402,7 +402,7 @@ module.exports = config({ }, { title: "Fedora CoreOS", - collapsable: false, + collapsable: true, children: [ 'coreos/', 'coreos/intro', @@ -413,7 +413,7 @@ module.exports = config({ 'appendix/faq/', { title: "热门镜像介绍", - collapsable: false, + collapsable: true, children: [ 'appendix/repo/', 'appendix/repo/ubuntu', @@ -430,7 +430,7 @@ module.exports = config({ }, { title: "Docker 命令", - collapsable: false, + collapsable: true, children: [ 'appendix/command/', 'appendix/command/docker', diff --git a/README.md b/README.md index 4c175876e..3c8f92e41 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初 * QQ 群 IX (已满):571502246 * QQ 群 X (可加):145983035 ->如果有容器相关的疑问,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。 +>如果有容器技术相关的疑问,请通过 [Issues](https://github.com/yeasy/docker_practice/issues/new/choose) 来提出。 ## 进阶学习 diff --git a/buildx/buildx.md b/buildx/buildx.md index ee7ec45c8..bdbfe9a1a 100644 --- a/buildx/buildx.md +++ b/buildx/buildx.md @@ -1,9 +1,5 @@ # 使用 Buildx 构建镜像 -## 启用 Buildx - -`buildx` 命令属于实验特性,请参考 [开启实验特性](../install/experimental.md) 一节开启 Docker CLI 实验特性。 - ## 使用 你可以直接使用 `docker buildx build` 命令构建镜像。 diff --git a/image/manifest.md b/image/manifest.md index 2e25797c4..b55d749ca 100644 --- a/image/manifest.md +++ b/image/manifest.md @@ -34,8 +34,6 @@ $ docker run -it --rm username/test 我们可以使用 `$ docker manifest inspect golang:alpine` 查看这个 `manifest` 列表的结构。 -> 该命令属于实验特性,请参考 [开启实验特性](../install/experimental) 一节。 - ```bash $ docker manifest inspect golang:alpine ``` diff --git a/install/experimental.md b/install/experimental.md index 037ea40d3..d32844eab 100644 --- a/install/experimental.md +++ b/install/experimental.md @@ -2,35 +2,11 @@ 一些 docker 命令或功能仅当 **实验特性** 开启时才能使用,请按照以下方法进行设置。 -## 开启 Docker CLI 的实验特性 +## Docker CLI 的实验特性 -编辑 `~/.docker/config.json` 文件,新增如下条目 +从 `v20.10` 版本开始,Docker CLI 所有实验特性的命令均默认开启,无需再进行配置或设置系统环境变量。 -```json -{ - "experimental": "enabled" -} -``` - -或者通过设置环境变量的方式: - -**Linux/macOS** - -```bash -$ export DOCKER_CLI_EXPERIMENTAL=enabled -``` - -**Windows** - -```powershell -# 临时生效 -$ set $env:DOCKER_CLI_EXPERIMENTAL="enabled" - -# 永久生效 -$ [environment]::SetEnvironmentvariable("DOCKER_CLI_EXPERIMENTAL","enabled","User") -``` - -## 开启 Dockerd 的实验特性 +## 开启 dockerd 的实验特性 编辑 `/etc/docker/daemon.json`,新增如下条目 diff --git a/install/mac.md b/install/mac.md index 9685c14ad..562631e6b 100644 --- a/install/mac.md +++ b/install/mac.md @@ -16,7 +16,9 @@ $ brew install --cask docker ### 手动下载安装 -如果需要手动下载,请点击以下 [链接](https://desktop.docker.com/mac/stable/Docker.dmg) 下载 Docker Desktop for Mac。 +如果需要手动下载,请点击以下 [链接](https://desktop.docker.com/mac/stable/amd64/Docker.dmg) 下载 Docker Desktop for Mac。 + +> 如果你的电脑搭载的是 M1 芯片(`arm64` 架构),请点击以下 [链接](https://desktop.docker.com/mac/stable/arm64/Docker.dmg) 下载 Docker Desktop for Mac。你可以在 [官方文档](https://docs.docker.com/docker-for-mac/apple-silicon/) 查阅已知的问题。 如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。 diff --git a/install/windows.md b/install/windows.md index 70fefb8be..ffe34f8e4 100644 --- a/install/windows.md +++ b/install/windows.md @@ -8,7 +8,7 @@ **手动下载安装** -点击以下 [链接](https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe) 下载 Docker Desktop for Windows。 +点击以下 [链接](https://desktop.docker.com/win/stable/amd64/Docker%20Desktop%20Installer.exe) 下载 Docker Desktop for Windows。 下载好之后双击 `Docker Desktop Installer.exe` 开始安装。 From 96fc5acc7552f4216509631c5b5570cd75a95acf Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 28 May 2021 21:50:15 +0800 Subject: [PATCH 163/201] Update laravel demo Signed-off-by: Kang Huaishuai --- image/multistage-builds/example/laravel/Dockerfile | 2 +- image/multistage-builds/laravel.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/image/multistage-builds/example/laravel/Dockerfile b/image/multistage-builds/example/laravel/Dockerfile index 3f247becf..ab455accd 100644 --- a/image/multistage-builds/example/laravel/Dockerfile +++ b/image/multistage-builds/example/laravel/Dockerfile @@ -5,7 +5,7 @@ COPY package.json /app/ RUN set -x ; cd /app \ && npm install --registry=https://registry.npm.taobao.org -COPY webpack.mix.js /app/ +COPY webpack.mix.js webpack.config.js tailwind.config.js /app/ COPY resources/ /app/resources/ RUN set -x ; cd /app \ diff --git a/image/multistage-builds/laravel.md b/image/multistage-builds/laravel.md index 07df96cf4..1d3b1fa89 100644 --- a/image/multistage-builds/laravel.md +++ b/image/multistage-builds/laravel.md @@ -63,7 +63,7 @@ COPY package.json /app/ RUN set -x ; cd /app \ && npm install --registry=https://registry.npm.taobao.org -COPY webpack.mix.js /app/ +COPY webpack.mix.js webpack.config.js tailwind.config.js /app/ COPY resources/ /app/resources/ RUN set -x ; cd /app \ @@ -181,7 +181,7 @@ COPY package.json /app/ RUN set -x ; cd /app \ && npm install --registry=https://registry.npm.taobao.org -COPY webpack.mix.js /app/ +COPY webpack.mix.js webpack.config.js tailwind.config.js /app/ COPY resources/ /app/resources/ RUN set -x ; cd /app \ From ba36c90b6cdb38b4866c25d0694b634e9fe4997e Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 31 May 2021 19:23:39 +0800 Subject: [PATCH 164/201] Update vuepress config Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 21 +++++++++++++++------ package.json | 5 ++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 19a29bd92..3910d64d9 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -39,7 +39,6 @@ module.exports = config({ // }, }, themeConfig: { - baseLang: 'zh-CN', blog: false, // comment: false, comment: { @@ -53,7 +52,7 @@ module.exports = config({ 'word', ], footer: { - content: "Made with vuepress-theme-hope", + content: "Made with vuepress-theme-hope", display: true, copyright: false, }, @@ -65,12 +64,22 @@ module.exports = config({ mdEnhance: { lineNumbers: true, }, + git: { + contributor: false, + }, themeColor: { blue: '#2196f3', // red: '#f26d6d', // green: '#3eaf7c', // orange: '#fb9b5f' }, + locales: { + "/": { + lang: "zh-CN" + } + }, + + darkmode: 'auto-switch', // @@ -117,10 +126,10 @@ module.exports = config({ text: "云计算", link: "/cloud/", }, - { - text: 'GitHub', - link: 'https://github.com/yeasy/docker_practice' - }, + // { + // text: 'GitHub', + // link: 'https://github.com/yeasy/docker_practice' + // }, // { // text: '捐赠', // link: '' diff --git a/package.json b/package.json index e7d5fb064..a35560b87 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,9 @@ "version": "1.0.0", "description": "docker_practice", "main": "index.js", - "dependencies": {}, "devDependencies": { - "chalk": "^2.4.2", - "commander": "^2.0.0", + "chalk": "^4.1.1", + "commander": "^7.2.0", "esm": "^3.0.0", "vuepress": "1.8.2", "vuepress-plugin-container": "^2.1.5", From 8705cede17147c77ce14a952aad57f3fd691a492 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 31 May 2021 19:42:07 +0800 Subject: [PATCH 165/201] Update jd.com link Signed-off-by: Kang Huaishuai --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c8f92e41..5d2139c5d 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,4 @@ Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初

欢迎鼓励项目一杯 coffee~

-[1]: https://union-click.jd.com/jdc?e=&p=AyIGZRtYFAcXBFIZWR0yEgRQH1kXAhs3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFwNXGVscMlVYLlAaXAV1Z1JHA0dWEHVXZTliY1QLWStaJQAWB10fXhwKEDdlG1wlUHzf462DsLMO0%2F%2BUjp2VIgZlG18RBBcCUBlbEAoTBWUcWxwySVI7HAhBBxEOBUgOFQYQUGUraxYyIjdVK1glQHxXUEhYEVEUUFQcC0IHGgRRSAgVARAPAhsLFgNCDl0ZWiUAEwZREg%3D%3D&t=W1dCFFlQCxxKQgFHREkdSVJKSQVJHFRXFk9FUlpGQUpLCVBaTFhbXQtWVmpSWRtYEAYQBVUS +[1]: https://union-click.jd.com/jdc?e=&p=JF8AANADIgZlGF0VAxUDVBJdHDISBFAfWRcCGzcRRANLXSJeEF4aVwkMGQ1eD0kdSVJKSQVJHBIEUB9ZFwIbGAxeB0gyS34PbFlHVHNkI0MQEAoIcSxyBWFLRAtZK1olABYHXR9eHAoQN2UbXCVQfN_jrYOwsw7T_5SOnZUiBmUbXBYBFwBVG14UBBAAZRxbHDJJUjscCEEHEQ4FSA4VBhBQZStrFjIiN1UrWCVAfARQT1gQA0cFAEwOEAcRDlMTDEALQAFTEwwRUhMAUR1cJQATBlES From baeb22245550eeca8421c77d3f981baba35a705c Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Jun 2021 10:50:31 +0800 Subject: [PATCH 166/201] Update vuepress config Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 3910d64d9..94ce5e68d 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -38,6 +38,11 @@ module.exports = config({ // onlyFirstAndLastCommit: true, // }, }, + locales: { + "/": { + lang: "zh-CN" + } + }, themeConfig: { blog: false, // comment: false, @@ -59,6 +64,7 @@ module.exports = config({ searchPlaceholder: 'Search', repo: 'yeasy/docker_practice', repoLabel: 'GitHub', + repoDisplay: true, hostname: 'https://vuepress.mirror.docker-practice.com', // author: 'yeasy', mdEnhance: { @@ -135,8 +141,9 @@ module.exports = config({ // link: '' // }, { - text: '云服务器特惠', - link: 'https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console' + text: '云服务器618特惠', + //link: 'https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console' + link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10488&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=activity' }, // { // text: '语言', From 330beb4fdb80a9491f3878c9263cf57b5b4b87e4 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 6 Jun 2021 20:19:28 +0800 Subject: [PATCH 167/201] don't push pages to coding.net Signed-off-by: Kang Huaishuai --- .github/workflows/ci.yaml | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 68724f463..c44061170 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -80,7 +80,8 @@ jobs: npx vuepress --version npm run vuepress:build - echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME + # echo "vuepress.docker-practice.com" > .vuepress/dist/CNAME + echo "vuepress.mirror.docker-practice.com" > .vuepress/dist/CNAME cp -r _images .vuepress/dist cp -r advanced_network/_images .vuepress/dist/advanced_network @@ -109,21 +110,21 @@ jobs: PCIT_MESSAGE: Build from yeasy/docker_practice@${{github.sha}} PCIT_TARGET_BRANCH: master PCIT_USERNAME: khs1994 - - name: Set coding.net CNAME - run: | - echo "vuepress.mirror.docker-practice.com" > .vuepress/dist/CNAME - - name: Upload Vuepress dist to coding.net - uses: docker://pcit/pages - if: github.repository == 'docker-practice/docker_practice' - env: - PCIT_EMAIL: khs1994@khs1994.com - PCIT_GIT_TOKEN: ${{ secrets.CODING_GIT_TOKEN }} - PCIT_GIT_URL: e.coding.net/dpsigs/docker_practice - PCIT_KEEP_HISTORY: "true" - PCIT_LOCAL_DIR: .vuepress/dist - PCIT_MESSAGE: Build from yeasy/docker_practice@${{github.sha}} - PCIT_TARGET_BRANCH: master - PCIT_USERNAME: ptt0xjqzbke3 + # - name: Set coding.net CNAME + # run: | + # echo "vuepress.mirror.docker-practice.com" > .vuepress/dist/CNAME + # - name: Upload Vuepress dist to coding.net + # uses: docker://pcit/pages + # if: github.repository == 'docker-practice/docker_practice' + # env: + # PCIT_EMAIL: khs1994@khs1994.com + # PCIT_GIT_TOKEN: ${{ secrets.CODING_GIT_TOKEN }} + # PCIT_GIT_URL: e.coding.net/dpsigs/docker_practice + # PCIT_KEEP_HISTORY: "true" + # PCIT_LOCAL_DIR: .vuepress/dist + # PCIT_MESSAGE: Build from yeasy/docker_practice@${{github.sha}} + # PCIT_TARGET_BRANCH: master + # PCIT_USERNAME: ptt0xjqzbke3 - name: Build vuepress docker image if: github.repository == 'docker-practice/docker_practice' run: | From 985e295d708dd22b87aa000fb7c728bbe8f31374 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sat, 12 Jun 2021 15:23:30 +0800 Subject: [PATCH 168/201] Add compose v2 Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 1 + CHANGELOG.md | 2 ++ SUMMARY.md | 1 + compose/v2.md | 7 +++++++ repository/dockerhub.md | 2 ++ 5 files changed, 13 insertions(+) create mode 100644 compose/v2.md diff --git a/.vuepress/config.js b/.vuepress/config.js index 94ce5e68d..3d0f6d169 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -186,6 +186,7 @@ module.exports = config({ ], '/compose/': [ 'introduction', + 'v2', 'install', 'usage', 'commands', diff --git a/CHANGELOG.md b/CHANGELOG.md index cfd3cfc49..2d80a1f69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ * 1.3.0 2021-YY-DD * 全面支持 Docker v20.10 新版本 + * 新增 Docker Compose v2 + * Docker Hub 自动构建转为付费功能 * 1.2.0 2020-12-20 * 错误修复 diff --git a/SUMMARY.md b/SUMMARY.md index 9cecb27e9..34035a201 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -82,6 +82,7 @@ * [使用 buildx 构建多种系统架构支持的 Docker 镜像](buildx/multi-arch-images.md) * [Docker Compose](compose/README.md) * [简介](compose/introduction.md) + * [Compose v2](compose/v2.md) * [安装与卸载](compose/install.md) * [使用](compose/usage.md) * [命令说明](compose/commands.md) diff --git a/compose/v2.md b/compose/v2.md new file mode 100644 index 000000000..d098db28f --- /dev/null +++ b/compose/v2.md @@ -0,0 +1,7 @@ +# Compose V2 + +目前 Docker 官方用 GO 语言 [重写](https://github.com/docker/compose-cli) 了 Docker Compose,并将其作为了 docker cli 的子命令,称为 `Compose V2`。你可以参照官方文档安装,然后将熟悉的 `docker-compose` 命令替换为 `docker compose`,即可使用 Docker Compose。 + +## 官方文档 + +* [Compose V2 beta](https://docs.docker.com/compose/cli-command/) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 6983c8277..9dfe4fa70 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -75,6 +75,8 @@ username/ubuntu ## 自动构建 +> 2021 年 6 月 18 日之后,该项功能仅限[付费用户](https://www.docker.com/blog/changes-to-docker-hub-autobuilds/)使用。 + 自动构建(`Automated Builds`)功能对于需要经常升级镜像内程序来说,十分方便。 有时候,用户构建了镜像,安装了某个软件,当软件发布新版本则需要手动更新镜像。 From 31ea892dfc0d65145ef97b3123957d9f20443cf8 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 27 Jun 2021 18:03:05 +0800 Subject: [PATCH 169/201] Update aliyun mirror Signed-off-by: Kang Huaishuai --- install/mirror.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/mirror.md b/install/mirror.md index 1f2a999d6..0a2ebfed4 100644 --- a/install/mirror.md +++ b/install/mirror.md @@ -2,7 +2,7 @@ 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如: -* [阿里云加速器(点击管理控制台 -> 登录账号(淘宝账号) -> 右侧镜像中心 -> 镜像加速器 -> 复制地址)](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu) +* [阿里云加速器(点击管理控制台 -> 登录账号(淘宝账号) -> 右侧镜像工具 -> 镜像加速器 -> 复制加速器地址)](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu) * [网易云加速器 `https://hub-mirror.c.163.com`](https://www.163yun.com/help/documents/56918246390157312) * [百度云加速器 `https://mirror.baidubce.com`](https://cloud.baidu.com/doc/CCE/s/Yjxppt74z#%E4%BD%BF%E7%94%A8dockerhub%E5%8A%A0%E9%80%9F%E5%99%A8) From 64b75e997fce6c8cd5d1790da7bc882a6de8527c Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 27 Jun 2021 22:34:53 +0800 Subject: [PATCH 170/201] Update project compose file Signed-off-by: Kang Huaishuai --- docker-compose.yml | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 598a48cd7..d54a15791 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,30 +2,31 @@ version: "3" services: - # $ docker-compose up server => up a server,Only Support Linux or macOS - server: - image: yeasy/docker_practice:latest - ports: - - 4000:4000 - volumes: - - ./:/srv/gitbook-src - command: server - - # $ docker-compose up build => build gitbook - - build: + gitbook-build: + &gitbook-build image: yeasy/docker_practice:latest volumes: - ./:/srv/gitbook-src command: build - # $ docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice - offline: + gitbook-server: + << : *gitbook-build + ports: + - 4000:4000 + command: server + + # docker run -it --rm -p 4000:80 dockerpracticesig/docker_practice + gitbook-offline: + &gitbook-offline # this image build by GitHub Action - image: dockerpracticesig/docker_practice + image: dockerpracticesig/docker_practice:gitbook ports: - 4000:80 + vuepress-offline: + << : *gitbook-offline + image: dockerpracticesig/docker_practice:vuepress + # developer test docker image development: From ca29ab51b121f43563f5d6659dedbda5cb6f048d Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Mon, 5 Jul 2021 00:35:13 +0800 Subject: [PATCH 171/201] Update SUMMARY.md Signed-off-by: Kang Huaishuai --- SUMMARY.md | 290 ++++++++++++++++++++++++++--------------------------- 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 34035a201..c906a784a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -4,173 +4,173 @@ * [修订记录](CHANGELOG.md) * [如何贡献](CONTRIBUTING.md) * [Docker 简介](introduction/README.md) - * [什么是 Docker](introduction/what.md) - * [为什么要用 Docker](introduction/why.md) + * [什么是 Docker](introduction/what.md) + * [为什么要用 Docker](introduction/why.md) * [基本概念](basic_concept/README.md) - * [镜像](basic_concept/image.md) - * [容器](basic_concept/container.md) - * [仓库](basic_concept/repository.md) + * [镜像](basic_concept/image.md) + * [容器](basic_concept/container.md) + * [仓库](basic_concept/repository.md) * [安装 Docker](install/README.md) - * [Ubuntu](install/ubuntu.md) - * [Debian](install/debian.md) - * [Fedora](install/fedora.md) - * [CentOS](install/centos.md) - * [Raspberry Pi](install/raspberry-pi.md) - * [Linux 离线安装](install/offline.md) - * [macOS](install/mac.md) - * [Windows 10](install/windows.md) - * [镜像加速器](install/mirror.md) - * [开启实验特性](install/experimental.md) + * [Ubuntu](install/ubuntu.md) + * [Debian](install/debian.md) + * [Fedora](install/fedora.md) + * [CentOS](install/centos.md) + * [Raspberry Pi](install/raspberry-pi.md) + * [Linux 离线安装](install/offline.md) + * [macOS](install/mac.md) + * [Windows 10](install/windows.md) + * [镜像加速器](install/mirror.md) + * [开启实验特性](install/experimental.md) * [使用镜像](image/README.md) - * [获取镜像](image/pull.md) - * [列出镜像](image/list.md) - * [删除本地镜像](image/rm.md) - * [利用 commit 理解镜像构成](image/commit.md) - * [使用 Dockerfile 定制镜像](image/build.md) - * [Dockerfile 指令详解](image/dockerfile/README.md) - * [COPY 复制文件](image/dockerfile/copy.md) - * [ADD 更高级的复制文件](image/dockerfile/add.md) - * [CMD 容器启动命令](image/dockerfile/cmd.md) - * [ENTRYPOINT 入口点](image/dockerfile/entrypoint.md) - * [ENV 设置环境变量](image/dockerfile/env.md) - * [ARG 构建参数](image/dockerfile/arg.md) - * [VOLUME 定义匿名卷](image/dockerfile/volume.md) - * [EXPOSE 暴露端口](image/dockerfile/expose.md) - * [WORKDIR 指定工作目录](image/dockerfile/workdir.md) - * [USER 指定当前用户](image/dockerfile/user.md) - * [HEALTHCHECK 健康检查](image/dockerfile/healthcheck.md) - * [ONBUILD 为他人作嫁衣裳](image/dockerfile/onbuild.md) - * [LABEL 为镜像添加元数据](image/dockerfile/label.md) - * [SHELL 指令](image/dockerfile/shell.md) - * [参考文档](image/dockerfile/references.md) - * [Dockerfile 多阶段构建](image/multistage-builds/README.md) - * [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md) - * [构建多种系统架构支持的 Docker 镜像](image/manifest.md) - * [其它制作镜像的方式](image/other.md) - * [实现原理](image/internal.md) + * [获取镜像](image/pull.md) + * [列出镜像](image/list.md) + * [删除本地镜像](image/rm.md) + * [利用 commit 理解镜像构成](image/commit.md) + * [使用 Dockerfile 定制镜像](image/build.md) + * [Dockerfile 指令详解](image/dockerfile/README.md) + * [COPY 复制文件](image/dockerfile/copy.md) + * [ADD 更高级的复制文件](image/dockerfile/add.md) + * [CMD 容器启动命令](image/dockerfile/cmd.md) + * [ENTRYPOINT 入口点](image/dockerfile/entrypoint.md) + * [ENV 设置环境变量](image/dockerfile/env.md) + * [ARG 构建参数](image/dockerfile/arg.md) + * [VOLUME 定义匿名卷](image/dockerfile/volume.md) + * [EXPOSE 暴露端口](image/dockerfile/expose.md) + * [WORKDIR 指定工作目录](image/dockerfile/workdir.md) + * [USER 指定当前用户](image/dockerfile/user.md) + * [HEALTHCHECK 健康检查](image/dockerfile/healthcheck.md) + * [ONBUILD 为他人作嫁衣裳](image/dockerfile/onbuild.md) + * [LABEL 为镜像添加元数据](image/dockerfile/label.md) + * [SHELL 指令](image/dockerfile/shell.md) + * [参考文档](image/dockerfile/references.md) + * [Dockerfile 多阶段构建](image/multistage-builds/README.md) + * [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md) + * [构建多种系统架构支持的 Docker 镜像](image/manifest.md) + * [其它制作镜像的方式](image/other.md) + * [实现原理](image/internal.md) * [操作容器](container/README.md) - * [启动](container/run.md) - * [守护态运行](container/daemon.md) - * [终止](container/stop.md) - * [进入容器](container/attach_exec.md) - * [导出和导入](container/import_export.md) - * [删除](container/rm.md) + * [启动](container/run.md) + * [守护态运行](container/daemon.md) + * [终止](container/stop.md) + * [进入容器](container/attach_exec.md) + * [导出和导入](container/import_export.md) + * [删除](container/rm.md) * [访问仓库](repository/README.md) - * [Docker Hub](repository/dockerhub.md) - * [私有仓库](repository/registry.md) - * [私有仓库高级配置](repository/registry_auth.md) - * [Nexus 3](repository/nexus3_registry.md) + * [Docker Hub](repository/dockerhub.md) + * [私有仓库](repository/registry.md) + * [私有仓库高级配置](repository/registry_auth.md) + * [Nexus 3](repository/nexus3_registry.md) * [数据管理](data_management/README.md) - * [数据卷](data_management/volume.md) - * [挂载主机目录](data_management/bind-mounts.md) + * [数据卷](data_management/volume.md) + * [挂载主机目录](data_management/bind-mounts.md) * [使用网络](network/README.md) - * [外部访问容器](network/port_mapping.md) - * [容器互联](network/linking.md) - * [配置 DNS](network/dns.md) + * [外部访问容器](network/port_mapping.md) + * [容器互联](network/linking.md) + * [配置 DNS](network/dns.md) * [高级网络配置](advanced_network/README.md) - * [快速配置指南](advanced_network/quick_guide.md) - * [容器访问控制](advanced_network/access_control.md) - * [端口映射实现](advanced_network/port_mapping.md) - * [配置 docker0 网桥](advanced_network/docker0.md) - * [自定义网桥](advanced_network/bridge.md) - * [工具和示例](advanced_network/example.md) - * [编辑网络配置文件](advanced_network/config_file.md) - * [实例:创建一个点到点连接](advanced_network/ptp.md) + * [快速配置指南](advanced_network/quick_guide.md) + * [容器访问控制](advanced_network/access_control.md) + * [端口映射实现](advanced_network/port_mapping.md) + * [配置 docker0 网桥](advanced_network/docker0.md) + * [自定义网桥](advanced_network/bridge.md) + * [工具和示例](advanced_network/example.md) + * [编辑网络配置文件](advanced_network/config_file.md) + * [实例:创建一个点到点连接](advanced_network/ptp.md) * [Docker Buildx](buildx/README.md) - * [BuildKit](buildx/buildkit.md) - * [使用 buildx 构建镜像](buildx/buildx.md) - * [使用 buildx 构建多种系统架构支持的 Docker 镜像](buildx/multi-arch-images.md) + * [BuildKit](buildx/buildkit.md) + * [使用 buildx 构建镜像](buildx/buildx.md) + * [使用 buildx 构建多种系统架构支持的 Docker 镜像](buildx/multi-arch-images.md) * [Docker Compose](compose/README.md) - * [简介](compose/introduction.md) - * [Compose v2](compose/v2.md) - * [安装与卸载](compose/install.md) - * [使用](compose/usage.md) - * [命令说明](compose/commands.md) - * [Compose 模板文件](compose/compose_file.md) - * [实战 Django](compose/django.md) - * [实战 Rails](compose/rails.md) - * [实战 WordPress](compose/wordpress.md) - * [实战 LNMP](compose/lnmp.md) + * [简介](compose/introduction.md) + * [Compose v2](compose/v2.md) + * [安装与卸载](compose/install.md) + * [使用](compose/usage.md) + * [命令说明](compose/commands.md) + * [Compose 模板文件](compose/compose_file.md) + * [实战 Django](compose/django.md) + * [实战 Rails](compose/rails.md) + * [实战 WordPress](compose/wordpress.md) + * [实战 LNMP](compose/lnmp.md) * [Swarm mode](swarm_mode/README.md) - * [基本概念](swarm_mode/overview.md) - * [创建 Swarm 集群](swarm_mode/create.md) - * [部署服务](swarm_mode/deploy.md) - * [使用 compose 文件](swarm_mode/stack.md) - * [管理密钥](swarm_mode/secret.md) - * [管理配置信息](swarm_mode/config.md) - * [滚动升级](swarm_mode/rolling_update.md) + * [基本概念](swarm_mode/overview.md) + * [创建 Swarm 集群](swarm_mode/create.md) + * [部署服务](swarm_mode/deploy.md) + * [使用 compose 文件](swarm_mode/stack.md) + * [管理密钥](swarm_mode/secret.md) + * [管理配置信息](swarm_mode/config.md) + * [滚动升级](swarm_mode/rolling_update.md) * [安全](security/README.md) - * [内核命名空间](security/kernel_ns.md) - * [控制组](security/control_group.md) - * [服务端防护](security/daemon_sec.md) - * [内核能力机制](security/kernel_capability.md) - * [其它安全特性](security/other_feature.md) - * [总结](security/summary.md) + * [内核命名空间](security/kernel_ns.md) + * [控制组](security/control_group.md) + * [服务端防护](security/daemon_sec.md) + * [内核能力机制](security/kernel_capability.md) + * [其它安全特性](security/other_feature.md) + * [总结](security/summary.md) * [底层实现](underly/README.md) - * [基本架构](underly/arch.md) - * [命名空间](underly/namespace.md) - * [控制组](underly/cgroups.md) - * [联合文件系统](underly/ufs.md) - * [容器格式](underly/container_format.md) - * [网络](underly/network.md) + * [基本架构](underly/arch.md) + * [命名空间](underly/namespace.md) + * [控制组](underly/cgroups.md) + * [联合文件系统](underly/ufs.md) + * [容器格式](underly/container_format.md) + * [网络](underly/network.md) * [Etcd 项目](etcd/README.md) - * [简介](etcd/intro.md) - * [安装](etcd/install.md) - * [集群](etcd/cluster.md) - * [使用 etcdctl](etcd/etcdctl.md) + * [简介](etcd/intro.md) + * [安装](etcd/install.md) + * [集群](etcd/cluster.md) + * [使用 etcdctl](etcd/etcdctl.md) * [Fedora CoreOS](coreos/README.md) - * [简介](coreos/intro.md) - * [安装](coreos/install.md) + * [简介](coreos/intro.md) + * [安装](coreos/install.md) * [Kubernetes - 开源容器编排引擎](kubernetes/README.md) - * [简介](kubernetes/intro.md) - * [基本概念](kubernetes/concepts.md) - * [架构设计](kubernetes/design.md) + * [简介](kubernetes/intro.md) + * [基本概念](kubernetes/concepts.md) + * [架构设计](kubernetes/design.md) * [部署 Kubernetes](kubernetes/setup/README.md) - * [使用 kubeadm 部署 kubernetes](kubernetes/setup/kubeadm.md) - * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) - * [一步步部署 kubernetes 集群](kubernetes/setup/systemd.md) - * [部署 Dashboard](kubernetes/setup/dashboard.md) + * [使用 kubeadm 部署 kubernetes](kubernetes/setup/kubeadm.md) + * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) + * [一步步部署 kubernetes 集群](kubernetes/setup/systemd.md) + * [部署 Dashboard](kubernetes/setup/dashboard.md) * [Kubernetes 命令行 kubectl](kubernetes/kubectl/README.md) * [容器与云计算](cloud/README.md) - * [简介](cloud/intro.md) - * [腾讯云](cloud/tencentCloud.md) - * [阿里云](cloud/alicloud.md) - * [亚马逊云](cloud/aws.md) - * [小结](cloud/summary.md) + * [简介](cloud/intro.md) + * [腾讯云](cloud/tencentCloud.md) + * [阿里云](cloud/alicloud.md) + * [亚马逊云](cloud/aws.md) + * [小结](cloud/summary.md) * [实战案例 - 操作系统](cases/os/README.md) - * [Busybox](cases/os/busybox.md) - * [Alpine](cases/os/alpine.md) - * [Debian Ubuntu](cases/os/debian.md) - * [CentOS Fedora](cases/os/centos.md) - * [本章小结](cases/os/summary.md) + * [Busybox](cases/os/busybox.md) + * [Alpine](cases/os/alpine.md) + * [Debian Ubuntu](cases/os/debian.md) + * [CentOS Fedora](cases/os/centos.md) + * [本章小结](cases/os/summary.md) * [实战案例 - CI/CD](cases/ci/README.md) - * [GitHub Actions](cases/ci/actions/README.md) - * [Drone](cases/ci/drone/README.md) - * [部署 Drone](cases/ci/drone/install.md) + * [GitHub Actions](cases/ci/actions/README.md) + * [Drone](cases/ci/drone/README.md) + * [部署 Drone](cases/ci/drone/install.md) * [在 IDE 中使用 Docker](ide/README.md) - * [VS Code](ide/vsCode.md) + * [VS Code](ide/vsCode.md) * [podman - 下一代 Linux 容器工具](podman/README.md) * [附录](appendix/README.md) - * [附录一:常见问题总结](appendix/faq/README.md) - * [附录二:热门镜像介绍](appendix/repo/README.md) - * [Ubuntu](appendix/repo/ubuntu.md) - * [CentOS](appendix/repo/centos.md) - * [Nginx](appendix/repo/nginx.md) - * [PHP](appendix/repo/php.md) - * [Node.js](appendix/repo/nodejs.md) - * [MySQL](appendix/repo/mysql.md) - * [WordPress](appendix/repo/wordpress.md) - * [MongoDB](appendix/repo/mongodb.md) - * [Redis](appendix/repo/redis.md) - * [Minio](appendix/repo/minio.md) - * [附录三:Docker 命令查询](appendix/command/README.md) - * [客户端命令 - docker](appendix/command/docker.md) - * [服务端命令 - dockerd](appendix/command/dockerd.md) - * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) - * [附录五:如何调试 Docker](appendix/debug.md) - * [附录六:资源链接](appendix/resources.md) + * [附录一:常见问题总结](appendix/faq/README.md) + * [附录二:热门镜像介绍](appendix/repo/README.md) + * [Ubuntu](appendix/repo/ubuntu.md) + * [CentOS](appendix/repo/centos.md) + * [Nginx](appendix/repo/nginx.md) + * [PHP](appendix/repo/php.md) + * [Node.js](appendix/repo/nodejs.md) + * [MySQL](appendix/repo/mysql.md) + * [WordPress](appendix/repo/wordpress.md) + * [MongoDB](appendix/repo/mongodb.md) + * [Redis](appendix/repo/redis.md) + * [Minio](appendix/repo/minio.md) + * [附录三:Docker 命令查询](appendix/command/README.md) + * [客户端命令 - docker](appendix/command/docker.md) + * [服务端命令 - dockerd](appendix/command/dockerd.md) + * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) + * [附录五:如何调试 Docker](appendix/debug.md) + * [附录六:资源链接](appendix/resources.md) * [归档](archive/README.md) - * [Docker Machine](machine/README.md) - * [安装](machine/install.md) - * [使用](machine/usage.md) - * [Docker Swarm](swarm/README.md) + * [Docker Machine](machine/README.md) + * [安装](machine/install.md) + * [使用](machine/usage.md) + * [Docker Swarm](swarm/README.md) From 1787c392c67348ede2bf1a313a197be7d83978a6 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 6 Jul 2021 23:12:55 +0800 Subject: [PATCH 172/201] Update os version requirement Signed-off-by: Kang Huaishuai --- install/debian.md | 2 +- install/fedora.md | 5 ++--- install/ubuntu.md | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/install/debian.md b/install/debian.md index a61753f8b..515353f0b 100644 --- a/install/debian.md +++ b/install/debian.md @@ -8,8 +8,8 @@ Docker 支持以下版本的 [Debian](https://www.debian.org/intro/about) 操作系统: +* Debian Bullseye 11 * Debian Buster 10 -* Debian Stretch 9 ### 卸载旧版本 diff --git a/install/fedora.md b/install/fedora.md index 2a07e0bf3..32f223475 100644 --- a/install/fedora.md +++ b/install/fedora.md @@ -8,9 +8,8 @@ Docker 支持以下版本的 [Fedora](https://getfedora.org/) 操作系统: -* 30 -* 31 -* 32 +* 33 +* 34 ### 卸载旧版本 diff --git a/install/ubuntu.md b/install/ubuntu.md index 60af93e4c..45d5cca06 100644 --- a/install/ubuntu.md +++ b/install/ubuntu.md @@ -8,10 +8,10 @@ Docker 支持以下版本的 [Ubuntu](https://ubuntu.com/server) 操作系统: +* Ubuntu Hirsute 21.04 * Ubuntu Groovy 20.10 * Ubuntu Focal 20.04 (LTS) * Ubuntu Bionic 18.04 (LTS) -* Ubuntu Xenial 16.04 (LTS) Docker 可以安装在 64 位的 x86 平台或 ARM 平台上。Ubuntu 发行版中,LTS(Long-Term-Support)长期支持版本,会获得 5 年的升级维护支持,这样的版本会更稳定,因此在生产环境中推荐使用 LTS 版本。 From 533f30a9393a3abf49d5dfcc520e968715394da6 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Tue, 6 Jul 2021 23:21:53 +0800 Subject: [PATCH 173/201] Update dead url Signed-off-by: Kang Huaishuai --- .gitignore | 2 ++ advanced_network/README.md | 2 +- basic_concept/repository.md | 2 +- repository/nexus3_registry.md | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index cd6ce1c4d..04f9bb93f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ _book/ node_modules/ package-lock.json + +docker-compose.override.yml diff --git a/advanced_network/README.md b/advanced_network/README.md index 52ea99073..02106c8d3 100644 --- a/advanced_network/README.md +++ b/advanced_network/README.md @@ -6,7 +6,7 @@ 当 Docker 启动时,会自动在主机上创建一个 `docker0` 虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。 -同时,Docker 随机分配一个本地未占用的私有网段(在 [RFC1918](https://tools.ietf.org/html/rfc1918) 中定义)中的一个地址给 `docker0` 接口。比如典型的 `172.17.42.1`,掩码为 `255.255.0.0`。此后启动的容器内的网口也会自动分配一个同一网段(`172.17.0.0/16`)的地址。 +同时,Docker 随机分配一个本地未占用的私有网段(在 [RFC1918](https://datatracker.ietf.org/doc/html/rfc1918) 中定义)中的一个地址给 `docker0` 接口。比如典型的 `172.17.42.1`,掩码为 `255.255.0.0`。此后启动的容器内的网口也会自动分配一个同一网段(`172.17.0.0/16`)的地址。 当创建一个 Docker 容器的时候,同时会创建了一对 `veth pair` 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 `eth0`;另一端在本地并被挂载到 `docker0` 网桥,名称以 `veth` 开头(例如 `vethAQI2QT`)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。 diff --git a/basic_concept/repository.md b/basic_concept/repository.md index 69175628d..29716c9ed 100644 --- a/basic_concept/repository.md +++ b/basic_concept/repository.md @@ -14,7 +14,7 @@ Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 -最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的 [官方镜像](https://hub.docker.com/search?q=&type=image&image_filter=official)。除此以外,还有 Red Hat 的 [Quay.io](https://quay.io/repository/);Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务;代码托管平台 [GitHub](https://github.com) 推出的 [ghcr.io](https://docs.github.com/cn/packages/guides/about-github-container-registry)。 +最常使用的 Registry 公开服务是官方的 [Docker Hub](https://hub.docker.com/),这也是默认的 Registry,并拥有大量的高质量的 [官方镜像](https://hub.docker.com/search?q=&type=image&image_filter=official)。除此以外,还有 Red Hat 的 [Quay.io](https://quay.io/repository/);Google 的 [Google Container Registry](https://cloud.google.com/container-registry/),[Kubernetes](https://kubernetes.io/) 的镜像使用的就是这个服务;代码托管平台 [GitHub](https://github.com) 推出的 [ghcr.io](https://docs.github.com/cn/packages/working-with-a-github-packages-registry/working-with-the-container-registry)。 由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(`Registry Mirror`),这些镜像服务被称为 **加速器**。常见的有 [阿里云加速器](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu)、[DaoCloud 加速器](https://www.daocloud.io/mirror#accelerator-doc) 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。在 [安装 Docker](../install/mirror.md) 一节中有详细的配置方法。 diff --git a/repository/nexus3_registry.md b/repository/nexus3_registry.md index 65184cbbf..de3c0d524 100644 --- a/repository/nexus3_registry.md +++ b/repository/nexus3_registry.md @@ -1,6 +1,6 @@ # Nexus3.x 的私有仓库 -使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry。在企业中把内部的一些工具包放入 `Nexus` 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/nexus/repository-oss-download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 +使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry。在企业中把内部的一些工具包放入 `Nexus` 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/product/repository-oss-download) 一个软件来管理 `Docker` , `Maven` , `Yum` , `PyPI` 等是一个明智的选择。 ## 启动 Nexus 容器 From 95aed0099e95c0002073b165d8c4011af1e605d3 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 15 Jul 2021 13:29:08 +0800 Subject: [PATCH 174/201] Update minio case Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 2 +- appendix/repo/minio.md | 36 ++++++++++++++------------------ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index e0fff2978..0a1080da2 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -58,7 +58,7 @@ jobs: "product.china-pub.com",\ "union-click.jd.com",\ "x.x.x.x/base",\ - "x.x.x.x:9000/minio/",\ + "x.x.x.x:9090",\ "yeasy.gitbooks.io",\ "download.fastgit.org",\ "www.aliyun.com" \ diff --git a/appendix/repo/minio.md b/appendix/repo/minio.md index c36d02d5d..627100d38 100644 --- a/appendix/repo/minio.md +++ b/appendix/repo/minio.md @@ -1,8 +1,8 @@ # minio -[TOC] -MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。 -MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。 +**MinIO** 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几 kb 到最大 5T 不等。 + +MinIO 是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。 [官方文档](https://docs.min.io/) @@ -11,12 +11,9 @@ MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合 测试、开发环境下不考虑数据存储的情况下可以使用下面的命令快速开启服务。 ```bash -docker pull minio/minio -docker run -p 9000:9000 minio/minio server /data +$ docker run -d -p 9000:9000 -p 9090:9090 minio/minio server /data --console-address ':9090' ``` - - ## 离线部署 许多生产环境是一般是没有公网资源的,这就需要从有公网资源的服务器上把镜像导出,然后导入到需要运行镜像的内网服务器。 @@ -26,37 +23,36 @@ docker run -p 9000:9000 minio/minio server /data 在有公网资源的服务器上下载好`minio/minio`镜像 ```bash -docker save -o minio.tar minio/minio:latest +$ docker save -o minio.tar minio/minio:latest ``` - +> 使用docker save 的时候,也可以使用image id 来导出,但是那样导出的时候,就会丢失原来的镜像名称,推荐,还是使用镜像名字+tag来导出镜像 ### 导入镜像 把压缩文件复制到内网服务器上,使用下面的命令导入镜像 ```bash -docker load minio.tar +$ docker load minio.tar ``` ### 运行 minio -- 把/mnt/data 改成要替换的数据目录 -- 替换 MINIO_ACCESS_KEY -- 替换 MINIO_SECRET_KEY +- 把 `/mnt/data` 改成要替换的数据目录 +- 替换 `MINIO_ROOT_USER` 的值 +- 替换 `MINIO_ROOT_PASSWORD` 的值 - 替换 name,minio1(可选) -- 如果9000端口冲突,替换端口前面的如:9009:9000 +- 如果 9000、9090 端口冲突,替换端口前面的如 `9009:9000` ```bash -sudo docker run -d -p 9000:9000 --name minio1 \ - -e "MINIO_ACCESS_KEY=改成自己需要的" \ - -e "MINIO_SECRET_KEY=改成自己需要的" \ +$ sudo docker run -d -p 9000:9000 -p 9090:9090 --name minio1 \ + -e "MINIO_ROOT_USER=改成自己需要的" \ + -e "MINIO_ROOT_PASSWORD=改成自己需要的" \ -v /mnt/data:/data \ --restart=always \ - minio/minio server /data + minio/minio server /data --console-address ':9090' ``` ### 访问 web 管理页面 -http://x.x.x.x:9000/minio/ - +http://x.x.x.x:9090 From 5caddf44134f273618ae752bbb1bdf10ad575074 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 16 Jul 2021 12:25:33 +0800 Subject: [PATCH 175/201] [Kubernetes] kubeadm cri based containerd Signed-off-by: Kang Huaishuai --- SUMMARY.md | 2 +- kubernetes/setup/kubeadm-docker.md | 187 ++++++++++++++++++++++++ kubernetes/setup/kubeadm.md | 226 ++++++++++++++++++++++++++++- 3 files changed, 406 insertions(+), 9 deletions(-) create mode 100644 kubernetes/setup/kubeadm-docker.md diff --git a/SUMMARY.md b/SUMMARY.md index c906a784a..42929a977 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -126,7 +126,7 @@ * [基本概念](kubernetes/concepts.md) * [架构设计](kubernetes/design.md) * [部署 Kubernetes](kubernetes/setup/README.md) - * [使用 kubeadm 部署 kubernetes](kubernetes/setup/kubeadm.md) + * [使用 kubeadm 部署 kubernetes(CRI 使用 containerd)](kubernetes/setup/kubeadm.md) * [在 Docker Desktop 使用](kubernetes/setup/docker-desktop.md) * [一步步部署 kubernetes 集群](kubernetes/setup/systemd.md) * [部署 Dashboard](kubernetes/setup/dashboard.md) diff --git a/kubernetes/setup/kubeadm-docker.md b/kubernetes/setup/kubeadm-docker.md new file mode 100644 index 000000000..9f5b0a222 --- /dev/null +++ b/kubernetes/setup/kubeadm-docker.md @@ -0,0 +1,187 @@ +# 使用 kubeadm 部署 kubernetes(使用 Docker) + +`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `kubernetes` 集群的最佳实践。 + +## 安装 Docker + +参考 [安装 Docker](../../install) 一节安装 Docker。 + +## 安装 **kubelet** **kubeadm** **kubectl** + +### Ubuntu/Debian + +```bash +$ apt-get update && apt-get install -y apt-transport-https +$ curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - + +$ cat < 执行可能出现错误,例如缺少依赖包,根据提示安装即可。 + +执行成功会输出 + +```bash +... +[addons] Applied essential addon: CoreDNS +I1116 12:35:13.270407 86677 request.go:538] Throttling request took 181.409184ms, request: POST:https://192.168.199.100:6443/api/v1/namespaces/kube-system/serviceaccounts +I1116 12:35:13.470292 86677 request.go:538] Throttling request took 186.088112ms, request: POST:https://192.168.199.100:6443/api/v1/namespaces/kube-system/configmaps +[addons] Applied essential addon: kube-proxy + +Your Kubernetes control-plane has initialized successfully! + +To start using your cluster, you need to run the following as a regular user: + + mkdir -p $HOME/.kube + sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config + sudo chown $(id -u):$(id -g) $HOME/.kube/config + +You should now deploy a pod network to the cluster. +Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: + https://kubernetes.io/docs/concepts/cluster-administration/addons/ + +Then you can join any number of worker nodes by running the following on each as root: + +kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ + --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe +``` + +### node 工作节点 + +在 **另一主机** 重复 **部署** 小节以前的步骤,安装配置好 kubelet。根据提示,加入到集群。 + +```bash +$ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ + --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe +``` + +## 查看服务 + +所有服务启动后,查看本地实际运行的 Docker 容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 + +### 主节点服务 + +* `apiserver` 是整个系统的对外接口,提供 RESTful 方式供客户端和其它组件调用; + +* `scheduler` 负责对资源进行调度,分配某个 pod 到某个节点上; + +* `controller-manager` 负责管理控制器,包括 endpoint-controller(刷新服务和 pod 的关联信息)和 replication-controller(维护某个 pod 的复制为配置的数值)。 + +### 工作节点服务 + +* `proxy` 为 pod 上的服务提供访问的代理。 + +### 其它服务 + +* Etcd 是所有状态的存储数据库; + +## 使用 + +将 `/etc/kubernetes/admin.conf` 复制到 `~/.kube/config` + +执行 `$ kubectl get all -A` 查看启动的服务。 + +由于未部署 CNI 插件,CoreDNS 未正常启动。如何使用 Kubernetes,请参考后续章节。 + +## 部署 CNI + +这里以 `flannel` 为例进行介绍。 + +### flannel + +检查 podCIDR 设置 + +```bash +$ kubectl get node -o yaml | grep CIDR + +# 输出 + podCIDR: 10.244.0.0/16 + podCIDRs: +``` + +```bash +$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.11.0/Documentation/kube-flannel.yml +``` + +## master 节点默认不能运行 pod + +如果用 `kubeadm` 部署一个单节点集群,默认情况下无法使用,请执行以下命令解除限制 + +```bash +$ kubectl taint nodes --all node-role.kubernetes.io/master- + +# 恢复默认值 +# $ kubectl taint nodes NODE_NAME node-role.kubernetes.io/master=true:NoSchedule +``` + +## 参考文档 + +* [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) diff --git a/kubernetes/setup/kubeadm.md b/kubernetes/setup/kubeadm.md index 6d2afb87a..6176d6ce6 100644 --- a/kubernetes/setup/kubeadm.md +++ b/kubernetes/setup/kubeadm.md @@ -1,12 +1,205 @@ -# 使用 kubeadm 部署 kubernetes +# 使用 kubeadm 部署 kubernetes(CRI 使用 containerd) `kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `kubernetes` 集群的最佳实践。 -## 安装 Docker +## 安装 containerd -参考 [安装 Docker](../../install) 一节安装 Docker。 +参考 [安装 Docker](../../install) 一节添加 apt/yum 源,之后执行如下命令。 -## 安装 **kubelet** **kubeadm** **kubectl** +```bash +# debian 系 +$ sudo apt install containerd.io + +# rhel 系 +$ sudo yum install containerd.io +``` + +## 配置 containerd + +新建 `/etc/systemd/system/cri-containerd.service` 文件 + +``` +[Unit] +Description=containerd container runtime for kubernetes +Documentation=https://containerd.io +After=network.target local-fs.target + +[Service] +ExecStartPre=-/sbin/modprobe overlay +ExecStart=/usr/bin/containerd --config //etc/cri-containerd/config.toml + +Type=notify +Delegate=yes +KillMode=process +Restart=always +RestartSec=5 +# Having non-zero Limit*s causes performance problems due to accounting overhead +# in the kernel. We recommend using cgroups to do container-local accounting. +LimitNPROC=infinity +LimitCORE=infinity +LimitNOFILE=infinity +# Comment TasksMax if your systemd version does not supports it. +# Only systemd 226 and above support this version. +TasksMax=infinity +OOMScoreAdjust=-999 + +[Install] +WantedBy=multi-user.target +``` + +新建 `/etc/cri-containerd/config.toml` containerd 配置文件 + +```toml +version = 2 +# persistent data location +root = "/var/lib/cri-containerd" +# runtime state information +state = "/run/cri-containerd" +plugin_dir = "" +disabled_plugins = [] +required_plugins = [] +# set containerd's OOM score +oom_score = 0 + +[grpc] + address = "/run/cri-containerd/cri-containerd.sock" + tcp_address = "" + tcp_tls_cert = "" + tcp_tls_key = "" + # socket uid + uid = 0 + # socket gid + gid = 0 + max_recv_message_size = 16777216 + max_send_message_size = 16777216 + +[debug] + address = "" + format = "json" + uid = 0 + gid = 0 + level = "" + +[metrics] + address = "127.0.0.1:1338" + grpc_histogram = false + +[cgroup] + path = "" + +[timeouts] + "io.containerd.timeout.shim.cleanup" = "5s" + "io.containerd.timeout.shim.load" = "5s" + "io.containerd.timeout.shim.shutdown" = "3s" + "io.containerd.timeout.task.state" = "2s" + +[plugins] + [plugins."io.containerd.gc.v1.scheduler"] + pause_threshold = 0.02 + deletion_threshold = 0 + mutation_threshold = 100 + schedule_delay = "0s" + startup_delay = "100ms" + [plugins."io.containerd.grpc.v1.cri"] + disable_tcp_service = true + stream_server_address = "127.0.0.1" + stream_server_port = "0" + stream_idle_timeout = "4h0m0s" + enable_selinux = false + selinux_category_range = 1024 + sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5" + stats_collect_period = 10 + # systemd_cgroup = false + enable_tls_streaming = false + max_container_log_line_size = 16384 + disable_cgroup = false + disable_apparmor = false + restrict_oom_score_adj = false + max_concurrent_downloads = 3 + disable_proc_mount = false + unset_seccomp_profile = "" + tolerate_missing_hugetlb_controller = true + disable_hugetlb_controller = true + ignore_image_defined_volumes = false + [plugins."io.containerd.grpc.v1.cri".containerd] + snapshotter = "overlayfs" + default_runtime_name = "runc" + no_pivot = false + disable_snapshot_annotations = false + discard_unpacked_layers = false + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + runtime_type = "io.containerd.runc.v2" + pod_annotations = [] + container_annotations = [] + privileged_without_host_devices = false + base_runtime_spec = "" + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] + # SystemdCgroup enables systemd cgroups. + SystemdCgroup = true + # BinaryName is the binary name of the runc binary. + # BinaryName = "runc" + # BinaryName = "crun" + # NoPivotRoot disables pivot root when creating a container. + # NoPivotRoot = false + + # NoNewKeyring disables new keyring for the container. + # NoNewKeyring = false + + # ShimCgroup places the shim in a cgroup. + # ShimCgroup = "" + + # IoUid sets the I/O's pipes uid. + # IoUid = 0 + + # IoGid sets the I/O's pipes gid. + # IoGid = 0 + + # Root is the runc root directory. + Root = "" + + # CriuPath is the criu binary path. + # CriuPath = "" + + # CriuImagePath is the criu image path + # CriuImagePath = "" + + # CriuWorkPath is the criu work path. + # CriuWorkPath = "" + [plugins."io.containerd.grpc.v1.cri".cni] + bin_dir = "/opt/cni/bin" + conf_dir = "/etc/cni/net.d" + max_conf_num = 1 + conf_template = "" + [plugins."io.containerd.grpc.v1.cri".registry] + config_path = "/etc/cri-containerd/certs.d" + [plugins."io.containerd.grpc.v1.cri".registry.headers] + # Foo = ["bar"] + [plugins."io.containerd.grpc.v1.cri".image_decryption] + key_model = "" + [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming] + tls_cert_file = "" + tls_key_file = "" + [plugins."io.containerd.internal.v1.opt"] + path = "/opt/cri-containerd" + [plugins."io.containerd.internal.v1.restart"] + interval = "10s" + [plugins."io.containerd.metadata.v1.bolt"] + content_sharing_policy = "shared" + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + [plugins."io.containerd.service.v1.diff-service"] + default = ["walking"] + [plugins."io.containerd.snapshotter.v1.devmapper"] + root_path = "" + pool_name = "" + base_image_size = "" + async_remove = false +``` + +## 安装 **kubelet** **kubeadm** **kubectl** **cri-tools** **kubernetes-cni** ### Ubuntu/Debian @@ -77,8 +270,14 @@ $ sudo systemctl daemon-reload ### master ```bash -$ sudo kubeadm init --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ +$ systemctl enable cri-containerd + +$ systemctl start cri-containerd + +$ sudo kubeadm init \ + --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --pod-network-cidr 10.244.0.0/16 \ + --cri-socket /run/cri-containerd/cri-containerd.sock \ --v 5 \ --ignore-preflight-errors=all ``` @@ -119,13 +318,23 @@ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ 在 **另一主机** 重复 **部署** 小节以前的步骤,安装配置好 kubelet。根据提示,加入到集群。 ```bash -$ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \ - --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe +$ systemctl enable cri-containerd + +$ systemctl start cri-containerd + +$ kubeadm join 192.168.199.100:6443 \ + --token cz81zt.orsy9gm9v649e5lf \ + --discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe \ + --cri-socket /run/cri-containerd/cri-containerd.sock ``` ## 查看服务 -所有服务启动后,查看本地实际运行的 Docker 容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 +所有服务启动后,通过 `crictl` 查看本地实际运行的容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。 + +```bash +CONTAINER_RUNTIME_ENDPOINT=/run/cri-containerd/cri-containerd.sock crictl ps -a +``` ### 主节点服务 @@ -185,3 +394,4 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master- ## 参考文档 * [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) +* [Container runtimes](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd) From 8dfdbc5b076067c5c6be591cf1cb0cee34a4eaab Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 16 Jul 2021 12:33:01 +0800 Subject: [PATCH 176/201] remove docker search Signed-off-by: Kang Huaishuai --- cases/os/busybox.md | 16 +--------------- cases/os/centos.md | 20 -------------------- cases/os/debian.md | 40 +--------------------------------------- 3 files changed, 2 insertions(+), 74 deletions(-) diff --git a/cases/os/busybox.md b/cases/os/busybox.md index ddf59229e..a2a81eae6 100644 --- a/cases/os/busybox.md +++ b/cases/os/busybox.md @@ -10,21 +10,7 @@ ## 获取官方镜像 -在 `Docker Hub` 中搜索 `busybox` 相关的镜像。 - -```bash -$ docker search busybox -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -busybox Busybox base image. 755 [OK] -progrium/busybox 63 [OK] -radial/busyboxplus Full-chain, Internet enabled, busybox made... 11 [OK] -odise/busybox-python 3 [OK] -multiarch/busybox multiarch ports of ubuntu-debootstrap 2 [OK] -azukiapp/busybox This image is meant to be used as the base... 2 [OK] -... -``` - -读者可以看到最受欢迎的镜像同时带有 `OFFICIAL` 标记,说明它是官方镜像。用户使用 `docker pull` 指令下载 `busybox:latest` 镜像: +可以使用 `docker pull` 指令下载 `busybox:latest` 镜像: ```bash $ docker pull busybox:latest diff --git a/cases/os/centos.md b/cases/os/centos.md index bc32c99f8..f2107f0c7 100644 --- a/cases/os/centos.md +++ b/cases/os/centos.md @@ -10,15 +10,6 @@ CentOS(Community Enterprise Operating System,中文意思是:社区企业 ### 使用 CentOS 官方镜像 -首先使用 `docker search` 命令来搜索标星至少为 `25` 的 `CentOS` 相关镜像。 - -```bash -$ docker search -f stars=25 centos -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -centos The official... 2543 [OK] -jdeathe/centos-ssh 27 [OK] -``` - 使用 `docker run` 直接运行最新的 `CentOS` 镜像,并登录 `bash`。 ```bash @@ -40,17 +31,6 @@ CentOS Linux release 7.2.1511 (Core) ### 使用 Fedora 官方镜像 -首先使用 `docker search` 命令来搜索标星至少为 `2` 的 `Fedora` 相关镜像,结果如下。 - -```bash -$ docker search -f stars=2 fedora -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -fedora Official Docker builds of Fedora 433 [OK] -dockingbay/fedora-rust Trusted build of Rust programming language... 3 [OK] -gluster/gluster-fedora Official GlusterFS image [ Fedora 21 + Glu... 3 [OK] -startx/fedora Simple container used for all startx based... 2 [OK] -``` - 使用 `docker run` 命令直接运行 `Fedora` 官方镜像,并登录 `bash`。 ```bash diff --git a/cases/os/debian.md b/cases/os/debian.md index df640c147..e9da8eb35 100644 --- a/cases/os/debian.md +++ b/cases/os/debian.md @@ -14,20 +14,7 @@ ### 使用 Debian 官方镜像 -读者可以使用 `docker search` 查找 `Debian` 镜像: - -```bash -$ docker search debian -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -debian Debian is... 1565 [OK] -neurodebian NeuroDebian... 26 [OK] -armbuild/debian port of debian 8 [OK] -... -``` - -官方提供了大家熟知的 `debian` 镜像以及面向科研领域的 `neurodebian` 镜像。 - -可以使用 `docker run` 直接运行 `Debian` 镜像。 +官方提供了大家熟知的 `debian` 镜像以及面向科研领域的 `neurodebian` 镜像。可以使用 `docker run` 直接运行 `Debian` 镜像。 ```bash $ docker run -it debian bash @@ -45,31 +32,6 @@ Debian GNU/Linux 8 ### 使用 Ubuntu 官方镜像 -`Ubuntu` 相关的镜像有很多,这里使用 `--filter=stars=10` 参数,只搜索那些被收藏 `10` 次以上的镜像。 - -```bash -$ docker search --filter=stars=10 ubuntu - -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -ubuntu Ubuntu is a Debian-based Linux operating sys… 10539 [OK] -dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 395 [OK] -rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 243 [OK] -consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 210 [OK] -ubuntu-upstart Upstart is an event-based replacement for th… 105 [OK] -ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with ansible 98 [OK] -neurodebian NeuroDebian provides neuroscience research s… 64 [OK] -1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5 ubuntu-16-nginx-php-phpmyadmin-mysql-5 50 [OK] -ubuntu-debootstrap debootstrap --variant=minbase --components=m… 42 [OK] -nuagebec/ubuntu Simple always updated Ubuntu docker images w… 24 [OK] -i386/ubuntu Ubuntu is a Debian-based Linux operating sys… 19 -1and1internet/ubuntu-16-apache-php-5.6 ubuntu-16-apache-php-5.6 14 [OK] -1and1internet/ubuntu-16-apache-php-7.0 ubuntu-16-apache-php-7.0 13 [OK] -eclipse/ubuntu_jdk8 Ubuntu, JDK8, Maven 3, git, curl, nmap, mc, … 12 [OK] -1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10 ubuntu-16-nginx-php-phpmyadmin-mariadb-10 11 [OK] -``` - -根据搜索出来的结果,读者可以自行选择下载镜像并使用。 - 下面以 `ubuntu:18.04` 为例,演示如何使用该镜像安装一些常用软件。 首先使用 `-ti` 参数启动容器,登录 `bash`,查看 `ubuntu` 的发行版本号。 From d4fc0a9da1469a9c57b56582d486f0375e4b889e Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 16 Jul 2021 12:43:50 +0800 Subject: [PATCH 177/201] remove deprecated features: machine and swarm Signed-off-by: Kang Huaishuai --- .github/workflows/check-link.yml | 3 +- .github/workflows/ci.yaml | 2 +- SUMMARY.md | 5 -- archive/README.md | 6 +- machine/README.md | 9 -- machine/install.md | 33 ------- machine/usage.md | 149 ------------------------------- manifest | 1 - swarm/README.md | 7 -- swarm_mode/create.md | 36 +------- 10 files changed, 9 insertions(+), 242 deletions(-) delete mode 100644 machine/README.md delete mode 100644 machine/install.md delete mode 100644 machine/usage.md delete mode 100644 swarm/README.md diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 0a1080da2..e6546e8db 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -25,7 +25,6 @@ jobs: "192.168.199.100",\ "github.com/settings",\ "github.com/docker/compose/releases/download",\ - "github.com/docker/machine/releases/download",\ "github.com/etcd-io/etcd/releases/download",\ "github.com/tianon/gosu/releases/download",\ "github.com/yeasy/docker_practice",\ @@ -65,6 +64,6 @@ jobs: --allow-dupe \ --skip-save-results \ -t 10 \ - `find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" \) -prune -o -name "*.md" -exec ls {} \;` + `find . \( -path "./mesos" -o -path "./swarm_mode" \) -prune -o -name "*.md" -exec ls {} \;` name: check-link timeout-minutes: 25 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c44061170..13c7206ad 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -75,7 +75,7 @@ jobs: git clone https://github.com/docker-practice/.vuepress .vuepress2 cp -r .vuepress2/. .vuepress/ rm -rf .vuepress2 - find . \( -path "./mesos" -o -path "./machine" -o -path "./swarm_mode" -o -path "./node_modules" -o -path "./.vuepress" -o -path "./_book" -o -path "./CHANGELOG.md" -o -path "./CONTRIBUTING.md" \) -prune -o -name "*.md" -exec sed -i 'N;2a\\n' {} \; + find . \( -path "./mesos" -o -path "./swarm_mode" -o -path "./node_modules" -o -path "./.vuepress" -o -path "./_book" -o -path "./CHANGELOG.md" -o -path "./CONTRIBUTING.md" \) -prune -o -name "*.md" -exec sed -i 'N;2a\\n' {} \; npx vuepress --version diff --git a/SUMMARY.md b/SUMMARY.md index 42929a977..4fd7b80c4 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -169,8 +169,3 @@ * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) -* [归档](archive/README.md) - * [Docker Machine](machine/README.md) - * [安装](machine/install.md) - * [使用](machine/usage.md) - * [Docker Swarm](swarm/README.md) diff --git a/archive/README.md b/archive/README.md index 5f748758a..00aa7b45f 100644 --- a/archive/README.md +++ b/archive/README.md @@ -1,7 +1,7 @@ # 归档项目 -以下项目不被官方支持或内容陈旧,将在下一版本中删除。 +以下项目不被官方支持或内容陈旧,将在下一版本中删除(或已经删除)。 -* Docker Machine +* [Docker Machine](https://github.com/yeasy/docker_practice/tree/ca29ab51b121f43563f5d6659dedbda5cb6f048d/machine) +* [Docker Swarm](https://github.com/yeasy/docker_practice/tree/ca29ab51b121f43563f5d6659dedbda5cb6f048d/swarm) * Mesos -* Docker Swarm diff --git a/machine/README.md b/machine/README.md deleted file mode 100644 index ebc1c3e21..000000000 --- a/machine/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Docker Machine 项目 - -![](https://docs.docker.com/machine/img/machine.png) - -Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境。 - -Docker Machine 项目基于 Go 语言实现,目前在 [Github](https://github.com/docker/machine) 上进行维护。 - -本章将介绍 Docker Machine 的安装及使用。 diff --git a/machine/install.md b/machine/install.md deleted file mode 100644 index 24afd532a..000000000 --- a/machine/install.md +++ /dev/null @@ -1,33 +0,0 @@ -## 安装 - -Docker Machine 可以在多种操作系统平台上安装,包括 Linux、macOS,以及 Windows。 - -### macOS、Windows - -`Docker Desktop for Mac/Windows` 自带 `docker-machine` 二进制包,安装之后即可使用。 - -查看版本信息。 - -```bash -$ docker-machine -v -docker-machine version 0.16.1, build cce350d7 -``` - -### Linux - -在 Linux 上的也安装十分简单,从 [官方 GitHub Release](https://github.com/docker/machine/releases) 处直接下载编译好的二进制文件即可。 - -例如,在 Linux 64 位系统上直接下载对应的二进制包。 - -```bash -$ sudo curl -L https://github.com/docker/machine/releases/download/v0.16.1/docker-machine-`uname -s`-`uname -m` > /usr/local/bin/docker-machine - -$ sudo chmod +x /usr/local/bin/docker-machine -``` - -完成后,查看版本信息。 - -```bash -$ docker-machine -v -docker-machine version 0.16.1, build cce350d7 -``` diff --git a/machine/usage.md b/machine/usage.md deleted file mode 100644 index a790f8ce4..000000000 --- a/machine/usage.md +++ /dev/null @@ -1,149 +0,0 @@ -## 使用 - -Docker Machine 支持多种后端驱动,包括虚拟机、本地主机和云平台等。 - -### 创建本地主机实例 - -#### Virtualbox 驱动 - -使用 `virtualbox` 类型的驱动,创建一台 Docker 主机,命名为 test。 - -```bash -$ docker-machine create -d virtualbox test -``` - -你也可以在创建时加上如下参数,来配置主机或者主机上的 Docker。 - -`--engine-opt dns=114.114.114.114` 配置 Docker 的默认 DNS - -`--engine-registry-mirror https://hub-mirror.c.163.com` 配置 Docker 的仓库镜像 - -`--virtualbox-memory 2048` 配置主机内存 - -`--virtualbox-cpu-count 2` 配置主机 CPU - -更多参数请使用 `docker-machine create --driver virtualbox --help` 命令查看。 - -#### macOS xhyve 驱动 - -`xhyve` 驱动 GitHub: https://github.com/zchee/docker-machine-driver-xhyve - -[`xhyve`](https://github.com/mist64/xhyve) 是 macOS 上轻量化的虚拟引擎,使用其创建的 Docker Machine 较 `VirtualBox` 驱动创建的运行效率要高。 - -```bash -$ brew install docker-machine-driver-xhyve - -$ docker-machine create \ - -d xhyve \ - # --xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso \ - --engine-opt dns=114.114.114.114 \ - --engine-registry-mirror https://hub-mirror.c.163.com \ - --xhyve-memory-size 2048 \ - --xhyve-rawdisk \ - --xhyve-cpu-count 2 \ - xhyve -``` - ->注意:非首次创建时建议加上 `--xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso` 参数,避免每次创建时都从 GitHub 下载 ISO 镜像。 - -更多参数请使用 `docker-machine create --driver xhyve --help` 命令查看。 - -#### Windows 10 - -Windows 10 安装 Docker Desktop for Windows 之后不能再安装 VirtualBox,也就不能使用 `virtualbox` 驱动来创建 Docker Machine,我们可以选择使用 `hyperv` 驱动。 - -> 注意,必须事先在 `Hyper-V` 管理器中新建一个 **外部虚拟交换机** 执行下面的命令时,使用 `--hyperv-virtual-switch=MY_SWITCH` 指定虚拟交换机名称 - -```bash -$ docker-machine create --driver hyperv --hyperv-virtual-switch=MY_SWITCH vm -``` - -更多参数请使用 `docker-machine create --driver hyperv --help` 命令查看。 - -### 使用介绍 - -创建好主机之后,查看主机 - -```bash -$ docker-machine ls - -NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS -test - virtualbox Running tcp://192.168.99.187:2376 v17.10.0-ce -``` - -创建主机成功后,可以通过 `env` 命令来让后续操作对象都是目标主机。 - -```bash -$ docker-machine env test -``` - -后续根据提示在命令行输入命令之后就可以操作 test 主机。 - -也可以通过 `SSH` 登录到主机。 - -```bash -$ docker-machine ssh test - -docker@test:~$ docker --version -Docker version 17.10.0-ce, build f4ffd25 -``` - -连接到主机之后你就可以在其上使用 Docker 了。 - -### 官方支持驱动 - -通过 `-d` 选项可以选择支持的驱动类型。 - -* amazonec2 -* azure -* digitalocean -* exoscale -* generic -* google -* hyperv -* none -* openstack -* rackspace -* softlayer -* virtualbox -* vmwarevcloudair -* vmwarefusion -* vmwarevsphere - -### 第三方驱动 - -请到 [第三方驱动列表](https://github.com/docker/docker.github.io/blob/master/machine/AVAILABLE_DRIVER_PLUGINS.md) 查看 - - -### 操作命令 - -* `active` 查看活跃的 Docker 主机 -* `config` 输出连接的配置信息 -* `create` 创建一个 Docker 主机 -* `env` 显示连接到某个主机需要的环境变量 -* `inspect` 输出主机更多信息 -* `ip` 获取主机地址 -* `kill` 停止某个主机 -* `ls` 列出所有管理的主机 -* `provision` 重新设置一个已存在的主机 -* `regenerate-certs` 为某个主机重新生成 TLS 认证信息 -* `restart` 重启主机 -* `rm` 删除某台主机 -* `ssh` SSH 到主机上执行命令 -* `scp` 在主机之间复制文件 -* `mount` 挂载主机目录到本地 -* `start` 启动一个主机 -* `status` 查看主机状态 -* `stop` 停止一个主机 -* `upgrade` 更新主机 Docker 版本为最新 -* `url` 获取主机的 URL -* `version` 输出 docker-machine 版本信息 -* `help` 输出帮助信息 - -每个命令,又带有不同的参数,可以通过 - -```bash -$ docker-machine COMMAND --help -``` - -来查看具体的用法。 diff --git a/manifest b/manifest index 107f15ce2..ba77f7836 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,5 @@ DOCKER_VERSION=20.10.0 DOCKER_COMPOSE_VERSION=1.27.4 -DOCKER_MACHINE_VERSION=0.16.1 ETCD_VERSION=3.4.0 KUBERNETES_VERSION=1.14.3 KUBERNETES_DASHBOARD=2.0.0 diff --git a/swarm/README.md b/swarm/README.md deleted file mode 100644 index 5518654f9..000000000 --- a/swarm/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Docker 三剑客之 Docker Swarm - -Docker Swarm 是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。 - -使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。 - -注意:Docker 1.12.0+ [Swarm mode](https://docs.docker.com/engine/swarm/) 已经内嵌入 Docker 引擎,成为了 docker 子命令 `docker swarm`,绝大多数用户已经开始使用 `Swarm mode`,Docker 引擎 API 已经删除 Docker Swarm。为避免大家混淆旧的 `Docker Swarm` 与新的 `Swarm mode`,旧的 `Docker Swarm` 内容已经删除,请查看 `Swarm mode` 一节。 diff --git a/swarm_mode/create.md b/swarm_mode/create.md index 91391242a..c40a7cc93 100644 --- a/swarm_mode/create.md +++ b/swarm_mode/create.md @@ -4,20 +4,10 @@ ## 初始化集群 -在 [`Docker Machine`](../machine) 一节中我们了解到 `Docker Machine` 可以在数秒内创建一个虚拟的 Docker 主机,下面我们使用它来创建三个 Docker 主机,并加入到集群中。 - -我们首先创建一个 Docker 主机作为管理节点。 - -```bash -$ docker-machine create -d virtualbox manager -``` - -我们使用 `docker swarm init` 在管理节点初始化一个 `Swarm` 集群。 +在已经安装好 Docker 的主机上执行如下命令: ```bash -$ docker-machine ssh manager - -docker@manager:~$ docker swarm init --advertise-addr 192.168.99.100 +$ docker swarm init --advertise-addr 192.168.99.100 Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager. To add a worker to this swarm, run the following command: @@ -35,34 +25,16 @@ To add a manager to this swarm, run 'docker swarm join-token manager' and follow ## 增加工作节点 -上一步我们初始化了一个 `Swarm` 集群,拥有了一个管理节点,下面我们继续创建两个 Docker 主机作为工作节点,并加入到集群中。 - -```bash -$ docker-machine create -d virtualbox worker1 - -$ docker-machine ssh worker1 - -docker@worker1:~$ docker swarm join \ - --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ - 192.168.99.100:2377 - -This node joined a swarm as a worker. -``` +上一步我们初始化了一个 `Swarm` 集群,拥有了一个管理节点,下面我们继续在两个 Docker 主机中分别执行如下命令,创建工作节点并加入到集群中。 ```bash -$ docker-machine create -d virtualbox worker2 - -$ docker-machine ssh worker2 - -docker@worker1:~$ docker swarm join \ +$ docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 This node joined a swarm as a worker. ``` ->注意:一些细心的读者可能通过 `docker-machine create --help` 查看到 `--swarm*` 等一系列参数。该参数是用于旧的 `Docker Swarm`,与本章所讲的 `Swarm mode` 没有关系。 - ## 查看集群 经过上边的两步,我们已经拥有了一个最小的 `Swarm` 集群,包含一个管理节点和两个工作节点。 From d1d4f0f47d9fec18404070c3019385fce666f705 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Fri, 16 Jul 2021 12:46:38 +0800 Subject: [PATCH 178/201] Update link Signed-off-by: Kang Huaishuai --- .vuepress/config.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.vuepress/config.js b/.vuepress/config.js index 3d0f6d169..e47b3fde1 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -141,9 +141,8 @@ module.exports = config({ // link: '' // }, { - text: '云服务器618特惠', - //link: 'https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console' - link: 'https://cloud.tencent.com/act/cps/redirect?redirect=10488&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=activity' + text: '云服务器99/元首年特惠', + link: 'https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=3a5255852d5db99dcd5da4c72f05df61&from=console' }, // { // text: '语言', From a613c78c333d39c50195d80d99a4eb22f0c43073 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 19 Sep 2021 17:58:20 +0800 Subject: [PATCH 179/201] [Drone] update to v2 Signed-off-by: Kang Huaishuai --- cases/ci/drone/docker-compose.yml | 3 +-- cases/ci/drone/install.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cases/ci/drone/docker-compose.yml b/cases/ci/drone/docker-compose.yml index 8ef416bad..2c04ee9d8 100644 --- a/cases/ci/drone/docker-compose.yml +++ b/cases/ci/drone/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: drone-server: - image: drone/drone:1 + image: drone/drone:2.3.1 ports: - 443:443 - 80:80 @@ -12,7 +12,6 @@ services: - ./ssl:/etc/certs restart: always environment: - - DRONE_AGENTS_ENABLED=true - DRONE_SERVER_HOST=${DRONE_SERVER_HOST:-drone.domain.com} - DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO:-https} - DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret} diff --git a/cases/ci/drone/install.md b/cases/ci/drone/install.md index 3d94ee5c1..124bafa57 100644 --- a/cases/ci/drone/install.md +++ b/cases/ci/drone/install.md @@ -30,7 +30,7 @@ version: '3' services: drone-server: - image: drone/drone:1 + image: drone/drone:2.3.1 ports: - 443:443 - 80:80 @@ -39,7 +39,6 @@ services: - ./ssl:/etc/certs restart: always environment: - - DRONE_AGENTS_ENABLED=true - DRONE_SERVER_HOST=${DRONE_SERVER_HOST:-https://drone.yeasy.com} - DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO:-https} - DRONE_RPC_SECRET=${DRONE_RPC_SECRET:-secret} From d5ce7f048b7a6606172dfeb177a3b1b635f03346 Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Sun, 19 Sep 2021 18:28:22 +0800 Subject: [PATCH 180/201] Update DD download link Signed-off-by: Kang Huaishuai --- install/mac.md | 4 ++-- install/windows.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/install/mac.md b/install/mac.md index 562631e6b..510d7354a 100644 --- a/install/mac.md +++ b/install/mac.md @@ -16,9 +16,9 @@ $ brew install --cask docker ### 手动下载安装 -如果需要手动下载,请点击以下 [链接](https://desktop.docker.com/mac/stable/amd64/Docker.dmg) 下载 Docker Desktop for Mac。 +如果需要手动下载,请点击以下 [链接](https://desktop.docker.com/mac/main/amd64/Docker.dmg) 下载 Docker Desktop for Mac。 -> 如果你的电脑搭载的是 M1 芯片(`arm64` 架构),请点击以下 [链接](https://desktop.docker.com/mac/stable/arm64/Docker.dmg) 下载 Docker Desktop for Mac。你可以在 [官方文档](https://docs.docker.com/docker-for-mac/apple-silicon/) 查阅已知的问题。 +> 如果你的电脑搭载的是 M1 芯片(`arm64` 架构),请点击以下 [链接](https://desktop.docker.com/mac/main/arm64/Docker.dmg) 下载 Docker Desktop for Mac。你可以在 [官方文档](https://docs.docker.com/docker-for-mac/apple-silicon/) 查阅已知的问题。 如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。 diff --git a/install/windows.md b/install/windows.md index ffe34f8e4..377877182 100644 --- a/install/windows.md +++ b/install/windows.md @@ -8,7 +8,7 @@ **手动下载安装** -点击以下 [链接](https://desktop.docker.com/win/stable/amd64/Docker%20Desktop%20Installer.exe) 下载 Docker Desktop for Windows。 +点击以下 [链接](https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe) 下载 Docker Desktop for Windows。 下载好之后双击 `Docker Desktop Installer.exe` 开始安装。 From 31f3540fbc475705fe2ffe745b8367ffd143fa60 Mon Sep 17 00:00:00 2001 From: Dup4 Date: Mon, 1 Nov 2021 19:27:25 +0800 Subject: [PATCH 181/201] fix: typo --- install/debian.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/debian.md b/install/debian.md index 515353f0b..506086cb4 100644 --- a/install/debian.md +++ b/install/debian.md @@ -60,7 +60,7 @@ $ echo \ # 官方源 # $ echo \ -# "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://https://download.docker.com/linux/debian \ +# "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ # $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ``` From b9455b21691554f095025487be8caa76738f2829 Mon Sep 17 00:00:00 2001 From: Baohua Yang Date: Wed, 1 Dec 2021 14:58:32 -0800 Subject: [PATCH 182/201] Fix format --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d2139c5d..08b5c6e3c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ 本书既适用于具备基础 Linux 知识的 Docker 初学者,也希望可供理解原理和实现的高级用户参考。同时,书中给出的实践案例,可供在进行实际部署时借鉴。前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍包括数据管理、网络等高级操作;第 10 ~ 12 章介绍了容器生态中的几个核心项目;13、14 章讨论了关于 Docker 安全和实现技术等高级话题。后续章节则分别介绍包括 Etcd、Fedora CoreOS、Kubernetes、容器云等相关热门开源项目。最后,还展示了使用容器技术的典型的应用场景和实践案例。 * 在线阅读:[docker-practice.com](https://vuepress.mirror.docker-practice.com/),[GitBook](https://yeasy.gitbook.io/docker_practice/),[Github](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md) -* [离线阅读 `$ docker run -it --rm -p 4000:80 ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice:vuepress`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) +* 离线阅读:[`$ docker run -it --rm -p 4000:80 ccr.ccs.tencentyun.com/dockerpracticesig/docker_practice:vuepress`](https://github.com/yeasy/docker_practice/wiki/%E7%A6%BB%E7%BA%BF%E9%98%85%E8%AF%BB%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3) Docker 自身仍在快速发展中,生态环境也在蓬勃成长。建议初学者使用最新稳定版本的 Docker 进行学习实践。欢迎 [参与项目维护](CONTRIBUTING.md)。 From 1ed8c2c81f4ea2c734e8dca7eb59ed9a0b904788 Mon Sep 17 00:00:00 2001 From: Xianxiang Li Date: Tue, 4 Jan 2022 10:41:51 +0800 Subject: [PATCH 183/201] Update best_practices.md Fix a typo --- appendix/best_practices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appendix/best_practices.md b/appendix/best_practices.md index e93f8e2ec..41afcb2a1 100644 --- a/appendix/best_practices.md +++ b/appendix/best_practices.md @@ -329,7 +329,7 @@ $ docker run --rm -it postgres bash 如果某个服务不需要特权执行,建议使用 `USER` 指令切换到非 root 用户。先在 `Dockerfile` 中使用类似 `RUN groupadd -r postgres && useradd -r -g postgres postgres` 的指令创建用户和用户组。 ->注意:在镜像中,用户和用户组每次被分配的 UID/GID 都是不确定的,下次重新构建镜像时被分配到的 UID/GID 可能会不一样。如果要依赖确定的 UID/GID,你应该显示的指定一个 UID/GID。 +>注意:在镜像中,用户和用户组每次被分配的 UID/GID 都是不确定的,下次重新构建镜像时被分配到的 UID/GID 可能会不一样。如果要依赖确定的 UID/GID,你应该显式的指定一个 UID/GID。 你应该避免使用 `sudo`,因为它不可预期的 TTY 和信号转发行为可能造成的问题比它能解决的问题还多。如果你真的需要和 `sudo` 类似的功能(例如,以 root 权限初始化某个守护进程,以非 root 权限执行它),你可以使用 [gosu](https://github.com/tianon/gosu)。 From 664ac88c856b080aa41231c970980d74a4df55e2 Mon Sep 17 00:00:00 2001 From: NPM Mirror Bot Date: Fri, 11 Feb 2022 13:56:55 +0000 Subject: [PATCH 184/201] update https://registry.npm.taobao.org to https://registry.npmmirror.com --- image/demo/buildkit/Dockerfile.buildkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/demo/buildkit/Dockerfile.buildkit b/image/demo/buildkit/Dockerfile.buildkit index effcfc9d6..9bbe3993f 100644 --- a/image/demo/buildkit/Dockerfile.buildkit +++ b/image/demo/buildkit/Dockerfile.buildkit @@ -8,7 +8,7 @@ COPY package.json /app/ RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \ --mount=type=cache,target=/root/.npm,id=npm_cache \ - npm i --registry=https://registry.npm.taobao.org + npm i --registry=https://registry.npmmirror.com COPY src /app/src From 1e415ac76cb6bb918d0eb00994a6b9c9bd282047 Mon Sep 17 00:00:00 2001 From: NPM Mirror Bot Date: Fri, 11 Feb 2022 22:09:47 -0500 Subject: [PATCH 185/201] update https://registry.npm.taobao.org to https://registry.npmmirror.com --- image/demo/buildkit/Dockerfile | 2 +- image/multistage-builds/laravel.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/image/demo/buildkit/Dockerfile b/image/demo/buildkit/Dockerfile index 7e16bbf63..18cf69ce9 100644 --- a/image/demo/buildkit/Dockerfile +++ b/image/demo/buildkit/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /app COPY package.json /app/ -RUN npm i --registry=https://registry.npm.taobao.org \ +RUN npm i --registry=https://registry.npmmirror.com \ && rm -rf ~/.npm COPY src /app/src diff --git a/image/multistage-builds/laravel.md b/image/multistage-builds/laravel.md index 1d3b1fa89..2053cc0ed 100644 --- a/image/multistage-builds/laravel.md +++ b/image/multistage-builds/laravel.md @@ -61,7 +61,7 @@ FROM node:alpine as frontend COPY package.json /app/ RUN set -x ; cd /app \ - && npm install --registry=https://registry.npm.taobao.org + && npm install --registry=https://registry.npmmirror.com COPY webpack.mix.js webpack.config.js tailwind.config.js /app/ COPY resources/ /app/resources/ @@ -179,7 +179,7 @@ FROM node:alpine as frontend COPY package.json /app/ RUN set -x ; cd /app \ - && npm install --registry=https://registry.npm.taobao.org + && npm install --registry=https://registry.npmmirror.com COPY webpack.mix.js webpack.config.js tailwind.config.js /app/ COPY resources/ /app/resources/ From 7c78d1c2564e07202e76ad83f0841e4e0e5f4c5b Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 24 Feb 2022 21:06:15 +0800 Subject: [PATCH 186/201] centos refer to centos:8, deprecated Signed-off-by: Kang Huaishuai --- cases/os/centos.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cases/os/centos.md b/cases/os/centos.md index f2107f0c7..28bed1272 100644 --- a/cases/os/centos.md +++ b/cases/os/centos.md @@ -10,17 +10,17 @@ CentOS(Community Enterprise Operating System,中文意思是:社区企业 ### 使用 CentOS 官方镜像 -使用 `docker run` 直接运行最新的 `CentOS` 镜像,并登录 `bash`。 +使用 `docker run` 直接运行 `CentOS 7` 镜像,并登录 `bash`。 ```bash -$ docker run -it centos bash +$ docker run -it centos:7 bash Unable to find image 'centos:latest' locally latest: Pulling from library/centos 3d8673bd162a: Pull complete Digest: sha256:a66ffcb73930584413de83311ca11a4cb4938c9b2521d331026dad970c19adf4 Status: Downloaded newer image for centos:latest [root@43eb3b194d48 /]# cat /etc/redhat-release -CentOS Linux release 7.2.1511 (Core) +CentOS Linux release 7.9.2009 (Core) ``` ## Fedora 系统简介 From 18028b8eaa41aa46f0347f99530778a1eabfbaab Mon Sep 17 00:00:00 2001 From: Kang Huaishuai Date: Thu, 24 Feb 2022 21:08:22 +0800 Subject: [PATCH 187/201] Update dockerhub autobuild Signed-off-by: Kang Huaishuai --- repository/dockerhub.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 9dfe4fa70..0b8e9586e 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -75,7 +75,7 @@ username/ubuntu ## 自动构建 -> 2021 年 6 月 18 日之后,该项功能仅限[付费用户](https://www.docker.com/blog/changes-to-docker-hub-autobuilds/)使用。 +> 2021 年 7 月 26 日之后,该项功能仅限[付费用户](https://www.docker.com/blog/changes-to-docker-hub-autobuilds/)使用。 自动构建(`Automated Builds`)功能对于需要经常升级镜像内程序来说,十分方便。 From 7014e4d87c056d5a0f25f7ccf2dbe5b093a666aa Mon Sep 17 00:00:00 2001 From: Baohua Yang Date: Wed, 16 Mar 2022 15:14:06 -0700 Subject: [PATCH 188/201] Create FUNDING.yml --- .github/FUNDING.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..c08c58549 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: yeasy +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 1c4a43e34e4c55cb38302ded7835dc53bee57626 Mon Sep 17 00:00:00 2001 From: mrnyg <36262603+mrnyg@users.noreply.github.com> Date: Sat, 9 Apr 2022 14:27:53 +0800 Subject: [PATCH 189/201] Update secret.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apache工作进程是www-data用户运行,而密钥文件(/run/secrets/wp_db_password)的属主是root,导致apache工作进程无法读取密钥,从而无法连接数据库 --- swarm_mode/secret.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm_mode/secret.md b/swarm_mode/secret.md index 28981d5f2..3c30f34b5 100644 --- a/swarm_mode/secret.md +++ b/swarm_mode/secret.md @@ -62,7 +62,7 @@ $ docker service create \ --network mysql_private \ --publish target=30000,port=80 \ --mount type=volume,source=wpdata,destination=/var/www/html \ - --secret source=mysql_password,target=wp_db_password,mode=0400 \ + --secret source=mysql_password,target=wp_db_password,mode=0444 \ -e WORDPRESS_DB_USER="wordpress" \ -e WORDPRESS_DB_PASSWORD_FILE="/run/secrets/wp_db_password" \ -e WORDPRESS_DB_HOST="mysql:3306" \ From 85be3008fa5247b69c59a0e23a6c28d1e34fde46 Mon Sep 17 00:00:00 2001 From: Baohua Yang Date: Thu, 12 May 2022 14:37:08 -0700 Subject: [PATCH 190/201] Update words Fix #501 --- repository/dockerhub.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/dockerhub.md b/repository/dockerhub.md index 0b8e9586e..cf0569372 100644 --- a/repository/dockerhub.md +++ b/repository/dockerhub.md @@ -77,7 +77,7 @@ username/ubuntu > 2021 年 7 月 26 日之后,该项功能仅限[付费用户](https://www.docker.com/blog/changes-to-docker-hub-autobuilds/)使用。 -自动构建(`Automated Builds`)功能对于需要经常升级镜像内程序来说,十分方便。 +自动构建(`Automated Builds`)可以自动触发构建镜像,方便升级镜像。 有时候,用户构建了镜像,安装了某个软件,当软件发布新版本则需要手动更新镜像。 From 93ea51ff078d6d22a776f758adc9d37da0afb392 Mon Sep 17 00:00:00 2001 From: WitchElaina <81346402+WitchElaina@users.noreply.github.com> Date: Sat, 22 Oct 2022 15:42:59 +0800 Subject: [PATCH 191/201] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=AD=E7=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原句:“这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一”中的“为什么”和“的原因”重复赘余,因此删除掉“为什么”确保本句语法正确。 --- image/build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/build.md b/image/build.md index 3d29ad98d..64ad73d43 100644 --- a/image/build.md +++ b/image/build.md @@ -40,7 +40,7 @@ FROM scratch 如果你以 `scratch` 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。 -不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 `FROM scratch` 会让镜像体积更加小巧。使用 [Go 语言](https://golang.google.cn/) 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。 +不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 `FROM scratch` 会让镜像体积更加小巧。使用 [Go 语言](https://golang.google.cn/) 开发的应用很多会使用这种方式来制作镜像,这也是有人认为 Go 是特别适合容器微服务架构的语言的原因之一。 ## RUN 执行命令 From fe7530c3f62f4e5c85d6964388ad1b70c9ef899e Mon Sep 17 00:00:00 2001 From: linhuizi <529246402@qq.com> Date: Fri, 11 Nov 2022 11:31:02 +0800 Subject: [PATCH 192/201] =?UTF-8?q?docs(install):=20=E4=BF=AE=E6=94=B9Mac?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E7=B3=BB=E7=BB=9F=E8=A6=81=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install/mac.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/mac.md b/install/mac.md index 510d7354a..46463f2b8 100644 --- a/install/mac.md +++ b/install/mac.md @@ -2,7 +2,7 @@ ## 系统要求 -[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Mojave 10.14。 +[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS 必须是 10.15 或更高版本, Catalina、Big Sur 或者 Monterey,建议升级到最新版本的 macOS。 ## 安装 From d80f3430b27c05dee8c176f1e146570722a59135 Mon Sep 17 00:00:00 2001 From: Yue JIN <40021217+kingyue737@users.noreply.github.com> Date: Wed, 21 Dec 2022 19:38:21 +0800 Subject: [PATCH 193/201] fix: typo --- image/dockerfile/references.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/dockerfile/references.md b/image/dockerfile/references.md index 96969eaf9..b9edb4fd5 100644 --- a/image/dockerfile/references.md +++ b/image/dockerfile/references.md @@ -1,6 +1,6 @@ # 参考文档 -* `Dockerfie` 官方文档:https://docs.docker.com/engine/reference/builder/ +* `Dockerfile` 官方文档:https://docs.docker.com/engine/reference/builder/ * `Dockerfile` 最佳实践文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ From e76b0b66a0d0998ccee5e22ee4e24631c0fbce44 Mon Sep 17 00:00:00 2001 From: Yue JIN <40021217+kingyue737@users.noreply.github.com> Date: Wed, 21 Dec 2022 20:32:46 +0800 Subject: [PATCH 194/201] fix: wrong key of registry mirrors --- repository/registry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/registry.md b/repository/registry.md index abba1830e..20fce3ace 100644 --- a/repository/registry.md +++ b/repository/registry.md @@ -103,7 +103,7 @@ REPOSITORY TAG IMAGE ID CREAT ```json { - "registry-mirror": [ + "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ], From 6443ddc07cb109f995484b1a384704c422acc383 Mon Sep 17 00:00:00 2001 From: Zhizhen He Date: Sat, 7 Jan 2023 23:45:41 +0800 Subject: [PATCH 195/201] fix: typo --- appendix/best_practices.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appendix/best_practices.md b/appendix/best_practices.md index 41afcb2a1..371c94e34 100644 --- a/appendix/best_practices.md +++ b/appendix/best_practices.md @@ -167,9 +167,9 @@ RUN apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists/* ``` -其中 `s3cmd` 指令指定了一个版本号 `1.1.*`。如果之前的镜像使用的是更旧的版本,指定新的版本会导致 `apt-get udpate` 缓存失效并确保安装的是新版本。 +其中 `s3cmd` 指令指定了一个版本号 `1.1.*`。如果之前的镜像使用的是更旧的版本,指定新的版本会导致 `apt-get update` 缓存失效并确保安装的是新版本。 -另外,清理掉 apt 缓存 `var/lib/apt/lists` 可以减小镜像大小。因为 `RUN` 指令的开头为 `apt-get udpate`,包缓存总是会在 `apt-get install` 之前刷新。 +另外,清理掉 apt 缓存 `var/lib/apt/lists` 可以减小镜像大小。因为 `RUN` 指令的开头为 `apt-get update`,包缓存总是会在 `apt-get install` 之前刷新。 > 注意:官方的 Debian 和 Ubuntu 镜像会自动运行 apt-get clean,所以不需要显式的调用 apt-get clean。 From 13b8e12f4435aeb480674f5139c52f8c06c80a5a Mon Sep 17 00:00:00 2001 From: Gao Zhenghua Date: Mon, 16 Jan 2023 16:10:32 +0800 Subject: [PATCH 196/201] [issue-518] Add document on how to use HTTP/HTTPS proxy --- SUMMARY.md | 1 + advanced_network/http_https_proxy.md | 74 ++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 advanced_network/http_https_proxy.md diff --git a/SUMMARY.md b/SUMMARY.md index 4fd7b80c4..4ad078a5c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -75,6 +75,7 @@ * [自定义网桥](advanced_network/bridge.md) * [工具和示例](advanced_network/example.md) * [编辑网络配置文件](advanced_network/config_file.md) + * [配置 HTTP/HTTPS 网络代理](advanced_network/http_https_proxy.md) * [实例:创建一个点到点连接](advanced_network/ptp.md) * [Docker Buildx](buildx/README.md) * [BuildKit](buildx/buildkit.md) diff --git a/advanced_network/http_https_proxy.md b/advanced_network/http_https_proxy.md new file mode 100644 index 000000000..d8dcc9242 --- /dev/null +++ b/advanced_network/http_https_proxy.md @@ -0,0 +1,74 @@ +# 配置 HTTP/HTTPS 网络代理 + +使用Docker的过程中,因为网络原因,通常需要使用 HTTP/HTTPS 代理来加速镜像拉取、构建和使用。下面是常见的三种场景。 + +## 为 dockerd 设置网络代理 + +"docker pull" 命令是由 dockerd 守护进程执行。而 dockerd 守护进程是由 systemd 管理。因此,如果需要在执行 "docker pull" 命令时使用 HTTP/HTTPS 代理,需要通过 systemd 配置。 + +- 为 dockerd 创建配置文件夹。 +``` +sudo mkdir -p /etc/systemd/system/docker.service.d +``` + +- 为 dockerd 创建 HTTP/HTTPS 网络代理的配置文件,文件路径是 /etc/systemd/system/docker.service.d/http-proxy.conf 。并在该文件中添加相关环境变量。 +``` +[Service] +Environment="HTTP_PROXY=http://proxy.example.com:8080/" +Environment="HTTPS_PROXY=http://proxy.example.com:8080/" +Environment="NO_PROXY=localhost,127.0.0.1,.example.com" +``` + +- 刷新配置并重启 docker 服务。 +``` +sudo systemctl daemon-reload +sudo systemctl restart docker +``` + +## 为 docker 容器设置网络代理 + +在容器运行阶段,如果需要使用 HTTP/HTTPS 代理,可以通过更改 docker 客户端配置,或者指定环境变量的方式。 + +- 更改 docker 客户端配置:创建或更改 ~/.docker/config.json,并在该文件中添加相关配置。 +``` +{ + "proxies": + { + "default": + { + "httpProxy": "http://proxy.example.com:8080/", + "httpsProxy": "http://proxy.example.com:8080/", + "noProxy": "localhost,127.0.0.1,.example.com" + } + } +} +``` + +- 指定环境变量:运行 "docker run" 命令时,指定相关环境变量。 + +| 环境变量 | docker run 示例 | +| -------- | ---------------- | +| HTTP_PROXY | --env HTTP_PROXY="http://proxy.example.com:8080/" | +| HTTPS_PROXY | --env HTTPS_PROXY="http://proxy.example.com:8080/" | +| NO_PROXY | --env NO_PROXY="localhost,127.0.0.1,.example.com" | + +## 为 docker build 过程设置网络代理 + +在容器构建阶段,如果需要使用 HTTP/HTTPS 代理,可以通过指定 "docker build" 的环境变量,或者在 Dockerfile 中指定环境变量的方式。 + +- 使用 "--build-arg" 指定 "docker build" 的相关环境变量 +``` +docker build \ + --build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \ + --build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \ + --build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" . +``` + +- 在 Dockerfile 中指定相关环境变量 + +| 环境变量 | Dockerfile 示例 | +| -------- | ---------------- | +| HTTP_PROXY | ENV HTTP_PROXY="http://proxy.example.com:8080/" | +| HTTPS_PROXY | ENV HTTPS_PROXY="http://proxy.example.com:8080/" | +| NO_PROXY | ENV NO_PROXY="localhost,127.0.0.1,.example.com" | + From eb327bf9086b821a22253a68c8f9434b79c3a2a9 Mon Sep 17 00:00:00 2001 From: ReginaldChen <41498289+ReginaldChen@users.noreply.github.com> Date: Fri, 24 Feb 2023 17:41:22 +0800 Subject: [PATCH 197/201] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E5=88=AB?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 轮寻应为轮询 --- kubernetes/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubernetes/concepts.md b/kubernetes/concepts.md index 99391f726..402d0d41d 100644 --- a/kubernetes/concepts.md +++ b/kubernetes/concepts.md @@ -62,7 +62,7 @@ Kubernetes 校验节点可用依赖于 ID。在当前的版本中,有两个接 * 集群范围内节点同步 * 单节点生命周期管理 -节点控制有一个同步轮寻,主要监听所有云平台的虚拟实例,会根据节点状态创建和删除。可以通过 `--node_sync_period`标志来控制该轮寻。如果一个实例已经创建,节点控制将会为其创建一个结构。同样的,如果一个节点被删除,节点控制也会删除该结构。在 Kubernetes 启动时可用通过 `--machines`标记来显示指定节点。同样可以使用 `kubectl` 来一条一条的添加节点,两者是相同的。通过设置 `--sync_nodes=false`标记来禁止集群之间的节点同步,你也可以使用 api/kubectl 命令行来增删节点。 +节点控制有一个同步轮询,主要监听所有云平台的虚拟实例,会根据节点状态创建和删除。可以通过 `--node_sync_period`标志来控制该轮询。如果一个实例已经创建,节点控制将会为其创建一个结构。同样的,如果一个节点被删除,节点控制也会删除该结构。在 Kubernetes 启动时可用通过 `--machines`标记来显示指定节点。同样可以使用 `kubectl` 来一条一条的添加节点,两者是相同的。通过设置 `--sync_nodes=false`标记来禁止集群之间的节点同步,你也可以使用 api/kubectl 命令行来增删节点。 ## 容器组 From 6acf209b9ab5c15deee6269b387df7b69fe4b12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=95=B0?= <61787040+wushu037@users.noreply.github.com> Date: Sun, 7 May 2023 21:34:34 +0800 Subject: [PATCH 198/201] Update volume.md Correct confusing words --- data_management/volume.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_management/volume.md b/data_management/volume.md index 27f388aec..a80cca4c8 100644 --- a/data_management/volume.md +++ b/data_management/volume.md @@ -1,6 +1,6 @@ # 数据卷 -`数据卷` 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性: +`数据卷` 是一个可供一个或多个容器使用的特殊目录,它绕过 UnionFS,可以提供很多有用的特性: * `数据卷` 可以在容器之间共享和重用 From 1563879830362ab5163e805817ab59a453cff627 Mon Sep 17 00:00:00 2001 From: tmmercad Date: Thu, 25 May 2023 01:51:56 +0530 Subject: [PATCH 199/201] Translating into english access_control --- advanced_network/access_control.md | 65 +++++++++++++----------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/advanced_network/access_control.md b/advanced_network/access_control.md index c99fb7787..4844bff68 100644 --- a/advanced_network/access_control.md +++ b/advanced_network/access_control.md @@ -1,56 +1,45 @@ -# 容器访问控制 +# Container Access Control +Container access control is mainly managed and implemented through the iptables firewall on Linux. iptables is the default firewall software on Linux and comes with most distributions. +Container Access to External Networks +For containers to access external networks, local system forwarding support is required. In Linux systems, check if forwarding is turned on. -容器的访问控制,主要通过 Linux 上的 `iptables` 防火墙来进行管理和实现。`iptables` 是 Linux 上默认的防火墙软件,在大部分发行版中都自带。 -## 容器访问外部网络 -容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。 - -```bash $sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1 -``` -如果为 0,说明没有开启转发,则需要手动打开。 -```bash -$sysctl -w net.ipv4.ip_forward=1 -``` -如果在启动 Docker 服务的时候设定 `--ip-forward=true`, Docker 就会自动设定系统的 `ip_forward` 参数为 1。 - -## 容器之间访问 -容器之间相互访问,需要两方面的支持。 -* 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 `docker0` 网桥上。 -* 本地系统的防火墙软件 -- `iptables` 是否允许通过。 +If it is 0, it means that forwarding is not turned on and needs to be turned on manually. -### 访问所有端口 -当启动 Docker 服务(即 dockerd)的时候,默认会添加一条转发策略到本地主机 iptables 的 FORWARD 链上。策略为通过(`ACCEPT`)还是禁止(`DROP`)取决于配置`--icc=true`(缺省值)还是 `--icc=false`。当然,如果手动指定 `--iptables=false` 则不会添加 `iptables` 规则。 -可见,默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在 `/etc/docker/daemon.json` 文件中配置 `{"icc": false}` 来禁止它。 +$sysctl -w net.ipv4.ip_forward=1 +If you set --ip-forward=true when starting the Docker service, Docker will automatically set the system's ip_forward parameter to 1. +Container-to-Container Access +Container-to-container access requires two levels of support. + - Whether the container's network topology is interconnected. By default, all containers are connected to the docker0 bridge. + - Whether the local system's firewall software -- iptables allows passage. -### 访问指定端口 -在通过 `-icc=false` 关闭网络访问后,还可以通过 `--link=CONTAINER_NAME:ALIAS` 选项来访问容器的开放端口。 +Access to All Ports +When starting the Docker service (i.e., dockerd), a forwarding policy is added to the local host iptables FORWARD chain by default. Whether the policy is passed (ACCEPT) or prohibited (DROP) depends on whether it is configured with --icc=true (default value) or --icc=false. Of course, if you manually specify --iptables=false, no iptables rules will be added. +As you can see, by default, different containers are allowed to communicate with each other over the network. For security reasons, you can configure {"icc": false} in the /etc/docker/daemon.json file to disable it. +Access to Specified Ports +After closing network access with -icc=false, you can also use the --link=CONTAINER_NAME:ALIAS option to access open ports of the container. +For example, when starting the Docker service, you can use both icc=false --iptables=true parameters to close network access that allows mutual access and allow Docker to modify system iptables rules. +At this point, the system's iptables rules may be similar -例如,在启动 Docker 服务时,可以同时使用 `icc=false --iptables=true` 参数来关闭允许相互的网络访问,并让 Docker 可以修改系统中的 `iptables` 规则。 -此时,系统中的 `iptables` 规则可能是类似 -```bash $ sudo iptables -nL ... Chain FORWARD (policy ACCEPT) -target prot opt source destination -DROP all -- 0.0.0.0/0 0.0.0.0/0 +target prot opt source destination +DROP all -- 0.0.0.0/0 0.0.0.0/0 ... -``` +Afterwards, use the --link=CONTAINER_NAME:ALIAS option when starting a container (docker run). Docker will add an ACCEPT rule for both containers in iptable, allowing mutual access to open ports (depending on the EXPOSE directive in the Dockerfile). +After adding the --link=CONTAINER_NAME:ALIAS option and adding an iptables rule. -之后,启动容器(`docker run`)时使用 `--link=CONTAINER_NAME:ALIAS` 选项。Docker 会在 `iptable` 中为 两个容器分别添加一条 `ACCEPT` 规则,允许相互访问开放的端口(取决于 `Dockerfile` 中的 `EXPOSE` 指令)。 -当添加了 `--link=CONTAINER_NAME:ALIAS` 选项后,添加了 `iptables` 规则。 -```bash $ sudo iptables -nL ... Chain FORWARD (policy ACCEPT) -target prot opt source destination -ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80 -ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80 -DROP all -- 0.0.0.0/0 0.0.0.0/0 -``` - -注意:`--link=CONTAINER_NAME:ALIAS` 中的 `CONTAINER_NAME` 目前必须是 Docker 分配的名字,或使用 `--name` 参数指定的名字。主机名则不会被识别。 +target prot opt source destination +ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80 +ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80 +DROP all -- 0.0.0.0/0 0.0.0.0/0 +Note: The CONTAINER_NAME in --link=CONTAINER_NAME:ALIAS must currently be a name assigned by Docker or a name specified using the --name parameter. Hostnames are not recognized." From 07a819c9746ffa7f8193d2868f1d2c61a7289f68 Mon Sep 17 00:00:00 2001 From: tmmercad Date: Thu, 25 May 2023 01:57:57 +0530 Subject: [PATCH 200/201] Second translating commit --- advanced_network/bridge.md | 41 +++++++++++++------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/advanced_network/bridge.md b/advanced_network/bridge.md index 0ce6a5298..1e27e7ba0 100644 --- a/advanced_network/bridge.md +++ b/advanced_network/bridge.md @@ -1,45 +1,32 @@ -# 自定义网桥 +# Custom Bridge +In addition to the default docker0 bridge, users can also specify a bridge to connect containers. +When starting the Docker service, use -b BRIDGE or --bridge=BRIDGE to specify the bridge to use. +If the service is already running, you need to stop the service and delete the old bridge. -除了默认的 `docker0` 网桥,用户也可以指定网桥来连接各个容器。 -在启动 Docker 服务的时候,使用 `-b BRIDGE`或`--bridge=BRIDGE` 来指定使用的网桥。 - -如果服务已经运行,那需要先停止服务,并删除旧的网桥。 - -```bash $ sudo systemctl stop docker $ sudo ip link set dev docker0 down $ sudo brctl delbr docker0 -``` +Then create a bridge bridge0. -然后创建一个网桥 `bridge0`。 -```bash $ sudo brctl addbr bridge0 $ sudo ip addr add 192.168.5.1/24 dev bridge0 $ sudo ip link set dev bridge0 up -``` +Check that the bridge has been created and started. -查看确认网桥创建并启动。 -```bash $ ip addr show bridge0 4: bridge0: mtu 1500 qdisc noop state UP group default - link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff - inet 192.168.5.1/24 scope global bridge0 - valid_lft forever preferred_lft forever -``` + link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff + inet 192.168.5.1/24 scope global bridge0 + valid_lft forever preferred_lft forever +Add the following content to the Docker configuration file /etc/docker/daemon.json to bridge Docker to the created bridge by default. -在 Docker 配置文件 `/etc/docker/daemon.json` 中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。 -```json { - "bridge": "bridge0", + "bridge": "bridge0", } -``` - -启动 Docker 服务。 - -新建一个容器,可以看到它已经桥接到了 `bridge0` 上。 - -可以继续用 `brctl show` 命令查看桥接的信息。另外,在容器中可以使用 `ip addr` 和 `ip route` 命令来查看 IP 地址配置和路由信息。 +Start the Docker service. +Create a new container and you can see that it is already bridged to bridge0. +You can continue to use the brctl show command to view bridging information. In addition, you can use the ip addr and ip route commands in the container to view IP address configuration and routing information. \ No newline at end of file From 281b2a9875603d4c7e628a1c2b38f21bccb67b86 Mon Sep 17 00:00:00 2001 From: tmmercad Date: Thu, 25 May 2023 02:06:18 +0530 Subject: [PATCH 201/201] Third translation --- advanced_network/config_file.md | 6 ++--- advanced_network/docker0.md | 47 +++++++++++++-------------------- advanced_network/example.md | 13 +++++---- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/advanced_network/config_file.md b/advanced_network/config_file.md index b084c79ad..467899cf8 100644 --- a/advanced_network/config_file.md +++ b/advanced_network/config_file.md @@ -1,5 +1,5 @@ -# 编辑网络配置文件 +# Editing Network Configuration Files -Docker 1.2.0 开始支持在运行中的容器里编辑 `/etc/hosts`, `/etc/hostname` 和 `/etc/resolv.conf` 文件。 +Starting with Docker 1.2.0, you can edit the /etc/hosts, /etc/hostname, and /etc/resolv.conf files in a running container. -但是这些修改是临时的,只在运行的容器中保留,容器终止或重启后并不会被保存下来,也不会被 `docker commit` 提交。 +However, these changes are temporary and are only retained in the running container. They are not saved after the container terminates or restarts and are not committed by docker commit. \ No newline at end of file diff --git a/advanced_network/docker0.md b/advanced_network/docker0.md index c21ce8b70..45221e2f0 100644 --- a/advanced_network/docker0.md +++ b/advanced_network/docker0.md @@ -1,37 +1,28 @@ -# 配置 docker0 网桥 +# Configuring the docker0 Bridge +The Docker service will create a docker0 bridge by default (with an internal docker0 interface on it), which connects other physical or virtual network cards at the kernel layer, putting all containers and the local host on the same physical network. +Docker specifies the IP address and subnet mask of the docker0 interface by default, allowing communication between the host and containers through the bridge. It also specifies the MTU (maximum transmission unit allowed by the interface), which is usually 1500 Bytes or the default value supported by the host network routing. These values can be configured when starting the service. + - --bip=CIDR IP address plus mask format, such as 192.168.1.5/24 + - --mtu=BYTES Override the default Docker mtu configuration -Docker 服务默认会创建一个 `docker0` 网桥(其上有一个 `docker0` 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。 +You can also configure DOCKER_OPTS in the configuration file and then restart the service. +Since Docker's bridge is currently a Linux bridge, users can use brctl show to view bridge and port connection information. -Docker 默认指定了 `docker0` 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。 - -* `--bip=CIDR` IP 地址加掩码格式,例如 192.168.1.5/24 -* `--mtu=BYTES` 覆盖默认的 Docker mtu 配置 - -也可以在配置文件中配置 DOCKER_OPTS,然后重启服务。 - -由于目前 Docker 网桥是 Linux 网桥,用户可以使用 `brctl show` 来查看网桥和端口连接信息。 - -```bash $ sudo brctl show -bridge name bridge id STP enabled interfaces -docker0 8000.3a1d7362b4ee no veth65f9 - vethdda6 -``` -*注:`brctl` 命令在 Debian、Ubuntu 中可以使用 `sudo apt-get install bridge-utils` 来安装。 +bridge name bridge id STP enabled interfaces +docker0 8000.3a1d7362b4ee no veth65f9 + vethdda6 +*Note: The brctl command can be installed on Debian and Ubuntu using sudo apt-get install bridge-utils. +Each time a new container is created, Docker selects an available IP address from the available address range and assigns it to the container's eth0 port. Use the IP of the docker0 interface on the local host as the default gateway for all containers. - -每次创建一个新容器的时候,Docker 从可用的地址段中选择一个空闲的 IP 地址分配给容器的 eth0 端口。使用本地主机上 `docker0` 接口的 IP 作为所有容器的默认网关。 - -```bash $ sudo docker run -i -t --rm base /bin/bash $ ip addr show eth0 24: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 - link/ether 32:6f:e0:35:57:91 brd ff:ff:ff:ff:ff:ff - inet 172.17.0.3/16 scope global eth0 - valid_lft forever preferred_lft forever - inet6 fe80::306f:e0ff:fe35:5791/64 scope link - valid_lft forever preferred_lft forever + link/ether 32:6f:e0:35:57:91 brd ff:ff:ff:ff:ff:ff + inet 172.17.0.3/16 scope global eth0 + valid_lft forever preferred_lft forever + inet6 fe80::306f:e0ff:fe35:5791/64 scope link + valid_lft forever preferred_lft forever + $ ip route default via 172.17.42.1 dev eth0 -172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3 -``` +172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3 diff --git a/advanced_network/example.md b/advanced_network/example.md index e8bf80214..cedf986b1 100644 --- a/advanced_network/example.md +++ b/advanced_network/example.md @@ -1,9 +1,8 @@ -# 工具和示例 +# Tools and Examples +Before introducing custom network topologies, you may be interested in some external tools and examples: -在介绍自定义网络拓扑之前,你可能会对一些外部工具和例子感兴趣: +# pipework +Jérôme Petazzoni wrote a [pipework](https://github.com/jpetazzo/pipework) shell script called pipework that helps users connect containers in more complex scenarios. -## pipework -Jérôme Petazzoni 编写了一个叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接。 - -## playground -Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 `HTTP` `SMTP` `POP` `IMAP` `Telnet` `SSH` `FTP` 的服务器。 +# playground +Brandon Rhodes created a Python (https://github.com/brandon-rhodes/fopnp/tree/m/playground), library that provides complete management of Docker container network topologies, including routing and NAT firewalls; as well as servers providing HTTP, SMTP, POP, IMAP, Telnet, SSH, and FTP.