Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Amazon ECS clustering for Docker #361

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ repository. To install this, follow the instructions below.
Clocker for [Apache Brooklyn](https://brooklyn.apache.org/) is a set of open
source, Apache Licensed tools designed to make working with [Docker](https://www.docker.com/)
containers as simple as a few clicks. Clocker contains [Brooklyn blueprints](http://brooklyn.apache.org/v/latest/start/blueprints.html)
to enable deployment and management of [Docker Swarm](https://www.docker.com/products/docker-swarm)
and [Kubernetes](http://kubernetes.io/) clusters.
to enable deployment and management of [Docker Swarm](https://www.docker.com/products/docker-swarm),
[Amazon ECS](https://aws.amazon.com/ecs/) and [Kubernetes](http://kubernetes.io/) clusters.

You will find the source code for the blueprints in this repository.

* [Docker](./common/catalog/docker/)
* [ECS](./ecs/src/main/resources/ecs/)
* [Swarm](./swarm/catalog/swarm/)
* [Kubernetes](./kubernetes/catalog/kubernetes/)

Expand All @@ -34,9 +35,11 @@ brooklyn.catalog:
brooklyn.libraries:
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.3.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-ecs&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT"
items:
- classpath://io.brooklyn.clocker.ecs:ecs/catalog.bom
- classpath://io.brooklyn.clocker.swarm:swarm/catalog.bom
- classpath://io.brooklyn.clocker.kubernetes:kubernetes/catalog.bom
```
Expand All @@ -47,6 +50,7 @@ You must add the following JARs to `./lib/dropins`:

* [brooklyn-etcd](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.3.0-SNAPSHOT)
* [common](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT)
* [ecs](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-ecs&v=2.1.0-SNAPSHOT)
* [swarm](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT)
* [kubernetes](https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT)

Expand All @@ -55,6 +59,7 @@ Then add the catalog entries using the following YAML:
```YAML
brooklyn.catalog:
items:
- classpath://ecs/catalog.bom
- classpath://swarm/catalog.bom
- classpath://kubernetes/catalog.bom
```
Expand Down
2 changes: 2 additions & 0 deletions clocker.bom
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ brooklyn.catalog:
brooklyn.libraries:
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.etcd&a=brooklyn-etcd&v=2.3.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-common&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-ecs&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-swarm&v=2.1.0-SNAPSHOT"
- "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=io.brooklyn.clocker&a=clocker-kubernetes&v=2.1.0-SNAPSHOT"
items:
- classpath://io.brooklyn.clocker.ecs:ecs/catalog.bom
- classpath://io.brooklyn.clocker.swarm:swarm/catalog.bom
- classpath://io.brooklyn.clocker.kubernetes:kubernetes/catalog.bom
20 changes: 10 additions & 10 deletions common/catalog/docker/catalog.bom
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
brooklyn.catalog:
items:
- classpath://io.brooklyn.clocker.common:docker/docker.bom
- classpath://io.brooklyn.clocker.common:docker/docker.bom

- id: docker-engine-template
name: "Docker Engine"
description: |
Creates a single docker engine.
itemType: template
iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
item:
services:
- type: docker-engine
- id: docker-engine-template
name: "Docker Engine"
description: |
Creates a single docker engine.
itemType: template
iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
item:
services:
- type: docker-engine
4 changes: 4 additions & 0 deletions ecs/catalog/ecs/catalog.bom
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
brooklyn.catalog:
items:
- classpath://io.brooklyn.clocker.common:docker/catalog.bom
- classpath://io.brooklyn.clocker.ecs:ecs/ecs.bom
286 changes: 286 additions & 0 deletions ecs/catalog/ecs/ecs.bom
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
brooklyn.catalog:
version: "2.1.0-SNAPSHOT" # CLOCKER_VERSION
publish:
description: |
Resources for working with Docker and Amazon ECS from Apache Brooklyn
license_code: APACHE-2.0
overview: README.md

items:
- id: ecs-cluster-template
name: "EC2 Container Service Docker Cluster"
description: |
Creates a cluster of Docker engines for use with Amazon ECS
itemType: template
iconUrl: classpath://io.brooklyn.clocker.ecs:icons/ecs.png
item:
services:
- type: ecs-cluster

- id: ecs-cluster
name: "EC2 Container Service Docker Cluster"
description: |
Creates a cluster of Docker engines for use with Amazon ECS
itemType: entity
iconUrl: classpath://io.brooklyn.clocker.ecs:icons/ecs.png
item:
type: org.apache.brooklyn.entity.stock.BasicApplication

brooklyn.parameters:
# Duplicated parameters for UI visibility
- name: docker.initial.size
label: "Initial Cluster Size"
description: |
Size of the docker cluster when created initially
type: integer
default: 1
- name: docker.max.size
label: "Maximum Cluster Size"
description: |
Maximum size the docker cluster can be scaled to
type: integer
default: 5
- name: docker.sharedsecuritygroup.create
label: "Create Docker SharedSecurityGroup"
description: |
Clocker blueprint will configure security groups to allow access between docker nodes and
to allow external access to deployed apps
type: boolean
default: true
- name: ecs.cluster.name
label: "ECS Cluster Name"
description: |
The name of the ECS cluster
type: string
default: "clocker"

brooklyn.children:
- type: ecs-docker-cluster
id: ecs-docker-cluster
name: "ecs-docker-cluster"

- id: ecs-docker-cluster
name: "ECS Docker Cluster"
description: |
Creates a cluster of Docker engines, of configurable initial size, and
configures them for use with the Amazon EC2 comtainer service.
itemType: entity
item:
type: cluster

brooklyn.parameters:
- name: docker.initial.size
label: "Initial Cluster Size"
description: |
Size of the Docker cluster when created initially
type: integer
default: 1
- name: docker.max.size
label: "Maximum Cluster Size"
description: |
Maximum size the Docker cluster can be scaled to
type: integer
default: 5
- name: docker.scaling.cpu.limit
label: "Docker Scaling CPU Limit"
description: |
The average CPU usage limit for the Docker cluster, before another node
will automatically be added. The default is 0.95 or 95%
type: double
default: 0.95
- name: docker.recovery.quarantineFailedEntities
label: "Quarantine"
description: |
Quarantine failed entities instead of destroying them
type: boolean
default: true
- name: docker.recovery.failOnRecurringFailuresInThisDuration
label: "Fail Duration"
description: |
Reports entity as failed if it fails two or more times in this time window
type: long
default: 300000

brooklyn.policies:
- type: org.apache.brooklyn.policy.ha.ServiceReplacer
brooklyn.config:
failureSensorToMonitor: $brooklyn:sensor("ha.entityFailed")
failOnRecurringFailuresInThisDuration:
$brooklyn:config("docker.recovery.failOnRecurringFailuresInThisDuration")
- type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
brooklyn.config:
autoscaler.metric:
$brooklyn:sensor("org.apache.brooklyn.entity.machine.MachineAttributes", "cpu.average")
autoscaler.metricLowerBound: 0.00
autoscaler.metricUpperBound:
$brooklyn:config("docker.scaling.cpu.limit")
autoscaler.minPoolSize:
$brooklyn:config("docker.initial.size")
autoscaler.maxPoolSize:
$brooklyn:config("docker.max.size")
autoscaler.resizeUpStabilizationDelay: 30s
autoscaler.resizeDownIterationMax: 0 # Disable scaling down

brooklyn.enrichers:
- type: org.apache.brooklyn.enricher.stock.Aggregator
brooklyn.config:
uniqueTag: ecs-docker-cluster-cpu-averageing
enricher.sourceSensor:
$brooklyn:sensor("org.apache.brooklyn.entity.machine.MachineAttributes", "machine.cpu")
enricher.targetSensor:
$brooklyn:sensor("org.apache.brooklyn.entity.machine.MachineAttributes", "cpu.average")
enricher.aggregating.fromMembers: true
transformation: average
- type: org.apache.brooklyn.enricher.stock.Aggregator
brooklyn.config:
uniqueTag: ecs-docker-cluster-tasks-total
enricher.sourceSensor: $brooklyn:sensor("ecs.tasks.count")
enricher.targetSensor: $brooklyn:sensor("ecs.tasks.total")
enricher.aggregating.fromMembers: true
transformation: sum

brooklyn.config:
cluster.initial.size: $brooklyn:config("docker.initial.size")
dynamiccluster.quarantineFailedEntities:
$brooklyn:config("docker.recovery.quarantineFailedEntities")
dynamiccluster.memberspec:
$brooklyn:entitySpec:
type: docker-engine-with-ecs
id: docker-engine
name: "docker-engine"

- id: docker-engine-with-ecs
name: Docker Engine with ECS
description: |
A docker-engine customised with the ECS agent
itemType: entity
iconUrl: classpath://io.brooklyn.clocker.common:icons/docker.png
item:
type: docker-engine

brooklyn.parameters:
- name: docker.recovery.stabilizationDelay
label: "Stabilization Delay"
description: |
Time period for which the service must be consistently in the same state to trigger an action.
Should be long enough that restart will not trigger failure.
type: org.apache.brooklyn.util.time.Duration
default: 5m

brooklyn.enrichers:
- type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
brooklyn.config:
serviceOnFire.stabilizationDelay:
$brooklyn:config("docker.recovery.stabilizationDelay")
entityFailed.stabilizationDelay:
$brooklyn:config("docker.recovery.stabilizationDelay")
entityRecovered.stabilizationDelay:
$brooklyn:config("docker.recovery.stabilizationDelay")
- type: org.apache.brooklyn.enricher.stock.Propagator
brooklyn.config:
uniqueTag: ecs-agent-tasks-propagator
producer: $brooklyn:child("ecs-agent")
propagating:
- $brooklyn:sensor("ecs.tasks.count")

brooklyn.config:
provisioning.properties:
customizer:
$brooklyn:object:
type: org.apache.brooklyn.location.jclouds.networking.SharedLocationSecurityGroupCustomizer
object.fields:
tcpPortRanges:
- "32768-65535"
enabled: $brooklyn:config("docker.sharedsecuritygroup.create")

brooklyn.children:
- type: ecs-agent
id: ecs-agent
name: "ecs-agent"

- id: ecs-agent
name: "ECS Agent"
description: |
The ECS agent Docker container
itemType: entity
iconUrl: classpath://io.brooklyn.clocker.ecs:icons/ecs.png
item:
type: child-software-process

brooklyn.parameters:
- name: ecs.agent.version
label: "ECS Agent Version"
type: string
default: "1.13.0"
- name: ecs.cluster.name
label: "ECS Cluster Name"
description: |
The name of the ECS cluster
type: string
default: "clocker"

brooklyn.config:
shell.env:
ECS_AGENT_VERSION: $brooklyn:config("ecs.agent.version")
ECS_CLUSTER_NAME: $brooklyn:config("ecs.cluster.name")

install.command: |
sudo yum install -y jq
sudo mkdir -p /var/log/ecs
sudo mkdir -p /var/lib/ecs/data
sudo sysctl -w net.ipv4.conf.all.route_localnet=1
sudo iptables -t nat -A PREROUTING \
-p tcp -d 169.254.170.2 --dport 80 \
-j DNAT --to-destination 127.0.0.1:51679
sudo iptables -t nat -A OUTPUT \
-d 169.254.170.2 -p tcp -m tcp \
--dport 80 -j REDIRECT --to-ports 51679

launch.command: |
docker run --name ecs-agent \
--detach=true \
--restart=on-failure:10 \
--volume=/var/run/docker.sock:/var/run/docker.sock \
--volume=/var/log/ecs/:/log \
--volume=/var/lib/ecs/data:/data \
--net=host \
--env=ECS_LOGFILE=/log/ecs-agent.log \
--env=ECS_LOGLEVEL=info \
--env=ECS_DATADIR=/data \
--env=ECS_CLUSTER=${ECS_CLUSTER_NAME} \
--env=ECS_ENABLE_TASK_IAM_ROLE=true \
--env=ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true \
amazon/amazon-ecs-agent:v${ECS_AGENT_VERSION}

checkRunning.command: |
[[ $(docker inspect --format "{{ .State.Running }}" ecs-agent) == "true" ]]

brooklyn.initializers:
- type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
brooklyn.config:
name: ecs.agent.version
description: |
ECS installed version details
targetType: string
command: |
curl http://localhost:51678/v1/metadata |
jq '.Version'
- type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
brooklyn.config:
name: ecs.instance.arn
description: |
ECS instance ARN identifier
targetType: string
command: |
curl http://localhost:51678/v1/metadata |
jq '.ContainerInstanceArn'
- type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
brooklyn.config:
name: ecs.tasks.count
description: |
ECS task count for the instance
targetType: integer
command: |
curl http://localhost:51678/v1/tasks |
jq '.Tasks[] | .Arn' ~/tmp/ecs/tasks.json |
wc -l
Loading