1. 概述

在本教程中,我们将演示如何将我们在 使用 Spring Boot 快速搭建一个简单应用 教程中创建的应用部署到 OpenShift 平台。

我们将完成以下几项工作:

  • ✅ 安装并配置 OpenShift 开发工具
  • ✅ 创建 OpenShift 项目和 MySQL 部署
  • ✅ 配置应用以使用 Spring Cloud Kubernetes
  • ✅ 使用 Fabric8 Maven 插件 构建和部署容器化应用,并进行测试与扩缩容

2. OpenShift 配置

首先,**我们需要安装 Minishift(本地单节点 OpenShift 集群)以及 OpenShift 客户端命令行工具**。

在使用 Minishift 前,我们需要为 developer 用户配置权限:

minishift addons install --defaults
minishift addons enable admin-user
minishift start
oc adm policy --as system:admin add-cluster-role-to-user cluster-admin developer

接着,我们可以通过浏览器访问 OpenShift 控制台来创建 MySQL 服务:

minishift console

如果未自动登录,请使用用户名和密码 developer/developer 登录。

然后创建一个名为 baeldung-demo 的项目,并从目录中添加一个 MySQL 数据库服务。设置如下参数:

  • Database Service 名称为 baeldung-db
  • MySQL Database Name 为 baeldung_db
  • 其他字段保持默认值即可

此时我们已经拥有了用于访问数据库的服务和密钥(Secrets)。注意记录数据库连接地址:
mysql://baeldung-db:3306/baeldung_db

此外,我们还需要允许应用程序读取 Kubernetes Secrets 和 ConfigMaps:

oc create rolebinding default-view --clusterrole=view \
  --serviceaccount=baeldung-demo:default --namespace=baeldung-demo

3. 引入 Spring Cloud Kubernetes 依赖

我们将使用 Spring Cloud Kubernetes 项目,以启用对 Kubernetes 原生 API 的支持,从而更好地适配 OpenShift 环境:

<profile>
  <id>openshift</id>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-kubernetes-dependencies</artifactId>
        <version>0.3.0.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>2023.0.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  </dependencies>
</profile>

同时,我们使用 Fabric8 Maven Plugin 来构建和部署容器镜像:

<plugin>
    <groupId>io.fabric8</groupId>
    <artifactId>fabric8-maven-plugin</artifactId>
    <version>3.5.37</version>
    <executions>
      <execution>
        <id>fmp</id>
        <goals>
          <goal>resource</goal>
          <goal>build</goal>
        </goals>
      </execution>
    </executions>
</plugin>

4. 应用配置

接下来,我们需要提供一些配置信息,确保正确的 Spring Profiles 和 Kubernetes Secrets 能作为环境变量注入到容器中

我们在 src/main/fabric8 目录下创建一个 YAML 片段,Fabric8 插件会在生成部署配置时使用它。

同时,我们还要为 Spring Boot Actuator 添加探针配置,因为 Fabric8 默认仍然尝试访问 /health 而不是新版的 /actuator/health

spec:
  template:
    spec:
      containers:
      - env:
        - name: SPRING_PROFILES_ACTIVE
          value: mysql
        - name: SPRING_DATASOURCE_USER
          valueFrom:
            secretKeyRef:
              name: baeldung-db
              key: database-user
        - name: SPRING_DATASOURCE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: baeldung-db
              key: database-password
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 180
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30

然后,我们在 openshift/configmap.yml 中保存一个 ConfigMap 文件,其中包含 MySQL 连接地址的 application.properties 配置:

apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-boot-bootstrap
data:
  application.properties: |-
    spring.datasource.url=jdbc:mysql://baeldung-db:3306/baeldung_db

在使用命令行客户端操作 OpenShift 之前,我们需要先登录。在 Web 控制台右上角点击用户图标,选择下拉菜单中的「Copy Login Command」,复制命令并在终端执行:

oc login https://192.168.42.122:8443 --token=<your-token>

确认当前使用的项目是 baeldung-demo

oc project baeldung-demo

然后上传刚刚创建的 ConfigMap:

oc create -f openshift/configmap.yml

5. 部署应用

在部署过程中,Fabric8 Maven 插件会尝试解析端口信息。由于我们原有的 application.properties 中使用了表达式定义端口,插件无法正确解析,因此需要注释掉这一行:

#server.port=${port:8080}

完成后即可开始部署:

mvn clean fabric8:deploy -P openshift

通过以下命令监控 Pod 状态,直到看到应用运行起来:

oc get pods -w

输出类似如下:

NAME                            READY     STATUS    RESTARTS   AGE
baeldung-db-1-9m2cr             1/1       Running   1           1h
spring-boot-bootstrap-1-x6wj5   1/1       Running   0          46s

部署完成后,查看路由信息:

oc get routes

输出示例:

NAME                    HOST/PORT                                                   PATH      SERVICES                PORT      TERMINATION   WILDCARD
spring-boot-bootstrap   spring-boot-bootstrap-baeldung-demo.192.168.42.122.nip.io             spring-boot-bootstrap   8080                    None

最后测试接口是否正常工作,比如添加一本书:

http POST http://spring-boot-bootstrap-baeldung-demo.192.168.42.122.nip.io/api/books \
  title="The Player of Games" author="Iain M. Banks"

预期响应如下:

HTTP/1.1 201 
{
    "author": "Iain M. Banks",
    "id": 1,
    "title": "The Player of Games"
}

6. 应用扩缩容

我们可以将部署副本数调整为 2:

oc scale --replicas=2 dc spring-boot-bootstrap

之后可以继续观察 Pod 状态、获取路由、测试接口等操作。

OpenShift 提供了丰富的性能管理和自动扩缩容机制,详情请参考官方文档:Managing Performance and Scaling

7. 总结

本次教程我们完成了以下内容:

  • ✅ 安装并配置了 OpenShift 开发环境
  • ✅ 部署了一个 MySQL 服务
  • ✅ 创建了 ConfigMap 和 Deployment 配置以注入数据库连接属性
  • ✅ 构建并部署了一个基于 Spring Boot 的容器化应用
  • ✅ 对应用进行了测试和扩缩容操作

更多细节请查阅 OpenShift 官方文档

本文涉及的完整代码示例可在 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/spring-boot-bootstrap


原始标题:Deploy a Spring Boot Application to OpenShift