当前位置: 首页 > news >正文

镜像多阶段构建-YAML-Compose

一、镜像 Cache 机制

1.镜像Cache机制简述

  • Docker Daemnon 通过 Dockerfile 构建镜像时,当发现即将新构建出的镜像与已有的某镜像重复时,可以选择放弃构建新的镜像,而是选用已有的镜像作为构建结果,也就是采取本地已经 cache 的镜像作为结果
# 在构建镜像的时候,会优先使用已缓存的镜像缩短构建时间
[root@localhost dockerfile-arg-env]# docker build -t nginx:v1 .=> CACHED [2/5] WORKDIR /data                                                                                                                 0.0s=> CACHED [3/5] COPY nginx.repo /etc/yum.repos.d/nginx.repo                                                                                   0.0s=> CACHED [4/5] RUN  yum -y install nginx-1:1.26.1-1.el9.ngx.x86_64 && yum clean all                                                          0.0s=> CACHED [5/5] RUN echo "daemon off;" >> /etc/nginx/nginx.conf    

注:所以在构建镜像的时候要尽量使用缓存

2.查看镜像缓存

[root@localhost ~]# docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLEBuild Cache     96        0         448.7MB   448.7MB

3.缓存注意事项

  • ADD 命令、COPY 命令和RUN 命令都会产生缓存
  • ADD 命令或者 COPY 命令后紧接的文件发生变化,则原则上不再使用缓存
  • RUN 命令存在外部依赖,如安装命令变更或更新,用户可以使用参数 --no-cache 确保获取最新的外部依赖,命令为docker build --no-cache -t="my_new_image"

注:只要一层不走缓存, 接下去的所有层都不走缓存(所以优先把不会变更的放前面,如静态的安装、配置命令)

二、Docker 多阶段构建

1.Go语言编译

1.编写Go文件
[root@localhost gin-demo]# pwd
/root/09-multistage-build/gin-demo
[root@localhost gin-demo]# cat main.go 
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {router := gin.Default()router.GET("/ping", func(c *gin.Context) {c.String(http.StatusOK, "PONG")})router.Run(":8080")
}2.编写配置文件
[root@localhost gin-demo]# cat Dockerfile-build
FROM golang:1.20 as buildENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn    # 使用代理WORKDIR /go/src/app
COPY . .RUN go mod download    # 下载依赖
RUN CGO_ENABLED=0 go build -o /go/bin/app    # 编译生成二进制文件3.制作镜像
[root@localhost gin-demo]# docker build -t go-app:v1 -f Dockerfile-build .4.从容器中提取二进制文件
[root@localhost gin-demo]# docker run -it go-app:v1 bash
root@a6f10e054cb9:/go/src/app#
# 另开终端
[root@localhost gin-demo]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS     NAMES
a6f10e054cb9   go-app:v1      "bash"                    22 seconds ago   Up 22 seconds             reverent_wilson[root@localhost gin-demo]# docker cp a6f10e054cb9:/go/bin/app .
Successfully copied 11.2MB to /root/09-multistage-build/gin-demo/.
[root@localhost gin-demo]# ls
app  Dockerfile  Dockerfile-build  Dockerfile-distroless  Dockerfile-multistage  go.mod  go.sum  main.go5.测试
[root@localhost gin-demo]# ./app
# 另开终端
[root@localhost gin-demo]# curl 127.0.0.1:8080/ping
PONG[root@localhost gin-demo]# 

2.Go语言制作镜像

配置文件:

[root@localhost gin-demo]# cat Dockerfile
FROM alpine:3.18
COPY app /
CMD ["/app"]

制作镜像:

[root@localhost gin-demo]# docker build -t go-app:v2 .
[root@localhost gin-demo]# docker images go-app:v2
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
go-app       v2        eefe620ec200   57 seconds ago   18.6MB# 可以看到当前镜像的大小只有18.6MB,可以直接运行
[root@localhost gin-demo]# docker run -d go-app:v2
3a292993c95cd7c8eb46a964c636ba66efa73f153006568120fe4abb5e2f53d0

3.多阶段构建

注:一次性构建镜像,将之前的两步结合在一起

配置文件:

[root@localhost gin-demo]# cat Dockerfile-multistage 
# Start by building the application.
FROM golang:1.20 as buildENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cnWORKDIR /go/src/app
COPY . .RUN go mod download
RUN CGO_ENABLED=0 go build -o /go/bin/app# Now copy it into our base image.
FROM alpine:3.18
COPY --from=build /go/bin/app /
CMD ["/app"]

制作镜像:

[root@localhost gin-demo]# docker build -t go-app:v3 -f Dockerfile-multistage .
[root@localhost gin-demo]# docker run -d go-app:v3 
440f8219b75fd2c2ae26e1b8b3079345683093bf1ac3ef9e071edc7a9b05ce0c
[root@localhost gin-demo]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS     NAMES
440f8219b75f   go-app:v3      "/app"                    3 seconds ago   Up 2 seconds             practical_heisenberg

问题:多阶段构建主要在什么场景下使用?

  • 适合编译型语言制作镜像时使用

4. Dockerfile 最佳实践 BP

  • 不要安装无效软件包

  • 应简化镜像中同时运行的进程数,理想状况下,每个镜像应该只有一个进程

  • 如果无法避免同一镜像运行多进程时,应选择合理的初始化进程(init process)

  • 最小化层级数

    • 最新的Docker只有 RUN、COPY、ADD 创建新层,其他指令创建临时层,不会增加镜像大小。比如 EXPOSE 指令就不会生成新层。

    • 多条 RUN 命令可通过连接符连接成一条指令集,以减少层数 &&

    • 通过多阶段构建减少镜像层数

  • 编写 Dockerfile 的时候,应该把变更频率低的编译指令优先构建,放在镜像底层,有效利用 build cache

  • 复制文件时,每个文件应独立复制,这确保某个文件变更时,只影响该文件对应的缓存

  • 选择可以满足业务需求最优的 base image

三、YAML语言

1.三种常见的数据格式

  • XML:可扩展标记语言, 可用于数据交换和配置

  • JSON:对象标记法, 主要用于数据交换和配置,不支持注释

  • YAML:不是一种标记语言, 主要用于应用启动时提供配置文件,大小写敏感

2.YAML 简介

YAML 语言实质上是一种通用的数据串行化格式,基本语法规则如下:

  • 使用空白与缩进表示层次(有点类似 Python),可以不使用花括号和方括号。

  • 可以使用 # 书写注释,比起 JSON 是很大的改进。

  • 对象(字典)的格式与 JSON 基本相同,但 Key 不需要使用双引号。

  • 数组(列表)是使用 - 开头的清单形式(有点类似 MarkDown)。

  • 表示对象的 : 和表示数组的 - 后面都必须要有 空格

  • 可以使用 --- 在一个文件里分隔多个 YAML 对象

3.YAML 数据结构

  • 对象:键值对的集合,又称为 映射(mapping)/ 哈希(hashes) / 字典(dictionary)

  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)

  • 纯量(scalars):单个的、不可再分的值

(1)数组

OS:- linux- macOS- Windows  

(2)对象

Kubernetes:master: 1worker: 3

(3)复合结构

languages:​- Ruby​- Perl​- Python ​
websites:​YAML: yaml.org ​Ruby: ruby-lang.org ​Python: python.org ​Perl: use.perl.org

(4)纯量 标量

# 数值直接以字面量的形式表示:
number: 12.30# 布尔值用true和false表示
isSet: true# 时间采用 ISO8601 格式
iso8601: 2001-12-14t21:59:43.10-05:00

(5)字符串

# 字符串默认不使用引号表示
str: 这是一行字符串# 如果字符串之中包含 空格或特殊字符,需要放在引号之中
str: '内容: 字符串'# 单引号和双引号都可以使用,双引号不会对特殊字符转义
s1: '内容\n字符串'
s2: "内容\n字符串"# 字符串可以写成多行,从第二行开始,必须有一个单空格缩进
str: 这是一段多行字符串# 多行字符串可以使用|保留换行符,也可以使用>折叠换行
this: |FooBar
that: >FooBar# +表示保留文字块末尾的换行,-表示删除字符串末尾的换行
s1: |FooBarSecond s2: |+Foos3: |-Foo

补充:可以用工具互相转换,参考网站

https://www.json2yaml.com/

http://www.bejson.com/json/json2yaml/

注:多行文本转换,注意缩进和管道符;多个yaml写到一个文件里面,注意用---隔开

四、Docker Compose

1.简介

  • Compose 负责实现对 Docker 容器集群的快速编排,一台服务器,多个容器编排
  • 定义和运行多个 Docker 容器的应用
  • 允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)
  • 服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。​
  • 项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
  • 默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理

2.安装

补充说明:目前 Docker 官方用 GO 语言重写了 Docker Compose,并将其作为了 docker cli 的子命令,称为 Compose V2。你可以参照官方文档安装,然后将 v1 版的 docker-compose 命令替换为 docker compose,即可使用 Docker Compose

  • 查看当前版本
[root@localhost ~]# docker compose version
Docker Compose version v2.40.3

3.compose应用模型

一个项目由以下几部分组成:

  • services

  • networks

  • volumes

  • configs

  • secrets

如何启动?

docker run  --name=webapp \-v /data/app/conf:/etc/nginx/conf.d:ro \ -v /data/app/certs:/etc/nginx/certs:ro \-p 443:443 \--network frontend \--network backend  \--restart=always \webapp:v1 # 站在容器的角度考虑,有很多参数我们是不清楚的,所以最好用compose.yml

Compose 声明文件:

services:  # 描述 容器frontend:image: example/webappports:- "443:8043"- "8080:80"networks:- front-tier- back-tierconfigs:- httpd-config  # 名字  secrets:- server-certificatebackend:image: example/databasevolumes:- db-data: /data/databasenetworks:- back-tiervolumes:db-data:driver: localdriver_opts:size: "10GiB"configs:httpd-config:file: ./httpd-config.confsecrets:server-certificate:file: ./xxx.crtnetworks:# The presence of these objects is sufficient to define themfront-tier: {}back-tier: {}

4.常用的顶级指令top-level

  • - services  必须 -描述 容器-启动方式 
  • - volumes
  • - networks 
  • - configs 
  • - secrets 

五、Compose 项目

1.配置安装相关文件

注:关于这些文件已经上传到资源中了,可以自行下载

[root@localhost 01-compose-python-demo]# pwd
/root/08-docker-compose/dockercompose-example/01-compose-python-demo
[root@localhost 01-compose-python-demo]# ll
总用量 16
-rw-r--r-- 1 root root 565  2月 21  2025 app.py
-rw-r--r-- 1 root root 162 11月 12 15:05 compose.yml
-rw-r--r-- 1 root root 241 11月 12 15:01 Dockerfile
-rw-r--r-- 1 root root  12  2月 21  2025 requirements.txt

2.安装python环境

# 安装pip命令
[root@localhost 01-compose-python-demo]# dnf -y install python3-pip
# 安装依赖
[root@localhost 01-compose-python-demo]# pip install -r requirements.txt

3.修改配置文件

# 镜像配置文件
[root@localhost 01-compose-python-demo]# cat Dockerfile 
FROM registry.cn-beijing.aliyuncs.com/xxhf/python:3.7-alpine 
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]# 定义compose声明文件
[root@localhost 01-compose-python-demo]# cat compose.yml 
services:web:image: python-app:v1 #build: .ports:- "8000:5000"redis:image: registry.cn-beijing.aliyuncs.com/xxhf/redis:alpine

4.制作python镜像

注:在当前目录下使用docker compose命令

[root@localhost 01-compose-python-demo]# docker build -t python-app:v1 .
# 启动容器
[root@localhost 01-compose-python-demo]# docker compose up -d
[+] Running 2/2✔ Container 01-compose-python-demo-redis-1  Started                                                                           0.7s ✔ Container 01-compose-python-demo-web-1    Started                                                                           0.8s # 显示当前项目的容器
[root@localhost 01-compose-python-demo]# docker compose ps
NAME                             IMAGE                                                COMMAND                   SERVICE   CREATED         STATUS          PORTS
01-compose-python-demo-redis-1   registry.cn-beijing.aliyuncs.com/xxhf/redis:alpine   "docker-entrypoint.s…"   redis     2 minutes ago   Up 31 seconds   6379/tcp
01-compose-python-demo-web-1     python-app:v1                                        "flask run"               web       2 minutes ago   Up 31 seconds   0.0.0.0:8000->5000/tcp, [::]:8000->5000/tcp# 测试
[root@localhost 01-compose-python-demo]# curl 127.0.1:8000/
Hello World! I have been seen 1 times.
[root@localhost 01-compose-python-demo]# curl 127.0.1:8000/
Hello World! I have been seen 2 times.
[root@localhost 01-compose-python-demo]# curl 127.0.1:8000/
Hello World! I have been seen 3 times.
[root@localhost 01-compose-python-demo]# curl 127.0.1:8000/ping
pong# 查看日志
[root@localhost 01-compose-python-demo]# docker compose logs -f# 停止运行
[root@localhost 01-compose-python-demo]# docker compose down
[+] Running 3/3✔ Container 01-compose-python-demo-web-1    Removed                                                                          10.2s ✔ Container 01-compose-python-demo-redis-1  Removed                                                                           0.3s ✔ Network 01-compose-python-demo_default    Removed                                                                           0.2s

注:不管是docker compose up 还是docker compose ps,都省略了指定路径的-f选项,默认选择了当前目录下的compose.yml文件

http://www.dtcms.com/a/603026.html

相关文章:

  • 每日一题 —— [NOIP 2007 普及组] 纪念品分组
  • 如何用wordpress建站自动搭建网站源码
  • 长沙竞价网站建设价格福田深圳网站建设
  • 查企业资质上什么网站网页源代码查找指定文字
  • 重庆蒲公英网站建设公司怎么样网络营销是什么 能做什么
  • c语言反编译工具 | 探讨C语言反编译工具的应用与发展趋势
  • 关系的网站织梦网站怎样做子域名
  • 最牛网站设计公司门户首页网站建设方案
  • 网站建设 seojsc易企秀类似的软件
  • LODE(Loss Decoupling)个人理解
  • 成都网站建设3六六俄罗斯门户网站
  • 淮南房地产网站建设网站睿思设计
  • 十七、自然语言处理概述
  • 微信手机网站流程湖南软件定制开发
  • 如何做自己产品网站企业网站建设杭州公司
  • C++ 离散化
  • 人力资源网站怎么做品牌网站设计公司价格
  • 网站建设包含专业html修改成wordpress主题
  • 网站开发总结与未来展望网络营销推广专家
  • 柳州企业网站建设价格wordpress宽屏
  • C++11——RAII 锁封装类
  • 怎样在工商局网站做公示南宁兴宁区建设局网站
  • 自己做网站的准备工作个人网站设计html
  • 张家界建设局网站电话号码郑州最新发布
  • 宁波网站建设在哪里服务好的武进网站建设
  • 被骗去国外做网站网站推广国外的建筑设计案例网站
  • 云服务器可以建设个人网站吗网页游戏开服表1区
  • 如何在 Windows 上安装 MySQL(保姆级教程2024版)
  • havoc安装
  • 长沙网站建设排名一个网站项目几个人做