Secure Applications with Service Sidecar Proxies
Consul service mesh allows you to deploy applications into a zero-trust network. A zero-trust network is a network where nothing is trusted automatically. All connections must be both authenticated and authorized. This paradigm is important in microservice and multi-cloud environments where a large number of services may be running in the same network. With Consul service mesh, service identity can be authenticated using mTLS and service operations can be authorized or blocked using intentions.
In this tutorial, you will deploy two services, web
and api
, into Consul's
service mesh running on a Kubernetes cluster. The two services will use Consul
to discover each other and communicate over mTLS using sidecar proxies.
The two services represent a simple two-tier application made of a backend api
service, and a frontend that communicates with the api
service over HTTP and
exposes the results in a web ui.
Prerequisites
A Kubernetes cluster with Consul service mesh - In the Service Mesh Deploy tutorial you used Helm to deploy Consul service mesh and enabled the use of Envoy as a sidecar proxy on a local Kubernetes cluster. You will be using that cluster to test the commands provided in this tutorial.
kubectl to interact with your Kubernetes cluster and deploy services.
Deploy services with sidecar proxies in Kubernetes
With the Consul connectInject
option enabled in the consul-values.yaml
file,
you have ensured that all the services deployed in the service mesh, that include
the "consul.hashicorp.com/connect-inject": "true"
annotation, will be automatically
registered in the Consul catalog.
When you apply this annotation, a sidecar proxy is automatically added to your pod. This proxy will handle inbound and outbound service connections, automatically ensuring all inter-service traffic occurs over verified TLS connections.
Using local sidecar proxies facilitates application integration, since application
code doesn't need to be aware of certificates, URLs, or namespaces. Since containers
within a pod share networking, as long as the application code uses localhost:pod-port
to access services within the mesh, the Consul managed Envoy proxy will
coordinate service discovery, mTLS, and policy enforcement with the Consul control
plane.
Note that the application also does not need to be aware of which port the
remote service is actually running on. The localhost:pod-port
example
only has meaning within the pod. Consul will handle the translation to the correct
target service ip:port combination. We'll cover this in more detail later in the
tutorial in the section that explains the upstream concept.
Define the services
To register services in Kubernetes you will create two service definition files
and deploy the services using kubectl
.
Create a folder to contain the configuration files.
Define the backend service
Use the following command to create a file named api.yaml
in the k8s_config
directory that contains the desired deployment configuration.
Define the frontend service
Use the following command to create a file named web.yaml
in the k8s_config
directory that contains the desired deployment configuration.
Understand the upstream concept
In this example, the web
frontend service depends on the api
backend service
to operate. The following statements explain the upstream and downstream relationship
between the services.
- The
web
frontend service depends on theapi
service and is therefore downstream from theapi
service. - The
api
service is upstream from theweb
service since theweb
service depends on it.
You may have noticed that the web
service deployment definition included an
additional Consul specific annotation.
By adding the consul.hashicorp.com/connect-service-upstreams
annotation, you
are explicitly declaring that the api
service is used by, and therefore, an
upstream dependency for the web
service.
By defining the upstream using the format consul-service-name:pod-port
(e.g. api:9091
),
you have provided Consul enough metadata that it will be able to make the api
service
that is registered in the catalog available at localhost:9091
in the web
service pod.
When the web
service makes a request to localhost:9091
, the sidecar proxy will
establish a secure mTLS connection with the api
service and forward the request.
Deploy the services
Once the configuration is completed, you can deploy the applications using
kubectl apply
.
After a few seconds you will be able to monitor the application's pods being created and running.
You can also confirm the status of the deployment in the Consul UI. To access the
Consul UI, set up port forwarding to port 18500
.
Now you will be able to view the Consul UI at http://localhost:18500.
Access the services
In the previous tutorial, you had to manually configure the access for Consul UI
using either an ingress or port forwarding. Similarly, to gain access to the ui
exposed by the web
service, you will have to permit access.
To access the web
service UI, set up port forwarding.
This will forward port 9090
from service/web
at port 9090
to your development
host. Once access is configured, the web UI will be available at
http://localhost:9090/ui.
Next steps
In this tutorial, you deployed a two-tier application in the Consul service mesh and
defined the ports and dependencies for each of the services composing your
application. Finally,you enabled external access for your web
service.
This configuration ensures that all the communication between the web
and the
api
services is passing through the Envoy sidecar proxies, and therefore, is
encrypted using mTLS.
In Enforce a Zero-trust Network with Consul Service Mesh you will learn how to configure intentions to define access control between services in the Consul service mesh and control which services are allowed or not allowed to establish connections. Give it a try now!