【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;"]
相关推荐
黄毛火烧雪下1 小时前
【Ruby 】脚本和自动化语言 常用的内容
运维·自动化·ruby
小白不想白a2 小时前
【shell】每日shell练习:安全日志入侵检测/系统配置文件合规检查
运维·服务器
洛克大航海3 小时前
Linux 中新建用户
linux·运维·服务器
三口吃掉你3 小时前
Docker安装Elasticsearch、kibana、IK分词器
elasticsearch·docker·kibana·ik分词器
dehuisun3 小时前
jenkins流水线部署springboot项目
运维·jenkins
fly五行4 小时前
Windows 系统下使用 Docker 安装 Milvus 向量数据库
windows·docker·milvus
爱宇阳4 小时前
离线环境下运行 Docker 容器编排指南
docker·容器·eureka
蜜蜜不吃糖4 小时前
解决Vcenter告警datastore存储容量不足问题
linux·运维·服务器
东城绝神4 小时前
《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署redis 7.4.5容器版分片集群》
linux·运维·redis·架构·分片集群
Java陈序员5 小时前
免费开源!一款操作 MySQL 和 MariaDB 的 Web 界面工具!
mysql·docker·php·mariadb