Automate Quarkus deployment with Ansible
让我们了解如何使用 Ansible构建并部署 Quarkus 应用程序。我们将了解如何通过使用 Maven 自动执行整个流程,包括从代码签出到应用程序编译,使用 Ansible 及其针对 Quarkus 的集合在目标系统上部署和启动服务(作为 systemd service)。
Let’s see how to build and deploy a Quarkus app using Ansible. We’ll see how we can automate the entire process, from the code checkout to the application compilation using Maven and then its deployment and start of the service, as a systemd service, on the target system using Ansible and its collection for Quarkus.
第一部分:应用程序代码签出、编译并在 Ansible 上打包(Ansible 运行的位置)。我们将使用其 Quarkus QuickStarts directory中提供的入门示例应用程序作为本教程的基础。我们还将使用 Ansible 的 Quarkus collection,这是一个 Ansible 扩展,它可以减轻样板文件所需的工作量,并使用 Ansible 快速构建和部署 Quarkus。
The first part, the application code checkout, compilation and packaging on the Ansible (where Ansible runs). We’ll use the getting-started sample application provided in its Quarkus QuickStarts directory as a base for this tutorial. We’ll also leverage the Quarkus collection for Ansible, an extension for Ansible that alleviates the boilerplate required and to quickly build and deploy a Quarkus using Ansible.
Prerequisites
Unresolved directive in ansible.adoc - include::{includes}/prerequisites.adoc[]
您需要在工作站上 install Ansible。完成后,您可以使用以下命令安装此专用于 Quarkus 的 Ansible 扩展:
You’ll need to install Ansible on your workstation. Once this is done, you can install this extension for Ansible dedicated to Quarkus with the following command:
$ ansible-galaxy collection install middleware_automation.quarkus
我们刚刚安装的 Ansible 集合仅支持使用 RPM 的 RHEL、Fedora 和其他 Linux 发行版。Ansible 将这些定义为“RedHat 系列”。虽然并非不可能,但使用其他平台(Windows、Debian、Ubuntu 等)上的内容将需要进行一些调整。 |
The Ansible collection we just installed only supports RHEL, Fedora, and other Linux distribution using RPMs. Ansible defines these as "RedHat family". Using the content on other platforms (Windows, Debian, Ubuntu, …), while not impossible, will require a few adjustments. |
Inventory file
如果您不熟悉 Ansible,请注意必须提供清单才能使上述命令正确运行。这是一个简单的文本文件,提供了 Ansible 在其管理的目标系统上所需的信息。有关 Ansible inventory的更多信息,请参阅 Ansible 文档。
If you are not familiar with Ansible, please note that the inventory must be provided for the command above to run properly. This is a simple text file providing the information Ansible requires on the target system it manages. Please refer to the Ansible documentation for more information about Ansible inventory.
[all]
10.0.0.1
10.0.0.2
要按照本教程进行操作,您可能只想使用一台机器(localhost),并跳过 ssh 身份验证设置。可以通过使用以下清单文件轻松实现此目的:
To follow the tutorial, you may want to use only one machine (localhost) and skip the ssh authentication setup. This can be easily achieved by using the following inventory file:
[all]
localhost ansible_connection=local
Root access on target system
由 Ansible 集合针对 Quarkus 执行的少数任务需要目标上的管理权限(创建组和用户帐户、安装软件包)。如果 Ansible 作为 root 运行,您需要将以下选项添加到 `ansible-playbook`命令行:
A few tasks performed by the Ansible collection for Quarkus will require administrative privileges on the target (create a group and user account, install packages). If Ansible does run as root, you’ll need to add the following options to the ansible-playbook
command line:
$ ansible-playbook -i inventory --ask-become-pass ...
Tutorial
在控制器上安装 Ansible 集合后,您已经可以使用随附的剧本直接构建和部署 Quarkus 应用程序:
With the Ansible collection installed on the controller, you can already directly use a playbook provided with it to build and deploy your Quarkus application:
ansible-playbook -i inventory \
middleware_automation.quarkus.playbook \
-e app_name=getting-started \
-e quarkus_app_repo_url='https://github.com/quarkusio/quarkus-quickstarts.git' \
-e quarkus_app_source_folder='getting-started' \
-e quarkus_path_to_folder_to_deploy=/opt/quarkus_deploy
提供给剧本的四个参数不言而喻。第一个参数 app_name`为应用程序的名称,在本示例中仅为 `getting-started
。第二个参数 `quarkus_app_repo_url`为签出 Git 存储库的 URL。第三个参数为可选参数,`quarkus_app_source_folder`指定在需要时从存储库中提取源代码的子文件夹。最后一个参数表示在目标位置安装应用程序的位置。
The four parameters provided to the playbook are pretty self-explanatory. The first one, app_name
, is the name of the application, in our case, it’s just getting-started
. The second one, quarkus_app_repo_url
, is the URL to the Git repository to checkout. The third one is optional, quarkus_app_source_folder
specifies, if needed, which subfolder from the repo the source code is located. Finally, the fourth one indicates where to install the application on the target.
Playbook run
成功运行上述命令后,您应该会看到类似于以下的输出:
Once the command above has successfully run, you should have an output similar to the one below:
…
PLAY [Build and deploy a Quarkus app using Ansible] ****************************
TASK [Build the Quarkus from https://github.com/quarkusio/quarkus-quickstarts.git.] ***
TASK [middleware_automation.quarkus.quarkus : Ensure required parameters are provided.] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Define path to mvnw script.] *****
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure that builder host localhost has appropriate JDK installed: java-17-openjdk] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Delete previous workdir (if requested).] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure app workdir exists: /tmp/workdir] ***
changed: [localhost]
TASK [middleware_automation.quarkus.quarkus : Checkout the application source code.] ***
changed: [localhost]
TASK [middleware_automation.quarkus.quarkus : Build the App using Maven] *******
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Display build application log] ***
skipping: [localhost]
TASK [Deploy webapp on target.] ************************************************
TASK [middleware_automation.quarkus.quarkus : Ensure required parameters are provided.] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure required OpenJDK is installed on target.] ***
skipping: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure Quarkus system group exists on target system] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure Quarkus user exists on target system.] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure deployement directory exits: /opt/quarkus_deploy.] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Set Quarkus app source dir (if not defined).] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Deploy application from to target system] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Deploy Systemd configuration for Quarkus app] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Perform daemon-reload to ensure the changes are picked up] ***
skipping: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure Quarkus app service is running.] ***
ok: [localhost]
TASK [middleware_automation.quarkus.quarkus : Ensure firewalld is available.] ***
skipping: [localhost]
TASK [middleware_automation.quarkus.quarkus : Configure firewall for 8080 ports] ***
skipping: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=15 changed=2 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0
…
用于 Quarkus 的 Ansible 集合在此执行所有 heavy lifting
。首先,它将从 Github 检出代码并从其源构建应用程序。它还确保用于此步骤的系统已安装所需的 OpenJDK。默认情况下,应用程序是在本地主机(Ansible 控制器)上构建的,但如果需要,可以在远程系统上执行此操作。构建应用程序后,集合将负责部署。
The Ansible collection for Quarkus does all the heavy lifting
here. First, it checks out the code from Github and builds the application from its sources. It also ensures the system used for this step does have the required OpenJDK installed. By default, the application is built on the localhost (the Ansible controller), but it can be performed on a remote system if needed. Once the application is built, the collection will take care of the deployment.
它再次检查目标系统上是否存在适当的 OpenJDK。然后确保目标系统上存在所需的用户和组。强烈建议此操作主要是为了能够使用普通用户而不是 root 帐户来运行 Quarkus 应用程序。
Here again, it checks that the appropriate OpenJDK is available on the target system. Then we ensure that the required user and group exist on the target. This is recommended mostly to be able to run the Quarkus app with a regular user, rather than with the root account.
满足这些要求后,jar 可以部署在目标上,以及将应用程序集成到 systemd 中作为服务的所需配置。对 systemd 配置的任何更改都需要重新加载其守护程序,而集合可确保在需要时执行此操作。所有这些都就绪后,唯一剩下的事情就是启动服务本身,Ansible 也将负责此操作。
With those requirements in place, the jar can be deployed on the target, along with the required configuration for the app integration into systemd as a service. Any change to the systemd configuration requires reloading its daemon, which the collection ensures will happen whenever it is needed. With all of that in place, the only thing that remains is to start the service itself, which Ansible will also take care of.
默认情况下,用于 Quarkus 的 Ansible 集合将安装并使用目标主机(或控制器)的 Yum 存储库中可用的 OpenJDK 17。如果您想要使用不同版本的 OpenJDK,请定义以下变量: By default, the Ansible collection for Quarkus will install and use the OpenJDK 17 available in the Yum repositories of the target host (or the controller). If you want to use a different version of OpenJDK, define the following variable:
|
Validate that deployment was successful
出于本教程的目的,您可能希望手动检查 playbook 是否正确部署了应用程序。以下有几种方法可供选择。
For the purpose of this tutorial, you may want to check manually, that the playbook did indeed deployed the app properly. Here is the few ways to do so.
首先,由于集合已集成,我们可以在其中一个目标上检查服务的状态:
First, because the collection integrated, we can check the status of the service on one of the targets:
# systemctl status getting-started.service
● getting-started.service - A Quarkus service named getting-started
Loaded: loaded (/usr/lib/systemd/system/getting-started.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2023-04-13 12:48:18 UTC; 2min 40s ago
Main PID: 853 (java)
Tasks: 43 (limit: 1638)
Memory: 73.3M
CGroup: /system.slice/getting-started.service
└─853 /usr/bin/java -jar /opt/quarkus_deploy/quarkus-run.jar
Apr 13 12:48:18 bd71f39642c8 systemd[1]: Started A Quarkus service named getting-started.
Apr 13 12:48:19 bd71f39642c8 java[853]: __ ____ __ _____ ___ __ ____ ______
Apr 13 12:48:19 bd71f39642c8 java[853]: --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
Apr 13 12:48:19 bd71f39642c8 java[853]: -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
Apr 13 12:48:19 bd71f39642c8 java[853]: --\___\_\____/_/ |_/_/|_/_/|_|\____/___/
Apr 13 12:48:19 bd71f39642c8 java[853]: 2023-04-13 12:48:19,284 INFO [io.quarkus] (main) getting-started 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.16.6.Final) started in 0.607s. Listening on: http://0.0.0.0:8080
Apr 13 12:48:19 bd71f39642c8 java[853]: 2023-04-13 12:48:19,309 INFO [io.quarkus] (main) Profile prod activated.
Apr 13 12:48:19 bd71f39642c8 java[853]: 2023-04-13 12:48:19,310 INFO [io.quarkus] (main) Installed features: [cdi, rest, smallrye-context-propagation, vertx]
您还可以手动测试应用程序是否可访问:
Manually, you can also test if the app is reachable:
# curl -I http://localhost:8080/
HTTP/1.1 200 OK
accept-ranges: bytes
content-length: 3918
cache-control: public, immutable, max-age=86400
last-modified: Thu, 2 Mar 2023 11:03:18 GMT
date: Thu, 2 Mar 2023 11:03:18 GMT
我们将在本教程的下一部分和最后一部分中了解如何自动执行这些验证。
We’ll see how to automate those validation in the next and last part of this tutorial.
Writing a playbook
当然,您很可能会需要在此基础上进行构建,因此您可能希望编写自己的 playbook,而不是仅仅使用集合提供的 playbook。以下是此类 playbook 的示例:
Of course, you’ll most likely need to build on this, so you may want to write up your own playbook, rather than just using the one provided by the collection. Below is an example of such playbook:
- name: "Build and deploy a Quarkus app using Ansible"
hosts: all
gather_facts: true
vars:
quarkus_app_repo_url: 'https://github.com/quarkusio/quarkus-quickstarts.git'
app_name: getting-started
quarkus_app_source_folder: getting-started
quarkus_path_to_folder_to_deploy: /opt/quarkus_deploy
pre_tasks:
- name: "Build the Quarkus from {{ quarkus_app_repo_url }}."
ansible.builtin.include_role:
name: quarkus
tasks_from: build.yml
tasks:
- name: "Deploy Quarkus app on target."
ansible.builtin.include_role:
name: quarkus
tasks_from: deploy.yml
要运行此 playbook,您再次使用 ansible-playbook 命令,但现在提供 playbook 的路径:
To run this playbook, you use again the ansible-playbook command, but providing now the path to the playbook:
$ ansible-playbook -i inventory playbook.yml
您还可以自动化我们在上一节中提到的验证部分。您可以使用 ansible.builtin.assert 模块并填充 service facts 以确保 Quarkus 应用程序的 systemd 服务正在运行,以及使用 ansible.builtin.uri 来检查 Quarkus 应用程序是否可访问。
You also can automate the validation part we mentioned in the previous section. You can use the ansible.builtin.assert module and populate the service facts to ensure the systemd service of the Quarkus app is running, along with ansible.builtin.uri to check that the Quarkus app is accessible.
post_tasks:
- name: Populate service facts
ansible.builtin.service_facts:
- name: "Check that systemd service {{ app_name }} is running."
ansible.builtin.assert:
that:
- ansible_facts.services is defined
- ansible_facts.services["{{ app_name }}.service"] is defined
- ansible_facts.services["{{ app_name }}.service"]['state'] == 'running'
- ansible_facts.services["{{ app_name }}.service"]['status'] == 'enabled'
quiet: true
- name: "Check that Quarkus app is accessible"
ansible.builtin.uri:
url: 'http://localhost:8080/'
就是这样,伙计们!
And that’s all, folks!