【DOCKER】-4 dockerfile镜像管理

文章目录

    • 1、镜像分层原理
      • [1.1 镜像分层的实际应用案例](#1.1 镜像分层的实际应用案例)
    • 2、dockerfile基础与语法
      • [2.1 指令分解](#2.1 指令分解)
      • [2.2 编写dockerfile的注意事项](#2.2 编写dockerfile的注意事项)
    • 3、dockerfile制作镜像实践
    • 4、dockerfile镜像优化
      • [4.1 镜像的优化策略](#4.1 镜像的优化策略)
      • [4.2 镜像优化实战](#4.2 镜像优化实战)
        • [4.2.1 减少镜像层,减少无效缓存](#4.2.1 减少镜像层,减少无效缓存)
        • [4.2.2 选择更合适的基础镜像](#4.2.2 选择更合适的基础镜像)
        • [4.2.3 多阶段构建](#4.2.3 多阶段构建)

1、镜像分层原理

1.1 镜像分层的实际应用案例

  • 在开发过程中,开发人员可以通过Dockerfile快速构建应用程序的镜像。由于Docker镜像采用分层结构,因此每次构建时只需要重新生成发生变化的层,从而大大提高了构建效率。
  • 在持续集成/持续部署(CI/CD)流程中,Docker镜像的分层结构使得每次构建、测试和部署都变得更加快速和可靠。通过利用缓存机制,可以避免重复构建相同的层,从而加速整个流程。
  • 在容器编排场景中,如Kubernetes等容器编排工具可以利用Docker镜像的分层结构来优化存储和网络传输。通过只传输发生变化的层,可以大大减少网络带宽的占用和存储空间的消耗。

2、dockerfile基础与语法

【注】:ARG为运行时所执行的命令

2.1 指令分解

bash 复制代码
FROM:指定基础镜像
指定构建新镜像时使用的基础镜像,通常必须是Dockerfile的第一个有效指令

# 格式
FROM <image:[版本标签]>
 
# 指定基础镜像
FROM centos
FROM ubuntu:20.04
 
# 说明:如果不指定版本标签,默认使用latest



LABEl:添加镜像的元数据
LABEL一般使用键值对方式。

# 格式
LABEL <key>=<value> <key>=<value>....
 
# 为镜像添加元数据
LABEL version="2.0" description="业务系统第二个版本"
 
# 说明:一条LABEL可以指定多条元数据,尽量不要写多个LABE


RUN:构建镜像时执行的命令
有两种执行方式

方式一:shell执行

# 格式
RUN <command>
 
# 示例
RUN yum update -y
 
# 说明:RUN 指令创建的中间镜像会被缓存,并在下次构建中使用。可以在构建时使用--no-cache取消缓存:
docker build --no-cache



ENV:在容器内部设置环境变量
# 格式
ENV <key> <value>
 
# 示例
ENV MYPATH /usr/local


ADD:将本地文件添加到镜像中
相当于scp。只是scp 需要将用户名和密码的权限验证,而ADD 不用。

tar 类型文件会自动解压,可以访问网络资源,类似 wget

# 语法
ADD <src> <dest>
ADD ["src", "dest"]
 
# 示例
COPY nginx.tar /opt
 
# 说明:路径可以是相对路径或绝对路径,建议使用绝对路径。
# 尽量不要把<src> 写成一个文件夹,如果<src> 是一个文件夹,复制整个目录的内容



COPY:将文件或目录复制到镜像中。
功能类似 ADD,但不会自动解压文件,也不能访问网络资源

# 语法
COPY <src> <dest>
COPY ["<src>", "<dest>"]



VOLUME:指定持久化目录
# 格式
VOLUME ["/path/to/dir"]
 
# 示例
VOLUME ["/data"]
VOLUME ["/data/log", "/data/config"]
# 一个卷可以存在于一个或多个容器的指定目录,

该目录可以绕过联合文件系统
容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。所以如果想要数据持久化,就得使用VOLUME

功能说明:卷可以在容器间共享和重用;修改卷后会立即生效;对卷的修改不会对镜像产生影响


 CMD:容器启动时运行的命令(不常用)
# 语法
CMD ["executable","param1","param2"]
CMD command param1 param2
  
# 示例
CMD echo $LANG


ENTRYPOINT:容器启动时运行的命令(常用)
# 语法
ENTRYPOINT ["executable", "param1", "param2"] 
ENTRYPOINT command param1 param2
  
# 示例
ENTRYPOINT java -jar /data/config.jar



ENTRYPOINT:容器启动时运行的命令(常用)
# 语法
ENTRYPOINT ["executable", "param1", "param2"] 
ENTRYPOINT command param1 param2
  
# 示例
ENTRYPOINT java -jar /data/config.jar

ENTRYPOINT和CMD的异同点:

共同点:都可以用来指定容器的启动命令
区别:ENTRYPOINT指定的容器启动命令优先级更高,如果ENTRYPOINT和CMD同时存在,那么
CMD指定的内容将作为ENTRYPOINT指定的命令传入参数使用。
COPY可以在多阶段构建种复制构建结果到当前构建中


EXPOSE:暴露容器运行时的监听端口给外部
# 格式:
EXPOSE <port> [<port>...]
 
# 示例:
EXPOSE 8080
EXPOSE 443/tcp 80/tcp

EXPOSE 并不会让容器的端口访问到主机。 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口

如果没有暴露端口,后期也可以通过docker run -p 8080:8080 方式映射端口,但不能通过 -P 形式映射

2.2 编写dockerfile的注意事项

  1. 精简镜像:尽量使用官方的基础镜像,减少不必要的文件和依赖,以降低镜像大小。
  2. 优化指令:合理安排Dockerfile中的指令顺序,利用Docker的缓存机制,提高构建效率。
  3. 权限设置:注意文件和目录的权限设置,确保容器运行时的安全性
  4. 可读性:保持Dockerfile的简洁明了,添加必要的注释,提高可读性。

3、dockerfile制作镜像实践

示例:

bash 复制代码
#创建工作目录
[root@localhost ~]#  mkdir /opt/nginx_dockerfile
[root@localhost ~]# cd /opt/nginx_dockerfile

#编写dockerfile
# 使用官方的Nginx基础镜像
FROM nginx:alpine
 
# 将当前目录下的内容复制到容器的/usr/share/nginx/html目录下
COPY . /usr/share/nginx/html
 
# 暴露80端口供外部访问
EXPOSE 80
 
# 当Docker容器启动时,自动启动Nginx服务
CMD ["nginx", "-g", "daemon off;"]

#准备网站页面
[root@localhost ~]# echo "this is nginx web" > index.html

#制作镜像
[root@localhost ~]# docker build -t nginx:v1 . --no-cache

#运行容器
docker run -d --name nginx_v1 -p 1218:80 nginx:v1

#测试访问
#浏览器访问 http://主机IP:1218/
#或curl http://主机IP:1218

4、dockerfile镜像优化

4.1 镜像的优化策略

  • 选择轻量级基础镜像:如Alpine、Debian等,避免使用过于庞大的基础镜像。
  • 多阶段构建:利用Dockerfile的多阶段构建特性,只将必要的文件和依赖打包到最终镜像中。
  • 使用.dockerignore文件:在构建镜像时,通过.dockerignore文件排除不必要的文件和目录,减少构建上下文的大小。
  • 清理无用文件和缓存:在Dockerfile中使用命令清理编译过程中生成的临时文件和缓存,减小镜像体积。

4.2 镜像优化实战

4.2.1 减少镜像层,减少无效缓存
bash 复制代码
##将RUN指令合并,把频繁变动的COPY指令后移,减少缓存失效

FROM centos:7
RUN rm -rf /etc/yum.repos.d/*
COPY CentOS-aliyun-lhr.repo epel-aliyun.repo /etc/yum.repos.d/
ADD nginx-1.22.0.tar.gz /opt
RUN yum clean all &&  yum makecache &> /dev/null && \
    yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null && \
    useradd -M -s /sbin/nologin nginx
ADD nginx-1.22.0.tar.gz /opt
RUN cd /opt/nginx-1.22.0 && \
    ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx &> /dev/null && \
    make &> /dev/null && \
    make install &> /dev/null && \
    ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
4.2.2 选择更合适的基础镜像
bash 复制代码
FROM alpine:3.22.0
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/' /etc/apk/repositories \
    && apk update && apk --no-cache add \
    tzdata gcc make net-tools \
    libc-dev libcurl \
    pcre-dev zlib-dev libnfs pcre pcre2  \
    && addgroup -g 888 -S nginx \
    && adduser -s /sbin/nologin -S -D -u 888 -G nginx nginx

ADD nginx-1.22.0.tar.gz /usr/local/src

RUN cd /usr/local/src/nginx-1.22.0 \
    && ./configure --prefix=/usr/local/nginx \
    && make \
    && make install \
    && ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx \
    && chown -R nginx:nginx /usr/local/nginx/ \
    && apk add bash
EXPOSE 80
CMD ["usr/local/nginx/sbin/nginx","-g","daemon off;"]
4.2.3 多阶段构建
bash 复制代码
# 第一阶段:构建环境
FROM alpine:3.18 as builder

ARG NGINX_VERSION=1.22.0
RUN apk add --no-cache \
    gcc \
    libc-dev \
    make \
    openssl-dev \
    pcre-dev \
    zlib-dev \
    && wget -O nginx.tar.gz http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz \
    && tar -xzf nginx.tar.gz \
    && cd nginx-${NGINX_VERSION} \
    && ./configure --prefix=/usr/local/nginx \
    && make \
    && make install

# 第二阶段:运行时镜像
FROM alpine:3.18 as runtime

COPY --from=builder /usr/local/nginx /usr/local/nginx
#COPY nginx.conf /usr/local/nginx/conf/nginx.conf
#COPY html/ /usr/local/nginx/html/

RUN adduser -D nginx \
    && chown -R nginx:nginx /usr/local/nginx

USER nginx
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
相关推荐
Gold Steps.14 分钟前
基于 Gitlab、Jenkins与Jenkins分布式、SonarQube 、Nexus 的 CiCd 全流程打造
运维·ci/cd·gitlab·jenkins
5283031 分钟前
Kubernetes 高级调度 01
云原生·容器·kubernetes
xujiangyan_42 分钟前
Kubernetes的微服务
微服务·容器·kubernetes
Ruimin05191 小时前
LSV负载均衡
linux·运维·服务器·负载均衡·lvs
AuroraDPY1 小时前
Linux 环境变量
linux·运维·服务器
Ronin3052 小时前
【Linux系统】进程切换 | 进程调度——O(1)调度队列
linux·运维·服务器·ubuntu
药9554 小时前
网络编程(TCP连接)
运维·服务器
ikun·5 小时前
Kubernetes 高级调度01
云原生·容器·kubernetes
菜萝卜子5 小时前
【Linux】Ubuntu22.04安装zabbix
linux·运维·zabbix