|
| 1 | +--- |
| 2 | +slug: inter-service-communication-with-rabbitmq-and-apl |
| 3 | +title: "Set Up Inter-Microservice Communication Using RabbitMQ On App Platform For LKE" |
| 4 | +description: "This guide shows how to deploy a RabbitMQ message broker architecture on Akamai App Platform for LKE. The architecture also includes a sample Python app used to produce and consume messages managed by RabbitMQ." |
| 5 | +authors: ["Akamai"] |
| 6 | +contributors: ["Akamai"] |
| 7 | +published: 2025-03-20 |
| 8 | +keywords: ['app platform','lke','linode kubernetes engine','rabbitmq','microservice','message broker'] |
| 9 | +license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)' |
| 10 | +external_resources: |
| 11 | +- '[Akamai App Platform for LKE](https://techdocs.akamai.com/cloud-computing/docs/application-platform)' |
| 12 | +- '[Akamai App Platform Docs](https://apl-docs.net/docs/akamai-app-platform/introduction)' |
| 13 | +--- |
| 14 | + |
| 15 | +{{< note title="Beta Notice" type="warning" >}} |
| 16 | +The Akamai App Platform is now available as a limited beta. It is not recommended for production workloads. To register for the beta, visit the [Betas](https://cloud.linode.com/betas) page in the Cloud Manager and click the Sign Up button next to the Akamai App Platform Beta. |
| 17 | +{{< /note >}} |
| 18 | + |
| 19 | +## Introduction |
| 20 | + |
| 21 | +Asynchronous messaging is a common microservice architecture pattern used to decouple inter-service communication. Akamai App Platform uses RabbitMQ to provide an integrated messaging and streaming broker. RabbitMQ is a widely-adopted, open source message broker that uses AMQP (Advanced Message Queuing Protocol) to communicate with producers (apps that send messages) and consumers (apps that receive messages). |
| 22 | + |
| 23 | +This guide provides steps for creating a RabbitMQ cluster on App Platform, as well as building and deploying an example Python application configured to send messages to a RabbitMQ queue using a fanout exchange. The example app consists of a static website built to send messages through the application server to a connected RabbitMQ cluster. |
| 24 | + |
| 25 | +### What is a Fanout Exchange? |
| 26 | + |
| 27 | +A "fanout" exchange is a message protocol method that relays messages to all bound queues. The result in this architecture is RabbitMQ sending all messages to all connected clients. |
| 28 | + |
| 29 | +The fanout exchange protocol is built into RabbitMQ and can be used to route one message to multiple users, where a common use case would be sending a single notification to all customers. A consideration for this use case is customer preference; some customers may wish to receive information via email while others prefer to receive messages over SMS or social media network. |
| 30 | + |
| 31 | +To address this, RabbitMQ allows you to bind, or link, each service - email, SMS, social media - to a fanout exchange, thus allowing you to send one message to reach all services. The means that when a message is delivered, queues bound to the exchange receive it and can then process the message to each connected client without needing to send multiple messages to reach each service. |
| 32 | + |
| 33 | +## Diagram |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +1. A **RabbitMQ** cluster is created using the _RabbitMQ-Cluster_ Helm chart in the App Platform Catalog. |
| 38 | + |
| 39 | +2. A **Tekton** pipeline is created by App Platform that pulls the source code from a GitHub repository. A **Buildpacks** task is used to build the image and push it to the private registry in **Harbor**. |
| 40 | + |
| 41 | +3. An **Argo CD** application is created by App Platform to deploy the image built by Buildpacks. |
| 42 | + |
| 43 | +4. The example Python web application sends messages to RabbitMQ's fanout exchange and binds to the exchange to receive the message. |
| 44 | + |
| 45 | +5. The **Istio** virtual service and ingress are created by App Platform to expose the example Python application to the public internet via the NGINX Ingress Controller. |
| 46 | + |
| 47 | +## Components |
| 48 | + |
| 49 | +### Infrastructure |
| 50 | + |
| 51 | +- **Linode Kubernetes Engine (LKE)**: LKE is Akamai’s managed Kubernetes service, enabling you to deploy containerized applications without needing to build out and maintain your own Kubernetes cluster. |
| 52 | + |
| 53 | +- **App Platform for LKE**: A Kubernetes-based platform that combines developer and operations-centric tools, automation, self-service, and management of containerized application workloads. App Platform for LKE streamlines the application lifecycle from development to delivery and connects numerous CNCF (Cloud Native Computing Foundation) technologies in a single environment, allowing you to construct a bespoke Kubernetes architecture. |
| 54 | + |
| 55 | +### Software |
| 56 | + |
| 57 | +- [**RabbitMQ**](https://www.rabbitmq.com/): An open source alternative message broker that uses queue-based messaging to provide customization and control over message routing and delivery patterns. |
| 58 | + |
| 59 | +- [**Harbor**](https://goharbor.io/): An open source registry that helps store and manage container images and OCI artifacts like Helm charts. Harbor uses RBAC (role-based access control) for secure artifact and policy management. |
| 60 | + |
| 61 | +- [**Argo CD**](https://argo-cd.readthedocs.io/en/stable/): An open source, declarative, continuous delivery tool for Kubernetes. Argo CD uses the GitOps workflow to continuously monitor applications and compare their current states against desired states in a Git repository. |
| 62 | + |
| 63 | +- [**Cloud Native Buildpacks**](https://buildpacks.io/): A buildpack is software used to take application source code and transform it into containerized images for building applications. |
| 64 | + |
| 65 | +- [**Istio**](https://istio.io/): An open source service mesh used for securing, connecting, and monitoring microservices. |
| 66 | + |
| 67 | +- [**Ingress NGINX Controller**](https://github.com/kubernetes/ingress-nginx): When creating a Service in App Platform, an `ingress` is created using NGINX's Ingress Controller to allow public access to internal services. |
| 68 | + |
| 69 | +## Prerequisites |
| 70 | + |
| 71 | +- A [Cloud Manager](https://cloud.linode.com/) account is required to use Akamai's cloud computing services, including LKE. |
| 72 | + |
| 73 | +- Enrollment into the Akamai App Platform's [beta program](https://cloud.linode.com/betas). |
| 74 | + |
| 75 | +- An provisioned and configured LKE cluster with App Platform enabled and [auto-scaling](https://techdocs.akamai.com/cloud-computing/docs/manage-nodes-and-node-pools#autoscale-automatically-resize-node-pools) turned on. An LKE cluster consisting of 3 Dedicated Compute Instances is sufficient for the deployment in this guide to run, but additional resources may be required during the configuration of your App Platform architecture. |
| 76 | + |
| 77 | + To ensure sufficient resources are available, it is recommended that node pool auto-scaling for your LKE cluster is enabled after deployment. Make sure to set the max number of nodes higher than your minimum. This may result in higher billing costs. |
| 78 | + |
| 79 | +To learn more about provisioning a LKE cluster with App Platform, see our [Getting Started with App Platform for LKE](https://techdocs.akamai.com/cloud-computing/docs/getting-started-with-akamai-application-platform) guide. |
| 80 | + |
| 81 | +## Set Up Infrastructure |
| 82 | + |
| 83 | +Once your LKE cluster with App Platform has been fully deployed, [sign in](https://techdocs.akamai.com/cloud-computing/docs/getting-started-with-akamai-application-platform#obtain-the-initial-access-credentials-and-sign-in) to the App Platform web UI using the `platform-admin` account, or another account that uses the `platform-admin` role. |
| 84 | + |
| 85 | +### Enable RabbitMQ and Harbor |
| 86 | + |
| 87 | +1. Select **view** > **platform** in the top bar. |
| 88 | + |
| 89 | +1. Select **Apps** from the left menu. |
| 90 | + |
| 91 | +1. Enable the **RabbitMQ** and **Harbor** apps by hovering over each app icon and clicking the **power on** button. It may take a few minutes for the apps to enable. |
| 92 | + |
| 93 | + Enabled apps move up and appear in color towards the top of the available app list. |
| 94 | + |
| 95 | + {{< note title="Using Object Storage With Harbor" >}} |
| 96 | + Optionally, Harbor can be configured to use object storage when first activated. While not necessary for the demo in this tutorial, it is recommended for production environments. |
| 97 | + {{< /note >}} |
| 98 | + |
| 99 | +### Create a New Team |
| 100 | + |
| 101 | +[Teams](https://apl-docs.net/docs/for-ops/console/teams) are isolated tenants on the platform to support Development and DevOps teams, projects, or even DTAP (Development, Testing, Acceptance, Production). A Team gets access to the Console, including access to self-service features and all shared apps available on the platform. |
| 102 | + |
| 103 | +When working in the context of an admin-level Team, users can create and access resources in any namespace. When working in the context of a non-admin Team, users can only create and access resources used in that Team's namespace. |
| 104 | + |
| 105 | +1. Select **view** > **platform**. |
| 106 | + |
| 107 | +1. Select **Teams** in the left menu. |
| 108 | + |
| 109 | +1. Click **Create Team**. |
| 110 | + |
| 111 | +1. Provide a **Name** for the Team. Keep all other default values, and click **Submit**. This guide uses the Team name `demo`. |
| 112 | + |
| 113 | +### Create a RabbitMQ Cluster with Workloads |
| 114 | + |
| 115 | +A [Workload](https://apl-docs.net/docs/for-devs/console/workloads) is a self-service feature for creating Kubernetes resources using Helm charts from the Catalog. |
| 116 | + |
| 117 | +1. Switch to your newly created team view by selecting **view** > **team** and **team** > **demo** in the top bar. You can switch back to team `admin` as needed by selecting **view** > **team** and **team** > **admin**. |
| 118 | + |
| 119 | +1. Select **Workloads** from the left menu, and then click **Create Workload**. |
| 120 | + |
| 121 | +1. Select the _Rabbitmq-Cluster_ Helm chart from the Catalog. |
| 122 | + |
| 123 | +1. Click **Values**. |
| 124 | + |
| 125 | +1. Provide a name for the Workload. This guide uses the Workload name `rabbitmq-demo`. |
| 126 | + |
| 127 | +1. Continue with the rest of the default values, and click **Submit**. The Workload may take a few minutes to become ready. |
| 128 | + |
| 129 | +1. A Workload is ready when there is a green checkmark in the **Status** column: |
| 130 | + |
| 131 | +  |
| 132 | + |
| 133 | +## Build the App |
| 134 | + |
| 135 | +This guide uses an example Python chat app to send messages to all connected clients. The steps below pull the example app code from the Linode Git repository and deploy it using the "Build" feature in App Platform. |
| 136 | + |
| 137 | +The example app in this guide is not meant for production workloads, and steps may vary depending on the app you are using. |
| 138 | + |
| 139 | +1. Select **view** > **team** and **team** > **demo** in the top bar. |
| 140 | + |
| 141 | +1. Select **Builds**, and click **Create Build**. |
| 142 | + |
| 143 | +1. Provide a name for the Build. This is the same name used for the image stored in the private Harbor registry of your Team. This guide uses the Build name `rmq-example-app` with the tag `latest`. |
| 144 | + |
| 145 | +1. Select the **Mode** `Buildpacks`. |
| 146 | + |
| 147 | +1. To use the example Python messaging app, provide the following GitHub repository URL: |
| 148 | + |
| 149 | + ```command |
| 150 | + https://github.com/linode/apl-examples.git |
| 151 | + ``` |
| 152 | + |
| 153 | +1. Set the **Buildpacks** path to `rabbitmq-python`. |
| 154 | + |
| 155 | +1. Click **Submit**. The build may take a few minutes to be ready. |
| 156 | + |
| 157 | + {{< note title="Make sure auto-scaling is enabled on your cluster" >}} |
| 158 | + When a build is created, each task in the pipeline runs in a pod, which requires a certain amount of CPU and memory resources. To ensure the sufficient number of resources are available, it is recommended that auto-scaling for your LKE cluster is enabled prior to creating the build. |
| 159 | + {{< /note >}} |
| 160 | + |
| 161 | +### Check the Build Status |
| 162 | + |
| 163 | +The backend status of the build can be checked from the **PipelineRuns** section of the Tekton app interface: |
| 164 | + |
| 165 | +1. Select **Apps** from the left menu, and open the _Tekton_ app. |
| 166 | + |
| 167 | +1. Click **PipelineRuns** in the left menu. |
| 168 | + |
| 169 | +1. Click the link of your build in the list of available Pipelines. |
| 170 | + |
| 171 | +1. A successful build is denoted with a green check mark and `Completed` status: |
| 172 | + |
| 173 | +  |
| 174 | + |
| 175 | +### Copy the Image Repository |
| 176 | + |
| 177 | +Once successfully built, copy the image repository link so that you can create a Workload for deploying the app in the next step. |
| 178 | + |
| 179 | +1. Select **Builds** to view the status of your build. |
| 180 | + |
| 181 | +1. When ready, use the "copy" button in the **Repository** column to copy the repository URL link to your clipboard. |
| 182 | + |
| 183 | +  |
| 184 | + |
| 185 | +## Deploy the App |
| 186 | + |
| 187 | +1. Select **view** > **team** and **team** > **demo** in the top bar. |
| 188 | + |
| 189 | +1. Select **Workloads**, and click **Create Workload**. |
| 190 | + |
| 191 | +1. Select the _K8s-Deployment_ Helm chart from the Catalog. |
| 192 | + |
| 193 | +1. Click **Values**. |
| 194 | + |
| 195 | +1. Provide a name for the Workload. This guide uses the Workload name `rmq-example-app`. |
| 196 | + |
| 197 | +1. Click on **Values**. |
| 198 | + |
| 199 | +1. Add or edit the following chart values. You may need to uncomment or add additional lines in the Values configuration: |
| 200 | + |
| 201 | + - Update {{< placeholder "<image-repo-link>" >}} under `image` > `repository`, where {{< placeholder "<image-repo-link>" >}} is the repository URL link from the `rmq-example-app` build in the previous section. |
| 202 | + |
| 203 | + - Update the `name` references under each `secretKeyRef` entry. The format is `{{< placeholder "<workload-name>" >}}-rabbitmq-cluster-default-user`, where {{< placeholder "<workload-name>" >}} is the name of the RabbitMQ cluster Workload, `rabbitmq-demo`. |
| 204 | + |
| 205 | + ``` |
| 206 | + image: |
| 207 | + repository: {{< placeholder "<image-repo-link>" >}} |
| 208 | + pullPolicy: IfNotPresent |
| 209 | + tag: {{< placeholder "latest" >}} |
| 210 | + env: |
| 211 | + - name: {{< placeholder "NOTIFIER_RABBITMQ_HOST" >}} |
| 212 | + valueFrom: |
| 213 | + secretKeyRef: |
| 214 | + name: {{< placeholder "<workload-name>" >}}-rabbitmq-cluster-default-user |
| 215 | + key: {{< placeholder "host" >}} |
| 216 | + - name: {{< placeholder "NOTIFIER_RABBITMQ_USER" >}} |
| 217 | + valueFrom: |
| 218 | + secretKeyRef: |
| 219 | + name: {{< placeholder "<workload-name>" >}}-rabbitmq-cluster-default-user |
| 220 | + key: {{< placeholder "username" >}} |
| 221 | + - name: {{< placeholder "NOTIFIER_RABBITMQ_PASSWORD" >}} |
| 222 | + valueFrom: |
| 223 | + secretKeyRef: |
| 224 | + name: {{< placeholder "<workload-name>" >}}-rabbitmq-cluster-default-user |
| 225 | + key: {{< placeholder "password" >}} |
| 226 | + ``` |
| 227 | + |
| 228 | +1. Click **Submit**. It may take a few minutes for the Workload to be ready. |
| 229 | + |
| 230 | +### Allow Traffic to the RabbitMQ Cluster |
| 231 | + |
| 232 | +In order for the RabbitMQ Cluster to be accessible, a Network Policy must be created. |
| 233 | + |
| 234 | +A [Network Policy](https://apl-docs.net/docs/for-devs/console/netpols) in App Platform is a self-service method of controlling traffic to and from your deployment. Ingress (inbound) policies control access to internal Team pods, and egress (outbound) policies control traffic to external endpoints. |
| 235 | + |
| 236 | +1. Select **Network Policies** from the left menu, and click **Create NetPol**. |
| 237 | + |
| 238 | +1. Provide a name for the policy. This guide uses the name `rabbitmq-example`. |
| 239 | + |
| 240 | +1. Select **Rule type** `ingress` using the following values. Make sure to replace {{< placeholder "rabbitmq-demo" >}} with the name you used for the RabbitMQ cluster Workload: |
| 241 | + |
| 242 | + - **Selector label name**: `otomi.io/app` |
| 243 | + |
| 244 | + - **Selector label value**: `{{< placeholder "rabbitmq-demo" >}}-rabbitmq-cluster` |
| 245 | + |
| 246 | +1. Set the **Mode** to `AllowOnly`. |
| 247 | + |
| 248 | +1. To give permissions to your Team, set the namespace to `team-demo` or your created team name. |
| 249 | + |
| 250 | +1. Optionally, you can limit the in-cluster exposure to the app by configuring Workload-level authentication. |
| 251 | + |
| 252 | + To do this, set the **Selector label name** to `otomi.io/app` and the **Selector label value** to the name of your app's Workload (i.e. `rmq-example-app`). |
| 253 | +
|
| 254 | +1. Click **Submit**. |
| 255 | +
|
| 256 | +## Expose the App |
| 257 | +
|
| 258 | +Create a service to expose the `rmq-example-app` application to external traffic. |
| 259 | +
|
| 260 | +1. Select **Services** in the left menu, and click **Create Service**. |
| 261 | +
|
| 262 | +1. In the **Name** dropdown menu, select the `rmq-example-app` service. |
| 263 | +
|
| 264 | +1. Under **Exposure**, select **External**. |
| 265 | +
|
| 266 | +1. Click **Submit**. The service may take a few minutes to be ready. |
| 267 | +
|
| 268 | +### Access the Demo App |
| 269 | +
|
| 270 | +1. In the list of Services, click the URL for the `rmq-example-app` application. This should bring you to the live chat demo application in your browser. |
| 271 | +
|
| 272 | +1. Enter an example message (i.e. `Hello World!`), and click **Send**: |
| 273 | +
|
| 274 | +  |
| 275 | +
|
| 276 | +1. Once sent, you should your message display in the messages list. This acts as confirmation that your message was received. |
0 commit comments