Запуск нескольких Sphinx search на одном сервере

Запуск нескольких Sphinx search на одном сервере

У нас часто возникает необходимость настроить поиск через Sphinx для нескольких проектов на одном сервере. Изначально мы просто давали разные имена источникам и индексам. Минусы такого подхода очевидны: мы не могли использовать разные версии sphinx’а, обновлять подобный конфиг было довольно неудобно. Позже мы просто собирали несколько версий с разными prefix’ами и запускали демоны с разными конфигами. Тут вроде бы все заметно лучше, но появляется много рутины со сборкой пакетов, в конфигах нужно прописывать разные пути к логам, индексам и pid-файлам. И появилась идея запускать сам Sphinx внутри docker контейнеров, а управлять этим всем добром централизованно с помощью puppet’а.

Кратко рассмотрим установку puppet

Запуск нескольких Sphinx search на одном сервере

Установка puppet master:

puppetmaster # wget https://apt.puppetlabs.com/puppetlabs-release-wheezy.deb -O /tmp/puppet.deb && dpkg -i /tmp/puppet.deb && rm /tmp/puppet.deb
puppetmaster # apt-get update && apt-get install puppetmaster

Установка мастера под высокие нагрузки (для большого количества нод) описана в официальной документации.

Установка puppet на ноду:

puppetnode # wget https://apt.puppetlabs.com/puppetlabs-release-wheezy.deb -O /tmp/puppet.deb && dpkg -i /tmp/puppet.deb && rm /tmp/puppet.deb
puppetnode # apt-get update && apt-get install puppet

Теперь поправим конфиг /etc/puppet/puppet.conf:

[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
templatedir=$confdir/templates
server=puppetmaster
runinterval=120

В server нужно прописать хост вашего puppet master.

Теперь нужно запустить:

puppetnode # puppet agent -t --waitforcert 30
 
Info: Creating a new SSL key for puppetnode
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for puppetnode
Info: Certificate Request fingerprint (SHA256): 67:F6:47:58:05:01:31:51:A4:61:AA:5D:2D:89:00:1F:CF:58:14:AB:27:22:5F:79:1A:64:4F:6B:D4:AD:E0:5E
Info: Caching certificate for ca

Идем на мастер и сравниваем fingerprint:

puppetmaster # puppet cert --list
"puppetnode" (SHA256) 67:F6:47:58:05:01:31:51:A4:61:AA:5D:2D:89:00:1F:CF:58:14:AB:27:22:5F:79:1A:64:4F:6B:D4:AD:E0:5E

Теперь подписываем сертификат клиента:

puppetmaster # puppet cert --sign puppetnode
Notice: Signed certificate request for puppetnode
Notice: Removing file Puppet::SSL::CertificateRequest puppetnode at '/var/lib/puppet/ssl/ca/requests/puppetnode.pem'

Добавим в /etc/puppet/manifests/site.pp конфигурацию ноды:

node 'puppetnode' {
  file { "/tmp/just-test.txt":
    ensure => "present",
    mode   => "700" 
  }
}

Запустим puppet на ноде:

puppetnode # puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetnode
Info: Applying configuration version '1421320391'
Notice: /Stage[main]/Main/Node[puppetnode]/File[/tmp/just-test.txt]/ensure: created
Notice: Finished catalog run in 0.06 seconds

Теперь на ноде должен появится файл /tmp/just-test.txt:

puppetnode # ls -l /tmp/just-test.txt
-rwx------ 1 root root 0 Jan 15 11:13 /tmp/just-test.txt

На этом с конфигурацией puppet'а у нас все готово.

Установка docker на Debian Wheezy

Запуск нескольких Sphinx search на одном сервере

Для того, чтобы запустить docker на Wheezy, нужно поставить ядро с backports. Давайте напишем для этого модуль на puppet. Для начала нам нужно добавить репозиторий с backports. Установим модуль, который позволяет добавлять репозитории в apt-системах:

puppetmaster # puppet module install puppetlabs-apt

Также нам потребуется модуль stdlib:

puppetmaster # puppet-module install puppetlabs/stdlib

Создадим иерархию директорий для нашего модуля:

puppetmaster # mkdir -p /etc/puppet/modules/install-docker-wheezy/{files,manifests,templates}

Или вы можете использовать команду puppet module generate имя для автоматической генерации иерархии.

Создадим класс для установки в /etc/puppet/modules/install-docker-wheezy/manifests/init.pp:

class install-docker-wheezy  ($docker_version="1.3.0"){
 
  apt::source { "deb-backports":
    location        => "https://http.debian.net/debian",
    release         => "wheezy-backports",
    repos           => "main",
  }
 
  package { 'linux-image-3.16.0-0.bpo.4-amd64':
    ensure  => installed,
    require => Apt::Source["deb-backports"]
  }
 
  exec { "download-docker":
    command => "/usr/bin/wget https://get.docker.com/builds/Linux/x86_64/docker-${docker_version} -O /usr/local/bin/docker",
    unless  => "/usr/bin/test -f /usr/local/bin/docker",
  }
 
  exec { "make-docker-exec":
    command => "/bin/chmod a+x /usr/local/bin/docker",
    unless  => "/usr/bin/test -x /usr/local/bin/docker",
    require => Exec["download-docker"]
  }
 
  file { "/etc/rc.local":
    ensure => present
  }->
  file_line { "docker-start":
    path  => '/etc/rc.local',
    line  => '/usr/local/bin/docker -d & exit 0',
    match => "^.*exit 0$",
  }
 
  file { "/usr/bin/docker.io":
    ensure  => 'link',
    target  => '/usr/local/bin/docker',
    require => Exec["download-docker"]
  }
 
  file { "/cgroup":
    ensure => "directory" 
  }
 
  mount { "/cgroup":
    device  => "cgroup",
    fstype  => "cgroup",
    ensure  => "mounted",
    options => "defaults",
    atboot  => "true",
    require => File["/cgroup"]
  }
}

И подключим его в конфигурацию ноды /etc/puppet/manifests/site.pp:

node 'puppetnode' {
  file { '/tmp/just-test.txt':
    ensure => 'present',
    mode   => '0700'
  }
 
  include install-docker-wheezy
}

После этого необходимо прогнать конфигурацию на ноде:

puppetnode # puppet agent -t
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for puppetnode
Info: Applying configuration version '1421403992'
Notice: /Stage[main]/Install-docker-wheezy/File_line[docker-start]/ensure: created
Notice: /Stage[main]/Install-docker-wheezy/Apt::Source[deb-backports]/File[deb-backports.list]/ensure: created
Info: /Stage[main]/Install-docker-wheezy/Apt::Source[deb-backports]/File[deb-backports.list]: Scheduling refresh of Exec[apt_update]
Notice: /Stage[main]/Apt::Update/Exec[apt_update]: Triggered 'refresh' from 1 events
Notice: /Stage[main]/Install-docker-wheezy/File[/cgroup]/ensure: created
Notice: /Stage[main]/Install-docker-wheezy/Mount[/cgroup]/ensure: defined 'ensure' as 'mounted'
Info: Computing checksum on file /etc/fstab
Info: /Stage[main]/Install-docker-wheezy/Mount[/cgroup]: Scheduling refresh of Mount[/cgroup]
Info: Mount[/cgroup](provider=parsed): Remounting
Notice: /Stage[main]/Install-docker-wheezy/Mount[/cgroup]: Triggered 'refresh' from 1 events
Info: /Stage[main]/Install-docker-wheezy/Mount[/cgroup]: Scheduling refresh of Mount[/cgroup]
Notice: /Stage[main]/Install-docker-wheezy/Exec[download-docker]/returns: executed successfully
Notice: /Stage[main]/Install-docker-wheezy/Exec[make-docker-exec]/returns: executed successfully
Notice: /Stage[main]/Install-docker-wheezy/Package[linux-image-3.16.0-0.bpo.4-amd64]/ensure: ensure changed 'purged' to 'present'
Notice: Finished catalog run in 234.61 seconds

Теперь нам нужно перезагрузить сервер, чтобы загрузилось новое ядро. После этого docker можно использовать.

Разворачиваем Sphinx search в контейнерах docker

Данный модуль мы выложили на Puppet Forge, для его установки достаточно выполнить:

puppetmaster # puppet module install stfalcon-sphinxsearchdocker

Подключить модуль можно, добавив его в конфигурацию ноды /etc/puppet/manifests/site.pp):

node 'puppetnode' {
  file { '/tmp/just-test.txt':
    ensure => 'present',
    mode   => '0700'
  }
 
  include install-docker-wheezy
  include sphinxsearchdocker
}

Также вы можете задать свой image, который выложен на hub.docker.com:

node 'puppetnode' {
  file { '/tmp/just-test.txt':
    ensure => 'present',
    mode   => '0700'
  }
 
  include install-docker-wheezy
 
  class { 'sphinxsearchdocker':
    docker_image_sphinx => 'someuser/sphinx'
  }
}

Теперь для запуска sphinx'а нужно только загрузить конфиг и объявить ресурс.

puppetmaster # mkdir -p /etc/puppet/modules/some-server-config/{files,manifests,templates}
 
/etc/puppet/modules/some-server-config/manifests/init.pp:
class some-server-conf {
  file { '/etc/docker-sphinx/coolsite-sphinx.conf':
    ensure => 'file',
    source  => "puppet:///modules/some-server-conf/coolsite.conf" 
  }
 
  sphinxsearchdocker::sphinxsearch { 'coolsite':
    sphinx_container_name => 'coolsite',
    sphinx_container_port => '3312',
    require               => File['/etc/docker-sphinx/coolsite-sphinx.conf']
  }
}

И подключить модуль к ноде /etc/puppet/manifests/site.pp.

После применения конфигурации на сервере мы получим запущенный контейнер docker с sphinx'ом:

puppetnode # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a85d848b1c6e jekakm/sphinx:latest "/usr/local/bin/run. 11 minutes ago Up 11 minutes 127.0.0.1:3312->3312/tcp sphinx-coolsite

Выполнить ротацию индексов можно командой:

puppetnode # docker exec sphinx-coolsite indexer --config /etc/sphinxsearch/sphinx.conf --rotate --all

Теперь есть смысл добавить эту команду в крон, это также можно сделать через puppet. Давайте добавим в класс some-server-conf еще один ресурс:

cron { 'rotate-sphinx-coolsite':
  command => '/usr/local/bin/docker exec sphinx-coolsite indexer --config /etc/sphinxsearch/sphinx.conf --rotate --all',
  user    => 'root',
  hour    => '*',
  minute  => '05'
}

После обновления конфигурации на ноде появиться новая cron-задача.

На этом все, теперь у нас есть инструмент, который позволяет достаточно быстро развернуть sphinx в нескольких экземплярах на произвольном количестве серверов.