docker dockerfile 编排
1. from
from指令用于指定其后构建新镜像所使用的基础镜像。
from
from :
from :
- from必须是dockerfile中第一条非注释命令
- 在一个dockerfile文件中创建多个镜像时,docker17.05版本以后,from可以多次出现。只需在每个新命令from之前,记录提交上次的镜像id。
- tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
多次使用from的情况时构建与运行分离的场景
基础镜像golang:1.10.3
是非常庞大的,因为其中包含了所有的go语言编译工具和库,而运行时候我们仅仅需要编译后的server程序
就行了,不需要编译时的编译工具,最后生成的大体积镜像就是一种浪费。
scratch
是内置关键词,并不是一个真实存在的镜像。 from scratch 会使用一个完全干净的文件系统,不包含任何文件。因为go语言编译后不需要运行时,也就不需要安装任何的运行库。from scratch可以使得最后生成的镜像最小化,其中只包含了server 程序。
当然,你也可以from一个你熟悉的并且空间占用小的镜像,比如:centos、ubuntu、busybox
等。
# 编译阶段
from golang:1.10.3
copy server.go /build/
workdir /build
run cgo_enabled=0 goos=linux goarch=amd64 goarm=6 go build -ldflags '-w -s' -o server
# 运行阶段
from scratch
# 从编译阶段的中拷贝编译结果到当前镜像中
copy --from=0 /build/server /
entrypoint ["/server"]
copy 指令的--from=0
参数,从前边的阶段中拷贝文件到当前阶段中,多个from语句时,0代表第一个阶段。除了使用数字,我们还可以给阶段命名,比如:
# 编译阶段 命名为 builder
from golang:1.10.3 as builder
# ... 省略
# 运行阶段
from scratch
# 从编译阶段的中拷贝编译结果到当前镜像中
copy --from=builder /build/server /
copy --from
不但可以从前置阶段中拷贝,还可以直接从一个已经存在的镜像中拷贝。比如,
from ubuntu:16.04
copy --from=quay.io/coreos/etcd:v3.3.9 /usr/local/bin/etcd /usr/local/bin/
2. copy
copy同样用于复制构建环境中的文件或目录到镜像中。
copy ...
copy ["",... ""]
copy --from=builder /build/server /
copy --from=quay.io/coreos/etcd:v3.3.9 /usr/local/bin/etcd /usr/local/bin/
copy指令非常类似于add,不同点在于copy只会复制构建目录下的文件,不能使用url也不会进行解压操作。
3. add
add用于复制构建环境中的文件或目录到镜像中。
add ...
add ["",... ""]
指定源文件位置,
来指定目标位置。
可以是一个构建上下文中的文件或目录,也可以是一个url,但不能访问构建上下文之外的文件或目录。
add复制一个网络文件:
add http://wordpress.org/test.zip $worker_path
另外,如果使用的是本地归档文件(gzip、bzip2、xz)时,docker会自动进行解包操作,类似使用tar -x
4. run
run用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行
在这种方式会在shell中执行命令,linux下默认使用/bin/sh -c
,windows下使用cmd /s /c
。
注意:通过shell命令修改run所使用的默认shell
run
run /bin/bash -c 'source $home/.bashrc; \
echo $home' #通过run执行多条命令时,可以通过\换行执行
run /bin/bash -c 'source $home/.bashrc; echo $home' #同一行中,通过分号分隔命令
exec执行
run ["executable", "param1", "param2"]
run指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定–no-cache参数,如:docker build --no-cache
。
5. cmd
cmd用于指定在容器启动时所要执行的命令。cmd有以下三种格式:
cmd ["executable","param1","param2"]
cmd ["param1","param2"]
cmd command param1 param2
cmd不同于run,cmd用于指定在容器启动时所要执行的命令,而run用于指定镜像构建时所要执行的命令。
cmd与run在功能实现上也有相似之处。如:
docker run -t -i ghostwritten/web_server /bin/true
等价于:
cmd ["/bin/true"]
- cmd在dockerfile文件中仅可指定一次,指定多次时,会覆盖前的指令。
- docker run命令也会覆盖dockerfile中cmd命令。
6. entrypoint
entrypoint用于给容器配置一个可执行程序。也就是说,每次使用镜像创建容器时,通过entrypoint指定的程序都会被设置为默认程序。entrypoint有以下两种形式:
entrypoint ["executable", "param1", "param2"]
entrypoint command param1 param2
- entrypoint与cmd非常类似,不同的是通过docker run执行的命令不会覆盖
entrypoint - docker run命令中指定的任何参数,都会被当做参数再次传递给entrypoint。
- dockerfile中只允许有一个entrypoint命令,多指定时会覆盖前面的设置,而只执行最后的entrypoint指令。
docker run运行容器时指定的参数都会被传递给entrypoint
,且会覆盖cmd命令指定的参数。如,执行docker run -d
时,-d参数将被传递给入口点。
也可以通过docker run --entrypoint
重写entrypoint入口点。
示例:
entrypoint ["/usr/bin/nginx"]
dockerfile
from ubuntu:16.04
run apt-get update
run apt-get install -y nginx
run echo 'hello world, 我是个容器' > /var/www/html/index.html
expose 80
entrypoint ["/usr/sbin/nginx"]
构建
docker build -t="ghostwritten/app" .
创建容器
docker run -i -t ghostwritten/app -g "daemon off;"
-g "daemon off;"
参数将会被传递给entrypoint
,最终在容器中执行的命令为/usr/sbin/nginx -g "daemon off;"
。
7. label
label用于为镜像添加元数据,元数以键值对的形式指定:
label = = = ...
使用label指定元数据时,一条label指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。
label version="1.0" description="这是一个web服务器" by="ghostwritten"
也可以换行
label multi.label1="value1" \
multi.label2="value2" \
other="value3"
docker inspect查看:
$ docker inspect itbilu/test
"labels": {
"version": "1.0",
"description": "这是一个web服务器",
"by": "ghostwritten"
},
注意:dockerfile中还有个maintainer
命令,该命令用于指定镜像作者。但maintainer并不推荐使用,更推荐使用label来指定镜像作者。如:
label maintainer="ghostwritten"
8. expose
expose用于指定容器在运行时监听的端口:
expose [...]
expose并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p
来发布这些端口,或通过-p
参数来发布expose导出的所有端口。
9. env
env用于设置环境变量,其有以下两种设置形式:
env
env = ...
示例:
env $worker_path /myapp
设置后,这个环境变量在env命令后都可以使用。如:
workerdir $worker_path
docker run可以通过 -e
新添环境变量或者覆盖环境变量。
docker run -tid --name test -e $worker_path /web -e ip=192.168.1.2 ghostwritten/web:v1.0
-e $worker_path /web
为覆盖env $worker_path /myapp
-e ip=192.168.1.2
为新添
10. volume
volume用于创建挂载点,即向基于所构建镜像创始的容器添加卷:
volume ["/data"]
一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
- 卷可以容器间共享和重用
- 容器并不一定要和其它容器共享卷
- 修改卷后会立即生效
- 对卷的修改不会对镜像产生影响
volume创建一个挂载点:
env worker_path /web
volume [$worker_path]
运行容器时,需-v
参将能本地目录绑定到容器的卷(挂载点)上,以使容器可以访问宿主机的数据。
docker run -itd --name web -v ~/data:/web/ ghostwritten/web:v1.0
11. user
user用于指定运行镜像所使用的用户
可以使用用户名、uid或gid,或是两者的组合。
user user
user user:group
user uid
user uid:gid
user user:gid
user uid:group
docker run
运行容器时,可以通过-u
参数来覆盖所指定的用户。
12. workdir
workdir用于在容器内设置一个工作目录:
workdir /path/to/workdir
通过workdir设置工作目录后,dockerfile中其后的命令run、cmd、entrypoint、add、copy等命令都会在该目录下执行。
workdir /a
workdir b
workdir c
run pwd
pwd最终将会在/a/b/c目录中执行。
docker run运行容器时,可以通过-w
参数覆盖构建时所设置的工作目录。
13. arg
arg用于指定传递给构建运行时的变量:
arg [=]
示例:
arg site
arg build_user=ghostwritten
以上我们指定了site和build_user两个变量,其中build_user指定了默认值。在使用docker build构建镜像时,可以通过--build-arg
参数来指定或重设置这些变量的值。
$ docker build --build-arg site=ghostwritten -t ghostwritten/test .
14. onbuild
onbuild用于设置镜像触发器:
onbuild [instruction]
onbuild add . /app/src
onbuild run /usr/local/bin/python-build --dir /app/src
当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发。
示例:
第一个构建镜像的dockerfile,文件名为base.df
from busybox:latest
workdir /app
run touch /app/base-evidence
onbuild run ls -al /app
构建
docker build -t ghostwritten/onbuild:v1.0 -f base.df .
第二个构建镜像的dockerfile,文件名downstream.df
from ghostwritten/onbuild:v1.0
run touch downstream-evidence
run ls -al .
构建
docker build -t ghostwritten/onbuild_down:v1.0 -f downstream.df .
onbuild指令在第一次构建时不会执行,在第二次被引用时会首先执行。
15. stopsignal
stopsignal用于设置停止容器所要发送的系统调用信号:
stopsignal signal
所使用的信号必须是内核系统调用表中的合法的值,如:9、sigkill。
16. shell
shell用于设置执行命令(shell式)所使用的的默认shell类型:
shell ["executable", "parameters"]
shell在windows环境下比较有用,windows下通常会有cmd和powershell两种shell,可能还会有sh。这时就可以通过shell来指定所使用的shell类型。
参考: