Skip to content

Latest commit

 

History

History
148 lines (113 loc) · 8.51 KB

README.md

File metadata and controls

148 lines (113 loc) · 8.51 KB

Plugins

Much of the behavior in InfraKit is defined by Plugins. Technically, a Plugin is an HTTP server with a well-defined API, listening on a unix socket.

Plugin Discovery

Multiple InfraKit plugins are typically used together to support a declared configuration. These plugins discover each other by looking for socket files in a common plugin directory, and communicate via HTTP.

The default plugin directory is ~/.infrakit/plugins, and can be overridden with the environment variable INFRAKIT_PLUGINS_DIR.

Note that multiple instances of a plugin may run, provided they have different names for discovery. This may be useful, for example, if a plugin can be configured to behave differently. For example:

The CLI shows which plugins are discoverable.

Plugin types

Group

When managing infrastructure like computing clusters, Groups make good abstraction, and working with groups is easier than managing individual instances. For example, a group can be made up of a collection of machines as individual instances. The machines in a group can have identical configurations (replicas, or cattle). They can also have slightly different properties like identity and ordering (as members of a quorum or pets).

InfraKit provides primitives to manage Groups: a group has a given size and can shrink or grow based on some specification, whether it's human generated or machine computed. Group members can also be updated in a rolling fashion so that the configuration of the instance members reflect a new desired state. Operators can focus on Groups while InfraKit handles the necessary coordination of Instances.

Since InfraKit emphasizes on declarative infrastructure, there are no operations to move machines or Groups from one state to another. Instead, you declare your desired state of the infrastructure. InfraKit is responsible for converging towards, and maintaining, that desired state.

Therefore, a group plugin manages Groups of Instances and exposes the operations that are of interest to a user:

  • commit a group configuration, to start managing a group
  • inspect a group
  • destroy a group

Default Group plugin

InfraKit provides a default Group plugin implementation, intended to suit common use cases. The default Group plugin manages Instances of a specific Flavor. Instance and Flavor plugins can be composed to manage different types of services on different infrastructure providers.

While it's generally simplest to use the default Group plugin, custom implementations may be valuable to adapt another infrastructure management system. This would allow you to use InfraKit tooling to perform basic operations on widely different infrastructure using the same interface.

Instance

Instances are members of a group. An instance plugin manages some physical resource instances. It knows only about individual instances and nothing about Groups. Instance is technically defined by the plugin, and need not be a physical machine at all.

For compute, for example, instances can be VM instances of identical spec. Instances support the notions of attachment to auxiliary resources. Instances may be tagged, and tags are assumed to be persistent which allows the state of the cluster to be inferred and computed.

In some cases, instances can be identical, while in other cases the members of a group require stronger identities and persistent, stable state. These properties are captured via the flavors of the instances.

Flavor

Flavors help distinguish members of one group from another by describing how these members should be treated. A flavor plugin can be thought of as defining what runs on an Instance. It is responsible for dictating commands to run services, and check the health of those services.

Flavors allow a group of instances to have different characteristics. In a group of cattle, all members are treated identically and individual members do not have strong identity. In a group of pets, however, the members may require special handling and demand stronger notions of identity and state.

Reference implementations

This repository contains several Plugins which should be considered reference implementations for demonstration purposes and development aides. With the exception of those listed as supported, Plugins in this repository should be considered not to be under active development and for use at your own risk.

Over time, we would prefer to phase out reference Plugins that appear to provide real value for implementations that are developed independently. For this reason, please file an issue to start a discussion before contributing to these plugins with non-trivial code.

plugin type description
swarm flavor runs Docker in Swarm mode
vanilla flavor manual specification of instance fields
zookeeper flavor run an Apache ZooKeeper ensemble
infrakit/file instance useful for development and testing
infrakit/terraform instance creates instances using Terraform
infrakit/vagrant instance creates Vagrant VMs

Supported implementations

The following Plugins are supported for active development. Note that these Plugins may not be part of the InfraKit project, so please double-check where the code lives before filing InfraKit issues.

plugin type description
infrakit/group group supports Instance and Flavor plugins, rolling updates
docker/infrakit.aws instance creates Amazon EC2 instances

Have a Plugin you'd like to share? Submit a Pull Request to add yourself to the list!

Creating a plugin

A plugin must be an HTTP server that implements one of the plugin APIs, lisetning on a Unix socket. While a plugin can be written in any programming language, utilities are available as libraries to simplify Plugin development in Go. Our reference implementations should provide a good starting point for building a new plugin using these utilities.

APIs

InfraKit plugins are exposed via HTTP, using JSON-RPC 2.0.

API requests can be made manually with curl. For example, the following command will list all groups:

$ curl -X POST --unix-socket ~/.infrakit/plugins/group http:/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"Group.InspectGroups","params":{},"id":1}'
{"jsonrpc":"2.0","result":{"Groups":null},"id":1}

API errors are surfaced with the error response field:

$ curl -X POST --unix-socket ~/.infrakit/plugins/group http:/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"Group.CommitGroup","params":{},"id":1}'
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Group ID must not be blank","data":null},"id":1}

Per the JSON-RPC format, each API call has a method and params. The following pages define the available methods for each plugin type:

See also: documentation on common API types.

Additionally, all plugins will log each API HTTP request and response when run with the --log 5 command line argument.

API identification

Plugins are required to identify the name and version of plugin APIs they implement. This is done with a request like the following:

$ curl -X POST --unix-socket ~/.infrakit/plugins/group http:/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"Plugin.Implements","params":{},"id":1}'
{"jsonrpc":"2.0","result":{"Interfaces":[{"Name":"Group","Version":"0.1.0"}]},"id":1}