4/23/2023

Using Istio Service Mesh To Have mTLS Connections Between Applications

 


https://istio.io/latest/docs/concepts/security/arch-sec.svg



The purpose of this post is to explain how we can have mTLS connections between applications, using Istio service mesh with the local Minikube server.


To learn more about Istio, please refer to this blog post.

Prerequisites : Please install below software in you machine


I have mentioned the versions that I have used for this setup.


  1. Minikube : 1.30.1

  2. Istioctl : 1.16.4

  3. Helm : 3.11.3

  4. Kubectl : 1.26.0

  5. Jq : 1.6

  6. Cert-manager : 1.11.1



One of the main components of this stack is cert-manager. Cert-manager will manage the full life cycle of certificates from a variety of Issuers.




Installing cert-manager


Setup Helm


helm repo add jetstack https://charts.jetstack.io

helm repo update


Install cert-manager CRDs


$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.1/cert-manager.yaml





Check the installation



Create a cert-manager Issuer and Issuing Certificate





Create istio-system namespace, to place certificates.


kubectl create namespace istio-system


An Issuer must be created in the istio-system namespace to sign Istiod and mesh workload certificates.  We'll create a self-signed root CA in our cluster because it's really simple to configure.



kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/istio-csr/example/example-issuer.yaml



Save Root Certificate to a file


kubectl get -n istio-system secret istio-ca -ogo-template='{{index .data "tls.crt"}}' | base64 -d > ca.pem




Create secret to keep the root certificate in cert-manager namespace


kubectl create secret generic -n cert-manager istio-root-ca --from-file=ca.pem=ca.pem



Installing istio-csr



The istio-csr project installs an agent that is responsible for verifying incoming certificate signing requests from Istio mesh workloads, and signs them through cert-manager via a configured Issuer.



helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \

--set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \

--set "volumeMounts[0].name=root-ca" \

--set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \

--set "volumes[0].name=root-ca" \

--set "volumes[0].secret.secretName=istio-root-ca"



You can see that istio-csr is installed successfully.




Installing Istio



We are going to use, custom manifest file to install istio.


The custom manifest does the following:


  • Disables the CA server in istiod,

  • Ensures that Istio workloads request certificates from istio-csr,

  • Ensures that the istiod certificates and keys are mounted from the Certificate created when installing istio-csr.



curl -sSL https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/istio-csr/example/istio-config-getting-started.yaml > istio-install-config.yaml


Install istio using custom configuration file.


$ istioctl install --set profile=demo -f istio-install-config.yaml


Let’s enable istio injection to namespace default


kubectl label namespace default  istio-injection=enabled --overwrite

Validating the installation



kubectl get pods -n istio-system




Test mTLS


All workload certificates will now be requested through cert-manager using the configured Issuer.


Let’s deploy two applications and test.


kubectl create ns foo

kubectl label ns/foo istio-injection=enabled


Install these minikube addons


  1. storage-provisioner 

  2. default-storageclass

  3. metrics-server



Run the sample sleep and httpbin workloads.



ISTIO_VERSION=1.16.4


kubectl apply -n foo -f https://raw.githubusercontent.com/istio/istio/release-$ISTIO_VERSION/samples/sleep/sleep.yaml


kubectl apply -n foo -f https://raw.githubusercontent.com/istio/istio/release-$ISTIO_VERSION/samples/httpbin/httpbin.yaml



Verify the sleep and httpbin deployments have successfully rolled-out.





Verify the sidecar proxy was injected for each workload. Each workload pod should show 2/2 containers are READY.


Apply this Istio configuration to make sure that workloads will use mTLS.


kubectl apply -n foo -f - <<EOF

apiVersion: security.istio.io/v1beta1

kind: PeerAuthentication

metadata:

  name: "default"

  namespace: foo

spec:

  mtls:

    mode: STRICT

EOF



Test mTLS from the sleep pod to the httpbin pod. It should return http 200 code.


kubectl -n foo exec -it deploy/sleep -c sleep -- curl -o /dev/null -s -w '%{http_code}\n' http://httpbin.foo:8000/headers




Visualize mTLS


Optionally, you can run Kiali to visualize the mTLS connections.



kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-$ISTIO_VERSION/samples/addons/prometheus.yaml


kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-$ISTIO_VERSION/samples/addons/kiali.yaml




Verify the Kiali and Prometheus deployments successfully rolled-out.


for i in prometheus kiali; do kubectl rollout status -n istio-system deploy/$i; done



Open Kiali dashboard


istioctl dashboard kiali



As in the image below, when you go to the application overview page you can see the traffic graph with padded lock symbol on the arrows.









2/28/2023

Microservices Based Architecture for Business APIs







The purpose of this document is to explain how microservices based architecture can help to build APIs for financial and banking sector. This document will discuss all the main layers, components and patterns related to banking, financial services and insurance (BFSI) in technical perspective.


Key components of the microservices-based architecture


API Gateway 


A single-entry point with standard APIs that are exposed to external & internal partners and developers to enable access to financial data, products, and services.

Sitting in front of APIs, the gateway acts as a protector, enforcing security and ensuring scalability and high availability. To put it simply, the API Gateway takes all API requests from a client, determines which services are needed, and combines them into a unified, seamless experience for the user.

Service Mesh


The layer that service orchestration and composition happens. 

These are the features/characteristics within the service mesh.

  1. Multiple microservices can be composed into a single API.

  2. Workflow orchestration between microservices - Example: SAGA/BPMN

  3. Integration with internal systems, services and products. Now a day’s event driven approach has become popular for internal service communication.

  4. Business rules can be executed as a service for relevant microservices. This segregation helps to isolate business logic from rule execution and same rules can be used by multiple microservices.

  5. The communication between services can be made secure with various security measures such as encryption, mTLS, certificate management and access controls.

  6. Service registry and discovery capability will help to remove that responsibility from microservice and which helps to wire services dynamically.

Also, to achieve above functionalities microservices should be integrated/communicated through various channels within service mesh. To do that we need different kinds of connectors and adaptors.

As an example, we can take the Kafka connector, Zeebe connector, Mule adapter and other integration tools.

Microservices


The key idea of the microservice architecture is functional decomposition. Instead of developing one large application, you structure the application as a set of services.

Communication Flow

  1. External API consumers always access microservices, as APIs all the way from API gateway and service mesh. They don’t have direct access to services or service mesh but APIs defined at API gateway.

  2. Internally there can be both API consumers and publishers. So microservices can be exposed via API gateway and via service mesh.


Scenario 01: via API gateway


Some live information needs to be exposed only to employees’ office mobile apps.

To access this data, the office mobile app will access this API through API gateway as a rest call.


Scenario 02: via service mesh


Trading platforms want to access core banking platforms and vice versa.

This can be done effectively with event sourcing communication channels via service mesh.

Good technological example for this is Kafka and Solace.


Microservices Architecture


Microservice architecture - is an architectural style that structures an application as a collection of services that are

  1. Highly maintainable and testable

  2. Loosely coupled

  3. Independently deployable

  4. Organized around business capabilities

  5. Owned by a small team

The microservice architecture structures an application as a set of loosely coupled services. The goal of the microservice architecture is to accelerate software development by enabling continuous delivery/deployment.


DESIGN ISN’T ABOUT LOOKS; IT’S ABOUT RELATIONSHIPS


Domain-Driven Design (DDD)



Domain-Driven Design is a concept introduced by a programmer Eric Evans in 2004 in his book Domain-Driven Design: Tackling Complexity in Heart of Software.

DDD has two concepts that are incredibly useful when applying the microservice architecture: subdomains and bounded contexts.

What is domain-driven design?


Domain-driven design (DDD) is a conceptual software development approach where the business domain is the focus of development.

Domain-driven design:

  • places a project’s focus on domain logic

  • bases complex designs on the domain model

  • encourages collaboration between developers and domain experts to address domain problems and create high-quality software


Bounded Context


A Bounded Context defines the boundaries of services that won’t have any conflicting models inside of them.

Bounded context tries to define boundaries of our complex domain into business context. Bounded contexts are important because they allow us to define a ubiquitous language that is shared and valid within a boundary.

Ubiquitous language is a model that acts as a universal language to help communication between software developers and domain experts.


Example: Online Purchase System

The meaning of a product for the shipping bounded context is not the same as for the product bounded context.


Maintain Consistency

Shipping service and pricing service will subscribe to product service. So, when a product change happens, those two will be notified and they will update their respective product details within their bounded context.

This way each service can maintain their own product entity/table.


Pattern: Decompose by subdomain


DDD refers to the application’s problem space - the business - as the domain. 

A domain is consisting of multiple subdomains. Each subdomain corresponds to a different part of the business.

Examples

The subdomains of an online store include:

  1. Product catalogue

  2. Inventory management

  3. Order management

  4. Delivery management

The corresponding microservice architecture would have services corresponding to each of these subdomains




Microservices Design Patterns


When it comes to transform from monolith to microservices, there are few patterns that we can follows. Now these patterns can be categorized into three areas.

  1. Application Patterns

  2. Infrastructure Patterns

  3. Application Infrastructure Patterns



A pattern language for microservices


“A Pattern Language” is not about architecture, but about how specific design choices can help us build better relationships.






As described in above diagram, you can see the relationships between design patterns and its components.

Application Patterns


Decomposition

How to decompose an application into services?

  • Decompose by business capability - define services corresponding to business capabilities

  • Decompose by subdomain - define services corresponding to DDD subdomains

  • Self-contained Service - design services to handle synchronous requests without waiting for other services to respond

Data management

How to maintain data consistency and implement queries?

  • Database per Service - each service has its own private database

  • Shared database - services share a database

  • Saga - use sagas, which are a sequence of local transactions, to maintain data consistency across services. In a way to manage distributed transactions with microservices.

  • API Composition - implement queries by invoking the services that own the data and performing an in-memory join

  • CQRS - implement queries by maintaining one or more materialized views that can be efficiently queried

  • Domain event - publish an event whenever data changes

  • Event sourcing - persist aggregates as a sequence of events


Testing

How to make testing easier?

  • Consumer-driven contract test - a test suite for a service that is written by the developers of another service that consumes it. 

This can be achieved with proxy services.

  • Consumer-side contract test - a test suite for a service client (e.g. another service) that verifies that it can communicate with the service. 

In here basically testing communication channels is working from client to service and vice versa.

  • Service component test - a test suite that tests a service in isolation using test doubles for any services that it invokes.

This is about functional testing of service itself.


Application Infrastructure Patterns


Transactional messaging

Coordination of distributed transactions

  • There are two ways of coordination sagas

Orchestration - an orchestrator (object) tells the participants what local transactions to execute.


Choreography - each local transaction publishes domain events that trigger local transactions in other services



Cross cutting concerns

This is mainly about configuration management

  • Externalized configuration - externalize all configuration such as database location and credentials

  • Service Template - a template that implements standard cross cutting concerns and is intended to be copied by a developer in order to quickly start developing a new service

Observability

How to understand the behaviour of an application and troubleshoot problems?

  • Application metrics - instrument a service’s code to gather statistics about operations

  • Audit logging - record user activity in a database

  • Distributed tracing - instrument services with code that assigns each external request a unique identifier that is passed between services. Record information (e.g. start time, end time) about the work (e.g. service requests) performed when handling the external request in a centralized service

  • Exception tracking - report all exceptions to a centralized exception tracking service that aggregates and tracks exceptions and notifies developers.

  • Health check - service API (e.g. HTTP endpoint) that returns the health of the service and is intended to be pinged, for example, by a monitoring service

  • Centralized Logging – This will easily manage, store and analyse application logs to get high value from it. Elastic tech stack would be a good example for this. Troubleshooting and doing business analysis are two major benefits of this.


Communication patterns - Style


Which communication mechanisms do services use to communicate with each other and their external clients (even outside the same business domain)?

  • Remote Procedure Invocation - use an RPI-based protocol for inter-service communication (example: gRPC )

  • Messaging - use asynchronous messaging for inter-service communication

 (example: pub-sub)

  • Domain-specific protocol - use a domain-specific protocol


Reliability

How to prevent a network or service failure from cascading to other services?

Circuit Breaker - invoke a remote service via a proxy that fails immediately when the failure rate of the remote call exceeds a threshold

https://martinfowler.com/bliki/CircuitBreaker.html


Security


As explained in the below diagram, we have used Kubernetes and Istio service mesh.

Istio’s security features involve multiple components:

  • Citadel for key and certificate management.

  • Sidecar and perimeter proxies to implement secure communication between clients and servers and to enforce policies.

  • Pilot to distribute the authentication policies and secure naming information to the proxies.

  • Mixer to manage authorization and auditing.


Istio security view



Infrastructure Patterns


Principles-of-Container-App-Design


Cloud-native applications anticipate failure; they run and scale reliably even when their infrastructure experiences outages.

These contracts ensure that applications they run conform to certain constraints and allow the platform to automate application management.


Build time
  • Single Concern: Each container addresses a single concern and does it well.

  • Self-Containment: A container relies only on the presence of the Linux kernel. Additional libraries are added when the container is built.

  • Image Immutability: Containerized applications are meant to be immutable, and once built are not expected to change between different environments.

Runtime
  • High Observability: Every container must implement all necessary APIs to help the platform observe and manage the application in the best way possible.

  • Lifecycle Conformance: A container must have a way to read events coming from the platform and conform by reacting to those events.

  • Process Disposability: Containerized applications must be as ephemeral as possible and ready to be replaced by another container instance at any point in time.

  • Runtime Confinement: Every container must declare its resource requirements and restrict resource use to the requirements indicated. The build time principles ensure that containers have the right granularity, consistency, and structure in place. The runtime principles dictate what functionalities must be implemented in order for containerized applications to possess cloud-native function. 





Deployment patterns

How to deploy an application’s services?

  • Multiple service instances per host - deploy multiple service instances on a single host

  • Service instance per Container - deploy each service instance in its container

  • Service deployment platform - deploy services using a highly automated deployment platform that provides a service abstraction (example: Docker & Kubernetes)


External API

How do external clients communicate with the services?

  • API gateway - a service that provides each client with unified interface to services



High Level Conceptual Solution Architecture for Personal Banking


Technology Stack

  1. Cloud Native Platform: Kubernetes 

  2. Service Mesh Framework: Istio   

  3. API Gateway: WSO2, APIGEE, Kong, Nginx

 

  1. Event Streaming: Kafka or Solace ( Solace is ideal for department level integration)

  1. Workflow Engine: Camunda





The below solution architecture based on above banking use case.





  • There is a separate workflow within each system, between different systems and products.

  • Products will expose their services/APIs via API gateway to banking customers.