Тест на вакансию

Установка, настройка и работа с Tarantool в Docker-контейнере

3 июня 2026 г.
167

Tarantool 2.x

Создадим кластер из двух master-хранилищ.
services:
  tarantool-storage-1:
    image: tarantool/tarantool:2.11
    container_name: tarantool-storage-1
    ports:
      - "3301:3301"
    volumes:
      - ./init.lua:/opt/tarantool/init.lua
    command: tarantool /opt/tarantool/init.lua
    networks:
      - tarantool-net
  tarantool-storage-2:
    image: tarantool/tarantool:2.11
    container_name: tarantool-storage-2
    ports:
      - "3302:3301"
    volumes:
      - ./init.lua:/opt/tarantool/init.lua
    command: tarantool /opt/tarantool/init.lua
    networks:
      - tarantool-net
networks:
  tarantool-net:
    driver: bridge

Создадим файл init.lua:
box.cfg({
    listen = '0.0.0.0:3301',
    replication = {
        'tarantool-storage-1:3301',
        'tarantool-storage-2:3301'
    },
    read_only = false,
    memtx_memory = 128 * 1024 * 1024,
    log_level = 5
})

Запуск контейнеров:
docker-compose up -d

Подключение к первому узлу:
docker exec -it tarantool-storage-1 tarantoolctl connect localhost:3301

Создаем тестовое пространство:
box.schema.space.create('test', {if_not_exists=true})
box.space.test:format({
    {name='id', type='unsigned'},
    {name='data', type='string'}
})
box.space.test:create_index('primary', {parts={1}})

Проверяем статус репликации:
box.info.status
box.info.replication

Затем на втором узле:
docker exec -it tarantool-storage-2 tarantoolctl connect admin:localhost:3301

И тоже проверяем статус репликации:
box.info.status
box.info.replication

Проверка master-master

На первом узле:
box.space.test:insert{1, 'Hello from master-1'}

На втором узле. Должны увидеть данные с первого узла:
box.space.test:select{}
box.space.test:insert{2, 'Hello from master-2'}

Снова на первом узле. Должны увидеть оба сообщения:
box.space.test:select{}
 

Tarantool 3.x

Теперь создадим кластер из двух master-хранилищ только под версию 3.x:
services:
  tarantool-storage-1:
    image: tarantool/tarantool:latest
    container_name: tarantool-storage-1
    environment:
      TT_INSTANCE_NAME: tarantool-storage-1
      TT_CLUSTER_COOKIE: my-secret-cookie
      TT_CONFIG: /config/cluster.yaml
    ports:
      - "3301:3301"
    volumes:
      - ./init.lua:/opt/tarantool/init.lua
      - ./config:/config
      - tarantool-data-1:/var/lib/tarantool
    command: tarantool /opt/tarantool/init.lua
    networks:
      - tarantool-net
  tarantool-storage-2:
    image: tarantool/tarantool:latest
    container_name: tarantool-storage-2
    environment:
      TT_INSTANCE_NAME: tarantool-storage-2
      TT_CLUSTER_COOKIE: my-secret-cookie
      TT_CONFIG: /config/cluster.yaml
    ports:
      - "3302:3301"
    volumes:
      - ./init.lua:/opt/tarantool/init.lua
      - ./config:/config
      - tarantool-data-2:/var/lib/tarantool
    command: tarantool /opt/tarantool/init.lua
    networks:
      - tarantool-net
    depends_on:
      - tarantool-storage-1
networks:
  tarantool-net:
    driver: bridge
volumes:
  tarantool-data-1:
  tarantool-data-2:

Создадим файл init.lua:
box.cfg()
if box.space.test == nil then
    box.schema.space.create('test', { if_not_exists = true })
    box.space.test:format({{name='id',type='unsigned'},{name='data',type='string'}})
    box.space.test:create_index('primary',{parts={'id'}, if_not_exists=true})
  
    pcall(box.space.test.insert, box.space.test, {1, 'Initial data'})
end
require('console').start()
Здесь происходит сразу заполнение данными. А также безопасная вставка: если узел получит эту запись по репликации от соседа, он не упадет с ошибкой "Duplicate key".

Создадим файл конфигурации (config/cluster.yaml):
credentials:
  users:
    guest:
      roles:
        - super
groups:
  my-group:
    replicasets:
      my-replicaset:
        instances:
          tarantool-storage-1:
            database:
              mode: rw  # Первый мастер
            iproto:
              listen:
                - uri: '0.0.0.0:3301'
              advertise:
                peer:
                  uri: 'tarantool-storage-1:3301'
                  login: 'guest'
                 
          tarantool-storage-2:
            database:
              mode: rw  # Второй мастер
            iproto:
              listen:
                - uri: '0.0.0.0:3301'
              advertise:
                peer:
                  uri: 'tarantool-storage-2:3301'
                  login: 'guest'

Запуск контейнеров:
docker-compose up -d

Подключение к первому узлу:
docker exec -it tarantool-storage-1 tt connect localhost:3301

Проверяем статус:
box.info.status

Вставляем данные:
box.space.test:insert{2, 'Hello from master-1'}

Проверяем:
box.space.test:select()

Аналогично подключаемcя ко второму узлу:
docker exec -it tarantool-storage-2 tt connect localhost:3301

Проверяем:
box.space.test:select()

Видим два сообщения. Добавляем сообщение со второго узла:
box.space.test:insert{3, 'Hello from master-2'}

Теперь на первом узле можно увидеть три сообщения.

Итого

Мы создали два рабочих кластера Tarantool в Docker: на версии 2.11 и на актуальной 3.x. Оба используют конфигурацию master-master, где любой узел принимает запросы на запись, а данные автоматически синхронизируются.
 

Как это работает:

  • Tarantool 2.11: файл init.lua содержит и конфигурацию (box.cfg), и создание пространства. Всё в одном месте.
  • Tarantool 3.x: конфигурация вынесена в отдельный файл cluster.yaml (порты, режим read_only, репликация), а init.lua отвечает только за создание пространства и начальных данных. Такой подход чище разделяет ответственность.
Поделиться: