| :doctype: book |
| |
| Title: Aries Containers |
| |
| = Aries Containers |
| |
| Aries Containers is an Apache Aries subproject to manage container deployments, such as docker-based microservices, from a Java API. |
| |
| Many technologies exist to manage container deployments. |
| Examples include Kubernetes, Marathon/Mesos, Docker Swarm, Amazon ECS and others. |
| While each technology provides specific features, many of these management technologies share common behaviour. |
| Aries Containers provides an abstraction that allows users to easily switch between these technologies. |
| |
| Benefits: |
| |
| * Requirements change - container deployers may find that they need to change target platforms at short notice. |
| Using an abstraction API helps making such changes without too much additional work. |
| * Testing - many container management systems require cluster of machines or otherwise large setup which may make testing during development difficult. |
| Aries Containers also contains a `docker.local` binding which makes it possible to run the same code with using a local docker installation on the developer's machine. |
| |
| Current Aries Containers modules: |
| |
| * `containers-api` - the API implemented by the various bindings. |
| * `containers-docker-local` - Binding that uses the local docker installation. |
| * `containers-marathon` - Marathon binding. |
| * `containers-parent` - Parent pom. |
| * `containers-examples` - Examples. |
| * ... |
| |
| This project could influence the design process of the https://github.com/osgi/design/blob/master/rfps/rfp-0179-ComputeManagementService.pdf[OSGi RFP 179]. |
| |
| = Source |
| |
| The Aries RSA source is in a separate https://git-wip-us.apache.org/repos/asf/aries-containers.git[git repository aries-containers] there is also a https://github.com/apache/aries-containers[mirror on github]. |
| |
| To build the source, just run: |
| |
| `mvn install` |
| |
| Java 1.8 or higher is required. |
| Maven 3.3.9+ is recommended. |
| |
| = Quick Start |
| |
| The easiest way to get started is with the examples and the local docker binding. |
| Aries Containers work well in an OSGi environment where bindings are provided as OSGi services. |
| |
| As an alternative, Aries Containers can also be used in a plain Java environment. |
| Instead of obtaining the bindings from the service registry, they need to be instantiated directly in this case. |
| |
| == OSGi example |
| |
| The OSGi example uses the Felix SCR implementation to get the currently active ServiceManager injected into a simple servlet. |
| The servlet provides a simple UI to perform some of the management operations. |
| |
| The servlet is written using OSGi Declarative Service annotations and OSGi Http Whiteboard annotations and can be found here: https://git-wip-us.apache.org/repos/asf?p=aries-containers.git;a=blob;f=containers-examples/containers-example-osgiservlet/src/main/java/org/apache/aries/containers/examples/osgiservlet/ServiceManagerServlet.java;hb=HEAD[ServiceManagerServlet.java] |
| |
| Main functionality of the servlet can be summarized as follows: |
| |
| .... |
| @Component(service = Servlet.class, |
| property = {HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN + "=/manager"}) |
| public class ServiceManagerServlet extends HttpServlet { |
| |
| @Reference |
| ServiceManager serviceManager; |
| |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
| PrintWriter pw = resp.getWriter(); |
| pw.println("<BODY><H1>Service Deployments</H1>"); |
| |
| pw.println("<UL>"); |
| for (String dep : serviceManager.listServices()) { |
| pw.println("<LI>" + dep); |
| } |
| .... |
| |
| In short - an OSGi Declarative Service Component is registered as a HTTP Whiteboard Servet. |
| The Aries Containers Service Manager is injected into the `serviceManager` field and then used in the servlet to manage services. |
| |
| This demo can be launched in any OSGi framework that supports Declarative Services and the HTTP Whiteboard. |
| For example, to run this demo with the Apache Felix OSGi framework, add: |
| |
| * http://www-us.apache.org/dist//felix/org.apache.felix.scr-2.0.10.jar[The Felix SCR Declarative Services Implementation] |
| * http://www-us.apache.org/dist//felix/org.apache.felix.configadmin-1.8.14.jar[Felix Configuration Admin Service Implementation] |
| * http://www-us.apache.org/dist//felix/org.apache.felix.eventadmin-1.4.8.jar[Felix Event Admin Service Implementation] |
| * http://www-us.apache.org/dist//felix/org.apache.felix.http.whiteboard-3.0.0.jar[Felix Http Whiteboard bundle] with http://www-us.apache.org/dist//felix/org.apache.felix.http.jetty-3.4.2.jar[Felix Jetty] and the http://www-us.apache.org/dist//felix/org.apache.felix.http.servlet-api-1.1.2.jar[Servlet API]. |
| |
| Then add the Aries Containers implementation with the appropriate binding and their dependencies. |
| To run with the Docker Local binding, add |
| |
| * Aries Containers API |
| * Aries Containers Docker Local |
| * http://repo2.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar[SLF4J API] and http://repo2.maven.org/maven2/org/slf4j/slf4j-simple/1.7.25/slf4j-simple-1.7.25.jar[implementation]. |
| |
| Finally add the OSGi demo bundle itself. |
| The resulting bundle list will look like this: |
| |
| lb |
| START LEVEL 1 |
| ID|State |Level|Name |
| 0|Active | 0|System Bundle (5.6.4)|5.6.4 |
| 1|Active | 1|jansi (1.16.0)|1.16.0 |
| 2|Active | 1|JLine Bundle (3.3.0)|3.3.0 |
| 3|Active | 1|Apache Felix Bundle Repository (2.0.10)|2.0.10 |
| 4|Active | 1|Apache Felix Gogo Command (1.0.2)|1.0.2 |
| 5|Active | 1|Apache Felix Gogo JLine Shell (1.0.6)|1.0.6 |
| 6|Active | 1|Apache Felix Gogo Runtime (1.0.6)|1.0.6 |
| 7|Active | 1|Apache Felix Declarative Services (2.0.10)|2.0.10 |
| 8|Active | 1|Apache Felix Http Jetty (3.4.2)|3.4.2 |
| 9|Active | 1|Apache Felix Servlet API (1.1.2)|1.1.2 |
| 10|Active | 1|Apache Felix Http Whiteboard (3.0.0)|3.0.0 |
| 11|Active | 1|Apache Felix Configuration Admin Service (1.8.14)|1.8.14 |
| 12|Active | 1|Apache Felix EventAdmin (1.4.8)|1.4.8 |
| 13|Active | 1|Apache Aries Containers API (0.0.1.201705261547)|0.0.1.201705261547 |
| 14|Active | 1|Apache Aries Containers impl for local Docker use (0.0.1.201705291452)|0.0.1.201705291452 |
| 15|Active | 1|slf4j-api (1.7.25)|1.7.25 |
| 16|Resolved | 1|slf4j-simple (1.7.25)|1.7.25 |
| 17|Active | 1|Container Example OSGi Servlet (0.0.1.201705291444)|0.0.1.201705291444 |
| |
| Now you can access the servlet at http://localhost:8080/containers/manager |
| |
| image::containers/osgidemo.png[screenshot] |
| |
| After adding a container you can inspect its result by querying `docker` for its running containers: |
| |
| $ docker ps |
| CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES |
| 7cc5c753777e httpd "httpd-foreground" Up 4 seconds 0.0.0.0:51467->80/tcp myapache |
| |
| == Plain Java example |
| |
| This example launches a small Java Application to create a service deployment. |
| Initially a single container is deployed. |
| The user can modify the number of replicas from within the application. |
| |
| The code can be found here: https://git-wip-us.apache.org/repos/asf?p=aries-containers.git;a=blob;f=containers-examples/containers-example-javaapp/src/main/java/org/apache/aries/containers/examples/javaapp/Main.java;hb=HEAD[Main.java] |
| |
| The main functionality is: |
| |
| .... |
| ServiceManager sm = new LocalDockerServiceManager(); |
| |
| // If you want to run with Marathon, use the following line |
| // ServiceManager sm = new MarathonServiceManager("http://192.168.99.100:8080/"); |
| |
| ServiceConfig sc = ServiceConfig.builder("mytesthttpd", "httpd"). |
| cpu(0.2).memory(32).port(80).build(); |
| Service svc = sm.getService(sc); |
| // The service is now created |
| .... |
| |
| If you are running this the Docker local binding, you can see the docker container created: |
| |
| $ docker ps |
| CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES |
| 7cc5c753777e httpd "httpd-foreground" Up 4 seconds 0.0.0.0:51467->80/tcp mytesthttpd |
| |
| The example also allows scaling up and down of replica containers for this service. |
| |
| #Bindings |
| |
| ##Docker Local |
| |
| This binding works by issuing `docker` commands on the local machine and is very useful for testing. |
| Make sure the environment variables normally provided via `docker-machine env <myenv>` are set. |
| |
| OSGi ServiceManager identifier property: `container.factory.binding = docker.local` |
| |
| Constructor, for use outside of OSGi: `org.apache.aries.containers.docker.local.impl.LocalDockerServiceManager` |
| |
| ##Marathon |
| |
| This binding uses Marathon as the underlying container manager. |
| It requires the following configuration to be set: |
| |
| service.pid: org.apache.aries.containers.marathon |
| marathon.url=<the URL where marathon can be contacted> |
| |
| Once configured, the Marathon binding will register its OSGi service. |
| |
| OSGi ServiceManager identifier property: `container.factory.binding = marathon` |
| |
| Constructors, for use outside of OSGi: `org.apache.aries.containers.marathon.impl.MarathonServiceManager` |
| |
| .... |
| /** |
| * Create the Marathon Service Manager. |
| * |
| * @param marathonURL The Marathon URL |
| */ |
| public MarathonServiceManager(String marathonURL); |
| |
| /** |
| * Create the Marathon Service Manager for use with DC/OS. |
| * |
| * @param marathonURL The Marathon URL. |
| * @param dcosUser The DCOS user or service-user. |
| * @param passToken The password or token to use. |
| * @param serviceAcct `true` if this is a service account `false` if this is a plain user. |
| */ |
| public MarathonServiceManager(String marathonURL, String dcosUser, String passToken, boolean serviceAcct); |
| .... |