Запускаем скрипт при старте и выключении Ubuntu

Довольно часто надо сделать так, чтоб при старте сервера запустился какой-либо скрипт. Это довольно просто и очень многие это знают. Просто добавляем запуск этого скрипта в /etc/rc.local и он будет запущен. Но что делать, если надо запустить скрипт при выключении сервера? Например, загрузить логи перед уничтожением облачного сервера.

Решение простое, если знаешь, как устроена система запуска Linux.

Надо всего-то положить скрипт в /etc/rc6.d.

Имя скрипта должно начинаться с K99 и дальше само имя.

Так же надо установить execute права на скрипт:

$ chmod +x /etc/rc6.d/K99example

При выключении этот скрипт отработает.

Расширяем раздел в EC2

Иногда, так случается, что надо расширить диск для какого-то EC2 инстанса. Это можно сделать не останавливая сам инстанс, чтоб не прерывать работу сервиса.

Для этого заходим в веб-консоль AWS, находим нужный volume и увеличиваем его размер.

Потом нужно увеличить раздел и саму файловую систему на этом разделе. Заходим по ssh на инстанс и расширяем раздел:

$ sudo growpart /dev/xvda 1

Получаем что-то типа:

CHANGED: partition=1 start=2048 old: size=16775135 end=16777183 new: size=41940959,end=41943007

Теперь даем понять ядру, что надо перечитать новую таблицу разделов:

$ sudo partprobe

И расширяем файловую систему:

$ sudo resize2fs /dev/xvda1

Результат:

resize2fs 1.42.13 (17-May-2015)
Filesystem at /dev/xvda1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/xvda1 is now 5242619 (4k) blocks long.

on-line resizing required говорит о том, что файловая система была расширена.

Python3 на MacOS Catalina: фиксим «Abort trap»

Иногда на бетах MacOS Catalina ломается python3 и все, что с ним связано. Просто показывается ошибка «Abort trap: 6» и все. Тот же pip3 не запускается совсем.

Я довольно не мало перерыл статей в поисках причины и нашел, что это связано с библиотеками OpenSSL. Фикс довольно простой:

ln -s /usr/local/Cellar/openssl@1.1/1.1.1d/lib/libcrypto.dylib /usr/local/lib/libcrypto.dylib
ln -s /usr/local/Cellar/openssl@1.1/1.1.1d/lib/libssl.dylib /usr/local/lib/libssl.dylib

Эта заметка скорее для себя самого, чтоб не забыть, если оно опять сломается.

SSH сквозь бастион хост

Концепция бастиона не нова и давно используется для доступа в охраняемый периметр. Но вот как получить доступ к внутренним серверам в прозрачном режиме? Тут мы это и рассмотрим.

ProxyJump

Опция командной строки

Начиная с версии SSH 7.3 есть настройка конфигурации клиента ProxyJump или -J флаг:

ssh -J <bastion-host> <remote-host>

Так же можно указать разные имена пользователей и порты:

ssh -J bastionuser@<bastion-host:port> user@<remote-host:port>

Так же, можно указать несколько бастионов:

ssh -J <bastion1>,<bastion2>,<bastion3> <remote-host>

SSH config

### The Bastion Host
Host bastion-host-nickname
  HostName bastion-hostname

### The Remote Host
Host remote-host-nickname
  HostName remote-hostname
  ProxyJump bastion-host-nickname

А дальше как обычно:

ssh remote-host-nickname

Альтернативный метод: форвардинг stdin и stdout

Если ваш ssh клиент более старый, чем 7.3, то можно использовать такой подход:

ssh -o ProxyCommand="ssh -W %h:%p bastion-host" remote-host

Собственно, это все так же можно оформить в конфиг, чтоб не запоминать:

Host remote-host
  ProxyCommand ssh bastion-host -W %h:%p

А дальше опять просто:

ssh remote-host

Зеркало pip в Китае

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

В случае с python pip это можно сделать так:

mkdir ~/.pip
cat <<EOF > ~/.pip/pip.conf
 [global]
 trusted-host =  mirrors.aliyun.com
 index-url = http://mirrors.aliyun.com/pypi/simple
EOF

После этого пакеты будут ставиться сильно быстрее.

Рестарт Passenger без простоя из Capistrano

Когда у вас достаточно нагруженный проект на RoR и для запуска вы используете Passenger, то рестарт приложения может вызывать небольшой (а иногда и простой) простой. Это не есть хорошо.

Passenger имеет две версии - Open Source и Enterprise. Так вот в Enterprise версии есть опция --rolling-restart, которая и позволяет не перезапускать сразу все инстансы приложения, а делать это поочереди.

В Capistrano это настраивается элементарно:

set :passenger_restart_options,
  -> { "#{deploy_to} --ignore-app-not-running --rolling-restart" }

Мониторим перезапуск вот так:

passenger-status

Деплой на много хостов с Capistrano

Не так часто, но бывает надо сделать деплой на, скажем, 20 хостов, которые находятся за bastion'ом.

Если у вас 5 хостов и все работает как часы, то нет проблем, казалось бы. Увеличиваем количество хостов, запускаем деплой, profit.

Но чаще всего вы получите ошибку и будете очень долго удивляться, как же так...

Ошибка будет вида:

cap aborted!
Errno::EPIPE: Broken pipe
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh/transport/server_version.rb:44:in `write'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh/transport/server_version.rb:44:in `negotiate!'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh/transport/server_version.rb:32:in `initialize'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh/transport/session.rb:84:in `new'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh/transport/session.rb:84:in `initialize'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh.rb:232:in `new'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/net-ssh-3.2.0/lib/net/ssh.rb:232:in `start'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/backends/connection_pool.rb:59:in `call'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/backends/connection_pool.rb:59:in `with'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/backends/netssh.rb:155:in `with_ssh'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/backends/netssh.rb:49:in `upload!'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/capistrano-3.6.1/lib/capistrano/tasks/git.rake:24:in `block (3 levels) in <top (required)>'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/backends/abstract.rb:29:in `instance_exec'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/backends/abstract.rb:29:in `run'
/Users/khiem-nguyen/workspace/ruby/nenga-onepiece/cl-chef/deploy/vendor/bundle/ruby/2.3.0/gems/sshkit-1.11.2/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
Tasks: TOP => git:check => git:wrapper
The deploy has failed with an error: Broken pipe
** Invoke deploy:failed (first_time)
** Execute deploy:failed


** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:

И дальше еще большой стэк-трейс, который вам ровным счетом ничего не даст.

Опытным путем вы прийдете к тому, что 10 хостов деплоятся нормально, а вот 11 уже нет. И дело тут совсем не в Capistrano, а в вашем ssh сервере на bastion'е.

Во всем виноваты значения по умолчанию опции MaxStartups. Увеличьте ее первое значение и все у вас полетит, как вы того ожидаете.

Итак, было:

# MaxStartups 10:30:60

Стало:

MaxStartups 30:30:60

Ошибка при установке gem mysql2

Если вы получаете ошибку типа:

Error installing mysql2: ERROR: Failed to build gem native extension.

то решение очень простое. Сначала ставим openssl

brew install openssl

А потом ставим gem необходимой версии:

gem install mysql2 -v '0.5.2' -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include

Версию gem'a поправьте под свою.

apg в Mac OS

apg - это генератор паролей как pwgen, только они запоминаются сильно легче.

Под Ubuntu он есть в репах, а в MacOS ставим так:

brew tap jzaleski/homebrew-jzaleski
brew install apg

Собираем логи из docker в GrayLog

logspout

Последнее время я все чаще стал ходить на сервера и смотреть логи руками. Но доккер так устроен, что найти что-то в логах крайне сложно. В результате я пришел к выводу, что пора собирать логи где-то в ElasticSearch.

Классический ELK я не очень люблю, а потому стал искать варианты, которые мне бы понравились. В итоге, пришел к GrayLog.

Оставался вопрос сборщика логов, для отправки их в GrayLog, который сложит их в ElasticSearch.

Перебрал кучку малую и остановился на Logspout. Он умеет отправлять логи в syslog, GELF и, что не маловажно, он умеет multiline logs. Т.е. Tracebacks будут не построчно, а целиком, как положено.

Ну что ж, поднимаем.
Читать далее...