OpenShift使用S2I运行微服务

点击左上角,关注:“锅外的大佬”

专注分享国外最新技术内容,帮助每一个技术人更优秀地成长


你可能优先选择 OpenShift而不是 Kubernetes的原因之一是运行一个新应用的简便性。使用 Kubernetes时,你需要提供已构建好的镜像和部署模板去运行它。 OpenShift引入了 Source-2-Image功能,用于从代码构建可运行的 Docker镜像。使用 S2I,不需要提供任何 KubernetesYAML模板或自己构建 Docker镜像, OpenShift将为你做这些。准备好示例的应用程序代码,测试它最好的方式是使用 Minishift

1. 准备代码

我已经在之前的一篇文章中描述了如何在 Kubernetes上运行 Java应用程序—— QuickGuidetoMicroserviceswithKubernetes,SpringBoot2.0andDocker。我们将使用那篇文章的代码,同时也方便你比较两份教程的异同。 Github地址: sample-spring-microservices-new,分支 openshift

示例的系统架构图:

OpenShift使用S2I运行微服务_第1张图片

每个微服务都是 SpringBoot应用,使用 Maven构建工具 spring-boot-maven-plugin,用于构建应用的 jar包,这是 source-2-image需要的:

	
    	
        	
            org.springframework.boot	
            spring-boot-maven-plugin	
        	
    	

每个应用程序都包含以下依赖:

	
    	
    	
        org.springframework.boot	
        spring-boot-starter-web	
    	
    	
    	
        org.springframework.boot	
        spring-boot-starter-actuator	
    	
    	
    	
        io.springfox	
        springfox-swagger2	
        2.9.2>/version<	
    	
    	
        io.springfox	
        springfox-swagger-ui	
        2.9.2	
    	
    	
    	
        org.springframework.boot	
        spring-boot-starter-data-mongodb	
    	

每个 SpringBoot应用程序都暴露 REST API,以便进行简单的 CRUD操作。 Controller层代码如下:

@RestController	
@RequestMapping(“/employee”)	
public class EmployeeController {	
    private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeController.class);	
    @Autowired	
    EmployeeRepository repository;	
    @PostMapping("/")	
    public Employee add(@RequestBody Employee employee) {	
        LOGGER.info("Employee add: {}", employee);	
        return repository.save(employee);	
    }	
    @GetMapping("/{id}")	
    public Employee findById(@PathVariable("id") String id) {	
        LOGGER.info("Employee find: id={}", id);	
        return repository.findById(id).get();	
    }	
    @GetMapping("/")	
    public Iterable findAll() {	
        LOGGER.info("Employee find");	
        return repository.findAll();	
    }	
    @GetMapping("/department/{departmentId}")	
    public List findByDepartment(@PathVariable("departmentId") Long departmentId) {	
        LOGGER.info("Employee find: departmentId={}", departmentId);	
        return repository.findByDepartmentId(departmentId);	
    }	
    @GetMapping("/organization/{organizationId}")	
    public List findByOrganization(@PathVariable("organizationId") Long organizationId) {	
        LOGGER.info("Employee find: organizationId={}", organizationId);	
        return repository.findByOrganizationId(organizationId);	
    }	
}

SpringBootMongoDB配置如下:

spring:	
  application:	
    name: employee	
  data:	
    mongodb:	
      uri: mongodb://${MONGO_DATABASE_USER}:${MONGO_DATABASE_PASSWORD}@mongodb/${MONGO_DATABASE_NAME}

服务间通信使用 OpenFeign定义的 RESTClient,包含微服务 department和 organization,示例代码:

@FeignClient(name = "employee", url = "${microservices.employee.url}")	
public interface EmployeeClient {	
    @GetMapping("/employee/organization/{organizationId}")	
    List findByOrganization(@PathVariable("organizationId") String organizationId);	
}

FeignClient访问的目标服务的地址在 application.yml中设置,通过 OpenShift/KubernetesService实现通信,每个服务的名称也通过环境变量注入。

spring:	
  application:	
    name: organization	
  data:	
    mongodb:	
      uri: mongodb://${MONGO_DATABASE_USER}:${MONGO_DATABASE_PASSWORD}@mongodb/${MONGO_DATABASE_NAME}	
microservices:	
  employee:	
    url: http://${EMPLOYEE_SERVICE}:8080	
  department:	
    url: http://${DEPARTMENT_SERVICE}:8080

2. 运行Minishift

本地运行,需要先下载 Minishft,拷贝 minishift.exe(Windows)到 PATH路径,然后使用 minishift start运行。更多详细内容参考 Quickguide to deployingJavaapps onOpenShift。当前使用的 Minishift版本是 1.29.0

启动 Minishift之后,我们需要运行其他的 oc命令启用 source-2-image。首先,给用户 admin添加权限,使其能够访问 openshift, 在这个项目中, OpenShift存储了所有使用的内置模板和 image stream,例如 S2I构建器。让我们从启用 admin-user 插件开始:

minishift addons apply admin-user

现在,我们可以将角色 cluster-admin授予用户 admin

oc login -u system:admin	
oc adm policy add-cluster-role-to-user cluster-admin admin	
oc login -u admin -p admin

至此,通过 admin/admin访问 web控制台,你应该可以看到 openshift项目。这还不够,默认情况下,用于构建可执行的 Javaapps的 openjdk18-openshift不可用,我们可以通过 ocimport-image命令应用插件 xpass

minishift addons apply xpaas

此时,你可以访问 web控制台了(我这边的地址是 https://192.168.99.199:8443),选择 openshift>Builds>Images,可以看到列表里的image stream redhat-openjdk18-openshift

OpenShift使用S2I运行微服务_第2张图片

3.使用 S2I 部署 Java 程序

首先,部署一个 MongoDB实例,因为 Mongo模板在构建服务的目录里面有,所以用 OpenShift非常容易。我们可以提供自己的配置设置或保留默认值。

OpenShift使用S2I运行微服务_第3张图片

OpenShift提供的 S2I构建器镜像可以通过 Image Stream redhat-openjdk18-openshift 使用,此镜像适用于通过主类运行的基于 Maven 的Java 独立项目,例如 SpringBoot 应用程序。如果在创建新应用时不提供任何构建器,则 OpenShift会自动检测应用的类型,Java 编写的源代码将部署在 WildFly 服务器上。当前版本的 Java S2I 构建器镜像支持 OpenJDK1.8、 Jolokia1.3.5 和 Maven3.3.9-2.8

从微服务 employee 开始,在 OpenShift 上部署第一个 Java 应用。在正常情况下,每个微服务都将位于独立的 Git 仓库中,在我们的示例中,所有项目都放在一个仓库中,因此我们通过设置参数 --context-dir 来提供当前应用的位置,我们还将默认分支修改为 openshift

oc new-app redhat-openjdk18-openshift:1.3~https://github.com/piomin/sample-spring-microservices-new.git#openshift --name=employee --context-dir=employee-service

由于所有的微服务都连接到 MongoDB,因此我们还必须将连接设置和 secert 注入应用 Pod,可以通过向 BuildConfig 对象注入 mongodb secret 来实现。

oc set env bc/employee --from="secret/mongodb" --prefix=MONGO_

BuildConfig 是运行 ocnew-app之后创建的 openshift 对象,同时也创建 DeploymentConfig、 Service、 ImageStream 以及最新的 docker 应用镜像。构建流程:下载 Git 代码 -> Maven 构建 -> 构建 Docker 镜像 -> 保存镜像到仓库。

接着,部署另外一个应用 department :

oc new-app redhat-openjdk18-openshift:1.3~https://github.com/piomin/sample-spring-microservices-new.git#openshift --name=department --context-dir=department-service -e EMPLOYEE_SERVICE=employee

和上面一样,注入 mongodb secret 到 BuildConfig对象:

oc set env bc/department --from="secret/mongodb" --prefix=MONGO_

手动执行构建 oc start-build department

部署最后一个微服务,命令如下:

oc new-app redhat-openjdk18-openshift:1.3~https://github.com/piomin/sample-spring-microservices-new.git#openshift --name=organization --context-dir=organization-service -e EMPLOYEE_SERVICE=employee -e DEPARTMENT_SERVICE=department	
oc set env bc/organization --from="secret/mongodb" --prefix=MONGO_

4. 深入了解创建的 OpenShift 对象

通过 web 控制台 Builds -> Builds,可以看到如下的三个 BuildConfig 对象,每个都是简单的应用。也可以通过命令 ocgetbc查看。

OpenShift使用S2I运行微服务_第4张图片

历史构建记录如下:

OpenShift使用S2I运行微服务_第5张图片

查看 BuildConfig 的 YAML 配置

OpenShift使用S2I运行微服务_第6张图片

每个应用的构建都会推送到镜像仓库, Minishift 内嵌的仓库地址:172.30.1.1:5000,可以通过 web 控制台 Builds -> Images 查看。

每个应用通过 service自动暴露端口 8080(HTTP)/8443(HTTPS)/8778(Jolokia),你也可以通过 Minishift 使用命令 oc expose 创建 OpenShiftRoute 暴露服务到外部。

OpenShift使用S2I运行微服务_第7张图片

5. 测试上述系统

执行测试前,需要先暴露服务,命令如下:

oc expose svc employee	
oc expose svc department	
oc expose svc organization

然后通过地址 http://${APP_NAME}-${PROJ_NAME}.${MINISHIFT_IP}.nip.io 访问服务,如下图所示:

OpenShift使用S2I运行微服务_第8张图片

每个微服务都生成了 Swagger2API 文档,页面 swagger-ui.html

OpenShift使用S2I运行微服务_第9张图片

值得注意的是,每个应用程序都使用三种方法将环境变量注入到 pod 中:

1、版本号存储在代码仓库中的 .s2i/environment中, S2I 构建器读取该文件中定义的所有属性,并将它们设置为构建器 Pod 的环境变量,然后是应用 Pod。我们的属性名是 VERSION,它是使用 Spring @Value 注入的,并设置为 SwaggerAPI(代码在下面可见)。

2、在为服务 department 和 organization 执行命令 ocnew-app 时,我已经将依赖服务的名称设置为 ENV 变量。

3、我还使用 ocsetenv 命令将 MongoDBsecret 注入每个 BuildConfig 对象。

@Value("${VERSION}")	
String version;	
public static void main(String[] args) {	
    SpringApplication.run(DepartmentApplication.class, args);	
}	
@Bean	
public Docket swaggerApi() {	
    return new Docket(DocumentationType.SWAGGER_2)	
        .select()	
            .apis(RequestHandlerSelectors.basePackage("pl.piomin.services.department.controller"))	
            .paths(PathSelectors.any())	
        .build()	
        .apiInfo(new ApiInfoBuilder().version(version).title("Department API").description("Documentation Department API v" + version).build());	
}

6.总结

本文介绍了在OpenShift上部署应用程序的简便性。你不需要创建任何YAML描述符文件或自己构建Docker镜像来运行您的应用程序。因为它是直接从你的源代码构建的。

原文链接:https://piotrminkowski.wordpress.com/2019/01/08/running-java-microservices-on-openshift-using-source-2-image/

作者:Piotr Mińkowski

译者:Anoyi

你可能感兴趣的:(OpenShift使用S2I运行微服务)