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 $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/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

51单片机入门_江协科技_27~28_OB记录的自学笔记_AT24C02数据存储秒表

27. AT24C02(I2C总线) 27.1. 存储器介绍 27.2. 存储器简化模型介绍&#xff0c;存储原理 27.3. AT24C02介绍 •AT24C02是一种可以实现掉电不丢失的存储器&#xff0c;可用于保存单片机运行时想要永久保存的数据信息 •存储介质&#xff1a;E2PROM •通讯接口&#xff1a;I2…

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…

【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件

【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件 往期回顾 【QT入门】Qt自定义控件与样式设计之QProgressBar用法及qss-CSDN博客 【QT入门】 Qt自定义控件与样式设计之QSlider用法及qss-CSDN博客 【QT入门】Qt自定义控件与样式设计之qss的加载方式-CSDN博客 一、最终…

P6170 [USACO16FEB] Circular Barn G

题目 [ 传送门 ] 题目描述 作为当代建筑的爱好者&#xff0c;Farmer John 建造了一个圆形新谷仓&#xff0c;谷仓内部 个房间排成环形&#xff0c;按顺时针顺序编号为&#xff0c;每个房间都有通往与其相邻的左右房间的门&#xff0c;还有一扇门通往外面。 现在 FJ 有 n 头奶牛…

第六季:RTSP协议详解与实时流视频预览

目录 前言1 环境准备2 H.264编码原理和基本概念2.1 图像冗余信息2.2 h.264编码相关的一些概念2.3 h264视频流总体分析2.4 H264的NAL单元详解22.4.1 相关概念 2.5 NALU详解2.6 sps和pps详解2.7 H264的profile和level2.8 序列sequence 前言 本篇文章用于记录实验过程 1 环境准备…

Django中间件路由映射自动加/斜杠问题原因及分析

输入 http://127.0.0.1:8000/main/index/ 输入 http://127.0.0.1:8000/main/index 路由定义情况 urlpatterns [path("index/", views.index) ]可以发现我在输入URL的index路由时&#xff0c;如果没有和Django定义的路由匹配规则一样的话&#xff0c;浏览器自…

深度学习在三维点云处理与三维重建中的应用探索

目录 点云数据处理 数据清洗 数据降噪和简化 数据配准 特征提取 数据增强 数据组织 性能考量 PointNet PointNet 算法问题 改进方法 三维重建 重建算法 架构模块 流程步骤 标记说明 优点和挑战 点云数据处理 数据清洗 去噪&#xff1a;点云数据通常包含噪声…

云计算:Linux 部署 OVS 集群(控制端)实现OpenFlow

目录 一、实验 1.环境 2.Linux 部署 OVS 集群&#xff08;控制端&#xff09; 3.控制端对接服务端OVS网元 4.服务端OVS添加流表 5.服务端删除OVS 二、问题 1. ODL如何查找已安装插件 2.查看流表显示不全 3.如何删除OVS流表 一、实验 1.环境 (1) 主机 表1 宿主机 主…

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

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

Node.js从基础到高级运用】二十三、Node.js中自动重启服务器

引言 在Node.js开发过程中&#xff0c;我们经常需要修改代码后重启服务器来应用这些更改。手动重启不仅效率低下&#xff0c;而且会打断开发流程。幸运的是&#xff0c;有一些工具可以帮助我们自动化这个过程。本文将介绍如何使用nodemon来实现Node.js服务器的自动重启。 什么是…

OR36 链表的回文结构

描述 对于一个链表&#xff0c;请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法&#xff0c;判断其是否为回文结构。 给定一个链表的头指针A&#xff0c;请返回一个bool值&#xff0c;代表其是否为回文结构。保证链表长度小于等于900。 测试样例&#xff1a; 1->…

Unity面经(自整)——移动开发与Shader

Unity与Android混合开发 为什么使用Flutter构建 Flutter 是 Google 的开源工具包&#xff0c;用于从单个代码库为移动、Web、桌面和嵌入式设备构建应用程序&#xff08;一套代码跨平台构建app是它最大的优点&#xff09;&#xff0c;并且可以构建高性能、稳定和丰富UI的应用程…

Django Rest Framework的序列化和反序列化

DRF的序列化和反序列化 目录 DRF的序列化和反序列化Django传统序列化Django传统反序列化安装DRF序列化器serializers序列化反序列化反序列化保存instance和data CBV和APIView执行流程源码解析CBV源码分析APIView源码分析 DRF的Request解析魔法方法__getattr__ 什么是序列化&…

第十二届蓝桥杯大赛软件赛省赛Java 大学 B 组题解

1、ASC public class Main {public static void main(String[] args) {System.out.println(

dns服务的正反向解析

目的&#xff1a;完成DNS正反向解析&#xff0c;将步骤及测试同时提交 一、正向解析 1、准备工作 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld 2、服务端、客户端均安装软件 [rootserver ~]# yum install bind -y [rootnode1 ~]# yum install b…

扭蛋机小程序:线上扭蛋机模式发展空间有多大?

潮玩行业近几年的发展非常快&#xff0c;推动了扭蛋机市场的发展&#xff0c;越来越多的人加入到了扭蛋机赛道中&#xff0c;市场迎来了新的发展期。如今&#xff0c;我国的二次元文化的发展不断成熟&#xff0c;扭蛋机主打的二次元商品迎来了更多的商业机会。 一、互联网扭蛋机…

使用shell管理和配置网络服务_1

1、请使用nmcli命令配置仅主机模式网络环境&#xff0c;要求如下: 1) 创建一个新的网卡连接eth1&#xff0c;该连接映射到ens32网卡上; 首先&#xff0c;确保 ens32 网卡没有被其他网络配置文件使用。然后&#xff0c;使用 nmcli 创建一个新的连接&#xff0c;并将其绑定到 e…

在Spring Boot中使用POI完成一个excel报表导入数据到MySQL的功能

最近看了自己玩过的很多项目&#xff0c;忽然发现有一个在实际开发中我们经常用到的功能&#xff0c;但是我没有正儿八经的玩过这个功能&#xff0c;那就是在Spring Boot中实现一个excel报表的导入导出功能&#xff0c;这篇博客&#xff0c;主要是围绕excel报表数据导入进行&am…

分享一下项目中遇到的排序失效问题

今天把原来的一个查询接口的业务代码进行了优化&#xff0c;减少了十几行冗余的代码。 原来的代码 ChongwuServiceImpl.java /*** author heyunlin* version 1.0*/ Slf4j Service public class ChongwuServiceImpl implements ChongwuService {Overridepublic JsonResult<…

云原生数据库海山(He3DB)PostgreSQL版核心设计理念

本期深入解析云原生数据库海山PostgreSQL版&#xff08;以下简称“He3DB”&#xff09;的设计理念&#xff0c;探讨在设计云原生数据库过程中遇到的工程挑战&#xff0c;并展示He3DB如何有效地解决这些问题。 He3DB是移动云受到 Amazon Aurora 论文启发而独立自主设计的云原生数…