Connecting to a Database

在本节中,我们将部署和连接 MongoDB 数据库,nationalparks应用程序将在其中存储位置信息。

最后,我们将 nationalparks 应用程序标记为地图可视化工具的后端,以便 `parksmap`组件可以使用 OpenShift 发现机制对其进行动态发现,并自动显示地图。

Application architecture

Background: Storage

大多数应用程序在某种程度上是“有状态的”或“动态的”,这通常是通过数据库或其他数据存储来实现的。在本实验中,我们将把 MongoDB 添加到我们的nationalparks应用程序中,然后重新连接它以通过 secret 使用环境变量与数据库通信。

我们将使用 OpenShift 附带的 MongoDB 映像。

默认情况下,使用 EmptyDir 进行数据存储,这意味着如果Pod 消失,数据也会消失。在实际应用程序中,您将使用 OpenShift 的持久性存储机制将存储(NFS、Ceph、EBS、iSCSI 等)附加到Pod,从而为它们提供一个持久的位置来存储其数据。

Background: Templates

在本模块中,我们将从模板 Template 创建 MongoDB ,这是 OpenShift 中用于为某些值定义参数的有用方法,例如数据库用户名或密码,这些值可以由 OpenShift 在处理时自动生成。

管理员可以将模板加载到 OpenShift 中并使所有用户都可以使用它们。用户可以创建模板并将其加载到自己的项目中,以供其他用户(具有访问权限)共享和使用。

模板重要意义在于,他们可以通过提供一个可以用一条命令部署“配置参数”,加快应用开发的部署流程。不仅如此,它们还可以从外部 URL 加载到 OpenShift 中,这将允许您将模板保存在版本控制系统中。

Exercise: Create a MongoDB Template 因为我们使用了developer-sandbox,请跳到部署 MongoDB

If you are using Developer Sandbox for Red Hat OpenShift, you can skip this section and jump to the next one called Exercise: Deploy MongoDB because MongoDB Template it’s already available on Developer Sandbox.

In this step we will create a MongoDB template inside our project, so that is only visible to our user and we can access it from Developer Perspective to create a MongoDB instance.

oc create -f https://raw.githubusercontent.com/openshift-labs/starter-guides/ocp-4.6/mongodb-template.yaml -n %PROJECT%

What just happened? What did you just create? The item that we passed to the create command is a Template. create simply makes the template available in your Project.

练习: 部署 MongoDB

正如您目前所见,Web 控制台可以非常轻松地将应用部署到 OpenShift。当我们部署数据库时,我们传入一些值进行配置。这些值用于设置数据库的用户名、密码和名称。

数据库映像的构建方式将使用提供的信息自动配置自己(假设持久存储中没有数据!)。该镜像将确保:

  • 存在具有指定名称的数据库

  • 存在具有指定名称的用户

  • 用户可以使用指定的密码访问指定的数据库

在workshop项目的开发者视图中,单击+Add然后单击Database。在数据库视图中,您可以单击Mongo以仅过滤 MongoDB。

确保不要在 类型 Type 部分选中 Operator 支持的 ( Operator Backed )选项
Data Stores

或者,您可以mongodb在搜索框中键入。深入查看 MongoDB 后,找到MongoDB (Ephemeral)模板并选择它。您会注意到有多个 MongoDB 模板可用。我们不需要具有持久存储的数据库,因此您应该选择临时 Mongo 模板。继续并选择临时模板,然后单击实例化模板按钮。

当我们执行应用程序构建时,没有模板。相反,我们直接选择了构建器映像,而 OpenShift 仅展示了标准构建工作流程。现在我们正在使用模板 - 一组预配置的资源,其中包括可以自定义的参数。在我们的例子中,我们关心的参数是——用户、密码、数据库和管理员密码。

MongoDB Deploy
确保您将数据库服务命名为 mongodb-nationalparks

您可以看到某些字段显示“如果为空则生成”。这是OpenShift中模板的一个功能。现在,请确保在各自的字段中使用以下值:

Database Service Name:

mongodb-nationalparks

MongoDB Connection Username:

mongodb

MongoDB Connection Password:

mongodb

MongoDB Database Name:

mongodb

MongoDB Admin Password:

mongodb
确保已MongoDB Database Name使用适当的值配置参数,因为它的默认值为sampledb.

输入上述信息后,单击“创建”进入下一步,这将允许我们添加绑定。

从左侧菜单中,单击 Secrets.

List Secrets

单击我们将用于Parameters 的列出的机密名称。该机密可用于其他组件(例如nationalparks后端)以对数据库进行身份验证。

现在连接和身份验证信息存储在我们项目中的 Secrets.中,我们需要将其添加到nationalparks后端。单击将 Secrets 添加到工作负载按钮。

National Parks Binding

选择nationalparks工作负载并单击保存。

Add binding to application

这种配置更改将触发nationalparks应用程序的新部署,并正确注入环境变量。

返回拓扑视图,如果您的 mongodb-nationalparks 组件不在表示workshop应用程序的浅灰色区域中,请在按住Shift 的同时单击并拖动组件以将其与其他两个组件一起添加到组中(如下所示)

Add mongodb to the workshop app

接下来,让我们修复分配给 mongodb-nationalparks 部署的标签。目前,我们无法在使用目录中的数据库模板时设置标签,因此我们将手动修复这些标签。

和以前一样,我们将添加 3 个标签:

应用组名称:

app=workshop

接下来是此部署的名称。

component=nationalparks

最后,这个组件在整个应用程序中扮演的角色。

role=database

执行以下命令:

oc label dc/mongodb-nationalparks svc/mongodb-nationalparks app=workshop component=nationalparks role=database --overwrite

练习: Exploring OpenShift Magic

一旦我们将 Secret 附加到Deployment,一些神奇的事情就发生了。OpenShift 认为这是一个足够重要的更改,可以保证更新ReplicaSet的内部版本号。您可以通过查看以下输出来验证这一点oc get rs:

NAME                       DESIRED   CURRENT   READY   AGE
nationalparks-58bd4758fc   0         0         0       4m58s
nationalparks-7445576cd9   0         0         0       6m42s
nationalparks-789c6bc4f4   1         1         1       41s
parksmap-57df75c46d        1         1         1       8m24s
parksmap-65c4f8b676        0         0         0       18m

我们看到当前部署的 DESIRED 和 CURRENT 实例数。其他实例的期望和当前数量为 0。这意味着 OpenShift 优雅地拆除了我们的“旧”应用程序并建立了一个“新”实例。

练习: Data, Data, Everywhere

现在我们已经部署了一个数据库,我们可以再次访问nationalparksWeb 服务来查询数据:

https://nationalparks-%PROJECT%.%CLUSTER_SUBDOMAIN%/ws/data/all

结果呢?

[]

数据在哪里?想想你经历的过程。您部署了应用程序,然后部署了数据库。但没有什么实际加载任何数据导入数据库。

该应用程序提供了一个端点来做到这一点:

https://nationalparks-%PROJECT%.%CLUSTER_SUBDOMAIN%/ws/data/load

结果呢?

Items inserted in database: 2893

如果你再回到 /ws/data/all 你现在会看到大量的 JSON 数据。那太棒了。我们的公园地图应该终于有用了!

Firefox 54 等浏览器报告了一些错误,无法正确解析生成的 JSON。这是浏览器问题,应用程序运行正常。
https://parksmap-%PROJECT%.%CLUSTER_SUBDOMAIN%

嗯…​…​只有一件事。主地图仍然没有显示公园。这是因为前端公园地图仅尝试与具有正确 *Label*的服务对话。

您可能想知道数据库连接是如何神奇地开始工作的?将应用程序部署到 OpenShift 时,最好使用环境变量variables、机密secrets或映射configMap 来定义与相关系统的连接。这允许跨不同环境的应用程序可移植性。可以在此处查看执行连接以及创建数据库架构的源文件:

http://www.github.com/openshift-roadshow/nationalparks/blob/master/src/main/java/com/openshift/evg/roadshow/parks/db/MongoDBConnection.java#L44-l48

简而言之:通过引用连接到服务(如数据库)的绑定,在 OpenShift 上的不同生命周期环境中推广应用程序可能很简单,而无需修改应用程序代码。

练习: Working With Labels

在之前的关于Services和Routes和Selectors实验中,我们知道标签 Label 只是一个键值对 key=value pair。一般来说,标签 Label 只是一个任意的键值对。这个可以是任何东西。

  • pizza=pepperoni

  • pet=dog

  • openshift=awesome

在parks map这个项目中,应用程序实际上是在查询 OpenShift API 并询问项目中的 RoutesServices 。如果它们中的任何一个具有 `type=parksmap-backend`的标签 Label ,应用程序知道询问 endpoints 以查找地图数据。您可以在此处查看执行此操作的代码 。

幸运的是,命令行为我们提供了一种方便的方式来操作标签。describe nationalparks 服务:

oc describe route nationalparks
Name:                   nationalparks
Namespace:              %PROJECT%
Created:                2 hours ago
Labels:                 app=workshop
                        app.kubernetes.io/component=nationalparks
                        app.kubernetes.io/instance=nationalparks
                        app.kubernetes.io/name=java
                        app.kubernetes.io/part-of=workshop
                        app.openshift.io/runtime=java
                        app.openshift.io/runtime-version=11
                        component=nationalparks
                        role=backend
Annotations:            openshift.io/host.generated=true
Requested Host:         nationalparks-%PROJECT%.%CLUSTER_SUBDOMAIN%
                        exposed on router router 2 hours ago
Path:                   <none>
TLS Termination:        <none>
Insecure Policy:        <none>
Endpoint Port:          8080-tcp

Service:                nationalparks
Weight:                 100 (100%)
Endpoints:              10.1.9.8:8080

你会看到它已经有了一些标签。现在,使用oc label:

oc label route nationalparks type=parksmap-backend

你会看到类似的东西:

route.route.openshift.io/nationalparks labeled

如果您现在检查浏览器:

https://parksmap-%PROJECT%.%CLUSTER_SUBDOMAIN%/
MongoDB

你会注意到公园突然出现了。这太酷了!