Multi-cluster applications with Consul Enterprise admin partitions
Consul admin partitions give organizations the option to define and administer boundaries for services using Consul. This can help organizations managing services across teams and business units. Teams can benefit from managing and customizing their own Consul environment, without impacting other teams, or other Consul environments.
Some organizations want to allow organizational or business units to deploy their own installations of Consul Enterprise on their own Kubernetes clusters. Centrally managing multiple Consul installations can be an operational challenge for organizations. Instead of giving teams their own clusters, the organization can consolidate these installations onto a shared multi-tenant server cluster. This cluster serves as the control plane for Consul clients in the tenant clusters, and ensures separation between tenants of the system. This deployment model provides teams the autonomy to configure Consul and application networking as they require. This increases the team's flexibility to manage application deployments, and eliminates the operational overhead associated with managing individual server clusters.
In this tutorial, you will install and configure Consul Enterprise on two Kubernetes clusters with Helm. You will configure Admin Partitions and deploy a micro-services application called HashiCups. The services will be distributed across these two Kubernetes clusters using Consul admin partitions. A diagram showing this architecture is displayed below.
Prerequisites
- An AWS account that is capable of deploying Amazon Elastic Kubernetes Service resources.
- A Consul Enterprise license. Request a trial license on the Consul Enterprise trial registration page.
Warning
The sample repository is a Terraform project that deploys billable resources to your Amazon Web Services account. At minimum it will deploy 2 Amazon EKS Clusters and the supporting infrastructure for it, including at least one additional Classic Load Balancer. A cleanup script is provided at the end of this tutorial, but you are ultimately responsible for the resources deployed to your account.
Setting up the infrastructure
Clone GitHub repository
If using the sample repository, begin by cloning it locally, and change into the directory where the sample code is stored.
Navigate into the repository folder.
Check out the git-tag associated with this tutorial.
Navigate into the project folder for this tutorial.
Uploading the Consul Enterprise license
Start the tutorial by placing your Consul Enterprise license file in the consul_enterprise/
directory before deploying the infrastructure. Terraform uploads the license on your behalf. Ensure the file is named consul.hclic
Deploy the Infrastructure
Start by initializing the terraform project.
Next, review the terraform plan.
You are now ready to deploy the infrastructure to AWS.
The infrastructure deployment takes approximately 30-40 minutes. You can use this time to review this tutorial, or watch the video below, demonstrating the usage and benefits of Consul admin partitions.
Deploying Kubernetes
Throughout the tutorial, you will complete tasks in context of Kubernetes and Consul Enterprise. To keep track, make note of the labels for each Consul and Kubernetes identifier:
Kubernetes cluster primary manages the Consul Enterprise server cluster.
Kubernetes cluster secondary manages the Consul Enterprise client cluster.
License upload verification
Verify the Consul Enterprise license secret named consul-ent-license
exists on both clusters with the two following commands.
Installing Consul Enterprise with Helm
Install Consul Enterprise with Helm by creating two values files for your Consul Enterprise installations. Navigate into the consul_enterprise
folder.
For the Consul server
cluster, create a values file named consul-values-server.yaml
. For the Consul client cluster, create a values file named consul-values-client.yaml
.
Add the HashiCorp helm chart repository to your helm installation.
The configuration for the server
and the client
clusters are shown below. Copy and paste each tab's content into the values files you previously created for the server
and the client
.
These files are configured for the tutorial. In non-tutorial deployments, make note of the highlighted lines. Your organization may have specific guidance for you to follow regarding the values in the highlighted lines.
1 2 3 4 5 6 7 8 9 10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
When admin partitions are enabled, the Consul server
cluster generates a partition for itself, named default
. For Consul client
clusters which register themselves to the Consul server
cluster, these partition names are configurable in the global.adminPartitions
stanza of the cluster's values file. For this tutorial, refer to line 14 of the consul-values-client.yaml
values file shown above.
To learn more about Consul on Kubernetes, visit the Consul on Kubernetes repository.
Consul Enterprise Server
For the server
Consul installation, install Consul Enterprise on the primary
Kubernetes cluster.
Confirm the Consul primary
cluster has admin partitions enabled, and includes a member named server-server-0
. Use the consul members
command inside the server-server-0
pod.
Observe the existence of the default partition name in the Partition column. The partition for the Consul server
cluster is always named default
.
Installing the Consul Enterprise client cluster.
Before installing Consul Enterprise on the Kubernetes secondary
cluster, configure the Consul client
installation to communicate with two following services:
The Kubernetes
primary
cluster's admin partition service, created by Consul.The Kubernetes control plane hosted on its own cluster.
Confirm the Kubernetes primary
cluster has an active service named consul-partition-service
with a value in the EXTERNAL-IP
column. This service is created by Consul during the Helm installation. This value is a hostname or IP address. A Consul client
uses this hostname to access and register its admin partition with the Consul Enterprise server
cluster. Copy this hostname. A shortcut to obtain the EXTERNAL-IP
is provided below.
Note
Admin Partitions, when enabled, creates a Load Balancer for itself. In AWS, this creates a new Classic Load Balancer, a billable resource.
Edit the file consul-values-client.yaml
, adding the hostname as a value for the client.join
and externalServers.host
keys.
Next, copy the control-plane hostname for the secondary
Kubernetes cluster. A shortcut is provided below.
The prefix to kubectl
, TERM=dumb
, removes the stylization of text that cluster-info
outputs when returning the hostname. This can cause issues when copying and pasting text, when the stylization is present.
Update the externalServers.k8sAuthMethodHost
key with the control-plane hostname of the secondary
Kubernetes cluster.
Below, observe the keys for each value where to update the consul-values-client.yaml
file.
1 2 3 4 5 6 7 8 9 10111213
Secrets Management for the Consul client cluster
For the Consul client
installation, configure the Consul Enterprise clusters to use HTTPS. The Consul server
cluster is already configured to use HTTPS. However, the Consul client
cluster requires you to perform a few actions before enabling HTTPS.
Copy the HTTPS CA certifcate and HTTPS CA Key from the primary
Kubernetes cluster to the secondary
Kubernetes cluster.
The Consul Enterprise client
cluster needs additional secrets generated by the Consul Enterprise server
installation. These secrets let the client
authenticate, and communicate with the Consul server
cluster. You will need access control list (ACL) tokens for the admin partition, client services, and for the initial bootstrap of the Consul client
cluster. You will also need the gossip encryption key required to use gossip encryption on the Consul client
cluster.
Use the commands below to copy the secrets from the primary
Kubernetes cluster to the secondary
Kubernetes cluster.
Partition Token
Client ACL token
Bootstrap ACL Token
Gossip Encryption Key
Confirm the secrets copied from the primary
Kubernetes cluster, are present on the secondary
Kubernetes cluster.
The secondary
Kubernetes cluster is prepared for Consul client
cluster installation. Deploy theconsul-values-client.yaml
chart with Helm.
Confirm the Consul Enterprise services and pods on the secondary
Kubernetes cluster have been deployed successfully. Issue the commands below in your environment for verification.
Note the difference from the output of this command in comparison to previously inputting the same command on the Consul primary
cluster. There is no server-server-0
pod running on this Kubernetes cluster, nor a consul-partition-service
service.
Verify the pods for Consul Enterprise are present and active on the Kubernetes secondary
cluster.
Confirming the client cluster's admin partition.
When you deployed the file consul-values-client.yaml
, a partition for the Consul client
cluster was created, named tereknor
. Confirm this admin partition is present on the Consul client
cluster and is registered to the Consul server
cluster.
From the output of the kubectl get pods --context secondary
command above, use one of the client pods affixed with random characters on the end, such as client-client-4tmnx
, to verify the members in the Consul client
cluster.
Notice that the server-server-0
node from the Consul Enterprise server
cluster is listed as the server for the client
cluster, in the type
column. This confirms that your Consul client
cluster is registered to the Consul server
cluster.
For additional verification, check the logs on the same pod, with kubectl
.
To further verify the partition is registered to the Consul server
cluster, use consul partition list
. This command returns all partitions the Consul server
cluster is aware of, and their descriptions. This is an authenticated command. You will use the ACL token from the primary
cluster to authenticate, and pass the value as an argument to the -token
flag in consul partition list
.
Begin by setting the token in a shell variable. The decoded value in your shell output will be unique in comparison to this tutorial's output below.
Use the variable $ACL_TOKEN
as the argument for the -token
flag.
To observe the members of a specific partition, use consul catalog nodes
with the --partition
flag, using the $ACL_TOKEN
to use this authenticated command.
Deploy HashiCups as a distributed application
To deploy an application to your cluster, you will use HashiCups, a micro-services architecture. HashiCups serves as a shopping cart for HashiCorp-themed beverages. It has specific permissions for service communication: Its database communicates with a product API service. The front end communicates with a public API service. The public api brokers communication between the product api and the payments service.
In this tutorial, the postgres database resides on the primary
Kubernetes cluster, belonging to the Consul server
cluster. This is a common database that other products can connect to, not just HashiCups. The remaining services are deployed to the secondary
Kubernetes cluster, belonging to the client
Consul Enterprise cluster.
With both Kubernetes clusters, any pod deployed will be bootstrapped with a consul agent to each container. When resources are deployed, they are assigned to the partition of that cluster. For the Consul server
cluster, resources will belong to the default
partition. For Consul client
clusters, resources will belong to the tereknor
partition.
Exporting services with Custom Resource Definitions
In your installation, Consul Enterprise is configured with Access Control Lists enabled. With ACLs enabled, you will export the services that communicate across partitions, namely the database service, and the products API. You will use Consul Intentions to grant services access to these cross-cluster services.
Note
Learn about Access Control Lists and Consul Intentions by visiting the Access Control Lists Learn Tutorial and the Application Aware Intentions with Consul Service Mesh Learn Tutorial
Primary Cluster
Secondary Cluster
Deploying HashiCups across clusters
The following code block groups create a tab for each service by their kind
value in the Kubernetes plan file. To deploy the services, a final tab Complete
is available in each code block group, containing all the of the services in one single continuous block. The deployment instructions reflect deploying the contents of this tab with a single file.
Primary Cluster
The database will be deployed inside Consul server
cluster's default
partition, on the primary
Kubernetes cluster. Consul assigns the services to their partition automatically.
Database
Create a file called postgres.yaml
and paste the contents of the "Complete" tab inside.
Deploy the database service:
Secondary Cluster
You will deploy the remaining HashiCups micro-services to the Consul client
cluster's tereknor
partition, on the secondary
Kubernetes cluster. Consul assigns the services to their partition automatically.
Products API
With the Products API deployment, note the db_connection
string in the data.config
stanza in the ConfigMap
plan file. The database is deployed to the primary
Kubernetes cluster in a separate network, but Consul Enterprise makes this service available to the Kubernetes secondary
cluster via the loopback address of 127.0.0.1
, via the Envoy Proxy. Learn about the Envoy proxy in the Load Balancing Services in Consul Service Mesh with Envoy Learn Tutorial.
Create a file called products-api.yaml
and paste the contents of the "Complete" tab inside.
Deploy the Products API service:
Public API
Create a file called public-api.yaml
and paste the contents of the "Complete" tab inside.
Deploy the Public API service:
Payments
Create a file called payments.yaml
and paste the contents of the "Complete" tab inside.
Deploy the Payments service:
Frontend
Create a file called frontend.yaml
and paste the contents of the "Complete" tab inside.
Deploy the Frontend service:
Validation steps
Next, verify the HashiCups deployment is active.
HashiCups services are deployed
Observe the pods for each Kubernetes plan file you deployed are in a ready state according to the READY
column. Each pod is ready when all defined pods are available. For example, the public-api
is defined with 3 pods. In the output below, 3 of 3 pods are ready.
HashiCups frontend is reachable
Verify the frontend
service has a value in the EXTERNAL-IP
column. Copy the EXTERNAL-IP
value for the frontend
service, and paste it into your web browser.
DNS propagation for the HashiCups application can take a few minutes on AWS, so you may initially observe NXDOMAIN
errors returned by DNS until the DNS Time To Live (TTL) refreshes its understanding of services associated with that hostname.
When the DNS successfully refreshes the hostname association for the frontend
service, the HashiCups front page loads, containing a graphical carousel of different types of HashiCups beverages.
Database can be written to by the frontend
In the portal, select a beverage and click on the Buy
button. Enter in fake credit card information and press Submit Payment
.
When you receive a status of "Payment processed successfully, card details returned for demo purposes, not for production", then the database in the primary
cluster is successfully communicating with services across the Consul and Kubernetes clusters.
Cleanup
Use terraform to remove the infrastructure from your account, now that this tutorial is complete. With AWS, this takes approximately 20 minutes.
Every effort has been made to make the cleanup of infrastructure resources in Terraform seamless. However, there are known issues with Terraform and the AWS provider, in which EKS creates resources for itself, not managed by Terraform, causing issues with removing all resources. A shim script in this repository mitigates this issue during terraform destroy
. Due to timing of the Amazon API when removing resources, you may encounter issues where the infrastructure does not completely finish its removal. Inputting terraform destroy
again should resolve the issue. But if not, you will need to remove the resources manually, from your AWS account.
Next steps
In this tutorial, you deployed a micro-services application, HashiCups, across multiple Kubernetes and Consul Enterprise clusters. You deployed a frontend service connected to a database deployed to another Kubernetes cluster, inside of another network. You confirmed that the client
partition was registered to the server
Consul Enterprise cluster.
To reiterate, Consul admin partitions give organizations the option to define and administer boundaries for services using Consul. This can assist organizations managing services across teams and business units. Teams can now benefit from managing and customizing their own Consul environment, without any impact to other Consul environments.
To learn more about admin partitions: