更好的阅读体验建议点击下方原文链接。
原文地址:http://maoqide.live/post/cloud/kubernetes-pattern/
docker build -f Dockerfile -t image_name:v1 .
执行docker build
命令时,docker client 会将当前目录下的文件打包并发送给 docker daemon,这就是 build context。
这个过程会有一定耗时,尤其是 build context 很大的时候,这时候可以用.dockerignore
文件建不需要的大文件忽略,用法和 git 的.gitignore
基本一致。
下面执行docker build
命令的目录, 使用.dockerignore
文件忽略了文件 test1
[root@centos11 images]# ls -la total 102408 drwxr-xr-x. 2 root root 70 Aug 18 22:25 . drwxr-xr-x. 3 root root 20 Aug 18 22:04 .. -rw-r--r--. 1 root root 6 Aug 18 22:11 .dockerignore -rw-r--r--. 1 root root 52 Aug 18 22:19 Dockerfile -rw-r--r--. 1 root root 0 Aug 18 22:08 test -rw-r--r--. 1 root root 104857600 Aug 18 22:11 test1
下面是 docker daemon 进行镜像构建的临时目录
[root@centos11 docker-builder226382581]# pwd /var/lib/docker/tmp/docker-builder226382581 [root@centos11 docker-builder226382581]# ll total 4 -rw-r--r--. 1 root root 52 Aug 18 22:19 Dockerfile -rw-r--r--. 1 root root 0 Aug 18 22:08 test
下面是使用.dockerignore
和不使用时的区别
[root@centos11 images]# time docker build --no-cache -t test . Sending build context to Docker daemon 3.584kB Step 1/2 : FROM alpine ---> a24bb4013296 Step 2/2 : ADD ./test /root ---> e31b37d08034 Successfully built e31b37d08034 Successfully tagged test:latest real 0m0.296s user 0m0.038s sys 0m0.027s
[root@centos11 images]# time docker build --no-cache -t test . Sending build context to Docker daemon 104.9MB Step 1/2 : FROM alpine ---> a24bb4013296 Step 2/2 : ADD ./test /root ---> 1be2b417545d Successfully built 1be2b417545d Successfully tagged test:latest real 0m2.535s user 0m0.069s sys 0m0.086s
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
基础镜像大小差异:
[root@centos11 ~]# docker images alpine REPOSITORY TAG IMAGE ID CREATED SIZE alpine latest a24bb4013296 2 months ago 5.57MB [root@centos11 ~]# docker images centos REPOSITORY TAG IMAGE ID CREATED SIZE centos 7 7e6257c9f8d8 13 days ago 203MB
小的基础镜像上传和下载速度更快,由于包含的软件更少,也能够降低一定的安全漏洞风险。
RUN
指令产生的临时文件需要在当前层清理
FROM alpine RUN dd if=/dev/zero of=temp_file bs=1M count=100 RUN rm -f temp_file
[root@centos11 images]# docker images test1 REPOSITORY TAG IMAGE ID CREATED SIZE test1 latest e0d48f43985e 13 seconds ago 110MB
FROM alpine RUN dd if=/dev/zero of=temp_file bs=1M count=100 &&\ rm -f temp_file
[root@centos11 images]# docker images test2 REPOSITORY TAG IMAGE ID CREATED SIZE test2 latest c31fabd926aa 7 seconds ago 5.57MB
另一种方式是使用多阶段构建(在 Docker 17.05 中引入)。多阶段构建可以在第一个“构建”容器中构建应用,并将结果用于其他容器,同时使用同一 Dockerfile。
FROM golang:1.10 as builder WORKDIR /tmp/go COPY hello.go ./ RUN CGO_ENABLED=0 go build -a -ldflags '-s' -o hello FROM scratch CMD [ "/hello" ] COPY --from=builder /tmp/go/hello /hello
RUN
, COPY
, ADD
指令会增加镜像的层数
RUN apt-get update && apt-get install -y \ aufs-tools \ automake \ build-essential \ curl \ dpkg-sig \ libcap-dev \ libsqlite3-dev \ mercurial \ reprepro \ ruby1.9.1 \ ruby1.9.1-dev \ s3cmd=1.1.* \ && rm -rf /var/lib/apt/lists/*
Docker 镜像缓存可以大幅度加速容器镜像的构建。镜像是逐层构建的,在 Dockerfile 中,每条指令都会在生成的镜像中创建一层。
使用镜像缓存时,Dockerfile 的 ADD 和 COPY 指令,会同时对比指令字符串和对应的文件内容和缓存是否一致,其他指令只会比较指令字符串是否一致,并且仅当所有先前的构建步骤都使用 Docker 的构建缓存时,Docker 才会使用缓存。要充分利用 Docker 构建缓存,必须将经常更改的构建步骤置于 Dockerfile 底部。因此,添加代码的操作应该尽可能放在 Dockerfile 下层。
由于容器与其托管的应用具有相同的生命周期,因此每个容器应仅包含一个应用。当容器启动时,应用也应该启动,当应用停止时,容器也应该停止。
此处“应用”被视为具有唯一父进程且可能具有多个子进程的单个软件。
如果一个容器中具有多个应用,则这些应用可能具有不同的生命周期或处于不同状态。例如,到最后可能出现容器在运行但其某个核心组件崩溃或无响应的情况。如果不进行额外的运行状况检查,则整个容器管理系统(Docker 或 Kubernetes)将无法判断该容器是否运行正常。
Liveness 探测的推荐方法是让应用公开 /health HTTP 端点。在此端点上收到请求后,如果认为运行状况良好,应用应发送“200 OK”响应。在 Kubernetes 中,运行状况良好意味着容器不需要终止或重启。运行状况良好的条件因应用而异,但通常意味着以下情况:
Readiness 探测的推荐方法是让应用公开 /ready HTTP 端点。当应用在此端点上收到请求时,如果其已准备好接收流量,则应发送“200 OK”响应。准备好接收流量意味着以下情况:
指标 HTTP 端点的实现方式和上面两种类似,它通常在 /metrics URI 上公开应用的内部指标。 响应如下:
http_requests_total{method="post",code="200"} 1027 http_requests_total{method="post",code="400"} 3 http_requests_total{method="get",code="200"} 10892 http_requests_total{method="get",code="400"} 97
通过 Prometheus 客户端 SDK 可以轻松生成如上格式的 HTTP 端点。
无状态意味着任何状态数据(任何类型的持久性数据)均存储在容器之外。这种外部存储可以采取多种形式:
不可变意味着容器在其生命周期内不会被修改,即没有更新、没有补丁程序,也没有配置更改。如果必须更新应用代码或应用补丁程序,则必须构建新镜像并重新部署。
不变性使容器部署更安全、更可重复,可在不同环境中使用同一镜像。如果需要回滚,只需重新部署旧镜像即可。
如需在不同环境中使用同一镜像,我们建议您外部化容器配置(监听端口、运行时参数等)在 Kubernetes 中,可以使用 Secrets 或 ConfigMaps 将容器中的配置作为环境变量或文件注入。
如果需要更新配置,请使用更新后的配置部署一个新容器(基于同一镜像)。