DOCKER最佳实践

2020-05-26  本文已影响0人  LittleTrue

让镜像保持小巧

RUN apt-get -y update
RUN apt-get install -y python

RUN apt-get -y update && apt-get install -y python

把应用数据存到哪里,怎样存储

不要通过存储引擎把应用数据存到容器的可写层中。这会增加容器的大小而且从I/O角度看比数据卷或挂载点效率更低。
取而代之的,使用宿主机数据卷存储数据(文件IO/内存IO/数据库IO)。

尽可能使用集群服务

使用持续集成/持续部署(CI/CD)进行开发和测试

当你在代码控制中进行了修改或创建了pull request时,用Docker Cloud或其他CI/CD流程自动构建docker镜像并打标签,然后测试它。Docker Cloud也能把测试过的应用直接发布到生产环境。


DOCKERFILE最佳实践

参考

以下知识点非常重要:
1、编写.dockerignore文件

构建镜像时,Docker需要先准备context ,将所有需要的文件收集到进程中。默认的context包含Dockerfile目录中的所有文件,但是实际上,我们并不需要.git目录,node_modules目录等内容。 .dockerignore 的作用和语法类似于 .gitignore,可以忽略一些不需要的文件,这样可以有效加快镜像构建时间,同时减少Docker镜像的大小。示例如下:

.git/
node_modules/
2、缓存的使用与强制更新

Dockerfile的每条指令都会将结果提交为新的镜像,下一个指令将会基于上一步指令的镜像的基础上构建,如果一个镜像存在相同的父镜像和指令(除了ADD),Docker将会使用镜像而不是执行该指令,即缓存。
为了有效地利用缓存,你需要保持你的Dockerfile一致,并且尽量在末尾修改。

FROM ubuntu
MAINTAINER Michael Crosby <michael@crosbymichael.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update && apt-get upgrade -y

更改MAINTAINER指令会使Docker强制执行RUN指令来更新apt,而不是使用缓存。

所以,我们应该使用常用且不变的Dockerfile开始(译者注:上面的例子)指令来利用缓存。

3、构建中的更新指令依赖基础层级镜像

基于第二点, 开始的层级镜像应该尽量保持不变, 除了尽量利用低层级的缓存外 , 把更新指令(例如APK更新)放到基础层级的镜像, 这也是防止高层级镜像变动持续带来镜像构建非常不确定。

4、基础镜像的标签不要使用latest

当镜像没有指定标签时,将默认使用latest 标签。因此, FROM ubuntu 指令等同于FROM ubuntu:latest。当时,当镜像更新时,latest标签会指向不同的镜像,这时构建镜像有可能失败。如果你的确需要使用最新版的基础镜像,可以使用latest标签,否则的话,最好指定确定的镜像标签。

5、设置WORKDIR和CMD

WORKDIR指令可以设置默认目录,也就是运行RUN / CMD / ENTRYPOINT指令的地方。

CMD指令可以设置容器创建是执行的默认命令。

6、CMD与ENTRYPOINT的语法注意以EXEC方式执行

CMD和ENTRYPOINT指令都非常简单,但它们都有一个隐藏的容易出错的“功能”,如果你不知道的话可能会在这里踩坑,这些指令支持两种不同的语法。

CMD /bin/echo
#or
CMD ["/bin/echo"]

这看起来好像没什么问题,但仔细一看其实两种方式差距很大。如果你使用第二个语法:CMD(或ENTRYPOINT)是一个数组,它执行的命令完全像你期望的那样。如果使用第一种语法,Docker会在你的命令前面加上/bin/sh -c, 如果你不知道Docker修改了CMD命令,在命令前加上/bin/sh -c可能会导致一些意想不到的问题以及难以理解的功能。因此,在使用这两个指令时你应当使用数组语法,因为数组语法会确切地执行你打算执行的命令。

使用CMD和ENTRYPOINT时,请务必使用数组语法。

7、COPY与ADD优先使用前者[COPY]

COPY指令非常简单,仅用于将文件拷贝到镜像中。ADD相对来讲复杂一些,可以用于下载远程文件以及解压压缩包(参考官方文档)。

8、设置默认的环境变量,映射端口和数据

运行Docker容器时很可能需要一些环境变量。在Dockerfile设置默认的环境变量是一种很好的方式。另外,我们应该在Dockerfile中设置映射端口和数据卷。示例如下:

FROM node:7-alpine
 
ENV PROJECT_DIR=/app
 
WORKDIR $PROJECT_DIR
 
COPY package.json $PROJECT_DIR 
RUN npm install 
COPY . $PROJECT_DIR
 
ENV MEDIA_DIR=/media \ 
    NODE_ENV=production \
    APP_PORT=3000
 
VOLUME $MEDIA_DIR 
EXPOSE $APP_PORT
 
ENTRYPOINT ["./entrypoint.sh"] 
CMD ["start"]
9、添加HEALTHCHECK

运行容器时,可以指定--restart always选项。这样的话,容器崩溃时,Docker守护进程(docker daemon)会重启容器。对于需要长时间运行的容器,这个选项非常有用。但是,如果容器的确在运行,但是不可(陷入死循环,配置错误)用怎么办?使用HEALTHCHECK指令可以让Docker周期性的检查容器的健康状况。我们只需要指定一个命令,如果一切正常的话返回0,否则返回1。对HEALTHCHECK感兴趣的话,可以参考这篇博客

上一篇下一篇

猜你喜欢

热点阅读