1、概览 Docker 推动了容器化技术的普及,简化了高度分布式应用的创建、交付和运行流程。我们通常使用 docker container 命令管理独立的 Docker 容器。
Docker 最初聚焦于开发者和开发周期,但现已演进为通过简洁强大的编排器提供编排服务。
本文将带你了解容器化技术及编排器(orchestrator)的必要性,继而分析 Docker 容器与编排服务的区别及其适用场景。
2、容器化与编排技术解析 将应用容器化为自治单元是软件开发周期的关键步骤。然而,随着容器数量增长,部署和管理将面临重大挑战:
少量容器:通过 Docker 手动管理仍可行,故障时可手动重启或更新。 现代架构:应用通常拆分为多个组件,每个组件部署为独立容器。 大规模部署:当数十甚至数百个容器需跨多服务器协同工作时,手动管理将不可行。 此时需引入容器编排引擎。
容器编排工具可自动化容器管理,主要保障以下特性:
资源高效利用。 高可用性。 容错能力。 容器化应用的透明扩展。 在这些工具中,Kubernetes 无疑是应用最广泛且功能最全面的解决方案。
Docker 也提供了内置编排器 Docker Swarm 模式,该模式通过 services(服务)概念实现 Docker 容器的编排。
3、Docker 独立容器 以独立模式运行容器指直接在本地主机启动容器,无需编排器参与。每个容器相互隔离,通过 Docker CLI 或 API 手动管理。
3.1、部署 假设我们需要部署 bael-api(一个小型 REST Web 服务,用于查询最新或即将发布的课程和教程),同时配置存储课程元数据的数据库:
$ docker network create bael-network $ docker volume create bael-db-data $ docker container run -d --name db -v bael-db-data:/var/lib/mysql --network bael-network mysql $ docker container run -d --name bael-api -p 8080:8080 --network bael-network bael-api 此处我们创建自定义 Docker 网络确保容器间通信,并配置数据持久化卷。接着使用 docker container run 启动两个容器:
1、概览 一个 Docker 容器会运行一个进程、应用程序,有时仅是一个脚本或命令,以执行其设计任务。
每个容器一旦内部没有任何进程或脚本运行,就会停止并退出。有些容器默认会持续运行,直到用户选择停止它们,例如 MySQL 数据库容器、Spring Boot Web 应用容器或 SMTP 邮件服务器容器。但有时,我们需要让容器在其主要任务完成后仍然保持运行,比如 Ubuntu 容器。
本文将带你了解如何使用 Docker Compose 实现这一需求。
2、Docker Compose 设置 Docker Compose 是我们用来定义和运行多容器服务的工具。唯一的前提条件是在受支持的操作系统平台上安装 Docker(包括 Docker Server、Docker Client 和 Docker Compose)。
本教程中我们使用 Linux Ubuntu。
3、运行 Ubuntu 容器 我们使用一个名为 docker-compose.yml 的示例 Docker Compose 配置文件来定义服务:
services: demo: image: ubuntu 3.1、启动 Docker Compose 服务 使用 -d 选项在后台运行服务的容器:
$ docker-compose up -d 输出如下,显示它创建了一个容器:
Creating ubuntu_demo_1 ... done 查看 Docker Compose 服务创建的容器是否正在运行。
使用 docker ps -a 命令列出容器:
1、概览 本文将带你了解如何利用 Docker 的多阶段构建功能高效地为多模块 Maven 项目构建 Docker 镜像,,以充分利用 Docker 的缓存机制。
然后,还会介绍 Google Jib Maven 插件,用于在没有 Dockerfile 或 Docker 的情况下构建 Docker 镜像。
2、多模块 Maven 项目 多模块 Maven 应用由不同功能的独立模块组成。Maven 通过管理依赖关系来构建应用,并将这些模块组装成一个可部署的单元。
在本文的代码示例中,我们将使用一个包含两个 Maven 模块的基本 Spring Boot 项目,这两个模块分别代表应用程序的 Domain 和 API。
Maven 项目的结构如下:
+-- parent +-- api | `-- src | `-- pom.xml +-- domain | `-- src | `-- pom.xml `-- pom.xml 查看父模块的 pom.xml 文件,就会发现它继承了 spring-boot-starter-parent,并包含了 domain 和 api 模块:
<project> <groupId>com.baeldung.docker-multi-module-maven</groupId> <artifactId>parent</artifactId> <packaging>pom</packaging> <version>0.
1、概览 随着越来越多的企业转向使用容器,Docker 在软件开发中的地位也越来越重要。为此,Spring Boot 2.3 的一大新功能就是为 Spring Boot 应用轻松创建 Docker 镜像提供了支持。
本文将带你了解如何为 Spring Boot 应用创建 Docker 镜像。
2、传统的 Docker 构建 使用 Spring Boot 构建 Docker 镜像的传统方法是使用 Dockerfile。
下面是一个简单的 Dockerfile 示例:
FROM openjdk:8-jdk-alpine EXPOSE 8080 ARG JAR_FILE=target/demo-app-1.0.0.jar ADD ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"] 然后,使用 docker build 命令创建 Docker 镜像。这对大多数应用都很有效,但也有一些缺点。
首先,我们使用的是 Spring Boot 创建的 Fat jar。这会影响启动时间,尤其是在容器化环境中。我们可以通过添加 Jar 文件的解压内容来节省启动时间。
其次,Docker 镜像是分层构建的。Spring Boot Fat Jar 的性质导致所有应用代码和第三方库都被放在一个层中。这意味着,即使只有一行代码发生变化,也必须重建整个层。
通过在构建之前解压 Jar 文件,应用代码和第三方库分别有自己的层。这使我们能够利用 Docker 的缓存机制,当更改一行代码时,只需要重新构建相应的层。
有了这个理念,让我们看看 Spring Boot 如何改进创建 Docker 镜像的过程。
1、简介 Docker 是创建独立应用的事实标准。从 2.3.0 版开始,Spring Boot 包含了多项增强功能,可帮助我们创建高效的 Docker 镜像。例如:它允许将应用分解成不同的层。
换句话说,源代码位于自己的层中。因此,它可以独立重建,从而提高效率并缩短启动时间。本文将带你了解如何利用 Spring Boot 重用 Docker 层。
2、Docker 中的分层 jar Docker 容器由基础镜像和额外的层组成。一旦层构建完成,它们将保持缓存状态。因此,后续的生成速度会更快:
对底层层级的更改也会重新构建上层层级。因此,不经常更改的层级应保持在底部,而经常更改的层级应放在顶部。
同样,Spring Boot 允许将工件(构建产物)内容映射到层中。默认的层映射如下:
你可以看到,应用有自己的层。修改源代码时,只会重新构建独立的层。loader 和依赖保持缓存,从而减少了 Docker 镜像的创建和启动时间。接下来看看如何使用 Spring Boot 实现这一点!
3、Spring Boot 创建高效的 Docker 镜像 在传统的构建 Docker 镜像的方式中,Spring Boot使用的是 “fat jar” 方法。一个工件就包含了所有依赖项和应用源代码。因此,源代码的任何变化都会迫使我们重建整个层。
3.1、Spring Boot 分层配置 Spring Boot 2.3.0 版引入了两个新功能来改进 Docker 镜像的生成:
Buildpack 支持提供了应用的 Java 运行时环境,因此现在可以跳过 Dockerfile,并自动构建 Docker 镜像。 分层 JAR 可以帮助我们最大限度地利用 Docker 层的生成 在本文中,我们将对分层 JAR 方法进行扩展。
首先,在 Maven 中设置分层 JAR 。在打包工件时,生成层。
1、概览 本文将带你了解如何使用 Docker Compose 来运行 Spring Boot 和 PostgreSQL。
2、创建 Spring Boot 应用 从 Spring Initializer 创建 Spring Boot 项目,添加 PostgreSQL 驱动和 Spring Data JPA 依赖。下载生成的 ZIP 文件并解压到文件夹后,就可以运行应用了:
./mvnw spring-boot:run 应用启动失败,因为连接数据库失败:
*************************** APPLICATION FAILED TO START *************************** Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class 3、Dockerfile 在使用 Docker Compose 启动 PostgreSQL 之前,需要将 Spring Boot 应用转化为 Docker 镜像。第一步是将应用打包为 JAR 文件:
1、简介 在容器化大行其道的今天,越来越多人选择把 Spring Boot 应用部署到 Docker 中。
本文将带你了解在 Docker 容器中启动 Spring Boot 应用时,如何设置其 Profile。
2、基本的 Dockerfile 一般来说,要容器化 Spring Boot 应用,只需提供一个 Dockerfile。
Spring Boot 应用的最小 Dockerfile,如下:
FROM openjdk:11 COPY target/*.jar app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] 然后,可以通过 docker build 来构建 Docker 镜像:
docker build --tag=docker-with-spring-profile:latest . 接着,我们就可以通过 docker-with-spring-profile 镜像运行应用了:
docker run docker-with-spring-profile:latest 你可以注意到,Spring Boot 应用以 “default” Profile 启动:
2022-04-22 22:34:25.268 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 11.0.14.1 on ea8851bea75f with PID 1 (/app.
1、简介 GraalVM 使用其 Ahead-Of-Time(AOT)编译器将 Java 应用程序编译为机器可执行文件。这些可执行文件直接在目标机器上执行,而无需使用即时编译器 (JIT)。GraalVM生成的二进制文件体积较小,启动速度快,并且在没有任何预热的情况下提供最佳性能。此外,这些可执行文件相比在 JVM 上运行的应用程序而言,内存占用和 CPU 使用率较低。
通过 Docker,我们可以将软件组件打包成 Docker Image,并作为 Docker 容器运行。Docker 容器包含应用程序运行所需的一切,包括应用程序代码、运行时、系统工具和库。
在本教程中,我们将了解如何创建 Java 应用程序的 GraalVM 原生(native)镜像,以及如何将该原生镜像用作 Docker 镜像,并将其作为 Docker 容器运行。
2、原生镜像是什么? 原生镜像(Native Image)是一种将 Java 代码提前编译成原生可执行文件的技术。该原生可执行文件只包含运行时需要执行的代码。这包括应用程序类、标准库类、语言运行时和 JDK 中静态链接的本地代码。
原生镜像生成器(Native Image Builder)会扫描应用程序类和其他元数据,以创建一个特定于操作系统和体系结构的二进制文件。本地镜像工具会执行静态应用程序代码分析,以确定应用程序运行时可访问的类和方法。然后,它将所需的类、方法和资源编译成二进制可执行文件。
3、原生镜像的优点 原生镜像可执行文件有几个好处:
由于原生镜像生成器只编译运行时所需的资源,因此可执行文件的体积很小 本地可执行文件的启动时间极短,因为它们是在目标机器中直接执行的,无需使用 JIT 编译器 由于只打包所需的应用程序资源,暴漏的攻击面较小 将其打包为轻量级容器镜像(如 Docker Image),有助于快速高效地部署 4、构建 GraalVM 原生镜像 在本节中,我们将为 Spring Boot 应用构建 GraalVM 原生镜像。首先,需要安装 GraalVM 并设置 JAVA_HOME 环境变量。其次,创建一个包含 Spring Web 和 GraalVM Native Support 依赖的 Spring Boot 应用:
1、简介 在本教程中,我们将了解如何把使用 Spring Boot 创建的 Java 应用作为 Docker 容器运行,具体来说,我们将在 Alpaquita Linux 上使用 Liberica JDK 来创建运行我们应用的 Docker 镜像。
Liberica JDK 和 Alpaquita Linux 是 BellSoft 产品的一部分。BellSoft 的愿景是使 Java 成为云原生应用程序的首选语言。
2、简单的 Spring Boot 应用 先用 Java 创建一个简单的应用,然后将其容器化。通过 Spring Boot,我们只需进行最少的配置,就能轻松创建基于 Spring 的独立生产级应用。
初始化 Spring Boot 应用的最简单方法是使用 Spring Boot CLI。通过它,可以在命令行中使用 start.springboot.io 创建一个新项目:
$ spring init --build=gradle --dependencies=web spring-bellsoft 如上,添加了 web 依赖,以构建 RESTful API,并将 Apache Tomcat 作为默认的嵌入式容器。选择 Gradle 作为构建工具,默认的语言是 Java。
然后,可以将生成的项目导入 IDE(如 IntelliJ Idea),开始开发应用。
添加一个简单的 REST API,接收一个 Integer 参数,并返回等于或小于该数字的斐波纳契数列:
在本文中,你将学习如何使用 Spring Boot 内置的 Testcontainers 和 Docker Compose 支持,在开发模式下运行外部服务。Spring Boot 在当前的最新版本 3.1 中引入了这些功能,你已经可以在 Spring Boot 应用的测试中利用 Testcontainers。在应用程序启动时运行外部数据库、message broker 或其他外部服务的功能是我一直期待的。尤其是竞争框架 Quarkus 已经提供了名为 Dev Services 的类似功能,这在我的开发过程中非常有用。此外,还有另一个令人兴奋的功能 - 与 Docker Compose 集成。
源代码 如果你想自己尝试,可以查看我的源代码。因为我经常使用 Testcontainers,所以你可以在我的多个仓库中找到示例。下面是我们今天要使用的仓库列表:
https://github.com/piomin/sample-spring-boot-on-kubernetes.git https://github.com/piomin/sample-spring-microservices-advanced.git https://github.com/piomin/sample-spring-kafka-microservices.git 你可以克隆它们,然后按照指导查看如何在开发模式下使用 Spring Boot 内置的 Testcontainers 和 Docker Compose 支持。
在测试中使用 Testcontainers 让我们从标准使用示例开始。第一个仓库中有一个连接 Mongo 数据库的 Spring Boot 应用程序。为了构建自动测试,我们必须包含以下 Maven 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>mongodb</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> 现在,我们可以创建测试了。我们需要用 @Testcontainers 来注解我们的测试类。然后,我们必须声明 MongoDBContainer Bean。在 Spring Boot 3.