Showing posts with label microservice. Show all posts
Showing posts with label microservice. Show all posts

Thursday, 29 July 2021

TLS Profiles in IBM API Connect v5 - Archive Post

This blog has been posted to retain an article written in September 2018 in my personal blog. Whilst it covers an older version of the product which is out of support in April 2022 it still might provide a useful reference for TLS Profiles for API Connect

Date: 2018/09/12 

by Aiden Gallagher & Peter Reeves (our podcast)

Introduction 

In API Connect - as in any system - transmission of data across a network can be protected and secured from tampering or theft using by using x509 key pairs in a key store and trust store. Messages can be secured for a number of reasons and in different ways, this provides:

  • Confidentiality - Encryption of messages to ensure they are not read by unintended parties.
  • Integrity - Signing messages to ensure they haven’t been altered in transit.
  • Non-Repudiation - Ensuring messages are sent by a specific author or program. 

In API Connect, a TLS Profile is created. This references: 

a) certificates to be presented as part of authentication, and 

b) trust stores to validate other applications’ certificates.

The TLS Profile has the settings for the TLS version and whether mutual authentication should be used.

Please see - TLS Profiles in APIC: Cloud Manager Console and API Manager at the bottom of this article for images of the TLS Profiles within API Connect.

This article will cover configuring TLS profiles on APIC - both for inbound and outbound traffic. The reader is expected to be comfortable with basic APIC topologies, the basic infrastructure of DataPower, and a basic understanding of x509 certificates. For introductions to these topics, see the below links:

https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.cmc.doc/ssl.html 
http://www.redbooks.ibm.com/redbooks/pdfs/sg247620.pdf

Authentication

When two applications wish to communicate with each other through an API Connect architecture, they can specify three different levels of authentication; 

No Authentication

Requires no Client-ID headers to be presented

One-way authentication 

Expects the sender to provide certificates that the receiver trusts. 

Mutual authentication. 

Requires both applications to present certificates that the other trusts.

 

No Authentication

Figure 1 - No Authentication

In Figure 1, an example is given of a request and response where no authentication is required or provided. 

  1. APP1 makes a request to APP2 across a network. 
  2. APP2 accepts the request and sends a response.

In this implementation, any application that has a network connection to APP2 is able to make a request. Providing they have the correct credentials, and a well-formed request, a response will be given. Messages sent without being signed are susceptible to being stolen or read during transit, and malicious requests may be made to APP2 such as a denial of service attack.

One-way Authentication using TLS Profiles

Figure 2 - One-way Authentication

In Figure 2, an example is given of a request and response where the receiving application expects the sender to provide a certificate which it trusts.

  1. APP1 makes a request to APP2. 
  2. APP2 establishes whether it trusts messages received from APP1.
    1. APP2 expects a certificate to be provided. APP1 has provided a certificate.
    2. APP2 validates whether the certificate is signed by a trusted Client Authority (CA).
  3. APP2 accepts the request and sends a response.

This level of authentication allows a server or receiving application to verify that an application making a request is trusted, and prohibits unauthorised applications gaining information it shouldn’t.

 For the client, this allows the request message to be protected through signing.  

Mutual Authentication 

Mutual Authentication works by a client and a server performing a handshake. This uses Secure Sockets Layer (SSL) and Transport Layer Security (TLS) Protocols which have a specific handshake procedure to describe how the two applications can authenticate each other for secure message sending and receiving.

Below is an overview of how the handshake works based on the section 7.4 of the TLS RFC: https://tools.ietf.org/html/rfc5246#section-7.4

Figure 3 - TLS Handshake

There are eleven steps for completing a TLS Handshake as shown in Figure 3 - TLS Handshake:

  1. Initially the server needs to make a ‘hello’ request to the client in order initiate the trust sequence. The two applications at this point can exchange security enhancement capabilities and reset configurations such as the hash and encryption algorithms. The server is entitled to make the request at any time and can repeat the process if it needs to but needs to know about the client before it can make this request.
  2. Typically, the server won’t know about the client until a connection is made, so for most first-time connections the first step will be for the client to send a ‘hello’ to the server as an introduction of itself to the server. After this first connection the client will respond with a ‘hello’ whenever the server makes a hello request.
  3. The server will respond to the client ‘hello’ with its own ‘hello’ with the purpose of choosing an algorithm that both the server and the client accept.
  4. The server will also send a certificate immediately following the server ‘hello’, except for anonymous negotiations. This provides the certificate chain of the server. The same structure of certificate will need to be used by the client later. 
  5. The server will also send a server key exchange if the certificate is not sent or does not provide enough data to complete the handshake. It should also only be sent providing the method is legal - RSA, DH_DSS, DH_RSA methods, for example, are not legal. 
  6. Providing that the negotiation is not anonymous, the server will request a client certificate. Anonymous servers requesting client certificates will fail. 
  7. The server tells the client it has finished sending all the information that it can or will send. At which point the client will validate that the server certificates are valid.
  8. If a client certificate had been requested - in step 6 - the client will provide a certificate chain. If there are no available certificates, the client will send a blank certificate which the server can choose to accept or reject for continuing the handshake process. 
  9. The client must then send their client key exchange, which provides the clients key information. This will either be an RSA-encrypted secret or a set of applicable parameters to approve a pre-master key with the server.
  10. At this point the client send a verification message for the associated client certificate.
  11. The server and the client now exchange cipher specifications and send a finished message. The two must confirm the messages received are the same. This then establishes a trusted connection which allows application data to be shared between the two applications.

Mutual Authentication TLS using TLS Profiles

Figure 4 - Mutual Authentication using TLS Profiles

In Figure 4 - Mutual Authentication using TLS Profiles, an example is given of mutual authentication when using TLS Profiles. 

  1. APP1 makes a request to APP2. 
  2. While invoking the TLS handshake, APP1 presents its certificates from the associated TLS Profile. The presented certificate is validated against APP2s Certificate Authorities (CA) trusted certificate chain stored in the TLS Profiles trust store.
  3. APP2 also presents its certificates to APP1 which completes the TLS handshake by also validating against the APP1 Certificate Authorities (CA) trusted certificate chain stored in the TLS Profiles trust store.
  4. Once the TLS Handshake is completed a response is given to any further requests whilst all the objects in both TLS Profiles remain valid.

A trust store may have one or all of the following three objects in its trust store certificate; 

  • Root CA - A root CA is a self-signed certificate that issues trusted certificates for use to applications and services. By having the Root CA in the trust store, implicit trust of any and all certificates signed by the Root CA is given. This leaves an application open to malicious use by any entity with access to a Root CA signed certificate.
  • Intermediate CA - To protect the Root CA keys, an intermediate CA can be issued and used in a trust store. This provides a link to the Root without exposing it. Using this CA gives a subset of applications access to the Root CA, reducing the risk of malicious connections to an application.
  • Common Name (CN) Certificate - Trusting a CN certificate means that traffic has to originate from a DNS domain that matches the CN. This gives a much more restricted trusted access to an application.

Each trust store object gives different layers of protection to the application which should be considered when creating the trust store certificate. 

In API Connect, the three authentication types need to be considered for all of the following situations;

  • When an application is calling an API deployed on the API Gateway Domain.
  • When an API on the DataPower Domain is calling another API locally.
  • When an API is calling out from the DataPower Domain to another application (externally hosted microservices, application, API, database etc.). 

TLS Profiles in API Connect

High Level Overview

  • Each API Connect DataPower Service creates a DataPower Domain on the servers included on the service (v5): https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.cmc.doc/config_gateway.html
  • A DataPower Service (Domain) must define a TLS Profile.
    • If a TLS Profile is not defined by the user, the default TLS Profile will be used.
  • Inbound traffic is managed by the TLS Profile that is referenced by the DataPower Services.
  • Outbound traffic is managed by TLS Profiles that are;
    • Defined, managed and made Public in the Cloud Manager Console - which makes them available to all Organisations and therefore all APIs. Caution: This will mean any Provider Organisation in the API Hub can use the TLS Profile and thus may have certificates to allow access to systems they should not have access to.
    • Defined and managed within an Organisation on API Manager.
  • APIs must include TLS Profiles in their swagger definitions/yaml. Please see Example API Yaml with TLS Profile at the bottom of the article.
  • TLS Profiles are stored on DataPower Servers within the Domain
  • TLS Profiles are expected in a p12 format
  • To be able to change a TLS Profile for a DataPower Service in the CMC, all servers must first be deleted from the Service.

To create a TLS Profile, follow the below knowledge centre instructions:
https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.cmc.doc/ssl.html 
https://www.ibm.com/support/knowledgecenter/en/SSFS6T/com.ibm.apic.apionprem.doc/task_apionprem_ssl.html 

API Connect Traffic Flows using TLS Profiles

In this section, some flows will show how TLS Profiles can be used within API Connect to secure traffic flowing through it and its associated objects. In each scenario, we will begin from a blank APIC topology featuring a single API Gateway with no APIs or products published, a single Management Server which entails both the APIM and CMC. Three applications are shown; a database, MicroService and a secondary Gateway, these represent any and all downstream applications that could be used.

Note: In the diagrams, Domains will be shown in the CMC where they are logically described and managed in APIC by an APIC administrator. In reality, the configuration is pushed to the API Gateway where the traffic flows through, not through the CMC or the Management Server. 

Default Settings

This scenario describes how API Connect protects traffic flow if used without any changes being made post-install.  

Use Case: A consumer Application (APP1) wishes to get information from a record owned by the provider company. An API is published that calls a downstream service, which in turn connects to the system of record and responds with the required data.

Figure 5 - Default Settings

  1. API1 is published to the Dev Domain with no TLS Profile in the definition.
  2. APP1 calls API1 using one-way authentication by accepting the gateway’s self-signed certificate.
  3. API1 invokes an API on the Internal Gateway which does not enforce mutual authentication TLS for inbound traffic, thus the APIs request is processed without any TLS certificate on its part.
  4.  A response to the request is received from the system of record and passed back to APP1 through both the internal and APIC API Gateway. 

API Defined TLS Profile

This scenario describes how API Connect presents certificates to downstream applications by setting a TLS Profile in the API definition.  

Use Case: A consumer Application (APP1) wishes to get information from a record owned by the provider company. An API is published that calls a downstream service which enforces one-way authentication. The downstream service then connects to the system of record and responds with the required data.

Figure 6 - API Defined TLS Profile

  1. API1 is published to the domain with a TLS Profile in the definition
  2. APP1 calls API1 using one-way authentication by accepting the gateway’s self-signed certificate.
  3. API1 calls the downstream service API presenting certificates in TLS Profile. The downstream service and API1 complete one-way authentication with the presented certificate validated against the downstream services trust store.
  4. A response to the request is received from the system of record and passed back to APP1 through both the internal and APIC API Gateway.

Domain Level Mutual Authentication

This scenario describes how API Connect completes mutual authentication for inbound traffic and presents certificates to downstream applications.  

Use Case: A consumer Application (APP1) wishes to get information from a record owned by the provider company. An API is published that calls a downstream service which enforces one-way authentication. The downstream service then connects to the system of record and responds with the required data.

Figure 7 - Domain Level Mutual Authentication

  1. API1 is published to the domain with a TLS Profile in the definition. The TLS Profile is created in API Manager and does not enforce Mutual Authentication.
  2. APP1 calls API1 but must first complete a TLS Handshake.
  3. Mutual Authentication is successfully completed.
  4. API1 calls the downstream service API presenting certificates in TLS Profile 4. The downstream service and API1 complete one-way authentication with the presented certificate validated against the downstream service’s trust store.
  5. A response to the request is received from the system of record and passed back to APP1 through both the internal and APIC API Gateway.

Outbound Mutual Authentication

This scenario describes how API Connect completes Mutual Authentication TLS Handshake for downstream traffic.  

Use Case: A consumer Application (APP1) wishes to get information from a record owned by the provider company. An API is published that calls a downstream service which enforces mutual authentication. The downstream service then connects to the system of record and responds with the required data.

Figure 8 - Outbound Mutual Authentication

  1. API1 is published to the domain with a TLS Profile in the definition. This TLS profile enforces mutual authentication on outbound connections to the microservice.
  2. APP1 calls API1 using one-way authentication by accepting the gateway’s self-signed certificate.
  3. API1 then invokes an API on a downstream microservice but must first complete a TLS Handshake.
  4. Mutual Authentication TLS handshake is completed successfully.
  5. A response to the request is received from the system of record and passed back to APP1 through the microservice and the APIC API Gateway. 

Total Mutual Authentication

This scenario describes how API Connect completes Mutual Authentication for both inbound and outbound traffic.

Use Case: A consumer Application (APP1) wishes to get information from a record owned by the provider company. All communication in and out of the API Gateway must complete mutual authentication. 

Figure 9 - Total Mutual Authentication

  1. API1 is published to the domain with a TLS Profile in the definition.
  2. APP1 calls API1 but must first complete a TLS Handshake.
  3. Mutual Authentication is successfully completed.
  4. API1 then invokes an API on a downstream microservice but must first complete a TLS Handshake.
  5. Mutual Authentication TLS handshake is completed successfully.
  6. A response to the request is received from the system of record and passed back to APP1 through the microservice and the APIC API Gateway.

APIs calling same domain APIs

This scenario describes how API Connect completes Mutual Authentication with API calls made to other APIs on the same API Gateway.

 Use Case: A consumer Application (APP1) wishes to get information from a record owned by the provider company. All communication in and out of the API Gateway must complete mutual authentication. API1 uses OAuth, which is defined in API2, and uses mutual authentication due to the configuration settings on the API Gateway.

 

Figure 10 - APIs calling same domain APIs

  1. Both APIs are published to the domain with TLS Profiles in the definitions (API1 and the DataPower Service use a public TLS Profile which enforces MATLS).
  2. APP1 calls API1 but must first complete a TLS Handshake.
  3. Mutual Authentication is successfully completed.
  4. API1 then invokes API2 which resides on the same domain. It completes Mutual Authentication with the DataPower Domain – like an external application calling the domain as the Domain expects mutual authentication from all incoming traffic indiscriminately.
  5. API2 then invokes an API on a downstream microservice but must first complete a TLS Handshake.
  6. Mutual Authentication TLS handshake is completed successfully.
  7. A response to the request is received from the system of record and passed back to APP1 through the microservice and the APIC API Gateway.

Summary

Securing APIs and the traffic that flows through an API Connect architecture is an important task that needs considering early on in the design phases of an architecture. Enabling TLS and mutual authentication is always going to be harder in an existing infrastructure that is already serving traffic, so it is important to understand the flows and considerations as early as possible.

This article should give a good understanding of how API Connect traffic will flow and how to secure messages passing through the system in a secure way.


TLS Profiles in APIC

Cloud Manager Console

Figure 11 - TLS Profiles in the Cloud Manager Console 

API Manager

Figure 12 - TLS Profiles in API Manager

Figure 13 - TLS Profile Trust Store and Present Certificate

Example API Yaml with TLS Profile

Figure 14 - API Specification with TLS Profile


Monday, 20 January 2020

The State of State - how state fits into modern applications

By Aiden Gallagher and Andy Garratt Special thanks to Callum Jackson for his review and thoughts.
Introduction
Modern applications are built to be light-weight, easy to deploy and expendable - especially when combined with containerised deployments. Because of this, a train of thought suggests that applications should therefore be stateless.

"My Application is Stateless."

Whilst an application can be stateless, this does not help in scenarios where applications simply cannot be stateless such as an application processing booking which includes add-ons, or payments being processed with a card holders bank. 

Even if state is secured primarily in some data store using some of the patterns outlined later in the article, it is still essential for processes like transformation, security and movement to be performed which are not best suited in the data store layer.

In this article we will discuss why state is important, how stateless processes are different to stateless applications, why stateful applications can be integral to a sophisticated and reliable system and why applications without any state have limited value.

Table of Contents

INTRODUCTION
12 FACTOR APPLICATIONS
SO, WHAT IS STATE?
CONSIDERATIONS OF STATE
STATE PATTERNS
Availability Patterns
Last Man Standing
Primary and replicas
Sharding
Storage Patterns
Data Lakes
Caching
Contention and locking
Transient State Patterns
Cargo Pattern
Event Sourcing
STATE PATTERNS IN CONTAINERS
Third Party Delegation (Volumes)
Replica Sets
Stateful Sets
MODERN STATEFUL APPLICATIONS
CONCLUSION

12 Factor Applications

One of the primary reference points for modern applications is the 12-Factor methodology, which gives advice on good practice when creating software as a service or web application.

A guiding principle of the 12-Factor (modern) Application is that applications should be stateless and that there is no sharing between processes.

"Twelve-factor processes are stateless and share-nothingAny data that needs to persist must be stored in a stateful backing service, typically a database." - https://12factor.net/processes

The driver behind this decision is the ability to have self-contained processes that can be deleted, rebuilt or upgraded easily and without risk to user journeys; but state is important and in many cases it cannot and should not be avoided.

Even in the case of containers, state can be managed if thought about and cared about. The application is able to gain greater control and independence by not relying on an external service where a large amount of trust must be held by the application developer in regards to the reliability and security of the datastore.

So, what is State?


"The particular condition that someone or something is in at a specific time." - Oxford Dictionary

There are three types of state that are used as part of the management, creation and usage of applications; whether to handle the configuration of an application, the replication of applications for availability or the messages that pass through the application itself. These are;
·      Long Term State - State that is held for a long period of time, usually in a database but occasionally in long term memory. This state is designed to be accessible over longer periods that might span generation of applications, software versions and even underlying products themselves.

Examples: Tax Returns, Grades received at university, Birth Death and Marriage Records, purchase records over time etc.

Additionally, there is transient state in applications - live information that is subject to change whilst part of a transaction. The information is important to the complete process that is being fulfilled and without it, the transaction will fail, will be repeated or will no longer be subject to audit.

·      Persisted Transient State - Whilst completing an application process, each point that the process reaches in the journey needs to be recorded for ‘in-flight recovery’ of transactions being made.

Examples: Payment failing - did it fail before or after the payment was made?, Application failed whilst adding new stock - Is the stock displaying the right amount or does it still need increasing?

·      Non-Persisted Transient State - During an application process the current progress is not needed. Often this is because a failure will not result in any harmful effects to the system the application interacts with.

Examples: An API that retrieves all existing supermarkets in a town, reloading a webpage with static data

State comes into play for a variety of reasons whether to pass relevant user information such as their permissions and account details, or to ensure that transactions are persisted, and their actions only committed a fixed number of times. State is also what is used to describe an application’s make up; its sizing’s, its connections, how it is expected to handle traffic by the wider system and how many instances are required - without this state applications cannot be deployed.

State can be difficult because it requires the tracking of a piece of data and any changes to that piece of data, it requires thoughts to what should happen to the state should a failure occur either in retrieving relevant state, the application flow, the application or the runtime hardware of the transaction. It is this difficulty that leads to the avoidance of its usage in the first place. 

As we see in the 12 Factor Application methodology rather than deal with all state as a necessary and needed part of an application, long term state and persisted transient state is instead passed to other services whilst non-persisted transient state is described as permittable through a single-transaction cache. However, the cache data is not assured and is never assumed to be available for any future transactions. 

Methodologies - like 12 Factor applications - that infer that state should be reduced and eliminated where possible misunderstand the importance of state within an application, and the limited value these applications provide.

There are methods for handling state that do not require a blanket ban on its usage which will be explored later in the article.

Considerations of State

There are a number of factors that derives state of an application and its acceptance into an application. It is important to understand how that state should be handled both in the application and at the storage layer. Below are some factors to be considered;

·      State 'Life' - What is the requirement for the state to be kept? What are the ramifications of losing the state? If a user had to resubmit the transaction what would the impact be? Can we lose the data safely? How should data be stored and how can it be accessed if the application was to be lost i.e. will the database lock

·      Order and Sequence - Does the State rely on the order and sequence of event being adhered to? Will calls be required to be synchronous or asynchronous? How does this fit into a general wider modern application strategy?

·      Governance – Who is permitted to use the State? How can the state be accessed? Can data be altered in transit? 

In Databases, state is managed by applying ACID properties:

·      Atomicity - Determination of whether a transaction happens or does not happen
·      Consistency - Use of standards to enforce consistency across the application
·      Isolation - Controlling of concurrency to give the application complete independence where other parts of the same application cannot see or interfere with the transaction being completed
·      Durability - When a transaction is completed the onus is on the application that the transaction has been passed to handle that state even if the system is to shut down.

Similar techniques can be applied to applications to aid in achieving transient stateful applications.

State Patterns

There are several patterns which are currently used by existing applications to ensure that state is handled correctly;

Availability Patterns

Last Man Standing

This pattern looks to dynamically assign voting power based on the number of remaining servers in a cluster to allow a set of weighted applications and servers to reduce to a single entity in the event of issues arising in the cluster. This looks to allow applications and state to continue to function as the number of entities in the cluster are reduced.

Advantages:

  • Allows all servers in a system to be utilised for availability by readjusting a quorum
  • Reduces chance of outages by allowing a single server to survive on its own


Disadvantages: 

  • Can lead to contention as to which is the current source of truth
  • Adds complexity to the architecture of the system
  • Requires that less than half the quorums 'votes' fail in an outage so that quorum can be rebalanced

Primary and replicas

By having a primary source of data that either pushes its state or has its state copied, then the Primary can be used as the single point of truth for all applications. The use of replicas means that there is a backup of data should anything happen to the primary whereby a replica might become the primary source of data.

Advantages: 

  • Little to no downtime in the event of an outage at the data source. 
  • Updating of replicas can be performed on changed files only making the procedure relatively quick
Disadvantages: 

  • Requires a lot of additional infrastructure
  • Has to contend with availability requirements
  • Can be affected by disassociation between Primary and secondary in the event of a network outage

Sharding

This method separates data into independent, self-contained data blocks known as 'portions' which can be moved across a cluster. This is also sometimes referred to as partitioning and in a database might be completed either at a vertical or horizontal level i.e. columns or rows respectively. 
NoteMany benefits listed below also make Sharding a ‘storage’ pattern too

Advantages: 

  • The spreading of data allows for greater requests to the database and faster processing in horizontal scaling
  • Searching for data can be quicker by looking for data across shards before honing into a individual shard rather than searching a whole database you search smaller parts of it to find the relevant data. i.e. searching for 'Fred' in Folder 'F' is much simpler than searching for the same name in Folder 'Names'.
  • Mitigates against outages by making the risk on a subset of the database not the whole thing, each partitions availability can be handled in isolation.
Disadvantages: 

  • Greater risk of loss of data or data corruption if not correctly thought out and implemented
  • Hard to revert back to a single database after Sharding has occurred
  • Partitioned can become 'unbalanced' meaning the risk is pushed into a single partition reducing the benefits. i.e. partitions based on home address would have a significantly more data for United States addresses than Monaco.

Storage Patterns

Data Lakes

This method stores all data being used in a common resource in its raw format. This data can then be selected and used as and when each system requires the information.

Advantages: 

  • Data can be obtained at any time, in any order by the connected application giving greater flexibility
  • Stores different data types in a single data store
  • Can be queried more diversely making it accessible to different application types.
Disadvantages: 

  • Data can end up sat unused in a giant expensive system – sometimes known as a data swamp
  • Storing all data in a single location can create risk as a single point of failure – even if highly available
  • Querying can take time which may lead to latency in transactions

Caching

This method stores data in a temporary storage area. This is usually relatively small data based on previous computation or the result of a previous request which is retrieved by the application or database from the cache on the next request. There are many forms of caching, below are some generic local caching advantages and disadvantages.

Advantages: 

  • Allows for reduced latency as data is already stored locally to the application or database meaning no waiting for further processing or a response
  • Throughput can be improved as a result of speed enhancements 
Disadvantages: 

  • Large Caches can cause memory usage on the application processing the requests which might slow the application processing speed
  • Inconsistencies may be found in the cache as the true state changes

Contention and locking 

This method, most commonly found in database update operations looks to lock either an entire table, a single row or a single cell in order to prevent contention between two versions of a table updated by two entities at a given time. In applications the same principles can be utilised to ensure that data and resources cannot be accessed whilst being used or altered. 

Advantages: 

  • Ensures that conflicting data cannot be saved at the same time
  • Ensures that the most up to date data is being accessed by all connecting applications
Disadvantages: 

  • Applications might have to 'wait' to update the data source
  • Applications waiting for access to the data source might fail, timeout or become indefinitely blocked
  • Applications that have locked the data source will be tightly coupled with issues of the data source i.e. if it runs out of space and needs manual intervention to proceed

Transient State Patterns

Cargo Pattern

This method is used for ‘picking up’ and ‘dropping off’ state as part of a transaction and determines if state is carried to the application at a specific time i.e. during an event, or if the application actively retrieves the data it requires at a determined point in the transaction.

Advantages: 

  • State is only retained and collected in the relevant locations – all state not carried everywhere
  • State can be stored by the relevant parties providing greater security of data
  • Based on the States status at each point of the transaction, it can be determined how far through a transaction a request has gone (for repudiation etc.)
Disadvantages: 

  • Data has to be stored between processes causing latency and overhead
  • Messages and state might need to be cleaned by a secondary process

Event Sourcing

This method stores information in an event object. At a basic level this pattern looks to ensure that changes are made in the order in which they are sequenced which allows us to understand how data has changed over time, not just how it currently exists.

Advantages: 

  • State can be traced across time and therefore a great picture of state changes over time can be established and losses of data greater understood
  • Application state can be destroyed and rebuilt by rerunning an event sequence
  • Greater control over how mistaken changes are rebuilt i.e. a change to the sequence before replay or a parallel implementation with correct change to understand divergence/affect with the new change
Disadvantages: 

  • Larger data storing required
  • Event objects themselves still need retaining and their availability secured
These patterns are not new and can be used in most modern applications and are the basis of many software’s both in containerised infrastructures and on traditional static deployments. But how do these patterns apply and how can they be used, safely, to allow applications to manage and use state.

State patterns in containers

When considering state in the context of containerised application there are three main patterns that can be used to manage and ensure that state is correctly handled and retained to prevent data loss. It is important to note that containers and their configuration are stateful concerns of containerised systems and must be treated as a stateful artefact which is a dependency of the application.

Third Party Delegation (Volumes)

State is never retained on the container or its application. Instead all Stateful data is passed off to a third party which can then be accessed via the application when the state is again needed. One example might be accessing a public certificate from a public endpoint via a REST API, or the configuration of a container is stored in a source repository.

Advantages:

  • Applications are expendable; can be killed or might fail without too much worry
  • State can be handled by none containerised application, modules etc
  • Configuration of containers and application data can be restored with relative ease
Disadvantages:

  • Availability of the Third Party needs to be assured
  • Messages lost in transit need to be completed again which adds complexity to integration flows

Replica Sets

Replicates the configuration of a container template, ensuring that a set number of replica containers exist. This is used to provide a load balancing style of high availability.

Advantages:

  • Availability of the container is assured
  • Can access persisted data on a third party without impacting the end user
Disadvantages:

  • Messages lost in transit need to be completed again which adds complexity to integration flows
  • Reliance on the underlying container management system
  • May be dependent on being able to retrieve updates of the configuration templates from their storage system

Stateful Sets

An application that has state retained within the container would need to be rebuilt with the same state if it was to be lost, additionally the order and uniqueness might be relevant to the redeployment decision of the container by the container management system. This would also need a volume; however, this might be locked to a container that has specific characteristics.

Advantages:

  • Applications are expendable; can be killed or might fail without too much worry
  • Not reliant on third party availability and connectivity
  • Messages not lost in transit as they are stored and retrieved from a volume
Disadvantages:

  • Requires stability in naming and sourcing of the container i.e. DNS
  • Requires the volume to be persisted
  • There are some complexities that might require manual intervention during container deployment

Modern Stateful applications

In modern applications replication of both the container and the state therein needs to be considered in the context of applications that can be terminated, scaled up/down or stopped both unexpectedly and on demand. 

The container management system handles a lot of this contention through the use of container stateful patterns which might include a mixture of stateful sets, replica sets and the storage of state on third party applications.

But state is not expendable and will continue to be important for a multitude of requirements such as the processing of payments - which should never be completed twice or that need to be audited. Container systems should still consider state patterns as dependence on external or third parties simply moves stateful requirements elsewhere. 

Even where state is offloaded the availability and connection to the third-party storage has to be hard wired into the applications functionality as contention, dissociation and other data issues might occur during transit or whilst making a connection.

By using a mixture of existing state patterns alongside container management system stateful functionality it is possible to create stateful applications that fit into the modern application architecture.

Conclusion

In the above article, we have shown what state is, how existing applications deal with state and how state can be effectively handled and managed by modern applications in containers.  The article looks at pattern usage in these environments and describes how stateful application might be scaled.