Lors de l'écriture d'un traitement par lots, etc. en utilisant la fonction de planification de tâches d'ECS, si la tâche est mise à jour plusieurs fois à l'aide de ʻecs-cli, la
révision` de la définition de tâche augmentera.
Il est gênant de supprimer la révision (désenregistrer) en cliquant sur l'écran de la console d'aws, et il existe également une méthode pour la supprimer en utilisant deregister-task-definition
de ʻawscli`, mais il est également gênant de l'exécuter à partir de la ligne de commande. ..
Comment supprimer avec awscli https://docs.aws.amazon.com/cli/latest/reference/ecs/deregister-task-definition.html
J'ai donc décidé de lancer Lambda
pour désenregistrer (désenregistrer) la révision.
--Pour le déploiement de ServerlessFrameWork lambda --serverless-python-requirements Pour déployer des packages externes de Python
Utilisez ʻecs.list_task_definitions dans
boto3` pour obtenir toutes les définitions de tâches.
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.list_task_definitions
J'ai défini sort = 'DESC'
comme argument, mais je l'ai défini sur' DESC'
car cela est nécessaire lors de l'utilisation de ʻitertools.groupby` plus tard.
import json
import boto3
import logging
logger = logging.Logger(__name__)
logger.setLevel(logging.DEBUG)
def get_task_definitions():
"""Obtenir la définition de tâche ECS
Returns:
list --Liste des définitions de tâches arn
"""
client = boto3.client('ecs')
try:
res = client.list_task_definitions(
status='ACTIVE',
sort='DESC')
logger.info(json.dumps(res))
except Exception as e:
logger.info(e)
else:
logger.info('Acquisition réussie de la définition des tâches')
list_task_definitions = res['taskDefinitionArns']
return list_task_definitions
Vous pouvez l'obtenir comme ça
[
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_a:3',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_a:2',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_a:1',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_b:5',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_b:4',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_b:3',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_b:2',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_b:1',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_c:5',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_c:4',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_c:3',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_c:2',
'arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXXX:task-definition/task_c:1'
]
Maintenant que nous avons la définition de la tâche, nous la regrouperons par le même nom de tâche et formaterons les données afin que nous puissions voir le nombre de révisions de la tâche. J'ai eu la définition de la tâche, mais pour être exact, il s'agit de la définition de la tâche, donc je la formate uniquement avec le nom de la tâche.
#La forme que vous souhaitez façonner
{
'task_a': ['3', '2', '1'],
'task_b': ['5', '4', '3', '2', '1'],
'task_c': ['5', '4', '3', '2', '1']
}
ʻUtilisez itertools.groupby pour les grouper. J'ai mis le tri dans ʻecs.list_task_definitions
parce que je dois trier à l'avance pour utiliser ʻitertools.groupby`.
a = [('a', '3'), ('a', '2'), ('a', '1'), ('b', '4'), ('b', '3'),
('b', '2'), ('b', '1'), ('c', '2'), ('c', '1')]
for key, group in groupby(a, lambda x: x[0]):
for team in group:
print(team)
print('')
Il sera regroupé comme ceci, donc je vais le formater dans un dictionnaire.
('a', '3')
('a', '2')
('a', '1')
('b', '4')
('b', '3')
('b', '2')
('b', '1')
('c', '2')
('c', '1')
from itertools import groupby
def groupby_task_definitions(list_task_definitions):
"""Mettre en place une liste d'arn dans la définition de tâche
Arguments:
list_task_definitions {list} --Liste des définitions de tâches arn
Returns:
dict --Nom de la tâche et liste des révisions
Example:
{
task_a: ['4', '3', '2', '1'],
task_b: ['2', 1]
}
"""
group_list = []
for task_definition in list_task_definitions:
#Couper uniquement le nom et la révision de la tâche
task_definition = task_definition.rsplit('/', 1)[1]
task_name, revision = task_definition.split(':')
#Ajouter à la liste sous forme de taple
group_list.append((task_name, revision))
result_dict = {}
for key, group in groupby(group_list, lambda x: x[0]):
revision_list = []
for _, v in group:
revision_list.append(v)
result_dict[key] = revision_list
return result_dict
Maintenant que nous avons créé un dictionnaire de définitions de tâches, nous allons supprimer les tâches ECS. Tournez le dictionnaire avec «for» et supprimez-le par «pop ()» jusqu'à ce que la longueur de la liste de «révision» obtenue atteigne le nombre spécifié.
ʻEcs.deregister_task_definition` peut être exécuté facilement en donnant le nom de la définition de tâche à l'argument.
def deregister_task_definition(groupby_task_definitions_dict, leave):
"""Supprimer la définition de tâche, en laissant les deux dernières révisions
Arguments:
groupby_task_definitions_dict {dict} --Un dict qui stocke une liste de noms de tâches et de révisions
"""
client = boto3.client('ecs')
for name, revision_list in groupby_task_definitions_dict.items():
logger.info(name)
try:
while len(revision_list) > 2:
revision = revision_list.pop()
client.deregister_task_definition(
taskDefinition='{}:{}'.format(name, revision)
)
except Exception as e:
logger.error(e)
else:
logger.info('{} : OK!'.format(name))
Nous n'avons défini aucun événement à ce stade, mais vous pouvez utiliser lambda invoke
ou vous pouvez utiliser CloudWatch Events
pour le faire régulièrement.
serverless.yml
Nous allons créer Lambda en utilisant Serverless Framework
, donc exposez serverless.yml
.
serverless.yml
service: ecs-task
provider:
name: aws
runtime: python3.7
region: ap-northeast-1
logRetentionInDays: 30
iamRoleStatements:
- Effect: Allow
Action:
- ecs:*
Resource: "*"
functions:
definition-lifecycle :
handler: handler.main
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
usePipenv: true
handler Le gestionnaire exécute simplement une fonction qui fait ce qu'il a fait jusqu'à présent.
def main(event, context):
list_task_definitions = get_task_definitions()
groupby_task_definitions_dict = groupby_task_definitions(
list_task_definitions)
logger.info(groupby_task_definitions_dict)
deregister_task_definition(groupby_task_definitions_dict, leave)
handler.py
import boto3
import json
from itertools import groupby
import logging
logger = logging.Logger(__name__)
logger.setLevel(logging.DEBUG)
def get_task_definitions():
"""Obtenir la définition de tâche ECS
Returns:
list --Liste des définitions de tâches arn
"""
client = boto3.client('ecs')
try:
res = client.list_task_definitions(
status='ACTIVE',
sort='DESC')
logger.info(json.dumps(res))
except Exception as e:
logger.info(e)
else:
logger.info('Acquisition réussie de la définition des tâches')
list_task_definitions = res['taskDefinitionArns']
return list_task_definitions
def groupby_task_definitions(list_task_definitions):
"""Mettre en place une liste d'arn dans la définition de tâche
Arguments:
list_task_definitions {list} --Liste des définitions de tâches arn
Returns:
dict --Nom de la tâche et liste des révisions
Example:
{
task_a: ['4', '3', '2', '1'],
task_b: ['2', 1]
}
"""
group_list = []
for task_definition in list_task_definitions:
#Couper uniquement le nom et la révision de la tâche
task_definition = task_definition.rsplit('/', 1)[1]
task_name, revision = task_definition.split(':')
group_list.append((task_name, revision))
result_dict = {}
for key, group in groupby(group_list, lambda x: x[0]):
revision_list = []
for _, v in list(group):
revision_list.append(v)
result_dict[key] = revision_list
return result_dict
def deregister_task_definition(groupby_task_definitions_dict):
"""Supprimer la définition de la tâche, en laissant les deux dernières révisions
Arguments:
groupby_task_definitions_dict {dict} --Un dict qui stocke une liste de noms de tâches et de révisions
"""
client = boto3.client('ecs')
for name, revision_list in groupby_task_definitions_dict.items():
logger.info(name)
try:
while len(revision_list) > 2:
revision = revision_list.pop()
client.deregister_task_definition(
taskDefinition='{}:{}'.format(name, revision)
)
except Exception as e:
logger.error(e)
else:
logger.info('{} : OK!'.format(name))
def main(event, context):
list_task_definitions = get_task_definitions()
groupby_task_definitions_dict = groupby_task_definitions(
list_task_definitions)
logger.info(groupby_task_definitions_dict)
deregister_task_definition(groupby_task_definitions_dict)
Vous pouvez supprimer (désinscrire) une définition de tâche uniquement pour les tâches ʻActive, puis passer à l'état ʻInactive
. Dans cet état, il ne peut pas être complètement effacé à ce stade, nous attendons donc la réponse d'AWS.
À ce stade, la définition de tâche INACTIVE reste indéfiniment détectable dans votre compte. Cependant, ce comportement est sujet à changement à l'avenir et ne doit pas dépendre de la définition de la tâche ACL conservée tout au long du cycle de vie de la tâche et du service associés.
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/deregister-task-definition.html
Recommended Posts