Update title style

Signed-off-by: Kang HuaiShuai <khs1994@khs1994.com>
This commit is contained in:
Kang HuaiShuai
2019-11-06 14:53:09 +08:00
parent 99e470eb2a
commit 5cb92f63cf
60 changed files with 224 additions and 232 deletions

View File

@@ -1,4 +1,4 @@
## 使用 Dockerfile 定制镜像
# 使用 Dockerfile 定制镜像
从刚才的 `docker commit` 的学习中我们可以了解到镜像的定制实际上就是定制每一层所添加的配置文件如果我们可以把每一层修改安装构建操作的命令都写入一个脚本用这个脚本来构建定制镜像那么之前提及的无法重复的问题镜像构建透明性的问题体积的问题就都会解决这个脚本就是 Dockerfile
@@ -23,7 +23,7 @@ RUN echo '<h1>Hello, Docker!</h1>' > /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

View File

@@ -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` 命令虽然可以比较直观的帮助理解镜像分层存储的概念但是实际环境中并不会这样使用

View File

@@ -1,3 +1,3 @@
## Dockerfile 指令详解
# Dockerfile 指令详解
我们已经介绍了 `FROM``RUN`还提及了 `COPY`, `ADD`其实 `Dockerfile` 功能很强大它提供了十多个指令下面我们继续讲解其他的指令

View File

@@ -1,4 +1,4 @@
## 镜像的实现原理
# 镜像的实现原理
Docker 镜像是怎么实现增量的修改和维护的

View File

@@ -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
```
### 虚悬镜像
## 虚悬镜像
上面的镜像列表中还可以看到一个特殊的镜像这个镜像既没有仓库名也没有标签均为 `<none>`
@@ -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` 参数

View File

@@ -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` 可以阅读官方博客

View File

@@ -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 .` 从上一阶段的镜像中复制文件我们也可以复制任意镜像中的文件

View File

@@ -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 项目依赖其他外部服务例如 redisMySQL请自行启动这些服务之后再进行测试本小节不再赘述
### 生产环境优化
## 生产环境优化
本小节内容为了方便测试将配置文件直接放到了镜像中实际在使用时 **建议** 将配置文件作为 `config` `secret` 挂载到容器中请读者自行学习 `Swarm mode` `Kubernetes` 的相关内容
### 附录
## 附录
完整的 `Dockerfile` 文件如下

View File

@@ -1,8 +1,8 @@
## 其它制作镜像的方式
# 其它制作镜像的方式
除了标准的使用 `Dockerfile` 生成镜像的方法外由于各种特殊需求和历史原因还提供了一些其它方法用以生成镜像
### rootfs 压缩包导入
## rootfs 压缩包导入
格式`docker import [选项] <文件>|<URL>|- [<仓库名>[:<标签>]]`
@@ -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` 命令可以将镜像保存为归档文件

View File

@@ -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` 并且进行交互式操作的话可以执行下面的命令

View File

@@ -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` 驱动