email

Tagged ,

MongoDB replica и Azure

Как-то понадобилось использовать в качестве бэкап-реплики инстанс на microsoft azure. Остальная часть кластера находится на другой площадке. Опыт подсказывал, что никаких подводны камней тут быть не может. Однако нет. Репликация успешно стартовала, но через часов 6 соединение пропадало.

Mon Apr  1 06:10:12.909 [rsSync]   Fatal Assertion 16233
0xdc7f71 0xd87cf3 0xbff47f 0xc1b101 0xc1bf1d 0xc1c1ec 0xe10879 0x7f569eeb1e9a 0x7f569e1c4cbd
 /usr/bin/mongod(_ZN5mongo15printStackTraceERSo+0x21) [0xdc7f71]
 /usr/bin/mongod(_ZN5mongo13fassertFailedEi+0xa3) [0xd87cf3]
 /usr/bin/mongod(_ZN5mongo11ReplSetImpl17syncDoInitialSyncEv+0x6f) [0xbff47f]
 /usr/bin/mongod(_ZN5mongo11ReplSetImpl11_syncThreadEv+0x71) [0xc1b101]
 /usr/bin/mongod(_ZN5mongo11ReplSetImpl10syncThreadEv+0x2d) [0xc1bf1d]
 /usr/bin/mongod(_ZN5mongo15startSyncThreadEv+0x6c) [0xc1c1ec]
 /usr/bin/mongod() [0xe10879]
 /lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a) [0x7f569eeb1e9a]
 /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x7f569e1c4cbd]
Mon Apr  1 06:10:12.919 [rsSync]

***aborting after fassert() failure

Mon Apr  1 06:10:12.919 Got signal: 6 (Aborted).

Mon Apr  1 06:10:12.923 Backtrace:
0xdc7f71 0x6ce459 0x7f569e1074a0 0x7f569e107425 0x7f569e10ab8b 0xd87d2e 0xbff47f 0xc1b101 0xc1bf1d 0xc1c1ec 0xe10879 0x7f569eeb1e9a 0x7f569e1c4cbd
 /usr/bin/mongod(_ZN5mongo15printStackTraceERSo+0x21) [0xdc7f71]
 /usr/bin/mongod(_ZN5mongo10abruptQuitEi+0x399) [0x6ce459]
 /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7f569e1074a0]
 /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x7f569e107425]
 /lib/x86_64-linux-gnu/libc.so.6(abort+0x17b) [0x7f569e10ab8b]
 /usr/bin/mongod(_ZN5mongo13fassertFailedEi+0xde) [0xd87d2e]
 /usr/bin/mongod(_ZN5mongo11ReplSetImpl17syncDoInitialSyncEv+0x6f) [0xbff47f]
 /usr/bin/mongod(_ZN5mongo11ReplSetImpl11_syncThreadEv+0x71) [0xc1b101]
 /usr/bin/mongod(_ZN5mongo11ReplSetImpl10syncThreadEv+0x2d) [0xc1bf1d]
 /usr/bin/mongod(_ZN5mongo15startSyncThreadEv+0x6c) [0xc1c1ec]
 /usr/bin/mongod() [0xe10879]
 /lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a) [0x7f569eeb1e9a]

После переписки с разработчиками  mongodb и серии экспериментов выяснилось, что проблема в сетевой структуре Azure. После большой нагрузки на сеть неактивные соединения просто дропаются.

Чтобы этого избежать достаточно изменить значения, влияющие на активность поддержания keepalive соединения:

echo 5 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 5 > /proc/sys/net/ipv4/tcp_keepalive_time

Сделать это нужно на строне реплики.

Tagged ,

nginx html return

Nginx -  замечательный веб-сервер. Очень быстрый и гибкий.

И есть у него замечательная директива - return.

в большинстве случаев она используется для возврата стандартного кода ответа клиенту. Например 403

location /topsecrets {
    return 403;
}

Если вы обратитесь к /topsecrets, то получите стандартную страничку с 403 ошибкой.

Вроде бы ничего необычного. Но с какой-то версии nginx у директивы return появился второй аргумент, которым может быть текст или url.

Url нас не очень интересует, а вот возможность вернуть текст в теле ответа очень интересна и полезна. Попробуем что-то получить.

location /note {
       return 200 "Hello world";
}

Обращаемся к note... и скачиваем текстовый файл "note" c текстом "Hello world" :).

Все правильно, стандартный тип данных в хедере nginx не является текстовым:

curl -I 127.0.0.1/note
HTTP/1.1 200 OK
Server: nginx/1.0.3
Content-Type: application/octet-stream

Просто добавим нужный хедер

location /note {
    add_header Content-Type: text/html;
    return 200 "Hello world ";
}

И увидим заветные строчки в уже в браузере. Теперь можно писать простые сообщения не используя ничего, кроме nginx!

Но это еще не все. Почему просто текст? Ведь можно использовать HTML и отдавать простые странички прямо из nginx. А если вспомнить про встроенные переменные, то получается рецепт простой заглушки для "не привелигированных"  IP:

server {
        error_page 403 = @forbidden;
        location /topsecret  {
                allow  127.0.0.1/32;
                deny all;
        }

        location @forbidden {
        default_type text/html;
        return 403 "<html> <center/><div><h1>Доступ Запрещен</h1> <h3>Ваш IP-адрес:<b> $remote_addr<b> </h3></div></center></html>";
        }
}

Конфиги ядер ubuntu

Иногда нужно знать текущий конфиг ядра (kernel).

В ubuntu конфиги ядер лежат

'/boot/config-version'

Конфиги всех ядер для для всех версий ubuntu можно посмотреть здесь

http://kernel.ubuntu.com/~kernel-ppa/configs/

Знакомимся с Salt.

Введение

image

Software Configuration Management - очень интересная и полезная тема, к которой должен придти каждый вменяемый системный администратор. ПО SCM позволяет получать одинаковый воспроизводимый результат на большим количестве машин с разным окружением за короткое время. Кроме того, использование SCM позволяет более четко понимать архитектуру разворачиваемой системы, а описание при помощи “рецептов” или “состояний” больше похоже на проектирование, нежели на настройку. Управлением конфигурациями пришло из производства, где конфиугурацией было сочетание состава деталей и их взаимного расположение.

Сегодня выбор ПО для SCM довольно широкий, в статье же речь пойдет о такой обойденной вниманием харба новике , да и вообще малоизвестной в рунете системе как Salt.

Описание

Простота

Независимо от размера вашего проекта развернуть и настроить Salt просто - используется простая клиент-серверная модель топологии. Salt может быть установлен даже на RaspberryPi, а также в masterless standalone режиме.

Параллельное выполнение команд

Базовой фичей Salt является параллельное выполненение там, где только это возомжно.

Построен на провернных технологиях

Сетевой уровень в Salt построен на замечательной библиотеке ZeroMQ.
Для аутентификации используется клиентов на сервере использвуются публичные ключи, AES шифрование для защиты канала передачи данных.

Интерфейс python

Salt написан на Python и легко расширеяем модулями. Процедуры могут быть написаны как обычные модули Python. Salt может быть вызван с помощью простого Python API или из командной строки для выполнениия одноразовых комнад или использован как часть более крупного приложения.

Быстрота, Гибкость, Расширяемость

Salt может выполнять комманды применительно к группам различный размеров на огромной скорости.Система очень быстра, легко настраивается, легко расширятся модулями и функциями.

Открытость

Salt распостраняется под лицензией Apache 2.0 и может быть использован как лоя открытых, так и для проприетарных проектов.

Установка

Salt пока что не доступен в стандартных репозиториях популярных дистрибутивов.
В Centos необходимо включить epel
Устанавливаем:
yum install salt-master
yum install salt-minion

В Ubuntu подключаем ppa:saltstack/salt, выполняем:

apt-get install salt-master
apt-get install salt-minion

Начальная настройка

Мастер процесс(сервер) называется salt-master, клиенты - salt-minion.
После установки настройки как мастера и миньона лежат в /etc/salt/
Файл master должен распологаться на master сервере и хорошо документирован сам по себе, вот настройки которые стоит установить сразу же:
interface: 0.0.0.0 # мастер процесс принимает входящие подключения на этом ip
publish_port: 4505 #порт для входящих подключений
user: root #пользователь, от которого работает salt
worker_threads: 5 #количество потоков мастера
file_roots: #Описание папок файл сервера
base:
 - /srv/salt

Файл minion распологается на миньонах(клиентах) обязательно требует 2 параметра:

master: master.example.com #адрес master’а
id: minion.example.com

Директория /etc/salt/pki содержит ключи аутентификации.

Настроив мастера и миньона перезапускаем процессы:

root@master.example.com:/# /etc/init.d/salt-master restart
root@minion.example.com:/# /etc/init.d/salt-minion restart

Теперь необоходимо авторизовать minion на master’e. Делать это нужно от того пользователя, под которым выполняется salt-master.

Просмотрим список всех ключей, про которые знает наш мастер:

root@master.example.com:/# salt-key -L
Unaccepted Keys:
minion.example.com
Accepted Keys:
Rejected:
Unaccepted Keys: - ключи с новых миньонов, еще не принятые.
Accepted Keys: - принятые, активные ключи.
Rejected: - непринятые ключи
Имя ключа совпадает с id миньона.
Удаленые ключи в списки не отображаются, потому что они удалены.

Примем ключ с вновь созданного миньона:

root@master.example.com:/# salt-key -a minion.example.com

Теперь снова посмотрим список ключей:

root@master.example.com:/# salt-key -L
Unaccepted Keys:
Accepted Keys:
minion.example.com
Rejected:

Для переименования миньона процедуру необходимо повторить заново, сначала удалив старый ключ:

root@master.example.com:/# salt-key -d minion.example.com

Миньон активирован на мастере и может принмать от него команды:

root@master.example.com:/# salt 'minion.example.com' test.ping
minion.example.com: True

Здесь ‘minion.example.com’ - цель, на которой будет выполнена команда. Можно использовать регекспы, например ‘*web*example.com’, а также ключи Grains. test - один из модулей salt. ping - метод модуля test.

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

root@master.example.com:/# salt '*' sys.doc | less

Модули можно легко дописывать и на лету подключать к salt.

В некоторых случаях может быть более удобным генерировать ключи на мастере и затем распостранять на миньонах.
Для amazon EC2 есть готовое решение Bootstrapping Salt on Linux EC2 with Cloud-Init

State

Прямое управление модулями salt не является основным use case! Главной и самой важной частью salt являются модуль State.
Это текстовое описание получаемой в результате системы. State могут быть написаны в yaml, json и python нотациях. Также могут быть использованы рецепты от других систем конфируационного менеждмента. По умолчанию используется yaml.
States должны распологаться в file_roots(/srv/salt/) master сервера.

Файл top .sls описывает какие states к каким миньоном должен применять master.

#/srv/salt/top.sls
base:
  ‘target’
    - app

Файл app.sls описывает какое либо состояние, к которому миньон должен придти:

#/srv/salt/app.sls
app:
  pkg:
    - installed
  service:
    - running
    - enabled: True

Чтобы применить state на миньонах необходимо выполнить команду

root@master.example.com:/# salt '*' state.highstate

Результатом будет состояние системы после применения описанных state. В случае неудачи текст будет красным, в случае успешного применения синим. Отображаются только изменения состояния.

Чтобы только протестировать, но не применять изменения, используется аргумент test

root@master.example.com:/# salt ‘*’ state.highstate test

app.sls также может быть папкой, тогда файл с состоянием будет называться init.sls - /srv/salt/app/init.sls

Один из вопросов, который возникает при использовании SCM - порядок испонения описанных состоянией. В salt по умолчанию все состояния равноценны и могут быть выполенены в произвольном порядке параллельно. Однако в большинсте случаев необходимо управлять процессом, заставляя те или иные действия выполнять в определенном порядке. Salt предлагает для это несколько инструментов.
Это require, watch, use и order.
State из предыдущего примера в реальном применении может принимать такой вид:
app:
  pkg:
    - installed
    - require:
      - cmd.run: app-repo
  service:
    - running
    - enabled: True
    - watch:
       - file.managed: /etc/app/app.conf

/etc/app/app.conf:
  file.managed:
    - source: salt://app/app.conf
    - require:
       - pkg: app

app-repo:
  cmd.run:
    - run
    - name: ‘echo |  apt-add-repository repo’
    - unless: ‘'apt-key list | grep 00000’
В этом примере порядок выполнения будет такой: app-repo - app.pkg - /etc/app/app.conf - app.service.
Различие watch и require в том, что require всего лишь требует наличия, а watch требует точного соответствия отслеживаемого состояния на мастере и а миньоне. Поэтому повторное применение state после правки app.conf приведет к перезагрузке сервиса app, при этом app-repo и app.pkg не сработают.
У watch и require есть браться близнецы watch_in и require_in. Они позволяют указать, какие состояния зависят от состояния, в котором указан watch_in и require_in.
Иногда необходимо явно указать порядок выполнения, для этого нужен order:
В сложных рецептах с большим количеством состояний, которые зависят от одного состяния (установленный репозиторий например) и спользование order позволит избежать перечислений всех зависимых состяний.

К последовательности выполнения не относится, но часто используется вместе с order такая опция как failhard

Grains

Эффективное управление конфигурациями невозможно без механизма получения и хранения информации о управляемых системах.
Grains представляет собой интерфейс для управления такой информацией.

Изначально grains cодержит такую информацию как id, os, arch, fqdn, kernel и другие 45 динамических параметров системы. Эти базовые параметры миньон собирает самостоятельно при старте и они могут быть расширены. Salt просто выполняет все публичные функции в директории file_roots (/srv/salt/_grains) . Функция должна возвращать тип dict. Пример расширения grains можно увидеть здесь.

Есть возможность создать статические ключи и присвоить им значения непосредственно в конфигурационном файле миньона:

#/etc/salt/minon
grains:
  roles:
    - webserver
    - memcache
  deployment: datacenter4
  cabinet: 13
  cab_u: 14-15

Чтобы начать использовать grains выполним команду:

root@master.example.com:/# salt ‘*’ grains.items
Таким образом мы получим все данные со всех миньонов.
Как уже говорилось выше, grains можно использовать в salt target:
root@master.example.com:/# salt -G ‘os:Ubuntu’ grains.item osrelease

Результатом команды будет версия Убунты со всех миньонов.

Первый use-case grains - обеспечение воспроизводимости конфигурации в различном окружнии. Конечно некоторый уровень абстракции дают сами модули Salt, но не всегда.
Пример установки app в дистрибутив-незавимой версии может принять вид:
#/srv/salt/app/init.sls
app:
  pkg:
    - installed
    - require:
      - cmd.run: app-repo
   {% if grains['os'] == 'RedHat' %}
   - name: package_name
   {% if grains['os'] == 'Ubuntu' %}
   - name: name_package
   {% endif %}
  service:
    - running
    - enabled: True
    - watch:
       - file.managed: /etc/app/app.conf

/etc/app/app.conf:
  file.managed:
    - source: salt://app/app.conf
    - require:
       - pkg: app

app-repo:
  {% if grains['os'] == 'RedHat' %}
  cmd.run:
    - run
    - name ‘rpm -ivh repo_uri’
    - unless ‘yum repolist | grep repo’
    {% elif grains['os'] == 'Ubuntu' %}
   cmd.run:
    - run
    - name: ‘echo |  apt-add-repository repo’
    - unless: ‘'apt-key list | grep repo_key’
  {% endif %}

Применив этот state к своим миньонам под управлением Redhat и Ubuntu вы получите одинаковый результат.

Другим use-case grains является получение разного результата на разных системах. Например в конфигурации может быть указан fqdn системы:

...
/etc/app/app.conf
  file.managed:
    - source: salt://app/app.conf
    - template: jinja
    - require:
       - pkg: app
...
#/srv/salt/app/app.conf
...
Hostname={{ grains['fqdn'] }}
...

Ресурсы

Множество вопросов выходит за рамки этой статьи. Большинство информации по Salt можно найти на следующих ресурсах:
Официальный сайт http://saltstack.org/

Документация http://salt.readthedocs.org/en/latest/index.html

Окружение-песочница на Vagrant для тестирования модулей Salt:

Резюме:

Salt - очень молодая, перспективная система управления конфиграциями. В настоящий момент поддерживаются в первую очередь Linux системы, но также уже есть частичная поддержка Windows. Не так давно добавлена поддержка FreeBSD. Salt уже успела обрасти сторонними модулями и проектами, сильным community и вполне может быть применена в проектах с большой и динамичной инфраструктурой.

Tagged

Подключаем JMX в jetty

Во первых понадобиться установить пакет libjetty-extra

далее в файле /etc/default/jetty

JAVA_OPTIONS="
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=53058"
Tagged

every

Every advance in civilization has been denounced as unnatural while it was recent. [R]

[R]Bertrand Russell, philosopher, mathematician, author, Nobel prize in literature (1872-1970)

Расчет времени работы от ИБП

Время работы оборудования от UPS (ИБП) можно рассчитать по формуле:

T [час] = C [А*час] * V [В] * η / P [Вт],

где:

C — суммарная емкость аккумуляторной батареи UPS в ампер-часах;

V — напряжение одного аккумулятора в вольтах;

η — КПД инвертора UPS;

P — средняя мощность подключенного к UPS оборудования в ваттах.

Пример расчета автономной работы коммутатора Dlink DGS-3120-24SC от ИБП SNR-UPS-ODC-1KVA:

Т = (2*7AH) * 12V * 0,85 / 34,1W = 4 часа 12 минут (4,2 часа).

THE NEVER-ENDING STORY OF IP FRAGMENTATION

Впервые я столкнулся с вопросом фрагментации IP пакетов почти 15 лет назад, когда народ начал развертывать небрежно сконфигурированные фаерволлы, блокирующие весь Internet Control Messages Protocol (ICMP) трафик.  Хотелось бы надеяться, что ситуация улучшится, если сетевые архитекторы и инженеры станут опытнее, но становиться только хуже с введением новых методов инкапсуляции, таких как PPP over Ethernet (PPPoE), используемые в DSL, Ipsec шфирование и IP over IP туннели, используемые для решения проблем с маршрутизацией или реализации топологии “сервис-провайдера”.    В этой статье вы найдете причины IP фрагментации, подробное описание работы Path MTU Discovery и различных механизмов, которые можно использовать на маршрутизаторах Cisco для решения проблем с IP фрагментацией.

MTU

Основы MTU

Основной факт в области сетевых технологий, в том, что не все технологии работают на одном уровне. Одним из отличительных особенностей технологий канального layer2 уровня является максимальая полезная нагрузка передаваемого фрейма. (обычно называемый Maximum Transmission Unit - MTU). Например, обычные пакеты Ethernet могут быть до 1518 байт (в том числе CRC - байты), но они могут передать только 1500 байт полезной нагрузки если вы используйте инкапсуляцию по умолчанию.  При использовании SNAP инкапсляции размер полезной нагрузки (maximum payload блеать)  уменьшается до до 1492 байт. Token Ring и FDDI может  передавать намного большие пакеты и использовать большие размеры пакетов для уменьшения накладных расходов при выскоскоростной передаче данных в одноранговых (p2p) сетях.

Примечание.

Фреймы, большие чем 1518 байт (jumbo), применяемые в Fast Ethernet and Gigabit Ethernet environments позволили получить те же результаты.

С другой стороны, медленные последовательные линки используют меньший размер MTU чтобы уменьшить  serialization delay. Передача одного 1500-байтного пакета на 64kbps линке занимает почти 200ms. Такое поведение редко можно увидеть сегодня в связи с широким  распространением  фрагментации и чередования канала (LFI) по каналам PPP.

Инкапсуляции и туннелирования добавляют свои собственные ограничения: например, если вы используйте PPP over  Ethernet, заголовок PPPoE занимает восемь байтов из Ethernet полезной нагрузки, оставляя 1492 байт для IP пакета. Аналогично, Generic Routing Protocol (GRE) использует 24 байт заголовка, снижая MTU внутри GRE до 1476 байт. Очевидно, что сочетание различных методов инкапсуляции еще больше снижает размер MTU. MTU GRE- туннеля запущенного поверх ADSL является 1468 байт.

Технические подробности

Хотя заголовок GRE всего 4 байта (если вы не используете GRE ключ, который расширяет заголовок GRE до восьми байт), IPoverIP инкапсуляция требует дополнительный заголовок IP (20 байт), в результате 24 байта накладных расходов (overhead).  Чистый IPoverIP туннель настроенный в режиме  IPIP отнимает 20 байт.

IPSec еще больше усложняет расчеты MTU, так как размер заголовка IPSec, вставляемый в  пакет IP зависит от параметров IPSec transform sets (сочетания режима туннелирования, шифрования, использования NAT-T и паддинг 8 или 16 байтных блоков применяется.

Примечание

Оригинальная парадигма IOS, где зашифрованные пакеты проходят через тот, же интерфейс, что и зашифрованный трафик не поможет, так как MTU больше не свойство интерфейса. Размер MTU меняется в зависимости от того, зашифрован пакет или нет.

Оригинал: The never-encding story of ip fragmentation