随着业务架构的整改,针对非容器化业务全部进行容器化改造,这就设计到了java写的业务代码构建业务镜像,并通过k8s发版,因此,就得学习如何使用dockerfile构建后端业务镜像,可能不止构建后端代码镜像,例如前端写的代码也有可能构建为镜像。还有可能就是要在原有镜像基础上进行二次封装,例如:在原有的业务镜像中封装skywalking链路追踪监控、jvm监控等等,后续就有示例。
Dockerfile 是一个用来构建镜像的文本文件, Dockerfile内容中包含了一条条构建镜像所需的指令和说明。最终采用docker build 命令通过dockerfile中指令构建镜像
格式:
FROM <image>
FROM <image>:<tag>
示例:
FROM mysql:5.7
注意:
tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
一般可以不用这个参数,使得镜像尽量小而轻
格式:
MAINTAINER <name>
示例:
MAINTAINER Yongxin Li
MAINTAINER inspur_lyx@hotmail.com
MAINTAINER Yongxin Li <inspur_lyx@hotmail.com>
格式:
COPY <src>... <dest>
示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
注意:
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行
格式:
RUN <command>
示例:
RUN yum install nginx
RUN pip install django
RUN mkdir test && rm -rf /var/lib/unusedfiles
注意:
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD ["/usr/bin/wc","--help"]
CMD ping www.baidu.com
注意:
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
ENTRYPOINT ["/usr/bin/wc","--help"]
ENTRYPOINT ["sh","-c","sh bin/launch.sh start && tail -f start.log"]
注意:
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
格式:
ENV <key> <value>
ENV <key>=<value>
示例:
ENV myName John
ENV myCat=fluffy
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注意:
EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
VOLUME <path>
示例:
# 在容器内创建一个挂载点 /data,用于存储数据。
VOLUME /data
# 在容器内创建两个挂载点 /data1 和 /data2。
VOLUME /data1 /data2
# 在容器内创建三个挂载点,其中前两个是匿名卷,最后一个是命名卷。命名卷允许通过名称进行引用,使其可以在多个容器之间共享和重用。
VOLUME ["/data1", "/data2", "named_volume:/data3"]
USER <user>[:<group>]
# 在容器中以 myuser 用户身份运行。
USER myuser
# 在容器中以 myuser 用户身份,且属于 mygroup 用户组运行。
USER myuser:mygroup
该dockerfile就是在原有的业务镜像基础上进行的二次封装,封装了skywalking监控、jmx_exporter监控组件
因为后端是java写的,所以用jdk8镜像为底层镜像
FROM xx.xx.xx.xx/xx/openjdk:8
COPY $jarPath/*.jar /usr/local/src/app.jar
COPY ./jmx_prometheus_javaagent-0.16.1.jar /export/server/skywalking/jmx/
COPY ./config.yaml /export/server/skywalking/jmx/
WORKDIR /usr/local/src/
ENTRYPOINT exec java -Xmx1024m -Xms1024m -Duser.timezone=Asia/Shanghai -javaagent:/export/server/skywalking/agent/skywalking-agent.jar -javaagent:/export/server/skywalking/agent/jmx_prometheus_javaagent-0.16.1.jar=19000:/export/server/skywalking/agent/config.yaml -jar app.jar
该dockerfile就是一个将前端也构建为镜像,进行启动管理.
FROM node:12.19.0
WORKDIR /output
COPY ./output /output
EXPOSE 3001
ENV NODE_ENV=production
CMD nohup npm run start >out.log 2>&1 && tail -f out.log
构建指令
docker build -t 镜像名称:标签 . (.点代表在Dockerfile目录层级下执行)
docker build -f /path/to/Dockerfile -t image_name:tag . (未在dockerfile目录层级下执行)
方法一、--platform=参数
docker build --platform=linux/arm64,linux/amd64 -t 镜像名称:标签 . 构建arm64和amd64操作系统的镜像
方法二、 Docker CLI 插件管理器buildx
1、安装buildx
docker buildx install
2、创建一个新的构建器实例
docker buildx create --name mybuilder
3、启用构建器实例
docker buildx use mybuilder
4、构建镜像
docker buildx build --platform <platform> -t image_name:tag .
- 不必要的内容不要放在镜像中
- 减少不必要的层文件
- 减少网络传输操作
- 可以适当的包含一些调试命令