阅读本文的其他语言版本:English。
Spring Boot 是常用 Java 微服务框架之一。Spring Cloud 拥有一组丰富的、良好集成的 Java 类库,用于应对 Java 应用程序堆栈中发生的运行时问题;而 Kubernetes 则提供了丰富的功能集来运行多语言微服务。这些技术彼此互补,为 Spring Boot 应用程序提供了强大的平台。
在此代码中,我们演示了如何在 Kubernetes 上部署一个简单的 Spring Boot 应用程序。此应用程序称为 Office Space,它模仿了电影上班一条虫 (Office Space) 中 Michael Bolton 的虚构应用程序创意。该应用程序利用了这样一个金融方案:通常不满一分钱的分币会四舍五入,而此方案将这部分币值转移到一个独立的银行账户中来计算交易利息。
该应用程序使用 Java 8/Spring Boot 微服务计算利息,然后将分币存入数据库。另一个 Spring Boot 微服务是通知服务。当账户余额超过 50,000 美元时,它会发送电子邮件。它是由计算利息的 Spring Boot Web 服务器触发的。前端使用 Node.js 应用程序来显示 Spring Boot 应用程序累积的当前账户余额。后端使用 MySQL 数据库来存储账户余额。
使用 Minikube 创建一个 Kubernetes 集群用于本地测试,使用 IBM Cloud Private 或者 IBM Cloud Container Service 创建一个 Kubernetes 集群以部署到云中。本文中的代码使用 Travis 定期使用基于 IBM Cloud Container Service 的 Kubernetes 集群 进行测试。
1.创建数据库服务
1.1 在容器中使用 MySQL 或者
1.2 使用 IBM Cloud MySQL服务
2.创建 Spring Boot 微服务
2.1 使用 Maven 构建项目
2.2 构建和推送 Docker 镜像
2.3 为 Spring Boot 服务修改 yaml 文件
2.3.1 在通知服务中使用默认电子邮件服务 或者
2.3.2 在通知服务中使用 OpenWhisk Actions
2.4 部署 Spring Boot 微服务
3.创建前端服务
4.创建交易生成器服务
5.访问应用程序
后端包含 MySQL 数据库和 Spring Boot 应用程序。每一项 微服务都包含一个 Kubernetes Deployment 和一个 Kubernetes Service。Kubernetes Deployment 用于管理每一项微服务所启动的 pod。Kubernetes Service 用于 为每一项微服务创建一个稳定的 DNS 记录,以便它们可以 根据域名相互引用。
- 创建 MySQL 数据库后端的方法有两种: 在容器中使用 MySQL 或者 使用 IBM Cloud MySQL 服务
$ kubectl create -f account-database.yaml
service "account-database" created
deployment "account-database" created
默认认证信息已使用 base64 在 secrets.yaml 中进行了编码。
base64 编码不会加密或隐藏您的密钥。请勿将其上传至您的 Github 仓库中。
$ kubectl apply -f secrets.yaml
secret "demo-credentials" created
下一步请参考步骤 2 。
通过 https://console.ng.bluemix.net/catalog/services/compose-for-mysql 在 IBM Cloud 中为 MySQL 提供 Provision Compose
转至 Service credentials 并查看您的凭证。包括 MySQL 主机名、端口、用户名和密码等信息位于凭证 URI 下,如下所示:
您将需要应用这些凭证作为 Kubernetes 集群中的密钥。这些信息应已被 base64
编码。
使用脚本 ./scripts/create-secrets.sh
。系统将提示您输入自己的凭证。这将对您输入的凭证进行编码,并创建 Kubenetes Secret 对象。
$ ./scripts/create-secrets.sh
Enter MySQL username:
admin
Enter MySQL password:
password
Enter MySQL host:
hostname
Enter MySQL port:
23966
secret "demo-credentials" created
您也可以编辑 secrets.yaml
文件,将其中的数据值编辑为自己的 base64 编码的凭证。然后执行 kubectl apply -f secrets.yaml
。
下一步请参考步骤 2 。
您需要安装 Maven 工具。 如果要修改 Spring Boot 应用程序,请在构建 Java 项目和 Docker 镜像之前完成修改。
Spring Boot 微服务包括 Compute-Interest-API 和 Send-Notification。
Compute-Interest-API 是一个需要使用 MySQL 数据库的 Spring Boot 应用程序。相关配置位于 spring.datasource*
中的 application.properties 中。
compute-interest-api/src/main/resources/application.properties
spring.datasource.url = jdbc:mysql://${MYSQL_DB_HOST}:${MYSQL_DB_PORT}/dockercon2017
# Username and password
spring.datasource.username = ${MYSQL_DB_USER}
spring.datasource.password = ${MYSQL_DB_PASSWORD}
application.properties
配置为使用 MYSQL_DB_* 环境变量。这些变量在 compute-interest-api.yaml
文件中定义。
compute-interest-api.yaml
spec:
containers:
- image: anthonyamanse/compute-interest-api:secrets
imagePullPolicy: Always
name: compute-interest-api
env:
- name: MYSQL_DB_USER
valueFrom:
secretKeyRef:
name: demo-credentials
key: username
- name: MYSQL_DB_PASSWORD
valueFrom:
secretKeyRef:
name: demo-credentials
key: password
- name: MYSQL_DB_HOST
valueFrom:
secretKeyRef:
name: demo-credentials
key: host
- name: MYSQL_DB_PORT
valueFrom:
secretKeyRef:
name: demo-credentials
key: port
ports:
- containerPort: 8080
YAML 文件已配置为从先前创建的 Kubernetes Secret 中获取值。这些信息将最终写入application.properties
并最终为 Spring Boot 应用程序所用。
Send-Notification 可配置为通过 Gmail 和/或 Slack 发送通知。通知仅在 MySQL 数据库中的账户余额超过 50,000 美元时推送一次。默认设置为使用 Gmail 。通知。您还可以使用事件驱动技术(在本例中为 OpenWhisk) 来发送电子邮件和 Slack 消息。要将 OpenWhisk 与您的通知微服务配合使用,请在构建和部署微服务映像之前遵循此处 的步骤进行操作。否则,只有在选择仅使用电子邮件通知后才能继续。
当 Maven 成功构建 Java 项目后,您需要使用在其相应文件夹中提供的 Dockerfile 构建 Docker 镜像。
备注:compute-interest-api 会将分币乘以 100,000,用于执行模拟。您可以编辑/移除
src/main/java/officespace/controller/MainController.java
中的remainingInterest *= 100000
行。当余额超过 50,000 美元时,程序还会发送通知, 您可以编辑if (updatedBalance > 50000 && emailSent == false )
行中的数字。保存更改后,就可以构建项目了。
Go to containers/compute-interest-api
$ mvn package
Go to containers/send-notification
$ mvn package
我们将使用 IBM Cloud 容器镜像仓库来保存镜像(由此进行映像命名),也可以使用 Docker Hub 保存镜像。
备注:本文使用 IBM Cloud 容器镜像库中保存镜像。
如果您计划使用 IBM Cloud 容器镜像库,需要首先设置帐户。请遵循此处 的教程进行操作。
您也可以使用 Docker Hub 保存镜像。
$ docker build -t registry.ng.bluemix.net/<namespace>/compute-interest-api .
$ docker build -t registry.ng.bluemix.net/<namespace>/send-notification .
$ docker push registry.ng.bluemix.net/<namespace>/compute-interest-api
$ docker push registry.ng.bluemix.net/<namespace>/send-notification
成功推送镜像后,您将需要修改 yaml 文件以使用自己的镜像。
// compute-interest-api.yaml
spec:
containers:
- image: registry.ng.bluemix.net/<namespace>/compute-interest-api # replace with your image name
// send-notification.yaml
spec:
containers:
- image: registry.ng.bluemix.net/<namespace>/send-notification # replace with your image name
存在两种可能的通知方式,请参见: 2.3.1 使用默认电子邮件服务 或 2.3.2 使用 OpenWhisk Actions。
您将需要修改 send-notification.yaml
中的 环境变量:
env:
- name: GMAIL_SENDER_USER
value: '[email protected]' # change this to the gmail that will send the email
- name: GMAIL_SENDER_PASSWORD
value: 'password' # change this to the the password of the gmail above
- name: EMAIL_RECEIVER
value: '[email protected]' # change this to the email of the receiver
现在,您可以继续执行步骤 2.4。
本部分的要求:
- 您的 Slack 团队中具有 Slack Incoming Webhook。
- IBM Cloud帐户,以便使用 OpenWhisk CLI。
本代码库的根目录中包含您创建 OpenWhisk Actions 时所需的代码。
如果您尚未安装 OpenWhisk CLI,请转至此处。
您可以使用 wsk
命令来创建 OpenWhisk Actions。创建操作使用以下语法:wsk action create < action_name > < source code for action> [add --param for optional Default parameters]
- 创建用于发送 Slack 通知 的 Action
$ wsk action create sendSlackNotification sendSlack.js --param url https://hooks.slack.com/services/XXXX/YYYY/ZZZZ
Replace the url with your Slack team's incoming webhook url.
- 创建用于发送 Gmail 通知 的 Action
$ wsk action create sendEmailNotification sendEmail.js
您可以使用 wsk action invoke [action name] [add --param to pass parameters]
测试 OpenWhisk Actions
- 调用 Slack 通知
$ wsk action invoke sendSlackNotification --param text "Hello from OpenWhisk"
- 调用电子邮件通知
$ wsk action invoke sendEmailNotification --param sender [sender's email] --param password [sender's password]--param receiver [receiver's email] --param subject [Email subject] --param text [Email Body]
至此,您应分别收到一条 Slack 消息和一封电子邮件。
您可以使用 wsk api create
为创建的 Action 映射 REST API 端点。其语法为 wsk api create [base-path] [api-path] [verb (GET PUT POST etc)] [action name]
- 创建用于 Slack 通知 的 REST API 端点
$ wsk api create /v1 /slack POST sendSlackNotification
ok: created API /v1/email POST for action /_/sendEmailNotification
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/slack
- 创建用于 Gmail 通知 的 REST API 端点
$ wsk api create /v1 /email POST sendEmailNotification
ok: created API /v1/email POST for action /_/sendEmailNotification
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/email
您可以使用以下命令查看 API 列表:
$ wsk api list
ok: APIs
Action Verb API Name URL
/Anthony.Amanse_dev/sendEmailNotificatio post /v1 https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/email
/Anthony.Amanse_dev/testDefault post /v1 https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/slack
请记录 这些 API URL,稍后我们将使用它们 。
- 测试用于 Slack 通知 的 REST API 端点。这里请使用您自己的 API URL。
$ curl -X POST -d '{ "text": "Hello from OpenWhisk" }' https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/slack
- 测试用于 Gmail 通知 的 REST API 端点。这里请使用您自己的 API URL。将参数 sender、password、receiver 和 subject 的值替换为您自己的值。
$ curl -X POST -d '{ "text": "Hello from OpenWhisk", "subject": "Email Notification", "sender": "[email protected]", "password": "passwordOfSender", "receiver": "receiversEmail" }' https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/email
一旦确认您的 API 运行正常,就可以将这些 URL 放入 send-notification.yaml
文件中了
env:
- name: GMAIL_SENDER_USER
value: '[email protected]' # the sender's email
- name: GMAIL_SENDER_PASSWORD
value: 'password' # the sender's password
- name: EMAIL_RECEIVER
value: '[email protected]' # the receiver's email
- name: OPENWHISK_API_URL_SLACK
value: 'https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/slack' # your API endpoint for slack notifications
- name: SLACK_MESSAGE
value: 'Your balance is over $50,000.00' # your custom message
- name: OPENWHISK_API_URL_EMAIL
value: 'https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/.../v1/email' # your API endpoint for email notifications
$ kubectl create -f compute-interest-api.yaml
service "compute-interest-api" created
deployment "compute-interest-api" created
$ kubectl create -f send-notification.yaml
service "send-notification" created
deployment "send-notification" created
此用户界面是 Node.js 应用程序,可显示账户总余额。
如果您在 IBM Cloud 中使用 MySQL 数据库,请记得填充 account-summary.yaml
文件中环境变量的值,否则请将其留空。这是在步骤 1 中执行的操作。
- 创建 Node.js 前端:
$ kubectl create -f account-summary.yaml
service "account-summary" created
deployment "account-summary" created
交易生成器是 Python 应用程序,可使用累积利息生成随机交易。
- 创建交易生成器 Python 应用程序:
$ kubectl create -f transaction-generator.yaml
service "transaction-generator" created
deployment "transaction-generator" created
您可以通过 Kubernetes Cluster IP 和 NodePort 访问应用程序。NodePort 应为 30080。
- 要查找 Cluster IP,请执行以下命令:
$ bx cs workers <cluster-name>
ID Public IP Private IP Machine Type State Status
kube-dal10-paac005a5fa6c44786b5dfb3ed8728548f-w1 169.47.241.213 10.177.155.13 free normal Ready
- 要查找账户摘要 (account-summary) 服务的 NodePort,请执行以下命令:
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
account-summary 10.10.10.74 <nodes> 80:30080/TCP 2d
...
- 要从头开始,请删除所有内容:
kubectl delete svc,deploy -l app=office-space
- John Zaccone - 通过 Docker 部署的 Office Space 应用程序 的原始作者。
- Office Space 应用程序是以 1999 年运用此理念的同名电影为基础编写的。
可以配置包含这个包的样本 Kubernetes Yaml 文件,以跟踪对 IBM Cloud 和其他 Kubernetes 平台的部署。每次部署时,都会将以下信息发送到 Deployment Tracker 服务:
- Kubernetes 集群提供者(
IBM Cloud、Minikube 等
) - Kubernetes 机器 ID (
MachineID
) - 这个 Kubernetes 作业中的环境变量。
此数据是从样本应用程序的 yaml 文件中的 Kubernetes Job 收集而来。IBM 使用此数据来跟踪将样本应用程序部署到 IBM Cloud 相关的指标,以度量我们的示例的实用性,从而让我们能够持续改进为您提供的内容。仅跟踪那些包含代码以对 Deployment Tracker 服务执行 ping 操作的样本应用程序的部署过程。
请注释掉/移除 account-summary.yaml
文件末尾的 Kubernetes Job 部分。