当前位置: 首页 > news >正文

第一部分——Docker篇 第三章 构建自定义镜像

关于系统的改造探索

开篇:系统改造的调研报告

第一部分——Docker篇

第一章 Docker容器
第二章 Docker安装
第三章 构建自定义镜像
第四章 搭建镜像仓库
第五章 容器编排
第六章 容器监控


文章目录

  • 关于系统的改造探索
      • 第一部分——Docker篇
  • 前言
  • 一、DockerFile
  • 二、docker-maven-plugin
  • 三、S2I
  • 总结


前言

    随着业务的发展,传统的架构已经不符合项目的要求了。双活、集群也渐渐提上了日程。。。


    前边已经安装好了 Docker 环境,接下来看下 Docker镜像 的内容。Docker镜像 主要分为两种,一种是由第三方公司提供的 公开镜像公开镜像 没啥好说的,直接拉取就能使用。还有一部分是 私有镜像,这部分 镜像 需要由公司自己构建,后边内容就对如何构建 私有镜像 进行讨论


一、DockerFile

    构建 Docker镜像 最直接的方式就是由官方提供的构建工具——DockerFile 进行构建,只需要按要求编写 DockerFile 文件即可。下边就以一个 SpringBoot 项目为例,来体验下如何使用 DockerFile 构建 镜像

    先用Idea 创建一个简单的Springboot项目。具体步骤想必大家都懂,这里就不赘述了。重点看下 pom.xml 文件。如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>docker-demo</artifactId>
    <version>1.0</version>
    <name>docker-demo</name>
    <description>docker测试项目</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>docker-demo</finalName>
        <plugins>
            <!-- docker插件 -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <!-- 镜像名称,'[a-z0-9-_.]'格式 -->
                    <imageName>${project.artifactId}:${project.version}</imageName>
                    <dockerDirectory>${project.basedir}/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                            <include>classes/application.*</include>
                        </resource>
                    </resources>
                    <!--这里用tcp,用提示协议错误-->
                    <dockerHost>http://192.168.233.135:2375</dockerHost>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.dockerdemo.DockerDemoApplication</mainClass>
                    <skip>false</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

    新建一个文件,名称就叫 DockerfileDocker 通过读取 Dockerfile 文件中的指令来自动构建镜像。通常,一个镜像基于另一个镜像,就像千层饼一样一层套一层。接下来就看下如何把 jar 文件打包成镜像吧。显然,Jdk镜像 是我们的基础 镜像Dockerfile 文件内容如下:

#引入jdk镜像
FROM openjdk:8-jre-slim
# 作者名
MAINTAINER hqd

#设置中国时区,否则容器内部时间显示美国时间。和实际时间对不上
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ADD docker-demo.jar /app.jar
ADD classes/application.* /config/
#创建具有指定名称的安装点,并将其标记为保存来自本机主机或其他容器的外部安装卷
VOLUME config
#实际上并未发布端口。它充当构建映像的人员和运行容器的人员之间的一种文档,有关要发布哪些端口。使用-p进行覆盖
EXPOSE 8080
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"]

接下来,需要把构建所需的文件放到服务器上(需要Docker环境)。目录结构如下:

在这里插入图片描述

而后,执行 Docker 命令进行构建,如下:

# .即当前目录,t即tag,为镜像名称
 docker build . -t docker-demo:1.0

在这里插入图片描述

如果出现异常,会产生仓库名、标签都是 none镜像,即 虚悬镜像

在这里插入图片描述
这时候只需执行清理即可,如下:

#清理镜像
docker image prune
#清理系统
docker system prune

二、docker-maven-plugin

    通常情况下,现在项目都是用 IDEA + Maven 进行开发,我们更希望直接通过 IDEA 进行远程部署,这时候就需要用到 DockerMaven插件DockerMaven插件 插件有好几种,大家可根据项目实际情况进行选择 ,这里使用的是 docker-maven-plugin。下边来看下 docker-maven-plugin 如何使用的

  1. Docker 开启 2375 端口
    想要远程构建镜像Docker需要先开启端口进行通信,修改 /etc/docker/daemon.json 文件,如下:
{
  "registry-mirrors": ["加速地址"],
  //这里配置是让docker信任该地址,否则会提示https安全问题
  "insecure-registries":["harbor-ip:8080","nexus-ip:8082","registry-ip:5000"]
  "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}

重启 Docker

systemctl daemon-reload
systemctl restart docker
  1. 项目添加 Dockerfile
    再把 Dockerfile 添加到项目中。如下:

在这里插入图片描述

  1. 添加 DockerMaven插件
    pom.xml 添加 DockerMaven插件 相关依赖。如下:
 <plugin>
     <groupId>com.spotify</groupId>
     <artifactId>docker-maven-plugin</artifactId>
     <version>1.2.2</version>
     <configuration>
         <!-- 镜像名称,'[a-z0-9-_.]'格式 -->
         <imageName>${project.artifactId}:${project.version}</imageName>
         <dockerDirectory>${project.basedir}/docker</dockerDirectory>
         <resources>
             <resource>
                 <targetPath>/</targetPath>
                 <directory>${project.build.directory}</directory>
                 <include>${project.build.finalName}.jar</include>
                 <include>classes/application.*</include>
             </resource>
         </resources>
         <!--这里用tcp,用提示协议错误-->
         <dockerHost>http://服务器Ip:2375</dockerHost>
     </configuration>
 </plugin>

完整 pom.xml 配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>docker-demo</artifactId>
    <version>1.0</version>
    <name>docker-demo</name>
    <description>docker测试项目</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>docker-demo</finalName>
        <plugins>
            <!-- docker插件 -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>
                <configuration>
                    <!-- 镜像名称,'[a-z0-9-_.]'格式 -->
                    <imageName>${project.artifactId}:${project.version}</imageName>
                    <dockerDirectory>${project.basedir}/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                            <include>classes/application.*</include>
                        </resource>
                    </resources>
                    <!--这里用tcp,用提示协议错误-->
                    <dockerHost>http://192.168.233.135:2375</dockerHost>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.dockerdemo.DockerDemoApplication</mainClass>
                    <skip>false</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

  1. 构建镜像
    点击 IDEA 右侧 Maven 进行构建。如下:
    在这里插入图片描述

三、S2I

    DockerMaven插件 虽然简化了 Docker镜像 的构建流程,但是依然要求开发人员必须要懂 Docker、Dockerfile 的相关知识,而此次系统改造的目的:是为了简化开发操作,要求团队中每个人都去学一遍 Docker ,显然学习成本是很大的,已经和此次改造的初衷背离。故而迫切的需要一款构建工具,让开发无需关注 Docker 相关内容,这个工具就是——S2I(Source-to-Image)

    下边是官网的简介:

Source-to-Image (S2I) 是一种用于构建可重复生成的 Docker 格式容器镜像的工具。它通过将应用程序源代码注入容器镜像并汇编新镜像来生成可随时运行的镜像。新镜像融合了基础镜像(构建器)和构建的源代码,并可搭配 buildah run 命令使用。S2I 支持递增构建,可重复利用以前下载的依赖项和过去构建的工件等

细节部分这里就不讨论了,有兴趣的小伙伴可以去 官网 自行查看,说一千道一万,不如实操一遍,下面一起来操作下吧

  1. 安装 S2I
    这里选择的版本是 v1.3.0 ,大家根据实际情况选择。确定好版本之后,可以去 Git 下载 S2I,也可以直接用命令进行操作。如下:
#下载s2i
wget  https://github.com/openshift/source-to-image/releases/download/v1.3.0/source-to-image-v1.3.0-eed2850f-linux-amd64.tar.gz

#解压到指定目录
mkdir s2i
tar -zxvf source-to-image-v1.3.0-eed2850f-linux-amd64.tar.gz   -C s2i

#移动到系统目录
chmod +x s2i/s2i
mv s2i/s2i /usr/local/bin/

#验证
s2i version

输出如下内容,则代表安装成功

在这里插入图片描述

  1. 添加 assemble脚本

S2I 运行时,需要根据脚本内容进行编译、打包、运行等操作。在项目根目录下,新建 .s2i/bin 目录,目录结构如下:

在这里插入图片描述

.s2i/bin 目录下,添加 assemble脚本,内容如下:

#!/bin/bash  -e

# 打印当前工作目录,以便于调试
echo "当前工作目录是: $(pwd)"

SOURCE_DIR=/tmp/src/

cd $SOURCE_DIR

echo "开始编译,项目目录为:$SOURCE_DIR"
# 编译 Maven 项目
mvn clean package -DskipTests=true -s settings.xml

# 检查编译结果
if [ $? -ne 0 ]; then
  echo "编译失败,退出。。。"
  exit 1
fi

# 可选:清理 Maven 构建过程中生成的文件
# mvn clean

# 复制构建的 jar 文件到指定目录
cp target/*.jar /deployments/app.jar
echo "开始扫描代码。。。"
#扫描代码
#sonar-scanner

# 打印成功信息
echo "编译成功。。。"

相比于 DockerfileShell 可能对开发更友好一点,assemble脚本 功能也很简单:就是 Maven 清理打包的命令

  1. 添加 run脚本
    如果说 assemble脚本 是打包命令,则 run脚本 就是运行命令,内容如下:
#!/bin/bash  -e

cd  /deployments
# 执行 Java 应用
# 假设你的jar文件名为 app.jar 并且已经被复制到了 `/deployments` 目录中
java -jar app.jar

相较于 assemble脚本run脚本 就更简单了,就是平时开发经常接触的 Java命令

除了 assemblerun 脚本是必须的,其他都是可选的,各个脚本的作用如下:

请添加图片描述

  1. 构建 镜像
    准备好脚本之后,就可以直接构建 镜像 了,命令如下:
#格式为:s2i build 《git地址》 《基础镜像》 《打包镜像名称》,--ref 为git分支 --loglevel 为日志级别
s2i  build  http://hqd:zs20240617@192.168.233.136/hqd/devops-demo.git fabric8/s2i-java  devops-demo  --ref v1 --loglevel 3

输入 docker images 查看镜像是否构建,如下:

在这里插入图片描述

S2I 工作流程如下:

在这里插入图片描述


总结

    在实践的过程中,技术是不断地演进的。最初笔者尝试让开发写 Dockerfile ,但是他们对这部分并不熟悉,与其让所有人都学习一遍 Docker ,不如让他们不在关注这部分内容,把重心放在开发上,所以最终抛弃 Dockerfile, 拥抱 S2I

相关文章:

  • 企业微信营销管理软件seo案例视频教程
  • 用.net做网站中含有论坛百度网站权重查询
  • 海外购物网站排名做网络推广怎么收费
  • 网站建设网页模板下载推广app赚佣金平台
  • 建设网站那个好模板建站公司
  • 一级做受网站网站快速收录
  • [特殊字符] 企业级网络压力测试全流程手册
  • Ubuntu 22 Linux上部署DeepSeek+RAG知识库操作详解(Dify方式)之2
  • 打造船岸“5G+AI”智能慧眼 智驱力赋能客船数智管理
  • PHP:将关联数组转换为索引数组的完整示例
  • Linux环境基础开发工具使用
  • AI比人脑更强,因为被植入思维模型【50】邓克效应思维模型
  • 电源测试系统自动化转型:Chroma 8000 与 NSAT-8000 核心功能对比解析
  • 第一章:SQL 基础语法与数据查询
  • 海运货代系统哪家好?能解决了哪些常见管理难题?
  • Less的使用
  • ​​如何测试一个API接口?从原理到实践详解
  • 【Dubbo】分布式服务框架的卓越之选
  • MySQL报Lock wait timeout exceeded; try restarting transaction
  • stm32+esp8266+机智云手机app
  • 《深度解析LightGBM与MySQL数据集成:高效机器学习的新范式》
  • 【Java设计模式】第5章 工厂方法模式讲解
  • 通过Aop实现限制修改删除指定账号的数据
  • QML Loader:动态加载与控件创建
  • git命令
  • LLM面试题十