A fabric is a collection of containers that share a fabric registry, where the fabric registry is a replicated database that stores all information related to provisioning and managing the containers. A fabric is intended to manage a distributed network of containers, where the containers are deployed across multiple hosts.
Figure 1.1. Containers in a Fabric
JBoss Fuse Fabric uses Apache ZooKeeper
(a highly reliable, distributed coordination service) as its registry to store the cluster configuration and the node registration data.
ZooKeeper is designed to provide data consistency and high availability across data centers. ZooKeeper protects against network splits using a quorum of ZooKeeper servers: for example, you might run five ZooKeeper servers and so long as you have quorum (that is, at least three out of the five servers available) you are reliable and are not affected by a network split.
Conceptually, the Fabric registry consists of two main parts:
Configuration Registry—the logical configuration of your fabric, which typically contains no physical machine information. It contains details of the applications to be deployed and their dependencies.
Runtime Registry—contains details of how many machines are actually running, their physical location, and what services they are implementing.
A Fabric Ensemble
is a collection of Fabric Servers that collectively maintain the state of the fabric registry. The Fabric Ensemble implements a replicated database and uses a quorum-based voting system
to ensure that data in the fabric registry remains consistent across all of the fabric's containers. To guard against network splits in a quorum-based system, it is a requirement that the number of Fabric Servers in a Fabric Ensemble is always an odd number
The number of Fabric Servers in a fabric is typically 1, 3, or 5. A fabric with just one Fabric Server is suitable for experimentation only. A live production system should have at least 3 or 5 Fabric Servers, installed on separate hosts, to provide fault tolerance.
A Fabric Server has a special status in the fabric, because it is responsible for maintaining a replica of the fabric registry. In each Fabric Server, a registry service is installed (labeled R in Figure 1.1, “Containers in a Fabric”
). The registry service (based on Apache ZooKeeper) maintains a replica of the registry database and provides a ZooKeeper server, which ordinary agents can connect to in order to retrieve registry data.
Fabric Container (managed container)
A Fabric container
(or managed container
) is aware of the locations of all of the Fabric Servers, and it can retrieve registry data from any Fabric Server in the Fabric Ensemble. A Fabric agent
(labeled A in Figure 1.1, “Containers in a Fabric”
) is installed in each Fabric container. The Fabric Agent actively monitors the fabric registry, and whenever a relevant modification is made to the registry, it immediately updates its container to keep the container consistent with the registry settings.
Fabric defines a provisioning agent or Fabric agent, which relies on profiles. The Fabric agent runs on each managed container and its role is to provision the container according to the profiles assigned to it. The Fabric agent retrieves the configuration, bundles and features (as defined in the profile overlay), calculates what needs to be installed (or uninstalled) and, finally, performs the required actions.
The Fabric agent does not just provision applications; it is also capable of provisioning Fabric and the OSGi framework.
The Fabric agent retrieves any required Maven artifacts from the Maven repositories specified by its profile, which are accessed through the Maven proxies managed by the fabric.
JBoss Fuse Fabric has git as the distributed version control mechanism for all configurations allowing for a full audit history; in addition, all changes are versioned and replicated onto each machine. By leveraging a well known technology users can easily perform diffs, merges, and continuous integration.
A Fabric profile is an abstract unit of deployment, capable of holding all of the data required for deploying an application into a Fabric Container. Profiles are used exclusively in the context of fabrics.
A profile consists of a collection of OSGi bundles and Karaf features to be provisioned, and a list of configurations for the OSGi Configuration Administration service. Multiple profiles can be associated with a given container, allowing the container to serve multiple purposes.
In theory, if you have a fabric in which each managed container runs exactly the same set of features, with exactly the same configuration, you need only one profile. However, in most real-world use cases, you need to provision different features across the nodes, or at least have different configurations.
For example, you might want to run different kinds of applications on different nodes: message brokers, web applications, ESBs, transformation engines, or proxies. Each kind of application can be defined by a profile that you manage as a single logical entity, irrespective of how many instances are deployed. Alternatively, you might want to run the same features everywhere, but with location specific configurations. You might deploy message brokers in different locations, or cache services in different data centres or geographical regions.
Profiles can also use inheritance, so that parts of a configuration can be shared across multiple profiles (which is conceptually similar to the use of trees in an LDAP repository). The aggregate of configuration settings is computed using an overlay mechanism, which allows a profile to override values from its parents. This approach provides power and flexibility, while avoiding the unnecessary repetition of configuration values.
Profiles are stored in the master node's git repository, which means that they are automatically and immediately propagated to all nodes in the fabric.
The presence of a Fabric agent in a container completely changes the deployment model, requiring you to use profiles exclusively as the unit of deployment. Although it is still possible to deploy an individual bundle or feature (using
features:install, respectively), these modifications are impermanent. As soon as you restart the container or refresh its contents, the Fabric agent replaces the container's existing contents with whatever is specified by the deployed profiles.