DockerDocker镜像构建Dockerfile详解镜像优化

Posted dezasseis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DockerDocker镜像构建Dockerfile详解镜像优化相关的知识,希望对你有一定的参考价值。

一、Docker简介

01_简介

  • Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
  • Docker是管理容器的引擎
  • Docker为应用打包、部署平台,而非单纯的虚拟化技术
  • 传统虚拟化与容器技术对比
    在这里插入图片描述
    在这里插入图片描述

02_容器工作原理

在这里插入图片描述

03_镜像的分层结构

在这里插入图片描述

  • 共享宿主机的内核kernel
  • base镜像提供的是最小的Linux发行版
  • 同一docker主机支持运行多种Linux发行版(redhat、ubuntu、debian等)
  • 采用分层结构的最大好处是:共享资源
    在这里插入图片描述
  • Copy-on-Write 可写容器层
  • 容器层以下所有镜像层都是只读的
  • docker从上往下依次查找文件
  • 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
  • 一个镜像最多127层

二、安装与配置

  • 配置软件仓库
    vim /etc/yum.repos.d/docker.repo
[docker]
name=docker-ce#社区版
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo

vim /etc/yum.repos.d/CentOS-Base.repo:执行:%s/$releasever/7/

  • 安装
    yum install -y docker-ce

  • 开启服务
    systemctl enable --now docker.service

  • 配置
    vim /etc/sysctl.d/docker.conf

net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1

sysctl --system

  • 查看信息检测是否成功
    docker info显示 Docker 系统信息,包括镜像和容器数,无警告

  • ip addr查看IP,自动创建接口,添加IP

在这里插入图片描述

三、Docker常用命令

  • docker search yakexi007:查询镜像
  • docker pull yakexi007/game2048:拉取镜像
  • docker images:查看本地镜像
  • docker tag yakexi007/game2048:latest game2048:latest:更改名字 tag为版本
  • docker rmi game2048:删除本地镜像
  • docker history yakexi007/game2048:latest:查看端口

在这里插入图片描述

  • docker run -d --name demo -p 80:80 yakexi007/game2048:后台运行,做端口映射
    在这里插入图片描述

  • docker ps:查看正在运行的容器

  • docker ps -a:查看所有容器

  • docker rm -f demo:删除容器

  • docker inspect yakexi007/game2048:latest:查看镜像的详细信息

  • docker load -i mario.tar :导入本地镜像

四、docker commit 构建新镜像

docker commit 构建新镜像三部曲

  • 运行容器
  • 修改容器
  • 将容器保存为新的镜像

缺点:

  • 效率低、可重复性弱、容易出错
  • 使用者无法对镜像进行审计,存在安全隐患

步骤:

  • 拉取busybox镜像
    docker pull busybox
  • 运行容器
    docker run -it --name demo busybox交互模式,退出即停止容器
  • 修改容器(建立文件)
    在这里插入图片描述
    ctrl+p+q退出交互模式不停止容器
  • 将容器保存为新的镜像
    docker commit -m "add files" demo demo:v1添加说明为add files,镜像名字为demo
  • 测试
    以新构建的镜像运行容器,之前建立的文件还在
    docker run -it --name demo1 demo:v1
    在这里插入图片描述
  • 缺点
    相对比较不知道在新建层做了哪些操作,不能审计
    在这里插入图片描述

五、Dockerfile详解

FROM

  • 指定base镜像,如果本地不存在会从远程仓库下载。

MAINTAINER

  • 设置镜像的作者,比如用户邮箱等。

WORKDIR

  • 为RUN、CMD、ENTRYPOINT、 ADD和COPY指令设置镜像中的当
    前工作目录,如果目录不存在会自动创建(相当于cd)

COPY

  • 把文件从build context复制到镜像
    支持两种形式: COPY src dest和COPY [“srC”, “dest”]
    src必须指定build context中的文件或目录

RUN

  • 运行命令
    创建新的镜像层,常用于安装软件包

mkdir docker

cd docker/

vim Dockerfile

FROM busybox
RUN touch file1
RUN mkdir westos
COPY index.html /

docker build -t demo:v1 .:构建镜像读取当前目录下的Dockerfile

-

docker history demo:v1:有详细的审计信息

-

docker run -it --rm demo:v1:进入查看信息(–rm不缓存)
在这里插入图片描述
ADD

  • 用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像
    ADD html.tar /var/www
    ADD http://ip/html.tar /var/www

tar zcf test.tar.gz /etc

vim Dockerfile

FROM busybox
RUN touch file1
RUN mkdir westos
COPY index.html /
ADD test.tar.gz /mnt##构建进入/mnt/后会自动解压

docker build -t demo:v2 .
在这里插入图片描述
ENV

  • 设置环境变量,变量可以被后续的指令使用:
    ENV HOSTNAME sevrer1.example.com

vim Dockerfile

FROM busybox
ENV HOSTNAME server1

docker build -t demo:v3 .
docker run -it --rm demo:v3
在这里插入图片描述
EXPOSE

  • 如果容器中运行应用服务,可以把服务端口暴露出去
#以nginx为例,导入nginx镜像
docker load -i nginx.tar
docker run -d --name demo nginx#不会映射端口号
docker run -d --name demo -P nginx#自动映射端口号
docker run -d --name demo -p 80:80 nginx #80映射到80端口

VOLUME

  • 申明数据卷,通常指定的是应用的数据挂在点:
    VOLUME ["/var/www/html"]

vim Dockerfile

FROM busybox
RUN touch file1
COPY index.html /
ADD test.tar.gz /mnt
ENV HOSTNAME server1
EXPOSE 80
VOLUME ["/data"]

docker build -t demo:v4 .

docker run -it --rm demo:v4
在这里插入图片描述在这里插入图片描述

docker run -it --name demo demo:v4
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
docker attach demo
在这里插入图片描述

docker rm demo
docker volume ls#查看卷
docker volume prune#删除未被占用的卷(未挂载)
在这里插入图片描述/var/lib/docker/volumes目录下没有卷
在这里插入图片描述
ENTRYPOINT与CMD

  • 这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker
    run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
  • docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
  • Dockerfile中只能指定一个ENTRYPOINT, 如果指定了很多,只有最后一个有效。

vim Dockerfile

FROM busybox
ENV HOSTNAME server1
CMD echo "hello $HOSTNAME"
#CMD ["echo","hello $HOSTNAME"]则是把变量值当成字符串输出hello $HOSTNAME
#CMD ["/bin/sh","-c","echo hello $HOSTNAME"]才是变量

docker build -t demo:v5 .
docker run --rm demo:v5
在这里插入图片描述

vim Dockerfile

RUN touch file1
RUN mkdir westos
COPY index.html /
ADD test.tar.gz /mnt
ENV HOSTNAME server1
EXPOSE 80
VOLUME ["/data"]
ENTRYPOINT ["echo", "hello"]
CMD ["world"]

docker build -t demo:v6 .
docker run --rm demo:v6
在这里插入图片描述
CMD被覆盖
在这里插入图片描述

docker rmi `docker images | grep demo|awk '{print $1":"$2}'批量删除镜像

六、加速器

cd /etc/docker/
vim daemon.json

{
  "registry-mirrors": ["https://qxj9x6qf.mirror.aliyuncs.com"]
}

systemctl daemon-reload
systemctl reload docker

七、镜像优化

  • 随着我们对docker镜像的持续使用,在此过程中如果不加以注意并且优化,镜像的体积会越来越多。很多时候我们在使用docker部署应用时,会发现镜像的体积至少有1G以上。镜像体积的增大,不单单会增加磁盘资源与网络资源的开销,也会影响应用的部署效率,使得应用的部署时间会越来越长。因此我们需要减少部署镜像的体积以加快部署效率,降低资源的开销。而对于镜像的优化,可以通过对dockerfile的优化来实现。
  • 选择最精简的基础镜像
  • 减少镜像层数(RUN命令的使用尽量少,因为一个RUN命令就会建立一层自定义镜像层)
  • 清理景象构建的中间产物
  • 注意优化网络请求
  • 尽量用构建缓存
  • 使用多阶段构建镜像

01_base镜像为官方nginx-1.18.0

docker load -i rhel7.tar:导入rhel7镜像

cd docker/

[root@server1 docker]# ls
Dockerfile  nginx-1.18.0.tar.gz

vim dvd.repo

[dvd]
name=rhel7.6 BaseOS
baseurl=http://192.168.17.1/rhel7.6/
gpgcheck=0

vim Dockerfile

FROM rhel7 as build
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.18.0 && yum remove -y gcc make &&  yum clean all

FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

docker build -t nginx:v1 .:构建镜像
docker images
在这里插入图片描述在这里插入图片描述

02_base镜像为nginx精简版

docker pull gsmlg/distroless-base:下载镜像或
docker pull nginx:1.18.0:下载官网的nginx镜像对比
docker load -i base-debian10.tar
mkdir nginx
cd nginx
vim Dockerfile

FROM nginx:1.18.0 as base

# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE

RUN mkdir -p /opt/var/cache/nginx && \\
    cp -a --parents /usr/lib/nginx /opt && \\
    cp -a --parents /usr/share/nginx /opt && \\
    cp -a --parents /var/log/nginx /opt && \\
    cp -aL --parents /var/run /opt && \\
    cp -a --parents /etc/nginx /opt && \\
    cp -a --parents /etc/passwd /opt && \\
    cp -a --parents /etc/group /opt && \\
    cp -a --parents /usr/sbin/nginx /opt && \\
    cp -a --parents /usr/sbin/nginx-debug /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \\
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \\
    cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \\
    cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \\
    cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime

FROM gcr.io/distroless/base-debian10

COPY --from=base /opt /

EXPOSE 80 443

ENTRYPOINT ["nginx", "-g", "daemon off;"]

docker build -t nginx:v2 .:构建镜像
docker images

在这里插入图片描述

  • 测试

docker run -d --name webserver nginx:v2

docker inspect webserver:查看IP为172.17.0.2
在这里插入图片描述

以上是关于DockerDocker镜像构建Dockerfile详解镜像优化的主要内容,如果未能解决你的问题,请参考以下文章

Docker 构建jdk1.8镜像

Docker——Dockerfile(构建自己的CentOS镜像和Tomcat镜像)并打包镜像发布上线

k8s中jenkins构建maven项目22

dockerdocker镜像和镜像发布方法

云原生|DockerDocker镜像操作

docker学习笔记 --- Dockerfile解析