• Docker镜像创建的方法及dockerfile详解


    目录

    1.镜像创建方法

    1.1 基于已有镜像创建

    1.2 基于本地模板创建

    1.3 基于dockerfile创建

    2.dockerfile详解

    2.1 联合文件系统

    2.2 镜像加载原理

    2.3 dockerfile

    3.CMD和ENTRYPOINT的区别

    4.ADD和COPY的区别



    1.镜像创建方法

    1.1 基于已有镜像创建

    通过已有的镜像容器来创建镜像

    docker commit [选项] 容器id/容器名 仓库名:标签

     常用选项

    • -m 说明信息
    • -a  作者信息
    • -p  生成过程中停止容器的运行

    1.2 基于本地模板创建

    通过导入操作系统模板文件生成新的镜像,模板可以从开源项目中下载

    wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
    

     下载后导入镜像

    cat debian-7.0-x86-minimal.tar.gz | docker import - debian:标签
    

    1.3 基于dockerfile创建

    通过编写dockerfile文件来创建镜像

    2.dockerfile详解

    2.1 联合文件系统

    UnionFS( 联合文件系统):Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

    另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。

    Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。

    Docker 目前支持的联合文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。

    2.2 镜像加载原理

    Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。

    bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。

    在docher镜像的最底层是bootfs,这一层与我们典型的Linu/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu, Centos等等。

    我们可以理解成一开始内核里什么都没有,操作一个命令下载debin,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在nocer 的体系里把这些rootis叫lhcocker的镜像。但是,此时的每一层srotfe都是read-onlty的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将ocker镜像进行实例化,系统会在一层或是多层read-only的rotis之上分配一层空的read-write的rootfs。

    2.3 dockerfile

    dockerfile结构大致分为:基础镜像信息、维护者信息、镜像操作指令和容器启动指令。dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以#开头的注释

    在编写Dockerfile时,有严格的格式需要遵循: ·第一行必须使用FROM指令指明所基于的镜像名称; 之后使用 MAINTAINER指令说明维护该镜像的用户信息;

    然后是镜像操作相关指令,如 RUN指令。每运行一条指令,都会给基础镜像添加新的一层。

    最后使用 CMD指令指定启动容器时要运行的命令操作。

    dockerfile的镜像分层

    镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上i面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果则除了容器,也就融除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

    • dockerfile中的每个指令都会创建一个新的镜像层
    • 镜像层将被缓存和复用
    • 当dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
    • 某一层的镜像缓存失效,它之后的镜像层缓存都会失效
    • 镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件再docker容器中不可见

    dockerfile常用指令

    指令含义
    FROM [镜像]指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令
    MAINTAINER [名字]说明新镜像的维护人信息
    RUN [命令]在所基于的镜像执行命令,并提交到新的镜像中
    CMD [“要运行的程序”,“参数1”、“参数2”]指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能执行最后一条
    EXPOSE [端口号]指定新镜像加载到Docker时要开启的端口
    ENV [环境变量] [变量值]设置一个环境变量的值,会被后面的RUN使用
    ADD [源文件/目录] [目标文件/目录]将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL,若源文件是压缩包则会将其解压缩
    COPY [源文件/目录] [目标文件/目录]将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中
    VOLUME [“目录”]在容器中创建一个挂载点
    USER [用户名/UID]指定运行容器时的用户
    WORKDIR [路径]为后续的RUN、CMD、ENTRYPOINT指定工作目录,相当于是一个临时的"CD",否则需要使用绝对路径
    ONBUILD [命令]指定所生成的镜像作为一个基础镜像时所要运行的命令(是一种优化)
    HEALTHCHECK健康检查

    使用dockerfile创建ssh镜像

    1. -----------------------构建SSH镜像-------------------------
    2. mkdir /opt/sshd
    3. cd /opt/sshd
    4. vim Dockerfile
    5. #第一行必须指明基于的基础镜像
    6. FROM centos:7
    7. #作者信息
    8. MAINTAINER this is ssh image <wl>
    9. #镜像的操作指令
    10. RUN yum -y update
    11. RUN yum -y install openssh* net-tools lsof telnet passwd
    12. RUN echo 'abc1234' | passwd --stdin root
    13. RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config #不使用PAM认证
    14. RUN sed -ri '/^session\s+required\s+pam_loginuid.so/ s/^/#/' /etc/pam.d/sshd #取消pam限制
    15. RUN ssh-keygen -t rsa -A #生成密钥认证文件
    16. RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
    17. EXPOSE 22
    18. CMD ["/usr/sbin/sshd" , "-D"] #/usr/sbin/sshd -D 用于前台启动sshd服务
    19. //生成镜像
    20. docker build -t sshd:centos .

    3.CMD和ENTRYPOINT的区别

    ​CMD指令​可以指定容器启动时要执行的命令,但它可以被docker run命令的参数覆盖掉。

    ​ENTRYPOINT指令​也可指定容器启动时要执行的命令。如果dockerfile中也有CMD指令,CMD中的参数会被附加到ENTRYPOINT 指令的后面。 如果这时docker run命令带了参数,这个参数会覆盖掉CMD指令的参数,并也会附加到ENTRYPOINT 指令的后面。

    4.ADD和COPY的区别

    ADD和COPY都是复制宿主机文件到镜像内部,但是ADD复制tar包时可以自动解压,COPY命令不行

    ADD支持从网络源下载文件到镜像内,COPY不支持。当ADD下载tar包时,不会进行解压。

  • 相关阅读:
    JMeter入门教程(13) --事务
    leetcode 887 ——扔鸡蛋
    对齐管理后台中的账户体系的四种方法
    回归预测、分类预测、时间序列预测 都有什么区别?
    ubuntu20.04.3中qt程序界面嵌套另一个qt界面
    IT运维:使用数据分析平台监控Windows Eventlog
    算法总结--搜索
    Java的HTML转义工具
    【YOLOv7】使用 YOLOv7 做目标检测 (使用自己的数据集 + 图解超详细)
    9_ROS-Service和ROS-Parameter 相关命令行工具
  • 原文地址:https://blog.csdn.net/kid00013/article/details/125484501