Update image
parent
7afb8991d3
commit
bc43b30964
|
@ -40,7 +40,7 @@ FROM scratch
|
||||||
|
|
||||||
如果你以 `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 执行命令
|
## RUN 执行命令
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM golang:1.9-alpine as builder
|
FROM golang:alpine as builder
|
||||||
|
|
||||||
RUN apk --no-cache add git
|
RUN apk --no-cache add git
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM golang:1.9-alpine
|
FROM golang:alpine
|
||||||
|
|
||||||
RUN apk --no-cache add git
|
RUN apk --no-cache add git
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM golang:1.9-alpine
|
FROM golang:alpine
|
||||||
|
|
||||||
RUN apk --no-cache add git ca-certificates
|
RUN apk --no-cache add git ca-certificates
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
`Dockerfile` 中的 `ARG` 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 `docker build` 中用 `--build-arg <参数名>=<值>` 来覆盖。
|
`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` 指令中。
|
ARG 指令有生效范围,如果在 `FROM` 指令之前指定,那么只能用于 `FROM` 指令中。
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
格式为 `EXPOSE <端口1> [<端口2>...]`。
|
格式为 `EXPOSE <端口1> [<端口2>...]`。
|
||||||
|
|
||||||
`EXPOSE` 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 `docker run -P` 时,会自动随机映射 `EXPOSE` 的端口。
|
`EXPOSE` 指令是声明容器运行时提供服务的端口,这只是一个声明,在容器运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 `docker run -P` 时,会自动随机映射 `EXPOSE` 的端口。
|
||||||
|
|
||||||
要将 `EXPOSE` 和在运行时使用 `-p <宿主端口>:<容器端口>` 区分开来。`-p`,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 `EXPOSE` 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
|
要将 `EXPOSE` 和在运行时使用 `-p <宿主端口>:<容器端口>` 区分开来。`-p`,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 `EXPOSE` 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
VOLUME /data
|
VOLUME /data
|
||||||
```
|
```
|
||||||
|
|
||||||
这里的 `/data` 目录就会在运行时自动挂载为匿名卷,任何向 `/data` 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:
|
这里的 `/data` 目录就会在容器运行时自动挂载为匿名卷,任何向 `/data` 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行容器时可以覆盖这个挂载设置。比如:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d -v mydata:/data xxxx
|
$ docker run -d -v mydata:/data xxxx
|
||||||
```
|
```
|
||||||
|
|
||||||
在这行命令中,就使用了 `mydata` 这个命名卷挂载到了 `/data` 这个位置,替代了 `Dockerfile` 中定义的匿名卷的挂载配置。
|
在这行命令中,就使用了 `mydata` 这个命名卷挂载到了 `/data` 这个位置,替代了 `Dockerfile` 中定义的匿名卷的挂载配置。
|
||||||
|
|
|
@ -33,4 +33,4 @@ WORKDIR c
|
||||||
RUN pwd
|
RUN pwd
|
||||||
```
|
```
|
||||||
|
|
||||||
`pwd` 输出的结果为 `/a/b/c`。
|
`RUN pwd` 的工作目录为 `/a/b/c`。
|
||||||
|
|
|
@ -24,11 +24,11 @@ $ docker run -it --rm username/test
|
||||||
|
|
||||||
这样做显得很繁琐,那么有没有一种方法让 Docker 引擎根据系统架构自动拉取对应的镜像呢?
|
这样做显得很繁琐,那么有没有一种方法让 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`)。
|
当用户获取一个镜像时,Docker 引擎会首先查找该镜像是否有 `manifest` 列表,如果有的话 Docker 引擎会按照 Docker 运行环境(系统及架构)查找出对应镜像(例如 `golang:alpine`)。如果没有的话会直接获取镜像(例如上例中我们构建的 `username/test`)。
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ $ docker manifest create username/test \
|
||||||
username/arm64v8-test
|
username/arm64v8-test
|
||||||
```
|
```
|
||||||
|
|
||||||
当要修改一个 `manifest` 列表时,可以加入 `-a,--amend` 参数。
|
当要修改一个 `manifest` 列表时,可以加入 `-a` 或 `--amend` 参数。
|
||||||
|
|
||||||
## 设置 `manifest` 列表
|
## 设置 `manifest` 列表
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ func main(){
|
||||||
编写 `Dockerfile.one` 文件
|
编写 `Dockerfile.one` 文件
|
||||||
|
|
||||||
```docker
|
```docker
|
||||||
FROM golang:1.9-alpine
|
FROM golang:alpine
|
||||||
|
|
||||||
RUN apk --no-cache add git ca-certificates
|
RUN apk --no-cache add git ca-certificates
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ $ docker build -t go/helloworld:1 -f Dockerfile.one .
|
||||||
例如,编写 `Dockerfile.build` 文件
|
例如,编写 `Dockerfile.build` 文件
|
||||||
|
|
||||||
```docker
|
```docker
|
||||||
FROM golang:1.9-alpine
|
FROM golang:alpine
|
||||||
|
|
||||||
RUN apk --no-cache add git
|
RUN apk --no-cache add git
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
|
||||||
例如,编写 `Dockerfile` 文件
|
例如,编写 `Dockerfile` 文件
|
||||||
|
|
||||||
```docker
|
```docker
|
||||||
FROM golang:1.9-alpine as builder
|
FROM golang:alpine as builder
|
||||||
|
|
||||||
RUN apk --no-cache add git
|
RUN apk --no-cache add git
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
|
||||||
我们可以使用 `as` 来为某一阶段命名,例如
|
我们可以使用 `as` 来为某一阶段命名,例如
|
||||||
|
|
||||||
```docker
|
```docker
|
||||||
FROM golang:1.9-alpine as builder
|
FROM golang:alpine as builder
|
||||||
```
|
```
|
||||||
|
|
||||||
例如当我们只想构建 `builder` 阶段的镜像时,增加 `--target=builder` 参数即可
|
例如当我们只想构建 `builder` 阶段的镜像时,增加 `--target=builder` 参数即可
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
从 Docker 镜像仓库获取镜像的命令是 `docker pull`。其命令格式为:
|
从 Docker 镜像仓库获取镜像的命令是 `docker pull`。其命令格式为:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
|
$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
|
||||||
```
|
```
|
||||||
|
|
||||||
具体的选项可以通过 `docker pull --help` 命令看到,这里我们说一下镜像名称的格式。
|
具体的选项可以通过 `docker pull --help` 命令看到,这里我们说一下镜像名称的格式。
|
||||||
|
|
||||||
* Docker 镜像仓库地址:地址的格式一般是 `<域名/IP>[:端口号]`。默认地址是 Docker Hub(docker.io)。
|
* Docker 镜像仓库地址:地址的格式一般是 `<域名/IP>[:端口号]`。默认地址是 Docker Hub(`docker.io`)。
|
||||||
* 仓库名:如之前所说,这里的仓库名是两段式名称,即 `<用户名>/<软件名>`。对于 Docker Hub,如果不给出用户名,则默认为 `library`,也就是官方镜像。
|
* 仓库名:如之前所说,这里的仓库名是两段式名称,即 `<用户名>/<软件名>`。对于 Docker Hub,如果不给出用户名,则默认为 `library`,也就是官方镜像。
|
||||||
|
|
||||||
比如:
|
比如:
|
||||||
|
@ -26,7 +26,7 @@ Status: Downloaded newer image for ubuntu:18.04
|
||||||
docker.io/library/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` 的摘要,以确保下载一致性。
|
从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 `sha256` 的摘要,以确保下载一致性。
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue