Як очистити осиротілі знімки AWS EC2?


22

Ми закінчуємо великою кількістю знімків AWS EC2, де AMI було видалено, але знімок залишився гнити. Мені б хотілося, щоб неручний спосіб виявити та видалити цих сиріт, щоб заощадити нам гроші та простір.

В ідеалі я думаю, що баш сценарій використовує CLI , але мій AWS-fu слабкий. Я припускаю, що хтось робив це раніше, але я не можу знайти сценарій, який насправді працює.

У найкращому випадку це також перевірить обсяги та очистить їх, але це може бути краще підходить для другого питання.


Моя версія на python. Як користуватися та посиланням github
E.Big

Відповіді:


13

В основному натхненний повідомленнями в блозі та суть, що вже пов'язана з іншими відповідями, ось мій погляд на проблему.

Я використовував деякі зведені функції JMESpath, щоб отримати список знімків, а не вимагати tr.

Відмова від відповідальності : Використовуйте на свій страх і ризик , я зробив усе можливе, щоб уникнути будь-яких проблем і зберегти розумні за замовчуванням, але я не буду брати на себе жодної провини, якщо це спричинить проблеми у вас.

#!/bin/sh
# remove x if you don't want to see the commands
set -ex

# Some variable initialisation with sane defaults
DRUN='--dry-run'
DO_DELETE=${1:-'no'}
REGION=${2:-'eu-west-1'}
ACCOUNTID=${3:-'self'}

# Get two temporary files
SNAP_FILE=$(mktemp)
IMAGE_FILE=$(mktemp)

# Get the snapshot list and the volume list
aws --region "$REGION" ec2 describe-snapshots --owner-ids "$ACCOUNTID" --query 'Snapshots[*].[SnapshotId]' --output text > "$SNAP_FILE"
aws --region "$REGION" ec2 describe-images --owners "$ACCOUNTID" --filters Name=state,Values=available --query 'Images[*].BlockDeviceMappings[*].Ebs.[SnapshotId]' --output text > "$IMAGE_FILE"

# Check if the outputed command should be dry-run (default) or not
if [ "$DO_DELETE" = "IAMSURE" ]
then
 DRUN=''
fi

# count each snapshot id, decrease when a volume reference it, print delete command for those with no volumes
awk -v REGION="$REGION" -v DRUN="$DRUN" '
FNR==NR { snap[$1]++; next } # increment snapshots and get to next line in file immediately

{ snap[$1]-- } # we changed file, decrease the snap counter when a volume reference it

END {
 for (s in snap) { # loop over the snapshots
   if (snap[s] > 0) { # if we did not decrese under 1 that means there is no volume referencing this snapshot
    cmd="aws --region " REGION " " DRUN " ec2 delete-snapshot --snapshot-id " s
    print(cmd)
  }
 }
}
' "$SNAP_FILE" "$IMAGE_FILE"
# Clean up the temp files
rm "$SNAP_FILE" "$IMAGE_FILE"

Я сподіваюся, що сам сценарій коментується досить.

Використання за замовчуванням (без парам) містить список видалених команд осиротілих знімків для поточного рахунку та регіону eu-west-1, витяг:

aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-81e5856a
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-95c68c7e
aws --region eu-west-1 --dry-run ec2 delete-snapshot --snapshot-id snap-a3bf50bd

Ви можете перенаправити цей вихід у файл для огляду перед тим, як знайти його для виконання всіх команд.

Якщо ви хочете, щоб сценарій виконав команду замість їх друку, замініть print(cmd)на system(cmd).

Використання полягає в наступному зі сценарієм з назвою snap_cleaner:

для команд, що працюють на сухому рівні у регіоні us-west-1

./snap_cleaner no us-west-1

для корисних команд в eu-central-1

./snap_cleaner IAMSURE eu-central-1 

Третій параметр може бути використаний для доступу до іншого облікового запису (я вважаю за краще перемикати роль на інший рахунок раніше).

Скинута версія сценарію з awk-скриптом як oneliner:

#!/bin/sh
set -ex

# Some variable initialisation with sane defaults
DRUN='--dry-run'
DO_DELETE=${1:-'no'}
REGION=${2:-'eu-west-1'}
ACCOUNTID=${3:-'self'}

# Get two temporary files
SNAP_FILE=$(mktemp)
IMAGE_FILE=$(mktemp)

# Get the snapshot list and the volume list
aws --region "$REGION" ec2 describe-snapshots --owner-ids "$ACCOUNTID" --query 'Snapshots[*].[SnapshotId]' --output text > "$SNAP_FILE"
aws --region "$REGION" ec2 describe-images --owners "$ACCOUNTID" --filters Name=state,Values=available --query 'Images[*].BlockDeviceMappings[*].Ebs.[SnapshotId]' --output text > "$IMAGE_FILE"

# Check if the outputed command should be dry-run (default) or not
if [ "$DO_DELETE" = "IAMSURE" ]
then
 DRUN=''
fi

# count each snapshot id, decrease when a volume reference it, print delete command for those with no volumes
awk -v REGION="$REGION" -v DRUN="$DRUN" 'FNR==NR { snap[$1]++; next } { snap[$1]-- } END { for (s in snap) { if (snap[s] > 0) { cmd="aws --region " REGION " " DRUN " ec2 delete-snapshot --snapshot-id " s; print(cmd) } } }' "$SNAP_FILE" "$IMAGE_FILE"
# Clean up the temp files
rm "$SNAP_FILE" "$IMAGE_FILE"

Чудовий! І крім випуску "слідкувати" (який має бути "слідувати" ІМО), я вважаю, що цю відповідь слід розглядати як зразок високоякісних постів. Єдине, що здається трохи зайвим - це відмова від відповідальності (все, що ви використовуєте з чогось на веб-сайті SE, поставляється з "використовувати його на свій страх і ризик"). Я можу подумати лише про одне додаткове вдосконалення, яке ви можете додати: вказівка, якщо ви протестували цей скрипт, і якщо так, як підвести підсумки його тесту (щось на кшталт "працює як розроблено"?). Очевидно, що якщо ви вже користуєтесь ним самим, це ще кращий показник.
Pierre.Vriens

@pierre написав це вранці, перевірений частково, ймовірно, увійде в наш конвеєр сьогодні вдень, і, хоча я погоджуюсь із загальною ідеєю «передбачено як є», рівень ризику видалення «резервної копії» високий, і я вважаю, що я повинен це наголосити навіть більше.
Тенсібай

Гм, тому ми можемо задіяти вас, щоб запустити безкоштовну послугу з написання коду для таких потреб DevOps (з доданими рядками рядків про відмову) ... цікаво! Я пропоную пізніше (коли настане час), ви додасте незначне оновлення (наприкінці) на кшталт " мій сценарій зайшов у наш конвеєр сьогодні вдень ".
Pierre.Vriens

@ Pierre.Vriens Я сказав, мабуть, не гарантую, може бути наступного тижня чи пізніше;)
Tensibai

1
Ідеально, дякую за редагування! Працює точно за призначенням.
Алекс

5

Я використовував наступний сценарій на GitHub від Rodrigue Koffi (bonclay7), і він працює досить добре.

https://github.com/bonclay7/aws-amicleaner

Команда:

amicleaner --check-orphans

З публікації в блозі з документацією зроблено ще деякі речі:

Це насправді робить трохи більше, ніж сьогодні, це дозволяє:

  • Видалення списку зображень та пов’язаних з ними знімків
  • Картування AMI:
    • Використання імен
    • Використання тегів
  • Фільтрування AMI:
    • використовується запущеними екземплярами
    • від груп автоматичного масштабування (конфігурації запуску) з бажаною ємністю, встановленою на 0
    • від конфігурацій запуску, відірваних від груп автоматичного масштабування
  • Визначення кількості AMI, які ви хочете зберегти
  • Чищення знімків-сиріт
  • Трохи звітності

3

Ось один сценарій, який допоможе вам знайти осиротілих знімків

comm -23 <(echo $(ec2-describe-snapshots --region eu-west-1 | grep SNAPSHOT | awk '{print $2}' | sort | uniq) | tr ' ' '\n') <(echo $(ec2-describe-images --region eu-west-1 | grep BLOCKDEVICEMAPPING | awk '{print $3}' | sort | uniq) | tr ' ' '\n') | tr '\n' ' '

( звідси )

Також ви можете перевірити цю статтю з сервера за замовчуванням

PS Звичайно, ви можете змінити регіон, щоб відобразити ваш

PPS Тут оновлений код:

 comm -23 \
<(echo $(aws ec2 describe-snapshots --region eu-west-1 |awk '/SNAPSHOT/ {print $2}' | sort -u) | tr ' ' '\n') \
<(echo $(aws ec2 describe-images --region eu-west-1 |  awk '/BLOCKDEVICEMAPPING/ {print $3}' | sort -u) | tr ' ' '\n') | tr '\n' ' '

Зразок пояснень, що робить код:

echo $(aws ec2 describe-snapshots --region eu-west-1 | awk '/SNAPSHOT/ {print $2}' | sort -u) | tr ' ' '\n')

відправити в STDOUT список знімків. ця конструкція:

<(...)

створити віртуальний тимчасовий commфайл- обробник, щоб зробити команду читання з двох "файлів" та порівняти їх


Ви тестували це? Я знайшов ту саму статтю, але не можу змусити її працювати. Якщо можете, помилка користувача в моєму кінці, але я побоююсь, що вона може застаріти залежно від віку статті.
Алекс

@ Алекс, можна перевірити завтра
Ромео Нінов

Команда див. Змінилася, використовуйте aws ec2 описуйте / видаляйте
Tensibai

1
Я знайшов те саме джерело, але прив'язка героя awk sort та uniq робить сумний мій кодер оболонки сумним, я опублікую свою версію завтра :)
Tensibai

1
Чудово для мене, я просто хотів надати вам деякі (конструктивні) відгуки, щоб ви могли знати, що те, що, мабуть, схоже на звичайну англійську для експерта (як ви), схоже на мене як китайську, правда? PS: і це не звучить по-фламандськи ... Залиште мені додатковий коментар, якщо ви хочете повідомити мене після того, як ви закінчите (якщо ви хочете, щоб мої оновлені відгуки потім були).
Pierre.Vriens

2

Ось фрагмент коду GitHub Gist саме того, про що ви просите Даніїла Ярославця.

Він використовує список усіх зображень та їх знімки та порівнює ідентифікатори зі списком усіх ідентифікаторів знімка. Що б не залишилося - це сироти. Код працює за тим же принципом, що і відповідь вище, але краще відформатований і трохи читабельніший.

Код використовує перевагу JMESPath з --query Snapshots[*].SnapshotIdопцією (ви також можете використовувати для цього утиліту командного рядка jp, якщо вона вже є у вашому розповсюдженні. Формати виводить у вигляді тексту --output text. Ось посилання на посилання на API та кілька прикладів. Це трохи більш елегантний, ніж довгий ланцюг греп / awk / sort / uniq / tr труб.

Попередження: Тодд Уолтон : Не помиляйтеся з утилітою 'jq', яка використовує різні мови запитів для розбору документів json.


Просто FYI, утиліта командного рядка jq - це не та сама мова запиту JSON, як та, якою використовується команда "aws". Команда "aws" використовує JMESPath.
Тодд Уолтон

Дякую, що вказали на це. Я сьогодні дізнався щось нове.
Іржі Клоуда

0

Я написав сценарій snapshots.py, який повторює всі знімки (у визначеному списку регіонів) та генерує report.csv. Цей файл містить інформацію про екземпляр, AMI та том, на який посилаються всі знімки.

Також є команда інтерактивно знімати звисаючі знімки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.