使用DCHQ自动部署和管理Docker Cloud /虚拟Java微服务

本文演示了一个在云或虚拟平台上,用于自动化部署和管理Docker Java微服务应用程序的解决方案。我们通过扩展现有项目Chris Richardson的示例——一个事件溯源(Event Sourcing)的基于微服务的资金转移程序。引入CQRSDocker来自动构建和部署该项目。我们的项目包含有用于每个微服务的Dockerfiles文件,还将提供一个可在Web服务器上运行的整合前端,这个前端可以提供所用到的微服务。我们使用Nginx Web sever,在前端页面的默认目录/ usr / share / nginx / html /中编写JavaScript代码。前端将暴露出如下功能:

  • 指定初始余额并创建一个新帐户。
  • 查询帐户余额。
  • 账户之间进行转账。
界面

我们将创建的资金转移应用程序作为一个采用事件朔源架构,由CQRS和Docker组成的构建和部署微服务的示例。基于微服务的应用程序具有高可扩展性和高可用性,通过polyglot持久化、事件朔源(ES)和命令查询的责任分离(CQRS)实现。微服务应用程序由使用事件进行通信的松耦合组件组成。这些组件可以作为独立的服务进行部署,也可以作为单个应用程序进行打包以简化开发和测试。本文介绍的项目中,我们专注于自动化前一种方法 —— 即自动在Docker容器上运行单一服务。

我们的目标是在13个不同的云和虚拟化平台(包括vSphere,OpenStack,AWS,Rackspace,Microsoft Azure,Google Compute Engine,DigitalOcean,IBM SoftLayer等)上运行和管理此项目中的事件朔源Docker Java微服务应用程序模板。 我们建议您执行以下操作之一:

背景

容纳企业级Java应用程序是一个巨大的挑战,主要是因为现有的应用程序组合框架无法解决复杂的依赖关系、外部集成关系以及添加服务实例之后(Post-Provision)的自动扩展流程等问题。此外,容器生存周期的短暂性也迫使开发人员在每次更新版本时,重新创建复杂的依赖关系和外部集成容器。

DCHQ(可用在托管版本或on-),通过高级应用程序组合框解决了这些挑战并简化了企业Java应用程序的集装箱化,该框架使用跨图像环境变量绑定扩展Docker Compose,可在请求时调用的可扩展BASH脚本插件时间或提供后,以及应用程序集群,以支持多个主机或区域的高可用性,并支持自动缩放。

一旦配置好了应用程序,用户就可以:

  • 监视正在运行的容器的CPU,内存和I / O,
  • 获取通知和提醒,
  • 访问应用程序备份,自动缩放工作流及插入工作流来更新正在运行的容器。

此外,即插即用的工作流程有助于基于Jenkins的持续交付(即将推出更多支持),使开发人员能够刷新正在运行应用程序的Java WAR文件,而不会干扰现有的依赖关系和集成。

在本作者的个人博客中,我们演示了跨越13层的多层基于Docker的应用程序堆栈中的更传统或典型的brownfield Java应用程序(如Names Directory,Pizza Shop和Movie Store应用程序)的端到端部署自动化不同的云和虚拟化平台。

在我们目前的项目中,我们将关注一个微服务架构,它不需要任何应用程序服务器。每个微服务都运行在一个非常轻量级的Java容器上。为了执行特定的任务(例如创建账户,查询账户或将资金从一个账户转移到另一个账户),构建了一个合并的前端,用于为每个连接的微服务创建REST API调用。微服务的一个主要优势(与典型的单一应用程序相比)是,这些模块化服务可以轻松替换和扩展,而无需更改其他微服务。从某种意义上说,这消除了单点故障,使开发人员更容易为整个项目做出贡献。

在这个项目中,我们将提供一个分步指南,用于在不同的云/虚拟基础架构上部署和管理这个Java应用程序。

我们需要执行以下每个步骤,我们将详细看到:

  • 获取Event Store的凭据
  • 应用修补程序并构建JAR文件
  • 使用DCHQ在此项目中自动构建来自Dockerfiles的Docker镜像
  • 构建基于YAML的应用程序模板,可以在任何地方运行的任何Linux主机上重复使用
  • 在任何云上配置和自动扩展底层基础架构(Rackspace就是这个博客中的例子)
  • 在Rackspace群集上部署多层Java应用程序
  • 监视正在运行的容器的CPU,内存和I / O
  • 与Jenkins一起启用持续交付工作流程,以在构建触发时更新正在运行的微服务的JAR文件

现在我们将详细介绍每个步骤:

获取Event Store的凭据

为了单独运行微服务,您需要获取Event Store的凭据

复制并粘贴EVENTUATE_API_KEY_IDEVENTUATE_API_KEY_SECRET的值到Event Sourcing Docker Java微服务应用程序模板中

应用修补程序并构建JAR文件

Docker映像中使用的JAR文件是从该项目构建的。

所有的JAR文件都是在2015年12月27日建立的,并在此处嵌入Docker镜像。

在构建JAR文件之前,将CORSFilter.java复制到“event-sourcing-examples / java-spring / common-web / src / main / java / net / chrisrichardson / eventstore / javaexamples / banking / web / util”目录中。然后你可以执行

./gradlew assemble.
git clone https://github.com/cer/event-sourcing-examples.git

wget https://github.com/dchqinc/event-sourcing-microservices/raw/master/patch/CORSFilter.java -O /event-sourcing-examples/java-spring/common-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/util/CORSFilter.java

cd /event-sourcing-examples/java-spring

./gradlew assemble

使用DCHQ在此项目中自动构建来自Dockerfiles的Docker镜像

该项目中的所有图像都已经构建并推送到DCHQ公共Docker Hub存储库供您参考。以下是将在应用程序模板中使用的自定义图像:

  • dchq / nginx的,微服务:最新
  • dchq /帐户命令侧服务
  • dchq /交易指令侧服务
  • dchq / transactions-command-side-service -

要构建图像并将它们推送到您自己的Docker HubQuay存储库中,可以使用DCHQ。以下是用于这些图像的四个GitHub项目:

一旦登录到DCHQ(托管的DCHQ.io或内部版本),您可以导航到Automate > Image Build,然后单击+按钮创建一个新的Dockerfile(Git / GitHub / BitBucket)图像版本。

提供所需的值如下:

  • Git URL
  • Git分支 - 此字段是可选的 - 但您可以从GitHub项目指定分支。默认分支是主。
  • Git Credentials - 您可以通过导航到Manage > Cloud Providers&Repos并单击+选择Credentials,将凭证安全地存储到DCHQ中的私人GitHub存储库中
  • 群集 - Docker镜像的构建是通过DCHQ代理编排的。因此,您需要选择一个代理将用于执行Docker映像构建的集群。如果还没有创建集群,请参阅本节以注册正在运行的主机或自动配置新的虚拟基础架构。
  • 推送到注册表 - 将新创建的图像推送到 Docker Hub或Quay上的公共或私人存储库。要注册Docker Hub或Quay帐户,请导航到Manage > Cloud Providers&Repos,然后单击+选择Docker注册表
  • 存储库 - 这是将在其上推送图像的存储库的名称。例如,我们的图像被推送到dchq / php-example:latest
  • 标签 - 这是您希望为新图片提供的标签名称。DCHQ中支持的标签名称包括:
    • {{日期}} - 格式化的日期
    • {{timestamp}} - 完整的时间戳
  • Cron Expression - 使用开箱即用的cron表达式来安排Docker镜像的构建。这有助于用户每日和每晚构建。

一旦必填字段完成,请点击保存

然后,您可以点击Play按钮来按需构建Docker镜像。

构建基于YAML的应用程序模板,可以在任何地方运行的任何Linux主机上重用

登录到DCHQ(托管的DCHQ.io或内部部署版本)后,用户可以导航到管理 > 应用程序/机器,然后单击+按钮创建一个新的Docker撰写模板。您可以参考此处创建Docker Compose应用程序模板的详细文档。

我们使用我们在前一步中构建的Docker镜像创建了一个应用程序模板。该模板包含以下组件:

  • Nginx - 用于托管此微服务应用程序的整合前端
  • 账户创建,账户查询和余额转移微服务 - 这些服务是从原始项目构建的。通过在“event-sourcing-examples / java-spring / common-web / src / main / java / net / chrisrichardson / eventstore / javaexamples / banking / web / util”目录中复制CORSFilter.java来应用修补程序。
  • Mongo - 用于数据库

插件在请求时和配置后配置Web服务器

在应用程序模板中,您会注意到Nginx容器正在请求时调用BASH脚本插件来配置容器。这个插件也可以在提供后执行。

这些插件可以通过导航到管理>插件来创建。一旦提供BASH脚本,DCHQ代理将在容器内执行该脚本。您可以指定在请求时间和提供后可覆盖的参数。以$符号开头的任何内容都被视为参数 - 例如,$ file_url可以是允许开发人员指定WAR文件的下载URL的参数。如果用户想要刷新正在运行的容器上的Java WAR文件,那么可以在请求时重写并在提供后进行此操作。

定义基于YAML的应用程序模板时,需要提供插件ID。例如,要调用Nginx的BASH脚本插件,我们将引用插件ID如下:

nginx:
  image: dchq/nginx-microservices:latest
  publish_all: true
  mem_min: 50m
  host: host1
  plugins:
    - !plugin
      id: Gl5Hi
      restart: true
      lifecycle: on_create
      arguments:
        - ACCOUNT_CMD_IP={{accountscommandside | ip}}
        - ACCOUNT_CMD_PORT={{accountscommandside | port_8080}}
        - ACCOUNT_TRANSFER_IP={{transactionscommandside | ip}}
        - ACCOUNT_TRANSFER_PORT={{transactionscommandside | port_8080}}
        - ACCOUNT_QUERY_IP={{accountsqueryside | ip}}
        - ACCOUNT_QUERY_PORT={{accountsqueryside | port_8080}}

在这个例子中,Nginx正在调用一个BASH脚本插件,动态地(或在请求时)在/usr/share/nginx/html/js/app.js文件中注入微服务容器IP和端口号。插件ID是Gl5Hi

带有插件生命周期阶段的服务发现

插件中的生命周期参数允许您指定执行插件的确切阶段或事件。如果没有指定生命周期,那么默认情况下,插件将被执行on_create。您可以参考此处设置Docker服务发现的详细文档。以下是支持的生命周期阶段:

  • on_create - 创建容器时执行插件
  • on_start - 在容器启动后执行插件
  • on_stop - 在容器停止前执行插件
  • on_destroy - 在销毁容器之前执行插件
  • post_create - 在容器创建并运行后执行插件
  • post_start [:Node] - 在另一个容器启动后执行该插件
  • post_stop [:Node] - 在另一个容器停止后执行插件
  • post_destroy [:Node] - 在另一个容器被销毁后执行插件
  • post_scale_out [:Node] - 在另一个容器集群被扩展后执行插件
  • post_scale_in [:Node] - 在缩放另一个容器集群后执行该插件

cluster_size和主机参数,用于跨多个主机进行HA部署

您会注意到cluster_size参数允许您指定要启动的容器数量(具有相同的应用程序依赖性)。

主机参数允许你指定你想使用容器部署主机。如果您在创建群集时选择了Weave作为网络层,确保跨不同主机(或区域)的应用程序服务器群集的高可用性,同时允许您遵守关联性规则以确保数据库运行在一个单独的主机上。以下是主机参数支持的值:

  • host1,host2,host3等 - 在数据中心(或群集)内随机选择一个主机进行容器部署
  • IP地址1,IP地址2等 - 允许用户指定用于容器部署的实际IP地址
  • 主机名1,主机名2等 - 允许用户指定用于容器部署的实际主机名
  • 通配符(例如“db- ”或“app-srv- ”)指定要在主机名内使用的通配符

跨图像的环境变量绑定

另外,用户可以通过引用另一个图像的环境变量来创建跨图像环境变量绑定。在这种情况下,我们做了几个绑定 - 包括ACCOUNT_CMD_IP = {{accountscommandside | ip}} - 帐户创建微服务容器IP在请求时动态解析,并用于确保Nginx可以与此微服务建立连接。

以下是支持的环境变量值列表:

  • {{字母数字| 8}} - 创建一个随机的8个字符的字母数字字符串。这对创建随机密码非常有用。
  • {{图片名称| ip}} - 允许您输入容器的主机IP地址作为环境变量的值。这对于允许中间件层与数据库建立连接非常有用。
  • {{图片名称| container_ip}} - 允许您输入容器的名称作为环境变量的值。这对于允许中间件层与数据库建立安全连接(不暴露数据库端口)非常有用。
  • {{图片名称| container_private_ip}} - 允许您输入容器的内部IP作为环境变量的值。这对于允许中间件层与数据库建立安全连接(不暴露数据库端口)非常有用。
  • {{图片名称| port_Port Number}} - 允许您输入容器的端口号作为环境变量的值。这对于允许中间件层与数据库建立连接非常有用。在这种情况下,指定的端口号需要是内部端口号 - 即不是分配给容器的外部端口。例如,{{PostgreSQL | port_5432}}将被转换为实际的外部端口,以允许中间件层与数据库建立连接。
  • {{图片名称| 环境变量名称}} - 允许您将图像的环境变量的值输入到另一个图像的环境变量中。这里的用例是无止境的 - 因为大多数多层应用程序都会有跨图像依赖性。

事件采购Docker Java微服务

nginx:
  image: dchq/nginx-microservices:latest
  publish_all: true
  mem_min: 50m
  host: host1
  plugins:
    - !plugin
      id: Gl5Hi
      restart: true
      lifecycle: on_create
      arguments:
        - ACCOUNT_CMD_IP={{accountscommandside | ip}}
        - ACCOUNT_CMD_PORT={{accountscommandside | port_8080}}
        - ACCOUNT_TRANSFER_IP={{transactionscommandside | ip}}
        - ACCOUNT_TRANSFER_PORT={{transactionscommandside | port_8080}}
        - ACCOUNT_QUERY_IP={{accountsqueryside | ip}}
        - ACCOUNT_QUERY_PORT={{accountsqueryside | port_8080}}

accountscommandside:
  image: dchq/accounts-command-side-service
  mem_min: 300m
  cluster_size: 1
  host: host1
  publish_all: true
  environment:
    - EVENTUATE_API_KEY_ID=<paste-your-key-here>
    - EVENTUATE_API_KEY_SECRET=<paste-your-key-here>

transactionscommandside:
  image: dchq/transactions-command-side-service
  mem_min: 300m
  cluster_size: 1
  host: host1
  publish_all: true
  environment:
    - EVENTUATE_API_KEY_ID=<paste-your-key-here>
    - EVENTUATE_API_KEY_SECRET=<paste-your-key-here>

accountsqueryside:
  image: dchq/accounts-query-side-service
  mem_min: 300m
  cluster_size: 1
  host: host1
  publish_all: true
  environment:
    - EVENTUATE_API_KEY_ID=<paste-your-key-here>
    - EVENTUATE_API_KEY_SECRET=<paste-your-key-here>
    - SPRING_DATA_MONGODB_URI=mongodb://{{mongodb | container_private_ip}}/mydb

mongodb:
  image: mongo:3.0.4
  host: host1

在任何云上配置和自动扩展底层基础架构

一旦保存了应用程序,您就可以注册一个云提供商,在12个不同的云终端上自动执行配置和自动扩展,包括VMware vSphere,OpenStack,CloudStack,亚马逊网络服务,Rackspace,Microsoft Azure,DigitalOcean,IBM SoftLayer,谷歌计算引擎等。

要为Rackspace注册云提供商(例如),请导航至管理 > 云提供商和回购站,然后单击+按钮选择Rackspace。需要提供Rackspace API密钥 - 可以从Rackspace Cloud控制面板的帐户设置部分检索。

然后,您可以使用自动缩放策略创建群集,以自动启动新的云服务器。这可以通过导航到“ 管理” >“ 群集”页面,然后单击“ +”按钮完成。您可以选择一个基于容量的放置策略,然后选择Weave作为网络层,以便在集群内的多个主机之间实现安全,密码保护的跨容器通信。该自动缩放策略,例如,可以虚拟机(或云服务器)的最大数量设置为10。

现在,您可以通过基于UI的工作流程或通过定义可从自助服务库请求的简单的基于YAML的Machine Compose模板,在新创建的群集上配置多个Cloud Server。

基于UI的工作流程 - 您可以通过导航到“ 管理” >“ 机器”然后单击“ +”按钮选择“ Rackspace”来请求Rackspace云服务器。选择Cloud Provider后,请选择所需的区域,大小和图像。默认情况下,Rackspace Cloud Servers会打开端口以适应端口要求(例如Docker的32000-59000,Weave的6783和RabbitMQ的5672)。然后选择一个群集并指定云服务器的数量。

基于YAML的机器撰写模板 - 您可以先导航到管理 > 应用/机器,然后选择机器撰写,然后为Rackspace创建一个机器撰写模板。

这是用于请求4GB云服务器的模板。

Medium:
  region: IAD
  description: Rackspace small instance
  instanceType: general1-4
  image: IAD/5ed162cc-b4eb-4371-b24a-a0ae73376c73
  count: 1

Machine Compose模板支持的参数汇总如下:

  • 描述:蓝图/模板的描述
  • instanceType:云提供商特定值(例如general1-4)
  • 地区:云提供商特定值(例如IAD)
  • 图像:必填 - 完全限定的图像ID /名称(例如IAD / 5ed162cc-b4eb-4371-b24a-a0ae73376c73或vSphere VM模板名称)
  • 用户名:可选 - 仅适用于vSphere VM模板用户名
  • 密码:可选 - 仅限vSphere VM模板加密密码。您可以使用端点加密密码
  • 网络:可选 - 云提供商特定值(例如默认值)
  • securityGroup:云提供商特定值(例如dchq-security-group)
  • keyPair:云提供商特定的值(例如私钥)
  • openPorts:可选 - 逗号分隔的端口值
  • count:虚拟机总数,默认为1。

一旦保存了机器撰写模板,您可以从自助服务请求本机。您可以单击Customize(自定义),然后选择用于配置这些Rackspace Cloud Server 的Cloud ProviderCluster

在Rackspace集群上部署多层Java应用程序

一旦配置了Cloud Server,您就可以在新的云服务器上部署基于Docker的多层Java应用程序。这可以通过导航到自助服务库,然后单击自定义来请求多层应用程序来完成。

选择一个环境标签(如DEV或QE)和您创建的Rackspace Cluster,然后单击运行。

访问正在运行的容器的浏览器内终端

命令提示符图标应位于Live Apps页面上容器名称旁边。这允许用户通过代理消息队列使用安全通信协议进入容器。租户管理员可以定义白名单,以确保用户不会对正在运行的容器进行任何有害更改。

例如,对于Nginx容器,我们使用命令提示符来确保app.js文件包含Docker Java微服务的正确IP和端口。

在此屏幕截图中,浏览器内终端用于在Nginx容器中显示/usr/share/nginx/html/js/app.js的内容。我们可以看到,使用DCHQ的插件框架将Docker Java微服务的IP和端口正确注入到此文件中。

监控正在运行的容器的CPU,内存和I / O利用率

一旦应用程序启动并运行,我们的开发人员将监视正在运行的容器的CPU,内存和I / O,以便在这些度量标准超出预定义阈值时收到警报。这在执行功能和负载测试时特别有用。

您可以执行历史监视分析,然后将问题关联到容器更新或构建部署。这可以通过点击统计,并选择一个自定义的日期范围来查看历史上的CPU,内存和I / O。

Jenkins触发构建时通过替换容器或更新正在运行的应用程序的JAR文件启用持续传递

“不可变”容器模型是一种常见的最佳实践,它通过重建包含应用程序代码的Docker镜像并在每次应用程序更新时启用新容器来完成。DCHQ提供了自动构建功能,允许开发人员从Dockerfiles或包含Dockerfiles的私有GitHub项目自动创建Docker镜像。然后将这些图像推送到Docker Private Registry,Docker Hub或Quay上的已注册私人或公共存储库之一。

您可以使用从Docker注册表中推送的最新映像启动的新容器自动“替换”正在运行的容器。这可以按需执行,也可以在Docker注册表中检测到新图像时自动完成。要用一个包含最新JAR文件的新包替换Docker Java微服务容器,用户只需单击Actions菜单并选择Replace。然后,用户可以输入将从其启动新容器的映像名称,以用相同的应用程序依赖关系替换已运行的容器。或者,用户可以指定此容器替换的触发器 - 可以基于简单的CRON表达式(即预定义的计划)或基于Docker注册表上的最新映像推送。

许多开发人员可能希望使用最新的Java JAR文件更新正在运行的容器。为此,DCHQ允许开发人员与Jenkins建立持续交付工作流程。这可以通过单击正在运行的应用程序的操作菜单,然后选择连续传送来完成。您可以选择一个Jenkins实例,该实例已经在DCHQ中注册,Jenkins上的实际工作将生成最新的JAR文件,然后选择一个BASH脚本插件来抓取该构建并将其部署到正在运行的应用程序服务器上。保存此策略后,任何时候触发构建,DCHQ都会从Jenkins获取最新的WAR文件,并将其部署到正在运行的应用程序服务器上。

因此,开发人员将始终在DEV / TEST环境中的运行容器上部署最新的JAR。

结论

容纳企业Java应用程序是一个挑战,主要是因为现有的应用程序组合框架无法解决复杂的依赖关系,服务发现或后置自动扩展工作流程。

DCHQ以托管和本地版本的形式提供,解决了所有这些挑战,并通过高级应用程序组合框架简化了企业Java应用程序的集装箱化,该框架有助于实现跨图像环境变量绑定,可在不同生活中调用的可扩展BASH脚本插件应用程序部署的循环阶段以及跨多个主机或区域提供高可用性的应用程序集群,并支持自动扩展。

免费注册在http://DCHQ.io或下载DCHQ内部部署以访问外的箱多层Java应用程序模板中包含监控应用程序生命周期管理功能,集装箱更新,规模沿着输入/输出和持续交付。

本文的版权归 轻吻晴雯 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨龙飞前端

scrollto 到指定位置

2494
来自专栏Golang语言社区

【Golang语言社区】GO1.9 map并发安全测试

var m sync.Map //全局 func maintest() { // 第一个 YongHuomap := make(map[st...

4708
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2526
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3105
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2050
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4838
来自专栏落花落雨不落叶

canvas画简单电路图

60911
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2702
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4005
来自专栏张善友的专栏

Silverlight + Model-View-ViewModel (MVVM)

     早在2005年,John Gossman写了一篇关于Model-View-ViewModel模式的博文,这种模式被他所在的微软的项目组用来创建Expr...

2958

扫码关注云+社区