containers

Получить список всех образов и их тегов из docker registry

  1. Установить утилиту crane
  2. При необходимости залогиниться в registry с помощью docker или crane
  3. Выполнить скрипт, формирующий файл со списком
REGISTRY_URL="registry.home.arpa"
cat /dev/null > catalog.txt
for image in $(crane catalog ${REGISTRY_URL}); do
  for tag in $(crane ls "${REGISTRY_URL}/${image}"); do
    echo "${REGISTRY_URL}/${image}:${tag}" >> catalog.txt
  done
done
  1. (Опционально) Посчитать количество существующих тегов для каждого образа cat catalog.txt | awk -F':' '{print $1$2}' | sort -n | uniq -c | sort -k1 -n

Посчитать занимаемое место образами в docker registry

Слои файловой системы могут переиспользоваться в разных образах. Поэтому это примерная информация о занимаемом месте

  1. Установить утилиту crane
  2. При необходимости залогиниться в registry с помощью docker или crane
  3. Посчитать суммарный размер слоёв каждого образа по тегу
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > size_images.txt
for tag in $(crane ls "${REGISTRY_URL}/${IMAGE}"); do
  img="${REGISTRY_URL}/${IMAGE}:${tag}"
  size="$(crane manifest "${img}" | jq -r '[.layers[].size | tonumber] | add')"
  echo "${img} ${size}" >> size_images.txt
done
  1. При необходимости получить суммарный размер cat size_images.txt | sort -rn | uniq | awk '{size+=$2;} END{print size;}'

Посчитать, сколько весят и как часто переиспользуются между тегами слои образов

  1. Установить утилиту crane
  2. При необходимости залогиниться в registry с помощью docker или crane
  3. Получить размеры всех слоёв образов для всех тегов
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > layers_size.txt
for tag in $(crane ls "${REGISTRY_URL}/${IMAGE}"); do
  img="${REGISTRY_URL}/${IMAGE}:${tag}"
  crane manifest "${img}" | jq -r '.layers[] | [.digest, .size] | @tsv' >> layers_size.txt
done
  1. Получить список уникальных слоёв с размерами этих слоёв и количеством переиспользования cat layers_size.txt | sort -n | uniq -c | awk '{print $2" "$3/1024/1024" "$1}' | sort -k2 -n > unique_layers_size.txt

Почистить образы из docker registry (на Nexus)

Каждый образ - это некий конечный объект с уникальной sha256 суммой (digest). Образ скачивается указанием его дайджейста. Для удобства на дайджейсты навешивают человекочитаемые теги. Их можно навесить сколько угодно на один дайджест

docker pull centos@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
docker pull centos:7.9.2009
docker pull centos:7

Чтобы удалить образы, нам нужно удалять их по дайджестам, а затем средствами Nexus подчистить “осиротевшие” теги, которые не ссылаются ни на какой дайджест, после чего выполнить compact blobstore

  1. Установить утилиту crane
  2. При необходимости залогиниться в registry с помощью docker или crane
  3. Сформировать список всех тегов целевого образа
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > all_tags.txt
for tag in $(crane ls "${REGISTRY_URL}/${IMAGE}"); do
  echo "${REGISTRY_URL}/${IMAGE}:${tag}" >> all_tags.txt
done
  1. Сформировать список НУЖНЫХ тегов целевого образа Тут, по сути, надо из всех тегов выделить те теги, которые нужно оставить. Например, исключить все, которые заканчиваются на PIPELINE_ID (5,6 - значный из gitlab) grep -vE '^.+[0-9]{5,6}$' all_tags.txt > keep_tags.txt
  2. Получить список уникальных дайджестов для всех тегов
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > all_digests.txt
for image in $(cat all_tags.txt); do
  echo "${REGISTRY_URL}/${IMAGE}@$(crane digest $image)" >> all_digests.txt;
done
sort -n all_digests.txt | uniq > all_digests_unique.txt
  1. Получить список уникальных дайджестов для НУЖНЫХ тегов
REGISTRY_URL="registry.home.arpa"
IMAGE="service01"
cat /dev/null > keep_digests.txt
for image in $(cat keep_tags.txt); do
  echo "${REGISTRY_URL}/${IMAGE}@$(crane digest $image)" >> keep_digests.txt;
done
sort -n keep_digests.txt | uniq > keep_digests_unique.txt
  1. Выбрать из списка всех дайджейстов те, которых нет в списке НУЖНЫХ дайджестов Флаг -u для uniq после сортировки двух списков выведет только те элементы, которые встречаются только один раз sort -n all_digests_unique.txt keep_digests_unique.txt | uniq -u > delete_digests.txt
  2. Удалить ненужные дайджесты
for digest in $(cat delete_digests.txt); do
  crane delete $digest;
done
  1. Запустить в Nexus таску для удаления “осиротевших” тегов (Docker - Delete unused manifests)
  2. Запустить compact соответствующего blobstore (Admin - Compact blob store)

Варианты запуска сборок

  1. Shell executor

    • Небезопасно, т.к. можно выполнять какие угодно docker команды на хосте, в т.ч. пробрасывать хостовые папки и запускать privileged контейнеры
  2. docker-in-docker

    • Изолированные друг от друга контейнеры, т.к. здесь child контейнеры от контейнера dind, а не от хостового docker.sock
    • Необходим запуск с privileged (небезопасно)
  3. Проброс docker.sock

    • Все контейнеры - siblings (видят друг друга), т.к. запускается через хостовый docker
    • Небезопасно, т.к. можно выполнять какие угодно docker команды на хосте, в т.ч. пробрасывать хостовые папки и запускать privileged контейнеры
  4. buildah/buildkit/img

    • Позволяют внутри докер контейнера запускать сборку образа без докер-демона
    • Требуется unprivileged_userns_clone (user namespaces), у которого свои security-риски
    • Синтаксис запуска отличается -> переучивать команду
  5. kaniko

    • Позволяют внутри докер контейнера запускать сборку образа без докер-демона
    • Не поддерживается установка бинарника в свой образ. Необходимо использовать официальный образ
    • Синтаксис запуска отличается -> переучивать команду

Потенциальные векторы атаки

  1. Источник

    • В сборке используется публичный образ, в котором в entrypoint выполняется команда проверки docker.sock и запуск контейнера через него
    • При сборке в зависимостях (напрмер, node) скачивается зловред, который запускается в процессе сборки. Далее проверка docker.sock и запуск контейнера через него
  2. Цель

    • Закрепиться в системе. Через докер возможно установить свои бинарники и сервисы в систему
    • Дальнейший скан сети и поиск уязвимостей для распространения и закрепления