SpringBoot编程基础教程:Docker容器化部署

发布于:2023-10-25 ⋅ 阅读:(84) ⋅ 点赞:(0)

作者:禅与计算机程序设计艺术

1.背景介绍

概述

本系列教程旨在对Spring Boot应用进行Docker镜像制作和发布,并通过Dockerfile文件对应用进行自动化打包、构建、分发。读者将能够掌握以下知识点:

  1. Docker相关工具安装配置及基本命令使用;
  2. Dockerfile文件的编写方法及其生效流程;
  3. Spring Boot项目的打包方式及Maven依赖管理;
  4. 通过DockerHub或其他第三方镜像仓库托管Spring Boot镜像;
  5. 使用容器云服务如阿里云容器服务(ACS)或腾讯云容器引擎(TCE)快速发布Spring Boot应用。

    Spring Boot介绍

    Spring介绍

    Spring是一个开源框架,主要用于解决企业级开发中常见的问题,比如安全性、事务性、消息总线、持久层框架等。Spring提供了很多模块可以集成到应用程序当中,比如Spring MVC、Spring Data JPA、Spring Security、Spring Social等。这些模块能够帮助我们快速开发出功能完善、健壮、可测试的软件系统。Spring还提供了一个全面的企业级开发规范(Spring Framework Reference Guide),里面包括了一整套完整的开发指南,从如何定义bean到面向切面的设计原则,都有相应的文档。而且Spring还有一个官方网站(spring.io),里面有很多学习资源和参考书籍。

    Spring Boot介绍

    Spring Boot是一个基于Spring平台的新型Web应用开发框架,用于简化新Spring应用的初始搭建以及开发过程。Spring Boot采用了特定的方式来进行配置,从而使开发人员不再需要编写复杂的XML文件。只需很少的注解或者属性设置,就可以创建独立运行的Spring应用程序。Spring Boot还包含了大量内嵌的依赖项,使得应用的初始配置变得简单。由于 Spring Boot 的轻量级特性和标准化配置,使得开发人员可以花更少的时间和精力来开发业务应用程序。

    Spring Boot优势

  • 创建独立运行的Spring应用程序,因此不需要关注 servlet 配置和 web.xml 文件;
  • 提供了一种便捷的初始化启动类,通过 @SpringBootApplication 注解开启组件扫描、自动配置以及 spring.factories 文件加载;
  • 为实现“无配置文件”的环境配置提供了一个autoconfigure机制;
  • 支持多种应用运行方式:嵌入式容器、传统 WAR 包形式、Docker 镜像形式等;
  • 提供 Actuator 端点监控 Spring 应用程序;
  • 默认提供了一个基于 Spring Web 的嵌入式 Tomcat 或 Jetty HTTP 服务器;
  • 支持 IntelliJ IDEA、Eclipse、NetBeans 等主流 IDE;
  • 无缝集成 Spring Cloud 和 Spring Cloud Alibaba 等生态组件。 综上所述,Spring Boot 是最佳实践、生产级的 Java EE 应用开发框架。它提供了简单易用的开发模式,让开发者关注于业务逻辑的开发,而不是配置和环境问题。此外,Spring Boot 为各种部署场景提供了统一的解决方案,开发者可以通过多种途径来发布 Spring Boot 应用。

    2.核心概念与联系

    Docker介绍

    Docker是一个开源的应用容器引擎,让开发者可以打包一个应用以及它的运行环境,然后共享这个镜像给其他人使用。它可以让开发者从繁琐的环境配置中解脱出来,专注于软件开发本身。其诞生之初就是为了更方便地创建、部署和运行分布式应用。

    Maven介绍

    Apache Maven是一个纯Java的项目管理工具,可以管理项目的构建、报告和文档生成等。由于Maven可以处理各种类型的项目,包括Java库、Java命令行程序、web站点、WAR文件、EJB JAR等等,因而非常适合管理多种类型项目。Maven官网:http://maven.apache.org/。

    Spring Boot Maven插件介绍

    Spring Boot Maven插件是一个Maven扩展插件,用于帮助开发者创建Spring Boot应用程序。它可以执行自动配置、运行测试、打包应用程序等任务。Spring Boot Maven Plugin官网:https://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-maven-plugin.html。

    Dockerfile介绍

    Dockerfile是一个文本文件,其中包含了一条条指令,用于创建一个镜像。Dockerfile通常由多个指令构成,每条指令指定该镜像应该怎么建立、运行。Dockerfile官网:https://www.docker.com/resources/what-container。

    ACS介绍

    阿里云容器服务(Container Service for Kubernetes,简称ACS)是基于Kubernetes的云原生PaaS,可以在阿里云上快速部署和管理容器化应用。ACS提供了基于Web的图形化界面,用户可以在浏览器上轻松完成集群的创建、删除、扩缩容、日志查询等操作。ACS具有高可用、弹性伸缩、数据安全、监控告警等优秀特性。

    TCE介绍

    腾讯云容器引擎(TCE,Tencent Cloud Container Engine)是腾讯云提供的基于kubernetes的容器服务。TCE可以让用户在腾讯云上轻松部署和管理容器化应用。TCE也提供了一个Web控制台,支持Web应用的发布、管理、运维。TCE具有高可用、弹性伸缩、数据安全、监控告警等优秀特性。

    3.核心算法原理和具体操作步骤以及数学模型公式详细讲解

    安装配置Docker

    首先,下载Docker安装包:https://download.docker.com/linux/static/stable/x86_64/,根据不同的操作系统选择对应的版本,将下载后的安装包上传至服务器,并解压。
    sudo mkdir -p /etc/docker
    sudo cp /path/to/docker/* /usr/bin/
    sudo chmod +x /usr/bin/docker*
    sudo usermod -aG docker ${USER} # 将当前用户加入docker组
    安装完成后,我们可以使用以下命令查看docker版本信息:
    $ sudo docker version
    Client:
    Version:           19.03.8
    API version:       1.40
    Go version:        go1.13.8
    Git commit:        afacb8b7f0
    Built:             Wed Mar 11 23:42:35 2020
    OS/Arch:           linux/amd64
    Experimental:      false
    

Server: Engine: Version: 19.03.8 API version: 1.40 (minimum version 1.12) Go version: go1.13.8 Git commit: afacb8b7f0 Built: Wed Mar 11 23:41:27 2020 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.3.3-0ubuntu2.1~18.04.4 GitCommit:
runc: Version: spec: 1.0.1-dev GitCommit:
docker-init: Version: 0.18.0 GitCommit:

## 使用Maven构建Spring Boot应用
对于Spring Boot应用来说,构建Docker镜像的第一步就是将Spring Boot应用打包成JAR文件。Maven是最流行的Java项目管理工具,我们可以使用Maven插件来构建JAR文件。以下是用Maven插件构建Spring Boot应用JAR文件的步骤:

1. 在pom.xml文件中添加如下插件配置:

   ```xml
   <build>
     <plugins>
       <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <!-- 自定义参数 -->
         <configuration>
           <imageName>${project.groupId}/${project.artifactId}</imageName>
           <imageTags>${project.version}</imageTags>
           <pushImage>false</pushImage>
           <arguments>
             <argument>-DskipTests=true</argument>
           </arguments>
         </configuration>
         <executions>
           <execution>
             <goals>
               <goal>repackage</goal>
             </goals>
           </execution>
         </executions>
       </plugin>
     </plugins>
   </build>
  1. 执行mvn clean package,编译Spring Boot应用并打包成JAR文件。如果项目下没有pom.xml文件,则执行mvn archetype:generate命令生成一个基础的pom.xml文件。

  2. 查看target目录,确认是否存在名为spring-boot-application-0.0.1-SNAPSHOT.jar的文件。

创建Dockerfile文件

Dockerfile文件是用来描述镜像内容和运行时环境的文本文件。Dockerfile中的指令会被Docker解析,然后按照顺序执行,最终产出一个满足Dockerfile中描述的镜像。以下是Dockerfile文件示例:

FROM openjdk:8-alpine as builder
WORKDIR /app
COPY../
RUN mvn package
CMD ["java", "-jar", "target/${project.artifactId}-${project.version}.jar"]

FROM alpine:latest
LABEL maintainer="John <<EMAIL>>"
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]

这里,Dockerfile共两段:

第1段:

FROM openjdk:8-alpine as builder
WORKDIR /app
COPY../
RUN mvn package
CMD ["java", "-jar", "target/${project.artifactId}-${project.version}.jar"]
  • FROM 指定基础镜像;
  • as 关键字为构建阶段命名;
  • WORKDIR 设置工作目录;
  • COPY 拷贝本地项目文件至镜像;
  • RUN 运行构建脚本命令,如编译项目;
  • CMD 设置容器启动命令,如启动JAR文件。

第2段:

FROM alpine:latest
LABEL maintainer="John <<EMAIL>>"
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
  • FROM 指定基础镜像;
  • LABEL 添加标签;
  • WORKDIR 设置工作目录;
  • COPY 从前一步构建阶段拷贝JAR文件至当前目录;
  • EXPOSE 暴露端口;
  • ENTRYPOINT 启动容器时执行的命令。

创建Docker Hub仓库

创建一个Docker Hub仓库,并记录其镜像名称。注意,注册Docker Hub账号并登录之后,才能够创建仓库。点击 https://hub.docker.com/signup ,注册账号并登录,点击创建新的仓库按钮:

填写仓库名称和描述,勾选Public/Private,点击Create即可。完成后,在页面左侧找到刚才创建的仓库,复制其镜像名称。例如,我的镜像名称为mycompany/myapp

构建Docker镜像

构建Docker镜像的命令如下:

$ cd myapp
$ docker build -t {your-repo}/myapp.

上面的命令表示进入Spring Boot应用目录,并且构建一个名为{your-repo}/myapp的Docker镜像。其中{your-repo}是之前记录的Docker Hub镜像名称,.表示Dockerfile所在目录。构建成功后,我们可以使用docker images命令查看镜像列表:

$ docker images | grep myapp
{your-repo}/myapp   latest              e6e48b1fbab5        5 minutes ago       839MB

推送Docker镜像到Docker Hub

推送Docker镜像到Docker Hub的命令如下:

$ docker push {your-repo}/myapp
The push refers to repository [{your-repo}/myapp]
caea4940c75b: Pushed 
7d1ce1a742cb: Pushed 
....
latest: digest: sha256:da31e737fb07e9d637c7cfba85af90c669e9b8b3b34a9ddbf0086e28e9be0a7b size: 2272

上面命令表示将刚才构建的Docker镜像推送到Docker Hub仓库。你可以通过访问Docker Hub页面查看你的镜像是否已经上传成功。

运行Docker容器

运行Docker容器的命令如下:

$ docker run -p 8080:8080 {your-repo}/myapp

-p选项表示将主机的8080端口映射到Docker容器的8080端口,{your-repo}/myapp表示要运行的镜像名称。执行成功后,我们可以使用docker ps命令查看正在运行的容器:

CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS         PORTS                    NAMES
571e719b2b32   {your-repo}/myapp:latest   "/usr/local/openjdk-…"   2 seconds ago   Up 1 second    0.0.0.0:8080->8080/tcp   goofy_swartz

通过访问http://localhost:8080/可以访问Spring Boot应用的默认首页。

配置容器环境变量

一般情况下,我们可能需要配置一些环境变量才能让Spring Boot应用正常运行。我们可以在Dockerfile文件中通过ENV指令来设置环境变量:

ENV JAVA_OPTS="-Xms512m -Xmx1024m" \
    SPRING_PROFILES_ACTIVE=prod

以上例子设置了两个环境变量:

  • JAVA_OPTS: JVM启动参数,-Xms设置最小堆内存大小,-Xmx设置最大堆内存大小;
  • SPRING_PROFILES_ACTIVE: 用来切换不同环境下的配置。

分发Docker镜像

前面我们演示了如何创建一个Docker镜像并推送到Docker Hub。然而,如果有多个环境(如测试环境、生产环境等)需要运行同一个Spring Boot应用,就需要为每个环境单独创建镜像。为此,我们可以利用容器云服务如阿里云容器服务(ACS)或腾讯云容器引擎(TCE)。

ACS概览

阿里云容器服务(Container Service for Kubernetes,简称ACS)是基于Kubernetes的云原生PaaS,可以在阿里云上快速部署和管理容器化应用。ACS提供了基于Web的图形化界面,用户可以在浏览器上轻松完成集群的创建、删除、扩缩容、日志查询等操作。ACS具有高可用、弹性伸缩、数据安全、监控告警等优秀特性。

TCE概览

腾讯云容器引擎(TCE,Tencent Cloud Container Engine)是腾讯云提供的基于kubernetes的容器服务。TCE可以让用户在腾讯云上轻松部署和管理容器化应用。TCE也提供了一个Web控制台,支持Web应用的发布、管理、运维。TCE具有高可用、弹性伸缩、数据安全、监控告警等优秀特性。

配置TCE集群

点击 https://console.cloud.tencent.com/tke2/index?rid=1&anchor=quickStart ,进入腾讯云容器引擎快速入门页面。

选择适合您的工作负载类型:

选择集群节点规格:

配置集群网络:

配置集群存储:

配置集群权限:

最后,点击立即创建,等待集群创建完成。

拉取Docker镜像

登陆TKE集群的机器上,执行以下命令拉取Docker镜像:

$ sudo docker login --username=<用户名> registry.<地域>.aliyuncs.com
$ sudo docker pull {your-repo}/myapp

其中<用户名><地域>需要替换为实际值。

配置TKE集群

点击TKE控制台左侧导航栏上的应用负载 > 容器服务,进入容器服务页面:

点击创建按钮,选择导入镜像,输入之前拉取到的镜像地址:

点击下一步,选择创建好的集群,并点击下一步:

配置容器组:

配置服务暴露:

点击下一步,点击创建按钮创建容器服务:

浏览器访问Spring Boot应用

打开浏览器,访问TKE集群的公网IP,查看Spring Boot应用是否正常运行。

4.具体代码实例和详细解释说明

本节展示一些代码实例,并详细说明代码的作用。为了便于阅读,省略了部分代码,但请读者自己动手尝试一下。

配置Docker环境

我们需要确保Docker服务已开启且已经正确安装。对于Linux环境,需要先安装Docker CE或者Docker EE。建议安装最新版本的Docker。

如果需要远程连接到Docker daemon,请确保TCP监听6443端口(TCP socket)。如果你使用的是CentOS,你可以执行以下命令开启TCP监听6443端口:

$ sudo firewall-cmd --zone=public --add-port=6443/tcp --permanent && sudo firewall-cmd --reload

同时,为了让当前用户免密码访问Docker,你还需要执行以下命令:

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

执行docker info命令检查Docker是否已经正常运行。

配置Maven环境

我们需要确保Maven环境已安装并且配置好。如果Maven尚未安装,你可以按照以下链接安装:https://maven.apache.org/install.html

编辑你的~/.bashrc文件,添加以下配置:

export MAVEN_HOME=/usr/share/maven
export PATH=$PATH:$MAVEN_HOME/bin

执行source ~/.bashrc刷新环境变量。

执行mvn --version命令检查Maven是否安装成功。

创建Spring Boot应用

使用IDEA新建项目,选择Maven坐标,Spring Boot版本,项目名,groupId,ArtifactId,包名,Dependencies等信息。

配置POM文件:

在POM文件中,增加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

创建HelloWorldController类:

创建控制器类HelloWorldController继承自RestController类,并添加一个简单的Hello World接口:

@RestController
public class HelloWorldController {

    @RequestMapping("/")
    public String index() {
        return "Hello World";
    }
}

编写配置文件:

src/main/resources目录下创建application.yml文件,写入以下配置:

server:
  port: 8080

编写Dockerfile

编写Dockerfile文件,保存为Dockerfile

FROM openjdk:8-jre-alpine

WORKDIR /app
ADD target/*.jar app.jar

EXPOSE 8080

CMD java -jar /app/app.jar

在Dockerfile文件中,我们指定基础镜像为OpenJDK 8 with JRE。我们将工作目录设置为/app,将JAR文件复制到镜像中,并设置容器对外暴露的端口为8080

编译运行Docker镜像

在命令行窗口,切换到Dockerfile所在目录,执行以下命令编译运行Docker镜像:

docker build -t myapp.
docker run -it -p 8080:8080 myapp

执行docker images命令,查看所有镜像,并查找myapp镜像的ID。

执行docker ps命令,查看所有正在运行的容器。

打开浏览器,访问http://localhost:8080,可以看到"Hello World"字样出现。

5.未来发展趋势与挑战

目前,Docker已经成为企业级应用部署的必备技术。随着容器技术的普及和落地,Docker会成为企业级应用部署的主流技术。因此,我们期望这一系列教程能够帮助读者提升自己的能力,更加熟练地使用Docker进行Java应用的容器化部署。下面,我将分享一些未来的发展方向与挑战。

Spring Boot+K8s+Istio微服务架构

目前,Kubernetes已经成为最火热的容器编排调度技术。Kubernetes通过提供容器集群管理、资源分配调度、动态部署和横向扩展等功能,可以快速响应容器化应用的变化,实现高度的可靠性和可用性。

对于Spring Boot微服务架构,Spring Cloud的微服务组件已经可以很好的兼容Kubernetes。Spring Cloud包括配置中心、服务注册发现、网关路由、服务调用链路追踪等功能,可以帮助我们构建复杂的分布式系统。

Istio是一个开源的服务网格,它提供包括流量管理、安全、可观察性等一系列功能。Istio可以帮助我们更加细粒度地管理微服务间的流量,并实施安全策略。

结合上述技术,我们可以构建一个完整的微服务架构,包括前端UI,API Gateway,后台服务等。通过Kubernetes、Istio和Spring Cloud,我们可以快速部署、管理、监控和扩展我们的Java应用。

Spring Boot应用Docker镜像版本管理

目前,我们需要手动将Spring Boot应用的JAR包上传至镜像仓库,这种方式费时耗力且容易出错。基于Docker的版本管理系统能够自动化处理Spring Boot应用的镜像版本更新,可以实现自动化的CI/CD流程。

GitHub Actions、Travis CI、Circle CI等CI/CD工具也可以用来自动化Spring Boot应用镜像版本更新。我们只需要在CI/CD过程中,构建Spring Boot应用的镜像并推送到Docker Hub仓库,就可以实现Spring Boot应用的版本更新。

JenkinsX微服务GitOps

为了实现Spring Boot应用的DevOps自动化,Jenkins X引入了一系列的工具,包括gitops、serverless、preview environments、secret management等。Jenkins X可以帮助我们实现微服务的GitOps自动化部署,实现应用的自动化交付和管理。

Spring Boot应用镜像体积优化

虽然Docker镜像的体积小,但是仍然占用磁盘空间,影响部署效率。因此,我们需要对Spring Boot应用镜像进行优化,降低体积。比如,压缩镜像,使用基于Alpine Linux的基础镜像等。

另外,我们还可以采用Spring Boot的内嵌web容器特性,通过定制Tomcat等容器,减少镜像的体积。

Spring Boot应用云原生与混合云架构

虽然Docker容器技术可以快速部署Java应用,但是应用的硬件要求往往比容器更高。为了能够在公有云、私有云、混合云等多种云计算平台上部署Java应用,我们需要考虑架构的变革。目前,Kubernetes社区正在探索多集群、多区域、多云部署架构。

6.附录常见问题与解答

Q1.为什么需要Spring Boot Docker镜像?

容器技术虽然方便快捷,但有些时候可能会遇到性能瓶颈,比如处理请求时间长,因为容器的隔离性导致容器之间资源不共享。所以,我们需要对Spring Boot应用进行性能优化,比如调整JVM参数,减少线程池数量,优化数据库连接池等。通过Docker镜像,我们可以将容器环境的配置和环境变量等信息封装起来,将Spring Boot应用打包进容器,这样就可以更有效地管理应用了。

Q2.什么是Dockerfile?

Dockerfile是一个文本文件,其中包含了一条条指令,用于创建一个镜像。Dockerfile通常由多个指令构成,每条指令指定该镜像应该怎么建立、运行。Dockerfile可以通过源代码、基础镜像、指令集合三种方式构建。

Q3.如何创建Dockerfile?

Dockerfile文件的内容一般来说都比较简单,通常包括三个部分:基础镜像定义、设置工作目录、复制文件、执行命令。以下是Dockerfile文件的示例:

FROM openjdk:8-alpine as builder
WORKDIR /app
COPY../
RUN mvn package
CMD ["java", "-jar", "target/${project.artifactId}-${project.version}.jar"]
  • FROM:指定基础镜像;
  • AS:为构建阶段命名;
  • WORKDIR:设置工作目录;
  • COPY:拷贝本地项目文件至镜像;
  • RUN:运行构建脚本命令,如编译项目;
  • CMD:设置容器启动命令,如启动JAR文件。

Q4.如何推送Docker镜像?

推送Docker镜像到Docker Hub仓库的命令如下:

$ docker push {your-repo}/myapp
The push refers to repository [{your-repo}/myapp]
caea4940c75b: Pushed 
7d1ce1a742cb: Pushed 
....
latest: digest: sha256:da31e737fb07e9d637c7cfba85af90c669e9b8b3b34a9ddbf0086e28e9be0a7b size: 2272

在这个命令中,{your-repo}是之前记录的Docker Hub镜像名称。执行成功后,我们可以打开浏览器访问Docker Hub页面,查看我们上传的镜像是否成功。

Q5.如何运行Docker容器?

运行Docker容器的命令如下:

$ docker run -p 8080:8080 {your-repo}/myapp

-p选项表示将主机的8080端口映射到Docker容器的8080端口,{your-repo}/myapp表示要运行的镜像名称。执行成功后,我们可以使用docker ps命令查看正在运行的容器。

Q6.如何配置容器环境变量?

一般情况下,我们可能需要配置一些环境变量才能让Spring Boot应用正常运行。我们可以在Dockerfile文件中通过ENV指令来设置环境变量:

ENV JAVA_OPTS="-Xms512m -Xmx1024m" \
    SPRING_PROFILES_ACTIVE=prod

以上例子设置了两个环境变量:

  • JAVA_OPTS: JVM启动参数,-Xms设置最小堆内存大小,-Xmx设置最大堆内存大小;
  • SPRING_PROFILES_ACTIVE: 用来切换不同环境下的配置。

Q7.如何分发Docker镜像?

前面我们演示了如何创建一个Docker镜像并推送到Docker Hub。然而,如果有多个环境(如测试环境、生产环境等)需要运行同一个Spring Boot应用,就需要为每个环境单独创建镜像。为此,我们可以利用容器云服务如阿里云容器服务(ACS)或腾讯云容器引擎(TCE)。

Q8.为什么需要ACI架构?

随着容器技术的发展,容器云服务越来越多,而其中某些服务商(如阿里云、腾讯云、百度云)的产品却又比其它服务商更适合做容器云服务。为了更好地应对容器化应用的架构,比如微服务架构、基于消息队列的架构等,国内一些厂商提出了ACI架构。

ACI架构分为四个部分:应用层(Application Layer)、中间件层(Middleware Layer)、操作系统层(Operating System Layer)和基础设施层(Infrastructure Layer)。应用层包括用户界面、Web应用、后台服务等;中间件层包括消息队列、缓存、数据库、搜索引擎等;操作系统层包括虚拟机、容器引擎、容器运行时、容器镜像、操作系统等;基础设施层包括网络、存储、安全、容器编排、监控等。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到