Docker 学习笔记(七):介绍 Dockerfile 相关知识,使用 Dockerfile 构建自己的 centos 镜像

一、前言

记录时间 [2024-4-12]

系列文章简摘:
Docker学习笔记(二):在Linux中部署Docker(Centos7下安装docker、环境配置,以及镜像简单使用)
Docker 学习笔记(三):Centos7 中 Docker 使用,镜像、容器,以及操作等常用命令小结
Docker 学习笔记(五):梳理 Docker 镜像知识,附带 Commit 方式提交镜像副本,安装可视化面板 portainer
Docker 学习笔记(六):挑战容器数据卷技术一文通,实战多个 MySQL 数据同步,能懂会用,初学必备

更多 Docker 相关文章请参考上面专栏哦,入门篇 1~5 已完结6 开始是精髓篇:容器数据卷、Dockerfile、Docker 网络。


本文主要介绍 Dockerfile,包括 Dockerfile 的构建过程、Dockerfile 的指令,以及 Dockerfile 的使用方式。通过实战,学会使用 Dockerfile 构建自己的 centos 镜像,讲述了 CMD 和 ENTRYPOINT 的区别,解决基础镜像 centos 无法使用 yum -y 命令的问题。

学习工具包:

  • Docker 学习视频
  • Docker 官方文档
  • Docker 远程仓库
  • Linux 云服务器/虚拟机
  • FinalShell 远程连接工具

二、Dockerfile 介绍

Dockerfile 是用来构建 Dokcer 镜像的文件,是一种命令参数脚本。

构建步骤如下:

  1. 编写一个 Dockerfile
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub / 阿里云镜像仓库)

在 DockerHub 中搜索 centos

在这里插入图片描述


我们来查看下 centos7 的 Dockerfile 脚本:

# scratch 是一个基础镜像,90% 的镜像来源于它
# 基于 scratch,然后添加需要的软件和配置来进行构建
FROM scratch# 添加一个压缩包
ADD centos-7-x86_64-docker.tar.xz /# 添加标签
LABEL \org.label-schema.schema-version="1.0" \org.label-schema.name="CentOS Base Image" \org.label-schema.vendor="CentOS" \org.label-schema.license="GPLv2" \org.label-schema.build-date="20201113" \org.opencontainers.image.title="CentOS Base Image" \org.opencontainers.image.vendor="CentOS" \org.opencontainers.image.licenses="GPL-2.0-only" \org.opencontainers.image.created="2020-11-13 00:00:00+00:00"# 控制台方式运行
CMD ["/bin/bash"]

不难发现,大部分官方镜像都是基础包,功能很少,在使用中我们通常会搭建自己的镜像。

接下来我们尝试自己制作镜像。


三、Dockerfile 构建过程

基础知识:

  • 保留关键字(指令)必须是大写字母
  • 指令从上到下顺序执行
  • # 表示注释
  • 每一个指令都会创建并提交一个新的镜像层

在这里插入图片描述


Dockerfile 面向开发,通过编写 Dockerfile 文件,我们可以构建镜像、发布项目。

  • Dockerfile:构建文件,相当于源代码,定义了所有步骤;
  • DockerImage:通过 Dockerfile 构建生成的镜像;
  • DockerContainer:容器提供镜像运行的服务器。

Docker 镜像逐渐成为企业交付的标准,实现开发,部署,运维全流程。


四、Dockerfile 指令

了解这些指令后,我们就可以构建自己的 Docker 镜像。

Dockerfile 中常用的指令有:

  • FROM:基础镜像,一切从这里开始构建。
  • MAINTAINER:镜像是谁写的?姓名 + 邮箱。
  • RUN:镜像构建的时候需要运行的命令。
  • ADD:添加构建内容,如构建 tomcat 镜像,就添加 tomcat压缩包。
  • WORKDIR:镜像的工作目录。
  • VOLUME:挂载的目录。
  • EXPOSE:暴露端口配置。
  • CMD:指定这个容器启动时要运行的命令,只有最后一个会生效,可被替代
  • ENTRYPOINT:指定这个容器启动时要运行的命令,可以追加命令
  • ONBUILD:当构建一个被继承的 Dockerfile 时,会运行 ONBUILD 指令,触发指令。
  • COPY:类似 ADD,将文件拷贝到镜像中。
  • ENV:构建的时候设置环境变量。

五、实战测试

实战测试:使用 Dockerfile 创建自己的 centos 镜像。

1. 准备工作

先看一眼官方创建的 centos

FROM scratch
ADD centos-7-x86_64-docker.tar.xz /LABEL \org.label-schema.schema-version="1.0" \org.label-schema.name="CentOS Base Image" \org.label-schema.vendor="CentOS" \org.label-schema.license="GPLv2" \org.label-schema.build-date="20201113" \org.opencontainers.image.title="CentOS Base Image" \org.opencontainers.image.vendor="CentOS" \org.opencontainers.image.licenses="GPL-2.0-only" \org.opencontainers.image.created="2020-11-13 00:00:00+00:00"CMD ["/bin/bash"]

运行下官方镜像,发现缺失了很多命令

[root@localhost ~]# docker run -it centos# 运行在根目录 /
[root@352a2c999b35 /]# pwd
/# 没有 vim 命令
[root@352a2c999b35 /]# vim
bash: vim: command not found# 没有 ifconfig 命令
[root@352a2c999b35 /]# ifconfig
bash: ifconfig: command not found

2. 编写 Dockerflie 文件

创建一个目录用来存放项目文件

[root@localhost ~]# mkdir /home/dockerfile
[root@localhost ~]# cd /home/dockerfile

在该目录下,新建 mydockerfile-centos 文件

vim mydockerfile-centos

编写文件:i 写入文件并 :wq 保存

FROM centos
MAINTAINER yuanyuan<1234567@qq.com>ENV MYPATH /usr/local
WORKDIR $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH
CMD echo "----------end--------"
CMD /bin/bash

写完后查看一下:

cat mydockerfile-centos

3. 通过文件构建镜像

# docker build -f dockerfile文件路径 -t 镜像名:版本号 .
docker build -f mydockerfile-centos -t mycentos:0.1 .

4. 报错解决

没报错就跳到下一步

错误描述

发现构建遇到报错:

ERROR [3/4] RUN yum -y install vim
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

错误原因:

  • 网络连接的问题,使用 ping baidu.com 检查是否可以连接外部网络;
  • centos 停止维护的问题,具体看公告,笔者遇到的是这种。

解决方式:替换基础镜像。

因为我们上面用的 FROM centos,官方基础镜像 centos 停止维护,所以我们要从 centos 镜像入手。

自己 commit 一个 centos 镜像。


问题分析

先运行下官方基础镜像 centos:

docker run -it centos

去查看 yum 的配置文件:

[root@62111d10f8a3 /]# cd /etc/yum.repos.d/
[root@62111d10f8a3 yum.repos.d]# ls
CentOS-Linux-AppStream.repo          CentOS-Linux-Devel.repo             CentOS-Linux-Media.repo
CentOS-Linux-BaseOS.repo             CentOS-Linux-Extras.repo            CentOS-Linux-Plus.repo
CentOS-Linux-ContinuousRelease.repo  CentOS-Linux-FastTrack.repo         CentOS-Linux-PowerTools.repo
CentOS-Linux-Debuginfo.repo          CentOS-Linux-HighAvailability.repo  CentOS-Linux-Sources.repo

随便挑一个配置文件看看:

[root@62111d10f8a3 yum.repos.d]# cat CentOS-Linux-AppStream.repo
# CentOS-Linux-AppStream.repo
#
# The mirrorlist system uses the connecting IP address of the client and the
# update status of each mirror to pick current mirrors that are geographically
# close to the client.  You should use this for CentOS updates unless you are
# manually picking other mirrors.
#
# If the mirrorlist does not work for you, you can try the commented out
# baseurl line instead.[appstream]
name=CentOS Linux $releasever - AppStream
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra
#baseurl=http://mirror.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

发现重点:如果 mirrorlist 不能用,就换成 baseurl 试试。

# If the mirrorlist does not work for you, you can try the commented out
# baseurl line instead.

思路就是把 mirrorlist 替换成 baseurl

但是测试发现 baseurl 通过 mirror.centos.org 也无法下载 appstream,所以替换成 vault.centos.org

总之就是要把镜像替换成能用的。


解决步骤

接下来开始替换:

  • mirrorlist 替换成 #mirrorlist
  • #baseurl=http://mirror.centos.org 替换成 baseurl=http://vault.centos.org
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

生成更新缓存

yum makecache

更新 yum

yum update -y

这样就把 yum 不能安装的问题解决了,exit 退出容器吧(记住这个容器的 id )


我们把这个容器 commit 提交为本地镜像yuanyuan/centos 是笔者给新镜像的仓库命名。

不加版本号,默认是最新版。

docker commit -a="yuanyuan" -m="yum update -y to centos" 容器id yuanyuan/centos

然后把 Dockerfile 中的基础镜像修改为这个:

vim mydockerfile-centos# 修改第一行为
FROM yuanyuan/centos

重新构建

重新 build 一下吧

docker build -f mydockerfile-centos -t mycentos:0.1 .

成功!

在这里插入图片描述


5. 测试运行 mycentos

测试运行 mycentos 发现,进入容器时,直接进入了工作目录

vimifconfig 命令能用了。

[root@localhost dockerfile]# docker run -it mycentos:0.1# 直接进入了工作目录 WORKDIR
[root@ab9ef08ece02 local]# pwd
/usr/local# vim ifconfig 命令能用了
[root@ab9ef08ece02 local]# vim test
[root@ab9ef08ece02 local]# ifconfig
eth0: flags=...
lo: flags=...

6. 进行对比

镜像类型运行进入目录命令情况
官方版本 centos根目录命令缺失
构建版本 mycentos工作目录vimifconfig 命令能用了

7. 查看镜像变更历史

列出本地镜像变更历史,查看 mycentos 镜像的构建过程

docker history 镜像id

在这里插入图片描述

通过这种方式,我们可以研究镜像的制作过程。


六、CMD 和 ENTRYPOINT 的区别

1. CMD 用法

Dockerfile 构建镜像

新建 CMD 测试文件

vim dockerfile-cmd-test

编写 Dockerfile

FROM centos
CMD ["ls", "-a"]
# ls -a  展现当前基本目录,镜像运行的时候会执行这个命令

构建镜像

docker build -f dockerfile-cmd-test -t cmdtest .

运行镜像

ls -a 展现当前基本目录,镜像运行的时候会执行这个命令

run 运行发现,ls -a 命令生效

[root@localhost dockerfile]# docker run cmdtest
.
..
.dockerenv
bin
dev
etc
home

追加参数试试,想追加一个命令 -l,组成 ls -al

发现报错了,CMD 情况下,-l 替换了 CMD ["ls", "-a"],而 -l 不是命令,所以报错。

[root@localhost dockerfile]# docker run cmdtest -l
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 

正确的使用方法是:

docker run cmdtest ls -al

2. ENTRYPOINT 用法

Dockerfile 构建镜像

新建 ENTRYPOINT 测试文件

vim dockerfile-entrypoint-test

编写 Dockerfile

FROM centos
ENTRYPOINT ["ls", "-a"]

构建镜像

docker build -f dockerfile-entrypoint-test -t entrypoint-test .

运行镜像

ls -a 展现当前基本目录,镜像运行的时候会执行这个命令

run 运行发现,ls -a 命令生效

[root@localhost dockerfile]# docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home

追加参数试试,发现命令依然生效

我们追加的参数,是直接拼接在 ENTRYPOINT 命令的后面

[root@localhost dockerfile]# docker run entrypoint-test -l
total 56
drwxr-xr-x   1 root root 4096 Apr 12 09:48 .
drwxr-xr-x   1 root root 4096 Apr 12 09:48 ..
-rwxr-xr-x   1 root root    0 Apr 12 09:48 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin

3. 二者区别

  • CMD:指定这个容器启动时要运行的命令,只有最后一个会生效,可被替代
  • ENTRYPOINT:指定这个容器启动时要运行的命令,可以追加命令

在 Dockerfile 中,类似 CMD 和 ENTRYPOINT 这样的相似命令还有很多。可以通过对比学习,来测试它们的使用效果。


七、总结

本文主要介绍 Dockerfile,包括 Dockerfile 的构建过程、Dockerfile 的指令,以及 Dockerfile 的使用方式。还通过实战,学会使用 Dockerfile 构建自己的 centos 镜像,讲述了 CMD 和 ENTRYPOINT 的区别,解决基础镜像 centos 无法使用 yum -y 命令的问题。

接下来将尝试使用 Dockerfile 制作 Tomcat 镜像,介绍如何将本地镜像发布到 DockerHub 和阿里云镜像仓库


一些参考资料

狂神说系列 Docker 教程:https://www.bilibili.com/video/BV1og4y1q7M4/

Docker 官方文档:https://docs.docker.com/engine/install/centos/

Docker 远程仓库:https://hub.docker.com/

FinalShell 下载:http://www.hostbuf.com/t/988.html

CentOS 公告:https://blog.centos.org/2020/12/future-is-centos-stream/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/614813.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MathJax —— Vue3的使用方法

版本&#xff1a; mathjax3 需要实现效果 一、使用方式 1. index.html 中引入 <!-- 识别单行&#xff0c;行内&#xff0c;\( \)样式的公式 --><script>MathJax {tex: {inlineMath: [[$, $],[$$, $$], [\\(, \\)]]},};</script><script id"MathJ…

使用vite从头搭建一个vue3项目(二)创建目录文件夹以及添加vue-router

目录 一、创建 vue3 项目 vite-vue3-project-js二、创建项目目录三、创建Home、About组件以及 vue-router 配置路由四、修改完成后页面 一、创建 vue3 项目 vite-vue3-project-js 使用 vite 创建一个极简 vue3 项目请参考此文章&#xff1a;使用Vite创建一个vue3项目 下面是我…

顺序表(增删减改)+通讯录项目(数据结构)

什么是顺序表 顺序表和数组的区别 顺序表本质就是数组 结构体初阶进阶 系统化的学习-CSDN博客 简单解释一下&#xff0c;就像大家去吃饭&#xff0c;然后左边是苍蝇馆子&#xff0c;右边是修饰过的苍蝇馆子&#xff0c;但是那个好看的苍蝇馆子一看&#xff0c;这不行啊&a…

使用SquareLine Studio创建LVGL项目到IMX6uLL平台

文章目录 前言一、SquareLine Studio是什么&#xff1f;二、下载安装三、工程配置四、交叉编译 前言 遇到的问题&#xff1a;#error LV_COLOR_DEPTH should be 16bit to match SquareLine Studios settings&#xff0c;解决方法见# 四、交叉编译 一、SquareLine Studio是什么…

GEE数据集——巴基斯坦国家级土壤侵蚀数据集(2005 年和 2015 年)

简介 巴基斯坦国家级土壤侵蚀数据集&#xff08;2005 年和 2015 年&#xff09; 该数据集采用修订的通用土壤流失方程 (RUSLE)&#xff0c;并考虑了六个关键影响因素&#xff1a;降雨侵蚀率 (R)、土壤可侵蚀性 (K)、坡长 (L)、坡陡 (S)、覆盖管理 (C) 和保护措施 (P)&#xff…

秋叶Stable diffusion的创世工具安装-带安装包链接

来自B站up秋葉aaaki&#xff0c;近期发布了Stable Diffusion整合包v4.7版本&#xff0c;一键在本地部署Stable Diffusion&#xff01;&#xff01; 适用于零基础想要使用AI绘画的小伙伴~本整合包支持SDXL&#xff0c;预装多种必须模型。无需安装git、python、cuda等任何内容&am…

面经:Presto/Trino高性能SQL查询引擎解析

作为一名专注于大数据技术的博主&#xff0c;我深知Presto&#xff08;现更名为Trino&#xff09;作为一款高性能SQL查询引擎&#xff0c;在现代数据栈中的重要地位。本文将结合我个人的面试经历&#xff0c;深入剖析Trino的核心特性和应用场景&#xff0c;分享面试必备知识点&…

2023年MathorCup数学建模D题航空安全风险分析和飞行技术评估问题解题全过程文档加程序

2023年第十三届MathorCup高校数学建模挑战赛 D题 航空安全风险分析和飞行技术评估问题 原题再现 飞行安全是民航运输业赖以生存和发展的基础。随着我国民航业的快速发展&#xff0c;针对飞行安全问题的研究显得越来越重要。2022 年 3 月 21 日&#xff0c;“3.21”空难的发生…

面经:HDFS分布式文件系统原理与故障排查

作为一名专注于大数据存储与处理技术的博主&#xff0c;我深知Hadoop Distributed File System&#xff08;HDFS&#xff09;作为一款广泛应用的分布式文件系统&#xff0c;在大数据生态系统中的基石地位。本篇博客将结合我个人的面试经历&#xff0c;深入剖析HDFS的底层原理、…

JWT重放漏洞如何攻防?你的系统安全吗?

大家好&#xff0c;我是石头~ 在数字化浪潮席卷全球的今天&#xff0c;JSON Web Token&#xff08;JWT&#xff09;作为身份验证的利器&#xff0c;已成为众多Web应用的首选方案。 然而&#xff0c;正如硬币有两面&#xff0c;JWT的强大功能背后也隐藏着潜在的安全风险&#xf…

性能分析-数据库(安装、索引、sql、执行过程)与磁盘知识(读、写、同时读写、内存速度测试)

数据库 数据库&#xff0c;其实是数据库管理系统dbms。 数据库管理系统&#xff0c; 常见&#xff1a; 关系型数据库&#xff1a; mysql、pg、 库的表&#xff0c;表与表之间有关联关系&#xff1b; 表二维表统一标准的SQL&#xff08;不局限于CRUD&#xff09;非关系型数据…

杂货铺 | Linux虚拟机Ubuntu操作系统下设置共享文件夹(以及找不到hgfs文件夹怎么办)

文章目录 &#x1f4da;步骤一&#xff1a;配置共享文件夹&#x1f4da;步骤二&#xff1a;配置挂载环境&#x1f4da;步骤三&#xff1a;解决权限问题&#x1f4da;步骤四&#xff1a;解决重启失效问题 &#x1f4da;步骤一&#xff1a;配置共享文件夹 建立本地共享文件夹&…