Docker——如何自定义镜像【将自己的项目制作成镜像】?

news2024/12/28 23:26:57

目录

前言:我们以前是如何部署项目的?

1、镜像由哪几部分构成的

2、如何手动自定义一个镜像

2.1、Dockerfile

2.2、dockerfile文本文件中,最终要写什么?

2.3、构建镜像

3、案例:部署java项目

4、如何与其他容器相互访问,例如:java项目镜像创建的容器与mysql容器相互访问

4.1、使用默认的网络 

4.1、网络相关命令

4.3、创建新的网络 


前言:我们以前是如何部署项目的?

        这个我在这篇文章中,有做说明,刚兴趣的小伙伴,可以去看看:http://t.csdnimg.cn/KPu7o

        另外,是来学习的伙伴们,需要自己准备一个java项目,并准备好他的jar包~  


1、镜像由哪几部分构成的

        传统的部署项目,大致有以下几个步骤:

  • 准备一个Linux服务器
  • 安装jdk并配置环境变量
  • 拷贝jar包【关于数据库,我们后面会单独说】
  • 运行jar包

        看到这些步骤,我们就要回顾一下,镜像是什么了?

        镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。那我们构建镜像其实就是上述这些文件打包的过程~

        到这里,就理解了,我们接下来,要构建的镜像就会包含以下几个方面:

        有一个Linux运行环境【镜像自己内部准备一个运行环境,那就不用担心系统不兼容等问题了】、有安装jre并配置环境变量、有拷贝jar包、并将运行jar包设置为一个启动脚本文件。这个文件糅合在一起,构成了一个我们的java应用镜像~

那我们一起来看看,他到底是怎么去糅合在一起的呢:

        因为我们搞一个什么运行环境,整一个系统函数库【因为我们不知道这个项目需要依赖哪些系统函数库,所以我们直接就把整个库都搬过来】,这一堆文件;而我们整个jre,再去配置环境变量和配置也是一堆文件;jar包也是个文件;运行脚本还是一个文件。那docker呢,就将这些个文件都进行分别压缩,最后这些压缩包合并在一起构成最终的一个镜像。因此镜像其实就是由很多个压缩包合并而成的,在Docker中,他们被称为LER,也就是层的意思。【我们其实在拉取镜像的时候,也会看到,他会打印几行日志,其实这一行就是对应了一层~】

        我们看图理解:

Docker为什么要把这些文件分别分层打包呢?

  • 可以实现某些层的共享

        例如:我们大部分镜像的第一层都是基础镜像【应用依赖的系统函数库、环境、配置、文件等】,我们上面说的是不知道要用哪些系统函数库,所以我们全部下载下来。那如果说,有一个大佬,把JRE所依赖的网络函数全部单独挑出来了,那这样的话,就可以大大的缩小镜像的体积。这样一来,就可以实现层的共享了~

  • 提升本地下载镜像的速度

        我们在本地拉取镜像时,按层一层一层拉取,如果说,第一个镜像拉取下来后,拉取第二个镜像时,他和第一层的某几层相同,那我们是不是就可以直接跳过,不用拉取这个层了,直接使用你本地的这个就可以了。这样一来,就可以提升本地下载镜像的速度了~


2、如何手动自定义一个镜像

        通过上面的了解,我们在制作镜像中,需要我们去给每一层打包,但我们真的这么操作的话,岂不是比以前部署项目还要复杂的多,就没必要了~

        所以Docker中,不需要我们手动去制作镜像,我们只需要描述清楚我们的镜像结构,描述清楚这个镜像的入口是什么?中间有哪些层?基础是什么? 描述清楚这些后,Docker就可以自动帮我们完成构建镜像这个操作了~

接下来,需要我们去了解一下Dockerfile,使用Dockerfile描述镜像结构~

2.1、Dockerfile

        Dockerfile就是一个文本文件,其中包含了一个个的指令,用指令来说明要执行什么操作来构建镜像。如何来书写这个文本文件呢?就需要借助他的相关指令了:

  • FROM  :指定基础镜像——例如,我们这里的基础镜像就是centos:6 / 7  ,例:FROM CentOS:6
  • ENV  :设置环境变量
  • COPY:拷贝本地文件到镜像的的指定目录,例:COPY  ./jdk8.tar.gz  /tmp
  • RUN  :执行Linux的shell命令,一般就是安装过程的命令,例:RUN  tar -axvf  /tmp/jdk8.tar.gz &&  EXPORTS path=/tmp/jdk8:$path
  • EXPOSE:指定容器运行时监听的端口 ,是给镜像使用者看的 ,例: EXPOSE 8080
  • ENTRYPOINT:镜像中应用的启动命令,容器运行时调用,例:ENTRYPOINT java -jar xx.jar &

举例该文本文件内部到底如何下:

# 制定基础镜像
FROM centos:6
# 配置环境变量,JDK的安装目录,容器内时区
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./xx.jar /tmp/app.jar
# 安装jdk
RUN cd $JAVA_DIR && tar -xf ./jdk8.tar.gz && mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 入口,java项目的启动命令
ENTRYPOINT ["java","-jar","/app.jar"]

说明:

        这个文件写完后,等我们下次再要制作新的java项目的镜像时,需要更改的内容有哪些呢:

        我们需要修改的,可能就只有这个待拷贝的java的jar包不同,那我们是不是可以对这个文本文件再优化~

2.2、dockerfile文本文件中,最终要写什么?

        上述我们已经看到了,文本文件内大致要写的内容,我们现在要做的是,可不可以继续优化一下:

        我们提到,文本文件中,每次要修改的只有拷贝jar包时,命令要稍微改一下,那思考一下,前面我们把基础镜像从拷贝全部的系统库函数到写一个镜像,只把我们要使用的库提出来,那在这里我们也可以这样做,我们把上述的基础镜像、拷jdk包、安装jdk,配置环境变量等操作,也可以做成一个镜像,供我们后续使用,例如已经有人做好的:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 拷贝jar包
COPY xx.jar /app.jar
# 入口
ENTRYPOINT ["java","-jar","/app.jar","&"]

说明:

2.3、构建镜像

        当我们编写好Dockerfile后,使用如下命令,来构建镜像,例如:

docker build -t myImage:1.0 .

说明:

  • docker build -t 后面跟你给这个镜像气的名字,冒号后面为版本,不写的话,默认为最新版
  • 后面的一个 .  指的是dockerfile所在的目录,当前目录就为 . 

3、案例:部署java项目

         首先,我们创建一个目录,为构建镜像做准备,任意命名,例如我的:

 一定要进到这个目录中来~

        然后,把你的java项目的jar扔到这个目录来:

然后创建一个文件,名为:Dockerfile:

 打开文件,填写内容:

 保存后,执行命令:docker build -t 镜像名【自定义】:

有了镜像,我们就去创建运行容器了:

然后,你的项目就可以正常与运行了~

        但是,项目虽然部署好了,我们全称部署也没有提到数据库MySQL呀,那我的项目就是要用到MySQL的呀。我们前面已经运行的有mysql容器了是不是【没有的伙伴,可以看:http://t.csdnimg.cn/uB6gl】所以,下面我们需要继续学习,可以把我们让我们的容器与容器之间相互访问:


4、如何与其他容器相互访问,例如:java项目镜像创建的容器与mysql容器相互访问

        在这里,就需要我们学习另一个知识点:网络~

4.1、使用默认的网络 

        我们在安装docker时,docker就创建一张虚拟的网卡,默认名字为docker0,并且会给这个虚拟的网卡创建一个虚拟的网桥,在我们不指定的情况下,我们创建的容器都会与默认的网卡建立连接,如下:

例如我们查看一下,我们之前的容器mysql和Nginx:

查看容器信息,输入命令:docker inspect 容器名

mysql:

Nginx:

        我们会看到,他俩的网关都是默认的127.17.0.1 ; 那是不是说明,他俩就可以相互访问了呢?例,进入我们刚才部署的java项目的这个容器】:

        一定要是进入我们创建的项目的容器内,进行ping操作,因为mysql容器和Nginx容器中,都没有提供ping的这个操作,安装的话,会比较麻烦~

        这个时候,有伙伴们就会说,那我们就不需要配置了呗,只要在我自己的项目中访问数据库的配置信息修改一下不就好了吗?

        例如:

改好后,重新部署一下不就好了吗?

         不!不好!!!  为什么呢?我们想想,当我们把mysql容器停掉后,重启;或者是我们把镜像推给别人~想一想这两种情况能够保证mysql容器每次的ip都一样吗?那不一样,不就会报错了吗?

        大家可能会说,可以把ip用容器名替代吗?他可以通过容器名解析到这个ip吗?

        回答是:可以但不完全可以。详细的说,就是默认的这个网卡是不可以的,但是如果我们不使用默认的网卡,我们自己去创建一个网络,把这些容器加入到这个新的网络中是可以做到的。例如,我们现在在默认网卡中试试:

        对吧?这是做不到的,所以我们又要学习新的知识,网络相关的: 

4.1、网络相关命令

  • docker network create : 创建一个网络
  • docker network ls : 查看所有网络
  • docker network rm : 删除指定网络
  • docker network prune :清楚未使用的网络
  • docker network connect :使指定容器连接加入某网络
  • docker network disconnect:使指定容器连接离开某网络
  • docker network inspect :查看网络详细信息

4.3、创建新的网络 

先查看我们原本有哪些网络:

创建一个网络:

使mysql容器加入该网络:

        我们可以看到这个mysql容器,先是创建容器时就自动加入了默认网络中,然后也加入了刚才我们指定的网络中,在这个网络中,这个网络的网关是172.18.0.1,这个容器在这个网络中的ip为172.18.0.2

如果说我们的java项目的容器不想让他加入默认的网络中呢?那需要我们把之前的启动的项目容器删掉,然后重新创建容器,在创建容器时就需要指定他所在的网络:

        此时,我们再来查看这个容器的信息:

就只一个这一个了~

此时,两个容器就可以一起相互访问了~ 可通过容器名,来直接访问,如下:

这时呢,我们只需要把项目的配置文件改一下:

好啦,我们重新打包上传的操作就不演示啦~

本期就结束啦!!下期见~ 

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

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

相关文章

Python 机器学习入门之ID3决策树算法

系列文章目录 第一章 Python 机器学习入门之线性回归 第一章 Python 机器学习入门之梯度下降法 第一章 Python 机器学习入门之牛顿法 第二章 Python 机器学习入门之逻辑回归 番外 Python 机器学习入门之K近邻算法 番外 Python 机器学习入门之K-Means聚类算法 第三章 Python 机…

华为云HECS云服务器docker环境下安装nacos

华为云HECS云服务器,安装docker环境,查看如下文章。 华为云HECS安装docker-CSDN博客 一、拉取镜像 docker pull nacos/nacos-server二、宿主机创建挂载目录 执行如下命令: mkdir -p /usr/local/nacos/logs mkdir -p /usr/local/nacos/con…

服务端监控要怎么做?

目录 前言 一、Google的四类黄金指标 二、RED方法 三、USE方法 RED方法 vs USE方法 四、监控指标 WEB服务监控 MySQL数据库监控 QPS TPS 最大连接数 缓存监控 总结 前言 众所周知,业界各种大中型软件系统在生产运行时,总会有一些手段来…

ESP32C3 LuatOS TM1650②动态显示累加整数

--注意:因使用了sys.wait()所有api需要在协程中使用 -- 用法实例 PROJECT "ESP32C3_TM1650" VERSION "1.0.0" _G.sys require("sys") local tm1650 require "tm1650"-- 拆分整数,并把最低位数存放在数组最大索引处 loc…

车载网关通信能力解析——SV900-5G车载网关推荐

随着车联网的发展,各类车载设备对车载网关的需求日益增长。车载网关作为车与车、车与路、车与云之间连接的关键设备,其通信能力直接影响整个系统的性能。本文将详细解析车载网关的通信能力,并推荐性价比高的SV900-5G车载网关。 链接直达:https://www.key-iot.com/i…

类与对象-对象特性-构造函数与析构函数

#include<iostream> using namespace std; class Person { public: //构造函数 : //没有返回值,不写void //函数名与类名相同 //构造函数可以有参数,能发生重载 //创建对象时,构造函数会自动调用,而且只调用一次 Person() { cout << &quo…

哈里斯鹰算法优化BP神经网络(HHO-BP)回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Python爬虫:ad广告引擎的模拟登录

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

Ubuntu桌面环境的切换方法

你在找它吗&#xff1f; 国内麒麟、深度等系统虽然界面更炫&#xff0c;但——软件仓库与Ubuntu官方已不兼容。国内系统遇到稳定性问题&#xff0c;还是得拿Ubuntu做参照。今天本来介绍下这款Linux桌面。 为什么在 Ubuntu 上考虑 LXQt&#xff1f; 性能&#xff1a;LXQt设计为…

基于SSM的教务管理系统运行教程

文章目录 1、前期必备1.1、所需软件版本说明1.2、下载源码1.3、下载开发工具1.4、下载JDK并配置环境变量1.5、安装数据库和数据库管理工具1.6、安装配置Maven 2、将SQL文件导入到数据库2.1、新建MySQL连接2.2、新建数据库并导入SQL 3、用Eclipse运行程序3.1、导入educationalMa…

操作系统【OS】操作系统的引导

激活CPU。 激活的CPU读取ROM中的boot程序&#xff0c;将指令寄存器置为BIOS(基本输入输出系统)的第一条指令&#xff0c; 即开始执行BIOS的指令。硬件自检。 启动BIOS程序后&#xff0c;先进行硬件自检&#xff0c;检查硬件是否出现故障。如有故障&#xff0c;主板会发出不同含…

【JavaEE】Java多线程编程案例 -- 多线程篇(3)

Java多线程编程案例 1. 单例模式1.1 代码的简单实现1.2 懒汉模式的线程安全代码 2. 阻塞队列2.1 阻塞队列的概念2.2 使用库中的BlockingDeque2.3 模拟实现阻塞队列2.4 生产者消费者模型 3. 定时器3.1 概念3.2 使用库的定时器 - Timer类3.3 模拟实现定时器 4. 线程池4.1 概念4.2…

JetBrains系列IDE全家桶激活

jetbrains全家桶 正版授权&#xff0c;这里有账号授权的渠道&#xff1a; https://www.mano100.cn/thread-1942-1-1.html 附加授权后的一张图片

YOLOv8改进实战 | 更换主干网络Backbone(二)之轻量化模型GhostnetV2

前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…

9 线程池

为什么要使用线程池&#xff1f; 1 重复利用已创建的线程&#xff0c;减少线程创建和销毁带来的开销 2 提高响应速度&#xff1a;任务可以不用等待线程创建就能立即执行&#xff08;T1 创建线程 T2执行任务 T3销毁线程&#xff09;&#xff0c;若T1T3>T2&#xff0c;可以通过…

macOS Tor 在启动期间退出

macos Tor 在启动期间退出。这可能是您的 torrc 文件存在错误&#xff0c;或者 Tor 或您的系统中的其他程序存在问题&#xff0c;或者硬件问题。在您解决此问题并重新启动 Tor 前&#xff0c;Tor 浏览器将不会启动。退出Tor、卸载Tor、删除目录 TorBrowser-Data、重启电脑 访…

关于antdpro的EdittableProTable编辑时两个下拉搜索框的数据联动以及数据回显(以及踩坑)

需求&#xff1a;使用antdpro的editprotable编辑两个下拉框&#xff0c;且下拉框是一个搜索下拉框。下拉框1和2的值是一个编码和名字的联动关系&#xff0c;1变化会带动2&#xff0c;2变化会带动1的一个联动作用。&#xff08;最后有略完整的代码&#xff0c;但是因为公司项目问…

059:mapboxGL监听键盘事件,通过eastTo控制左右旋转

第059个 点击查看专栏目录 本示例是介绍演示如何在vue+mapbox中监听键盘事件,通过eastTo控制左右旋转。 本例通过easeTo方法来加减一定数值的bearing角度,通过.addEventListener的方法来监听键盘的按键动作。这里一定要设置interactive: false, 否则展现不出来旋转效果。 直…

小微企业低成本获客攻略,媒介盒子无偿分享

品牌推广已经成为企业获客的主要手段&#xff0c;品牌推广能够使企业将自身的品牌、产品信息传递到受众面前&#xff0c;但是小微企业在公司成立之初往往资金有限&#xff0c;那么小微企业如何用低成本精准获客呢&#xff1f;可以试试软文。接下来媒介盒子就告诉大家&#xff0…

IO入门day1

课程分为三部分&#xff1a;IO文件-动态库、静态库制作&#xff0c;进程&#xff08;本地进程间通信&#xff09;&#xff0c;线程&#xff08;线程通信&#xff09; 特点&#xff1a;学习大量的函数接口调用-函数名及功能、man手册查看参数 一、IO介绍 1、概念 对文件的输入输…