PunchMorning recap: Again, Nigerians lose savings to Ponzi scheme, Dangote refinery raises petrol gantry price, other top storiesESPN Deportes49ers extienden contrato de Shanahan, fuentesוואלהדיווח: ארה"ב תגביל את חלונות הזמן להגנה אווירית על מכליות במצר הורמוזESPNBen Shelton's shot at history comes Sunday in the US Open finalInquirerRidon to Sara Duterte: Attend Monday’s Senate impeachment trialХабрВы узнаете о клике через девять дней, и не от того, кто кликнулSözcüAmasya’da motosiklet bariyerlere çarptı: 18 yaşındaki sürücü hayatını kaybettiRapplerNew rules, new season: What to know about UAAP 2026-2027Cumhuriyetİzmir'in en uç noktasında saklanan el değmemiş cennet! Nergis kokulu sokakları ve turkuaz koyları ile Karaburun...InteriaPolski oficer w pojedynkę zatrzymał Niemców. Generał oddał mu własny orderLa NaciónUn geriátrico en Chile sufrió un incendio: hay al menos 16 muertos20 MinutenEinbrecher in der Villa – Thierry nimmt die Verfolgung auf
The Daily Newsstand · Free, Always
Saturday, September 12, 2026

Реестр контейнеров, который живёт внутри ячеек электронной таблицы

Translate

Привет, Хабр! Значю, что вам на это плевать и вы не хотите это читать, но я все равно продолжу это писать:) В общем, Sheet-Native Computing Foundation продолжает цвести и пахнуть и у нас даже есть сторонние контрибьюторы. А чего добились вы?

Итак, вот что теперь можно сделать в таблице: запушить в неё настоящий OCI-образ контейнера и вытянуть его обратно. Не ссылку на образ, не метаданные о нём — сами слои, хранящиеся как base64 по ячейкам, с адресацией по sha256, собирающиеся байт-в-байт на выходе. У SheetHub — нашего форжа в стиле GitLab, который работает на Google-таблице — появился реестр контейнеров, и он целиком живёт в ячейках.

Этот пост — про то, как это всё устроено.

Впервые тут? SheetHub — DevOps-форж (репозитории, issues, merge requests, релизы), который хранит всё во вкладках Google-таблицы. Это часть Sheet-Native Computing Foundation (SNCF) — работающей пародии на CNCF, где весь стек живёт в таблицах: оркестратор (Sheeternetes), формат образов (SICF), сертификация, живые демо. sncfoundation.github.io · github.com/sncfoundation

Что это

Реестр контейнеров, если говорить проще, — это content-addressed хранилище блобов плюс немного метаданных: слои образа под ключом их sha256-дайджеста и манифест, который говорит, из каких слоёв собран какой образ. Docker Hub держит эти блобы в объектном хранилище. Этот реестр держит их в ячейках таблицы.

Работу выполняют две вкладки:

  • Registry — по строке на образ: repo, name, tag, digest, размер, число чанков, кто запушил, таймстемпы. Метаданные.

  • RegistryChunks — сами байты слоёв. Каждый слой кодируется в base64 и режется на куски по ≤30 000 символов, по одному на ячейку, и в каждой строке — дайджест слоя и индекс чанка.

Зачем резать? Потому что у ячейки таблицы жёсткий лимит на символы — 32 767 в Excel, 50 000 в Google Sheets — а настоящий слой куда больше, чем влезает в одну ячейку. Поэтому слой шардится по подряд идущим ячейкам и сшивается обратно на чтении. Дайджест считается по собранным байтам, так что одна битая ячейка проваливает проверку sha256, а не молча отдаёт вам сломанный образ.

Вот и весь фокус — тот же принцип, что в OCI (адресация по sha256), просто с максимально неуместным носителем.

Видно байты

Больше всего мне нравится, что хранилище не спрятано. Любой реестр — это просто ячейки, которые можно открыть и посмотреть, и UI на это опирается. Нажимаешь Inspect Shard Map на любом образе — и видишь, в каких именно ячейках лежит слой:

Разбор шардов: этот слой лежит в ячейках D2 и D3 вкладки RegistryChunks

Разбор шардов: этот слой лежит в ячейках D2 и D3 вкладки RegistryChunks

Это traefik/whoami — настоящий образ — лежит в ячейках D2 и D3 вкладки RegistryChunks, 49 152 байта в двух чанках, каждый с запасом под лимитом ячейки, у каждого показан base64-preview. Между «реестром» и «таблицей» нет никакой абстракции. Реестр и есть таблица, и можно ткнуть пальцем в ячейку, где живут байты.

Push и pull

Ведёт себя так, как и должен реестр. Есть CLI:

sheethub registry push  sncf/hello-web  traefik/whoami:latest  layer.tar
sheethub registry pull  sncf/hello-web  traefik/whoami:latest  out.tar
sheethub registry view  sncf/hello-web  traefik/whoami:latest
sheethub registry list  sncf/hello-web

push кодирует слой в base64, считает его sha256, шардит по ячейкам и пишет строку манифеста. pull читает чанки обратно по порядку, склеивает, пересчитывает дайджест и проверяет его, декодирует бинарный слой. Дайджест авторитетный и считается на сервере, так что положить контент под несовпадающий digest нельзя. Та же гарантия, что даёт настоящий реестр, обеспеченная тем же хешем.

А поскольку всё хранилище — одна таблица, это по-настоящему air-gapped, self-hosted реестр: ни объектного хранилища, ни Harbor, ни внешнего сервиса. Одна таблица — и форж, и хранилище образов. Для маленьких образов, для которых это реально годится (статические бинарники, scratch/alpine, WASM-модули), — это настоящее свойство, а не просто панчлайн.

Пределы и ограничения

Пропустить их было бы нечестно (ну вы же знаете, клоды и чатыГПТ всегда трут за честность в сгенерированных ими текстах, пришлось идти у них на поводу и оставить здесь только свой искрометный остроумный комментарий, чтобы показать все, что я не просто генерирую эти тексты, а еще и читаю их перед публикацией), и мы уже провели для них нагрузочное тестирование: реестр на таблице — для маленьких образов. Лимит ячейки вынуждает шардинг; потолок в 10 млн ячеек на книгу и квота записи Sheets API (~60 запросов/мин на пользователя) ограничивают, сколько и как быстро можно пушить. Образ в пару сотен мегабайт технически влезает, но делает файл тяжёлым, а пуши медленными. Это реестр для того, что должно жить в ячейках, а не замена Docker Hub — и он это понимает.

Ещё приятная деталь, которую мы проверили по ходу: чанк base64 может законно начинаться с +, а таблица попыталась бы прочитать это как формулу. Реестр экранирует такие ячейки, чтобы таблица их не исполняла, и экранирование собирается обратно байт-в-байт — так что sha256 сходится. Content addressing держит в честности всех, включая слой хранения.

Куда это вписывается

Картинка крупнее: SNCF уже хранит образы в ячейках через SICF (наш Sheet-Native Image Container Format), и Sheeternetes умеет шедулить и запускать sicf:-образ прямо из таблицы. Этот реестр — «парадная дверь» форжа к той же идее: пушишь через SheetHub, а в планах — сделать эти образы доступными для sheetbuild и рантайма Sheeternetes напрямую, чтобы форж и кластер делили одно хранилище образов в таблице. Это выравнивание — следующий шаг.

SheetHub, форж, с новой вкладкой Container Registry

SheetHub, форж, с новой вкладкой Container Registry

Реестр приехал как внешний вклад от prateeekbuilds (который реализовал и сам SheetHub, существоваший до этого только в виде дизайн пропозала в ишьюсах) — он и правда постарался, провел 50+ тестов и всё такое. Спасибо. Не знаю, на кой пёс это ему сдалось и понимает ли что его вклад с Sheet-Native хоть и неоценим с точки зрения истории человечества, вряд ли будет оценен будущими работодателями. Но кто мы такие, чтобы его осуждать.

История SheetHub

История SheetHub

Не запускайте продовый реестр на таблице. Но откройте карту шардов — это самый наглядный взгляд на content-addressed storage, какой можно получить, потому что можно ткнуть пальцем в ячейку.

Присоединяйтесь

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.