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

news2024/11/27 6:11:57

一、前言

记录时间 [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 $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD 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.coloradmin.cn/o/1590696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LDF、DBC、BIN、HEX、S19、BLF、ARXML、slx等

文章目录 如题 如题 LDF是LIN报文格式文件&#xff0c;把这个直接拖到软件里面&#xff0c;可以发报文和接收报文 DBC是CAN报文格式文件&#xff0c;把这个直接拖到软件里面&#xff0c;可以发报文和接收报文 BIN文件烧录在BOOT里面&#xff08;stm32&#xff09;&#xff0c…

适用于 Windows 的 10 个免费数据恢复工具集合

有时&#xff0c;我们都会在个人计算机上意外删除一些重要文件或数据。我们无需再担心此类问题&#xff0c;因为我们可以借助互联网上提供的免费数据恢复工具来恢复宝贵的数据和图像。 互联网上有许多免费的数据恢复工具&#xff0c;从一长串工具中&#xff0c;我们列出了最好…

蓝桥杯-STL-string

目录 字符串定义 字符串初始化 字符串输入输出 字符串输出 字符串输入 字符串访问 字符串拷贝 字符串拼接 直接相加 append(const char*str,int n) 字符串比较 ​编辑字符串长度length()/size() 字符串查找find(string str) 查找子串substr(int a,int b) 字符串的…

webpack-loader的使用

引入css后执行打包命令 "build": "npx webpack --config wk.config.js"发现报错&#xff1a; webpack默认只能处理js其他的像css,图片都需要借助loader来处理 css-loader loader可以用于对模块的源代码进行转换&#xff0c;可以把css看成一个模块&…

Transformer模型-decoder解码器,target mask目标掩码的简明介绍

今天介绍transformer模型的decoder解码器&#xff0c;target mask目标掩码 背景 解码器层是对前面文章中提到的子层的包装器。它接受位置嵌入的目标序列&#xff0c;并将它们通过带掩码的多头注意力机制传递。使用掩码是为了防止解码器查看序列中的下一个标记。它迫使模型仅使用…

【高效开发工具系列】obsutil安装与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

广州图创 图书馆集群管理系统 updOpuserPw SQL注入漏洞复现

0x01 产品简介 广州图创计算机软件开发有限公司是集产品研发、应用集成、客户服务为一体的高新技术企业,主要目标是为图书馆行业用户提供高质量的应用软件系统设计、集成和维护服务。 0x02 漏洞概述 由于广州图创 图书馆集群管理系统 updOpuserPw 接口处未对用户输入的SQL语…

minio-docker单节点部署SDK测试文件上传下载

目录 一&#xff0c;docker部署minio单节点单磁盘 二&#xff0c;SDK测试上传下载 一&#xff0c;docker部署minio单节点单磁盘 1.拉取镜像 # 下载镜像 docker pull minio/minio 2.查看镜像 docker images 3.启动minio(新版本) 创建本机上的挂载目录&#xff0c;这个可以…

鸿蒙OS开发学习:【第三方库调用】

介绍 本篇Codelab主要向开发者展示了在Stage模型中&#xff0c;如何调用已经上架到[三方库中心]的社区库和项目内创建的本地库。效果图如下&#xff1a; 相关概念 [Navigation]&#xff1a;一般作为Page页面的根容器&#xff0c;通过属性设置来展示页面的标题、工具栏、菜单。…

【AIGC】本地部署通义千问 1.5 (PyTorch)

今天想分享一下 Qwen 1.5 官方用例的二次封装&#xff08; huggingface 说明页也有提供源码&#xff09;&#xff0c;其实没有太多的技术含量。主要是想记录一下如何从零开始在不使用第三方工具的前提下&#xff0c;以纯代码的方式本地部署一套大模型&#xff0c;相信这对于技术…

50. QT/QML中创建多线程的方式汇总

1. 说明 在QT / QML中创建线程主要有三种方式。第一种:在定义类时继承 QThread 这个类,然后重写父类的虚函数 run(),将子线程需要执行的业务代码放到 run() 函数当中即可。**注意:**这种方式官方已经摒弃了。第二种:使用moveToThread()函数将需要在子线程中执行的函数类移…

软件设计师-基础知识科目-标准化与软件知识产权基本知识11

十一、标准化与软件知识产权基本知识&#xff1a; 知识产权&#xff1a; 主要包括&#xff1a;著作权及邻接权、专利权、工业品外观设计权、商标权、地理标志权、继承电路布图设计权。邻接权是指与著作权相邻近的权利&#xff0c;是指作品传播者&#xff0c;对其传播作品过程…

文献速递:深度学习肝脏肿瘤诊断---基于多相增强 CT 和临床数据的恶性肝肿瘤鉴别诊断深度学习

Title 题目 Deep learning for diferential diagnosisof malignant hepatic tumors based on multi-phase contrast-enhanced CT and clinical data 基于多相增强 CT 和临床数据的恶性肝肿瘤鉴别诊断深度学习 Abstract 摘要 Liver cancer remains the leading cause of can…

中介者模式:简化对象间通信的协调者

在面向对象的软件开发中&#xff0c;中介者模式是一种重要的行为型设计模式&#xff0c;用于降低多个对象间通信的复杂性。通过提供一个中心化的对象来处理不同组件之间的交互&#xff0c;中介者模式使得组件间不必显式引用彼此&#xff0c;从而使其松散耦合、更易于维护。本文…

ElasticSearch中使用bge-large-zh-v1.5进行向量检索(一)

一、准备 系统&#xff1a;MacOS 14.3.1 ElasticSearch&#xff1a;8.13.2 Kibana&#xff1a;8.13.2 BGE是一个常见的文本转向量的模型&#xff0c;在很多大模型RAG应用中常常能见到&#xff0c;但是ElasticSearch中默认没有。BGE模型有很多版本&#xff0c;本次采用的是bg…

享元模式:优化资源利用的高效策略

在面向对象的软件开发中&#xff0c;享元模式是一种结构型设计模式&#xff0c;旨在减少内存使用&#xff0c;通过共享尽可能多的相似对象来提高应用程序的效率。本文将详细介绍享元模式的定义、实现、应用场景以及优缺点。 1. 享元模式的定义 享元模式&#xff08;Flyweigh…

手写一个简单的 OrbitControls 轨道控制器

手写一个简单的 OrbitControls 轨道控制器 相信使用过THREE.JS的同学&#xff0c;都知道 OrbitControls 这个的轨道控制器&#xff0c;他是绕着一个观察点&#xff0c;来进行什么什么的… 反正就是那么个意思。 所以很明显OrbitControls的运动轨迹是一个球体&#xff0c;他是绕…

软件定义车队面临网络安全的曲折之路

当以色列 REE Automotive 设计其 P7 电动汽车底盘时&#xff0c;它是从软件开始工作的&#xff1a;扁平的车辆底盘完全可配置&#xff0c;每个轮胎附近有四个独立的模块&#xff0c;用于转向、制动、悬架和动力传动系统&#xff0c;每个模块均由电子驱动控制单元&#xff08;EC…

JavaEE初阶——多线程(二)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章延续上一篇文章,与大家分享Thread常见的方法以及线程的状态相关知识 其他内容我们下一篇再见! 如果有错误或不足请您指出!!! 目录 3.Thread类及常见方法3.1Thread常见的构造方法3.2Thread…

【小技巧】机器学习中可视化高维向量的两种方法PCA和t-SNE,以及其原理介绍和代码示例(附代码)

使用情景&#xff1a;比如说现在我有一批numpy的多维向量&#xff0c;比如说都是256维度的&#xff0c;X.shape(n, 256), 已知它们都是经过训练能够在256dim的超球面上实现分类或聚类的&#xff0c;现在我想把它们可视化出来看看各个簇在超球面上的分布是怎样的&#xff1f; 1…