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.rhkb.cn/news/307044.html

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

相关文章

【MoS2】应变增强的单层MoS2光电探测器

这篇文章的标题是《Strain-Enhanced Large-Area Monolayer MoS2 Photodetectors》&#xff0c;作者是Borna Radatovic等人&#xff0c;发表在《ACS Applied Materials & Interfaces》期刊的2024年第16卷。文章主要研究了应变增强的大面积单层MoS2光电探测器的性能和应用潜力…

【安全】挖矿木马自助清理手册

一、什么是挖矿木马 挖矿木马会占用CPU进行超频运算&#xff0c;从而占用主机大量的CPU资源&#xff0c;严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源&#xff0c;一般都会对全网进行无差别扫描&#xff0c;同时利用SSH爆破和漏洞利用等手段攻击主机。 …

GC垃圾回收

垃圾回收 1、什么是 垃圾回收机制&#xff1a; 理解Java的垃圾回收机制&#xff0c;就要从&#xff1a;“什么时候”&#xff0c;“对什么东西”&#xff0c;“做了什么”三个方面来具体分析。 ​ 第一&#xff1a;“什么时候”即就是GC触发的条件。 ​ GC触发的条件有两种…

相机模型浅析

相机模型 文章目录 相机模型四个坐标系针孔相机模型世界坐标系到相机坐标系相机坐标系到图像坐标系图像坐标到像素坐标 四个坐标系 ①世界坐标系&#xff1a;是客观三维世界的绝对坐标系&#xff0c;也称客观坐标系。因为数码相机安放在三维空间中&#xff0c;我们需要世界坐标…

【opencv】示例-image_alignment.cpp 利用ECC 算法进行图像对齐

affine imshow("image", target_image); imshow("template", template_image); imshow("warped image", warped_image); imshow("error (black: no error)", abs(errorImage) * 255 / max_of_error); homography 这段代码是一个利用EC…

【300套】基于Springboot+Vue的Java毕业设计项目(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f9e1;今天给大家分享300的Java毕业设计&#xff0c;基于Springbootvue框架&#xff0c;这些项目都经过精心挑选&#xff0c;涵盖了不同的实战主题和用例&#xff0c;可做毕业…

银行司库系统应用架构介绍

继国务院国资委印发了《关于推动中央企业加快司库体系建设进一步加强资金管理的意见》以及《关于中央企业加快建设世界一流财务管理体系的指导意见》&#xff0c;司库体系建设开始得到了更多重视。其中&#xff0c;作为改革风向标&#xff0c;央企数字化转型及司库建设对整个行…

【YUNBEE云贝-进阶课】MySQL8.0性能优化实战培训

众多已经学习过MySQL 8.0 OCP认证专家的课程的同学们对 MySQL 8.0 的安装部署、体系结构、配置监控、用户管理、主从复制、系统运维、MGR等基础操作和动手实验有了一定的学习基础.很多学员反馈希望更进一步提升技术能力、解决工作中碰到的性能问题。 针对MySQL8.0的数据库性能优…

Ubuntu 20.04 设置开启 root 远程登录连接

Ubuntu默认不设置 root 帐户和密码 Ubuntu默认不设置 root 帐户和密码 Ubuntu默认不设置 root 帐户和密码 如有需要&#xff0c;可在设置中开启允许 root 用户登录。具体操作步骤如下&#xff1a; 操作步骤 1、首先使用普通用户登录 2、设置root密码 macw:~$ sudo passwd …

基于STM32F103单片机的时间同步项目

一、前言 本项目为前一个时间同步项目的更迭版本&#xff0c;由于之前的G031开发板没有外部晶振&#xff0c;从机守时能力几乎没有&#xff0c;5秒以上不同步从机时间就开始飞了。在考虑成本选型后&#xff0c;选择了带有外部有缘晶振的STM32F103C8T6最小单片机&#xff0c;来作…

DRF的认证、权限、限流、序列化、反序列化

DRF的认证、权限、限流、序列化、反序列化 一、认证1、直接用&#xff0c;用户授权2、认证组件源码3、第三方认证djangorestframework-simplejwt 二、权限1. 直接使用&#xff0c;用户权限2.权限组件源码 三、序列化1. 序列化1.1 自定义Serailizer类序列化1.2 在视图APIView中使…

嵌入式驱动学习第七周——GPIO子系统

前言 GPIO子系统是用来统一便捷地访问实现输入输出中断等效果。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xff0c;一起讨论一起学习。现在关注就是老粉啦&#xff0…

spring boot整合Redis监听数据变化

一、前言 Redis提供了数据变化的通知事件&#xff0c;可以实时监测key和value的变化&#xff0c;客户端可以通过订阅相关的channel来接收这些通知事件&#xff0c;然后做相应的自定义处理&#xff0c;详细的介绍可以参考官方文档Redis keyspace notifications | Docs 使用Red…

httpsok-快速申请谷歌SSL免费证书

&#x1f525;httpsok-快速申请谷歌SSL免费证书 使用场景&#xff1a; 部署CDN证书、OSS云存储证书证书类型&#xff1a; 单域名 多域名 通配符域名 混合域名证书厂商&#xff1a; ZeroSSL Lets Encrypt Google证书加密类型&#xff1a; ECC、 RSA 一、证书管理 进入 证书管…

【数学建模】2024Mathorcup数学建模C题完整思路与代码论文解析

2024Mathorcup数学应用挑战赛C题|图神经网络的预测模型ARIMA时间序列预测模型人员排班混合整数规划模型|完整代码和论文全解全析 我们已经完成了2024Mathorcup数学建模挑战赛C题的40页完整论文和代码&#xff0c;相关内容可见文末&#xff0c;部分图片如下&#xff1a; 问题分…

[蓝桥杯] 岛屿个数(C语言)

提示&#xff1a; 橙色字体为需要注意部分&#xff0c;红色字体为难点部分&#xff0c;会在文章“重难点解答”部分精讲。 题目链接 蓝桥杯2023年第十四届省赛真题-岛屿个数 - C语言网 题目理解 这道题让我们求岛屿个数&#xff0c;那么我们就应该先弄懂&#xff0c;对于一…

Qt5 编译oracle数据库

库文件 1、Qt源码目录&#xff1a;D:\Qt5\5.15.2\Src\qtbase\src\plugins\sqldrivers\oci 2、oracle客户端SDK: https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 下载各版本中的如下压缩包&#xff0c;一定要版本相同的 将两个压缩包…

【简单讲解如何安装与配置Composer】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Rust语言入门第四篇-变量与可变性以及隐藏(Shadowing)

文章目录 Rust语言入门第四篇-变量与可变性以及隐藏&#xff08;Shadowing&#xff09;概要let 关键字自动判断变量类型隐藏&#xff08;Shadowing&#xff09;let关键字支持的数据类型let 关键字声明的变量类型转换 Rust语言入门第四篇-变量与可变性以及隐藏&#xff08;Shado…

机器学习和深度学习 -- 李宏毅(笔记与个人理解)Day 13

Day13 Error surface is rugged…… Tips for training :Adaptive Learning Rate critical point is not the difficult Root mean Square --used in Adagrad 这里为啥是前面的g的和而不是直接只除以当前呢? 这种方法的目的是防止学习率在训练过程中快速衰减。如果只用当前的…