Akka Management

Akka Management is the core module of the management utilities which provides a central HTTP endpoint for Akka management extensions.

Dependencies

Akka management requires Akka 2.5 or later.

The main Akka Management dependency is called akka-management. By itself however it does not provide any capabilities, and you have to combine it with the management extension libraries that you want to make use of (e.g. cluster http management, or cluster bootstrap). This design choice enables users to include only the minimal set of features they actually want to use (and load) in their project.

sbt
libraryDependencies += "com.lightbend.akka.management" %% "akka-management" % "0.20.0"
Gradle
dependencies {
  compile group: 'com.lightbend.akka.management', name: 'akka-management_2.12', version: '0.20.0'
}
Maven
<dependency>
  <groupId>com.lightbend.akka.management</groupId>
  <artifactId>akka-management_2.12</artifactId>
  <version>0.20.0</version>
</dependency>

And in addition to that, include all of the dependencies for the features you’d like to use, like akka-management-bootstrap etc. Refer to each extensions documentation page to learn about how to configure and use it.

Basic Usage

Remember that Akka Management does not start automatically and the routes will only be exposed once you trigger:

Scala
AkkaManagement(system).start()
Full source at GitHub
Java
AkkaManagement.get(system).start();
Full source at GitHub

This allows users to prepare anything further before exposing routes for the bootstrap joining process and other purposes.

Basic Configuration

You can configure hostname and port to use for the HTTP Cluster management by overriding the following:

akka.management.http.hostname = "127.0.0.1"
akka.management.http.port = 8558
Full source at GitHub

Note that the default value for hostname is InetAddress.getLocalHost.getHostAddress, which may or may not evaluate to 127.0.0.1.

When running Akka nodes behind NATs or inside docker containers in bridge mode, it is necessary to set different hostname and port number to bind for the HTTP Server for Http Cluster Management:

application.conf
  # Get hostname from environmental variable HOST
  akka.management.http.hostname = ${HOST}
  # Use port 8558 by default, but use environment variable PORT_8558 if it is defined
  akka.management.http.port = 8558
  akka.management.http.port = ${?PORT_8558}
  # Bind to 0.0.0.0:8558 'internally': 
  akka.management.http.bind-hostname = 0.0.0.0
  akka.management.http.bind-port = 8558

It is also possible to modify the base path of the API, by setting the appropriate value in application.conf:

application.conf
akka.management.http.base-path = "myClusterName"

In this example, with this configuration, then the Akka Management routes will will be exposed at under the /myClusterName/..., base path. For example, when using Akka Cluster Management routes the members information would then be available under /myClusterName/shards/{name} etc.

Configuring Security

Note

HTTPS is not enabled by default, as additional configuration from the developer is required. This module does not provide security by default. It is the developer’s choice to add security to this API, and when. If enabled, it is generally advisable not to expose management endpoints publicly.

The non-secured usage of the module is as follows:

Scala
AkkaManagement(system).start()
Full source at GitHub
Java
AkkaManagement.get(system).start();
Full source at GitHub

Enabling TLS/SSL (HTTPS) for Cluster HTTP Management

To enable SSL you need to provide an SSLContext. You can find more information about it in Server HTTPS Support.

Scala
val management = AkkaManagement(system)

val https: HttpsConnectionContext = ConnectionContext.https(sslContext)
management.setHttpsContext(https)
management.start()
Full source at GitHub
Java
AkkaManagement management = AkkaManagement.get(system);

HttpsConnectionContext https = ConnectionContext.https(sslContext);
management.setHttpsContext(https);
management.start();
Full source at GitHub

You can also refer to AkkaManagementHttpEndpointSpec where a full example configuring the HTTPS context is shown.

Enabling Basic Authentication

To enable Basic Authentication you need to provide an authenticator object before starting the management extension. You can find more information in Authenticate Basic Async directive

Scala
def myUserPassAuthenticator(credentials: Credentials): Future[Option[String]] =
  credentials match {
    case p @ Credentials.Provided(id) ⇒
      Future {
        // potentially
        if (p.verify("p4ssw0rd")) Some(id)
        else None
      }
    case _ ⇒ Future.successful(None)
  }
// ...
val management = AkkaManagement(system)
management.setAsyncAuthenticator(myUserPassAuthenticator)
management.start()
Full source at GitHub
Java
final Function<Optional<SecurityDirectives.ProvidedCredentials>, CompletionStage<Optional<String>>>
  myUserPassAuthenticator = opt -> {
  if (opt.filter(c -> (c != null) && c.verify("p4ssw0rd")).isPresent()) {
    return CompletableFuture.completedFuture(Optional.of(opt.get().identifier()));
  } else {
    return CompletableFuture.completedFuture(Optional.empty());
  }
};
// ...
// FIXME https://github.com/akka/akka-management/issues/338
// management.setAsyncAuthenticator(myUserPassAuthenticator);
management.start();
Full source at GitHub
Note

You can combine the two security options in order to enable HTTPS as well as basic authentication. In order to do this, invoke both setAsyncAuthenticator as well as setHttpsContext before calling start().

Stopping Akka Management

In a dynamic environment you might stop instances of Akka Management, for example if you want to free up resources taken by the HTTP server serving the Management routes.

You can do so by calling stop() on AkkaManagement. This method return a Future[Done] to inform when the server has been stopped.

Scala
val management = AkkaManagement(system)
management.start()
//...
val bindingFuture = management.stop()
bindingFuture.onComplete { _ =>
  println("It's stopped")
}
Full source at GitHub
Java
val management = AkkaManagement(system)
management.start()
//...
val bindingFuture = management.stop()
bindingFuture.onComplete { _ =>
  println("It's stopped")
}
Full source at GitHub

Developing Extensions

This project provides a set of management extensions. To write third-party extensions to Akka Management, here are few pointers about how it all works together.

The akka-management module provides the central HTTP endpoint to which extensions can register themselves.

An extension can contribute to the exposed HTTP routes by appending to the akka.management.http.route-providers list in its own reference.conf (make sure to use += instead of =). The core AkkaManagement extension collects all the routes and serves them together under the Management HTTP server. This enables easy extension of management capabilities (such as health-checks or cluster information etc) without the boilerplate and overhead to start separate HTTP servers for each extension.

For example, the “Cluster HTTP Management” module exposes HTTP routes that can be used to monitor, and even trigger joining/leaving/downing decisions via HTTP calls to these routes. The routes and logic for these are implemented inside the akka-management-cluster-http.

As a best practice, Management extensions that do something proactively should not be started automatically, but rather manually by the user. One example of that is Cluster Bootstrap. It contributes routes to Akka Management, but the bootstrapping process does not start unless ClusterBootstrap().start() is invoked. Thus, the user can decide when exactly the application is ready to start joining an existing cluster.

The source code for this page can be found here.