This is the notebook we use to create running services on the AWS Ec2 Container Service. In the following we assume you have created a ECS Cluster. The steps for how to do that are simple and described in the book. To make this run you need your AMI identity arn string (see hte third box below).
We assume that this notebook is running on a machine with your credentials in your .aws directory and that your ECS cluster is call tutorial-cluster.
import boto3
client = boto3.client('ecs')
if we didn't, then go to the portal and do so. instructions are in the book.
let's see if we can find it
client.list_clusters()['clusterArns']
Next let's see how many VMs (called containers in ecs) we have. there shoud be two.
instance_list = client.list_container_instances(cluster='tutorial-cluster')['containerInstanceArns']
instance_list
we can even get their IP addresses
ec2instances = [ client.describe_container_instances(
cluster='tutorial-cluster',
containerInstances=[instance]
)[u'containerInstances'][0][u'ec2InstanceId'] for instance in instance_list]
ec2 = boto3.resource('ec2')
instances = ec2.instances.filter( Filters=[{'Name': 'instance-id', 'Values': ec2instances}])
for instance in instances:
print(instance.id, instance.instance_type, instance.image_id, instance.public_ip_address)
we will have four services.
This first version is the one that uses the Azure table service. we are going to make it listen on port 8055.
response = client.register_task_definition(
family='tableserviceAzure',
networkMode='bridge',
taskRoleArn= 'arn:aws:iam::066301190734:role/mymicroservices',
containerDefinitions=[
{
'name': 'tableserviceAzure',
'image': 'dbgannon/table-service-bottle-azure',
'cpu': 20,
'memory': 400,
'memoryReservation': 123,
'portMappings': [
{
'containerPort': 8055,
'hostPort': 8055,
'protocol': 'tcp'
},
],
'essential': True,
},
],
)
client.list_task_definitions(familyPrefix='tableserviceAzure')['taskDefinitionArns']
note that when we create a task definition it gives it a sequnce number.
that is because we often revises the task definition during debugging. We specify that we want at least 50% of our requested instances running at all time. we specify that we want 3 instances of this service running. because we have three nodes in our cluster, this will put one on each node because the port binding will take port 8055 for one container only.
response = client.create_service( cluster='tutorial-cluster',
serviceName='tableserviceAzure',
taskDefinition='tableserviceAzure:1',
desiredCount=3, deploymentConfiguration={
'maximumPercent': 100,
'minimumHealthyPercent': 50 }
)
In this case we use a different container (because the code for DynamoDB is different than Azure tables). Here we map to port 8050.
response = client.register_task_definition(
family='tableserviceAWS',
networkMode='bridge',
taskRoleArn= 'arn:aws:iam::066301190734:role/mymicroservices',
containerDefinitions=[
{
'name': 'tableserviceAWS',
'image': 'dbgannon/table-service-bottle',
'cpu': 20,
'memory': 400,
'memoryReservation': 123,
'portMappings': [
{
'containerPort': 8050,
'hostPort': 8050,
'protocol': 'tcp'
},
],
'essential': True,
},
],
)
response = client.create_service( cluster='tutorial-cluster',
serviceName='tableserviceAWS',
taskDefinition='tableserviceAWS:1',
desiredCount=3, deploymentConfiguration={
'maximumPercent': 100,
'minimumHealthyPercent': 50 }
)
In this case we use the container predictor-new which takes one argument: this is the port that it expects to find the table service. This is the azure version.
response = client.register_task_definition(
family='predictorAzure',
networkMode='bridge',
taskRoleArn= 'arn:aws:iam::066301190734:role/mymicroservices',
containerDefinitions=[
{
'name': 'predictorAzure',
'image': 'dbgannon/predictor-new',
'cpu': 20,
'memoryReservation': 400,
'essential': True,
'command': ['8055']
},
],
)
client.list_task_definitions(familyPrefix='predictorAzure')['taskDefinitionArns']
As you can see from the above i am on the 4th iteration of the predictor (earlier versions had a few bugs). Note that we are creating 8 copies of this service.
response = client.create_service( cluster='tutorial-cluster',
serviceName='predictorAzure',
taskDefinition='predictorAzure:1',
desiredCount=1, deploymentConfiguration={
'maximumPercent': 100,
'minimumHealthyPercent': 50 }
)
now check to see how many services i have and how many tasks. There should be 10 tasks
client.list_services( cluster='tutorial-cluster')['serviceArns']
client.list_tasks(cluster='tutorial-cluster')['taskArns']
now we will create the aws table service and predictor for the AWS version. same container. just a different parameter for the port
response = client.register_task_definition(
family='predictorAWS',
networkMode='bridge',
taskRoleArn= 'arn:aws:iam::066301190734:role/mymicroservices',
containerDefinitions=[
{
'name': 'predictorAWS',
'image': 'dbgannon/predictor-new',
'cpu': 20,
'memoryReservation': 400,
'essential': True,
'command': ['8050']
},
],
)
response = client.create_service( cluster='tutorial-cluster',
serviceName='predictorAWS',
taskDefinition='predictorAWS:1',
desiredCount=3, deploymentConfiguration={
'maximumPercent': 100,
'minimumHealthyPercent': 50 }
)