В прошлых уроках мы поставили инстанс и научили его подниматься. Теперь нужно с ним поговорить. У Tarantool есть несколько каналов связи с живым процессом, и они принципиально разные по протоколу, правам и назначению. Разобравшись в их механике, вы перестанете путать "почему здесь admin без пароля, а там guest и access denied".
Три способа подключиться:
- Интерактивная консоль tt - обёртка от утилиты tt, которой вы пользуетесь чаще всего.
- Admin-сокет (console socket) - текстовый административный канал, Unix-сокет, пользователь всегда admin.
- net.box - программный клиент по бинарному протоколу iproto, тот же канал, что использует приложение.
У работающего инстанса есть два разных слушающих интерфейса, и это ключ ко всему уроку.
Бинарный порт (iproto). Задаётся через iproto.listen (в 3.x) или box.cfg{listen=...} (классика). По нему общаются драйверы, репликация и net.box. Протокол двоичный, на базе MessagePack, называется iproto. Подключение требует аутентификации: если логин/пароль не передали, вы входите как guest - пользователь с минимальными правами. Поэтому "голый" net.box к чужому инстансу часто упирается в access denied: guest по умолчанию почти ничего не может.
Admin-сокет (console). Это отдельный канал. Утилита tt при старте инстанса автоматически создаёт Unix-сокет в рабочем каталоге (обычно var/run/<инстанс>/tarantool.control). По нему работает текстовый протокол: вы шлёте строку Lua, сервер скармливает её встроенному интерпретатору и возвращает результат в YAML. Здесь нет аутентификации по паролю - сам факт доступа к файлу-сокету и есть авторизация (доступ к нему регулируется правами ОС на файл). Поэтому текущий пользователь в admin-консоли всегда admin со всеми правами. Это локальный канал для оператора, не для приложений.
Что делает tt connect. Команда умеет оба режима и выбирает его по аргументу:
- Передали имя инстанса (create_db:instance001) - tt идёт через локальный admin-сокет. Аутентификация не нужна, вы admin.
- Передали URI (127.0.0.1:3301 или user:pass@host:port) - tt открывает удалённое соединение по бинарному порту (фактически net.box внутри). Без креденшелов вы guest, со связкой user:pass - указанный пользователь.

Три канала к инстансу: tt, admin-сокет, net.box
Первые команды
Поднимаем инстанс из прошлого урока и проверяем статус:
Код: Выделить всё
$ tt start create_db
$ tt status create_db
INSTANCE STATUS PID MODE CONFIG BOX UPSTREAM
create_db:instance001 RUNNING 8685 RW ready running --
Код: Выделить всё
$ tt connect create_db:instance001
• Connecting to the instance...
• Connected to create_db:instance001
create_db:instance001>
Код: Выделить всё
create_db:instance001> box.info.ro
---
- false
...
create_db:instance001> 2 + 2
---
- 4
...
Код: Выделить всё
box.session.user() -- 'admin'
box.schema.space.create('bands')
box.space.bands:format({
{ name = 'id', type = 'unsigned' },
{ name = 'band_name', type = 'string' },
{ name = 'year', type = 'unsigned' }
})
box.space.bands:create_index('primary', { parts = { 'id' } })
box.space.bands:insert{ 1, 'Roxette', 1986 }
box.space.bands:select{ 1 }
Подключение по URI (бинарный порт). Та же утилита, но уже net.box-канал и guest:
Код: Выделить всё
$ tt connect 127.0.0.1:3301
Код: Выделить всё
-- выполнить ОДИН раз в admin-консоли
box.schema.user.grant('guest', 'execute', 'universe', nil, { if_not_exists = true })
Код: Выделить всё
local netbox = require('net.box')
local conn = netbox.connect('127.0.0.1:3301')
conn:ping() -- true
conn.space.bands:select{ 1 } -- удалённый select
conn:call('box.info') -- вызов функции на той стороне
conn:eval('return 2 + 2') -- выполнить Lua удалённо (нужно право execute)
conn:close()
Частые заблуждения и грабли
"tt connect всегда даёт права админа." Нет. Права админа вы получаете только по admin-сокету (подключение по имени инстанса). По URI вы guest, пока не указали пользователя.
- access denied у guest. Сообщение вида "Execute access denied for user 'guest'" или "Read access denied" означает, что вы зашли по бинарному порту без прав. Решение для учёбы - grant guest; для прода - заведите отдельного пользователя с точечными правами.
- Admin-сокет - это не сетевой порт. Это файл на диске. Удалённо по нему не подключиться: нужен либо доступ к файловой системе хоста, либо проброс. Не путайте его с iproto.listen.
- Опасность grant execute на universe. Это фактически удалённое исполнение произвольного Lua кем угодно, кто достучался до порта. Годится только для локальной песочницы.
- Ctrl+C против Ctrl+D. В консоли Ctrl+D (или \q) закрывает клиента. Инстанс продолжает работать. Остановить его - отдельной командой tt stop.
- Переключение языка. В консоли можно переключиться на SQL командой \set language sql и обратно \set language lua. По умолчанию активен Lua.
- Текстовый YAML-вывод - только для людей. Не парсите его из скриптов; для программного доступа есть net.box с нативными Lua-значениями.
- Запустите create_db и зайдите через admin-сокет по имени. Выполните box.session.user() и убедитесь, что вы admin.
- Создайте спейс bands со схемой и primary-индексом, вставьте пару кортежей.
- Выдайте guest право execute на universe. Откройте net.box-соединение к 127.0.0.1:3301, сделайте conn:ping() и удалённый select из bands.
- Сравните: какой пользователь активен в admin-консоли и какой - при подключении по URI без креденшелов?
- Чем admin-сокет отличается от бинарного порта по протоколу, по транспорту и по аутентификации?
- Почему tt connect create_db:instance001 даёт права admin, а tt connect 127.0.0.1:3301 - права guest?
- Что технически происходит при conn.space.bands:select{1} в net.box: это локальный или сетевой вызов?
- Почему grant 'guest','execute','universe' удобно в песочнице, но недопустимо в проде?