В этой статье мы рассматриваем один из вариантов реализации масштабируемой архитектуры большой почтовой системы.
6 декабря 2012 г. Google прекратил регистрацию новых аккаунтов для бесплатной версии Google Apps.
У клиентов нашей компании постоянно возникает потребность в электронной почте, обслуживающей их сайты.
Раньше мы настраивали им Google Apps, но после 6 декабря, изучив предлагаемые на рынке решения, решили, что настала пора строить собственную почтовую систему.
Как известно, аппетит приходит во время еды. Если уж решились строить что-то свое, то тогда стоит сразу закладывать возможности для роста.
Для проектируемой почтовой системы были сформулировали следующие требования:
На самом деле выбор был небольшой:
После оценки количества сервисов, предоставляемых «из коробки», а также изучения нюансов использования, нами было решено остановиться на dbmail.
Вот краткий список вкусностей, которые предоставляет dbmail:
В качестве MTA был выбран postfix. Поскольку мы давно с ним работаем, с уверенностью полагаем его вполне быстрой, гибкой и легко настраиваемой программой. Тем более, что на сайте dbmail есть инструкция по настройке связки postfix+dbmail.
А балансировщиком нагрузки работает лучший прокси всех времен и народов: nginx.
Web-интерфейс к почтовым ящикам может предоставлять любая из десятков доступных программ. Для начало было решено воспользоваться на RoundCube.
1. На переднем крае у нас запущен nginx с включенным модулем Mail, он принимает от клиентов коннекты по протоколам SMTP, IMAP, POP3 и, на основании имени пользователя и пароля, проксирует коннект на нужный сервер.
2. В глубине обороны работает множество postfix и dbmail, каждый из которых обслуживает свои домены.
Для внешнего мира все это выглядит как один большой почтовый сервер.
Каждый модуль системы будет работать в своем контейнере OpenVZ. По мере увеличения нагрузки, мы будем клонировать/переносить контейнеры на новые физические серверы.
В отдельные контейнеры положим nginx, postfix с различными фильтрами почты, dbmail и хранилище писем в MySQL базе данных разместим в одном контейнере, так как dbmail не должен сильно загружать процессор, а объемы данных, передаваемые между dbmail и mysql будут большими (дублирование данных в хранилище писем будем реализовывать через механизм MySQL репликации master-slave, организуя для каждого dbmail-модуля свой hotbackup-модуль).
Так же, для удобства, в отдельные контейнеры можно выделить веб-серверы с roundcube и панелью управления всей системой.
Все контейнеры общаются между собой по локальной сети с «серыми» адресами.
Реальные интернет адреса планировалось выдать только nginx-контейнерам.
В процессе установки и настройки nginx выяснилось, что SMTP-сессии без авторизации он проксировать не умеет. Решение данной проблемы немного изменило первоначально планируемую архитектуру проекта, что привело к повышению отказоустойчивости и расширяемости. Мы отказались от проксирования SMTP трафика через nginx, и решили, что postfix-модули будут получать его напрямую.
Все postfix-модули системы сделали одинаковыми, каждый со своим реальным IP-адресом, а определяем какому именно dbmail-модулю передавать почту через transport_maps.
В итоге любой postfix-модуль может принять почту для любого домена в системе, применить различные фильтры и доставить в нужное хранилище.
Балансироваться они будут через round-robin записи в DNS:
В домене клиента добавляются необходимые записи:
Почтовые клиенты пользователей настраиваются на прием почты с pop3.dbmail.io или imap.dbmail.io, а отправку почты через smtp.dbmail.io
Не дублированными и уникальными остались только dbmail-модули, но из напрямую интернета они не доступны, поэтому необходимости в динамическом распределении нагрузки на них пока нет.
Каждый из dbmail-модулей хранит почту для нескольких доменов, если ресурсы модуля будут заканчиваться,
часть доменов можно выселить в отдельный модуль.
А в дальнейшем есть планы перейти на хранение почты в какой-либо выделенной кластерной базе данных и унифицировать dbmail-модули.
Все элементы нашей почтовой системы общаются между собой по стандартным протоколам и, как наивно представлялось, — все должно было заработать сразу и без необходимости строить подпорки.
К сожалению, конструкцию пришлось допиливать напильником.
Историю настройки и отладки читайте в следующих статьях.
6 декабря 2012 г. Google прекратил регистрацию новых аккаунтов для бесплатной версии Google Apps.
У клиентов нашей компании постоянно возникает потребность в электронной почте, обслуживающей их сайты.
Раньше мы настраивали им Google Apps, но после 6 декабря, изучив предлагаемые на рынке решения, решили, что настала пора строить собственную почтовую систему.
Как известно, аппетит приходит во время еды. Если уж решились строить что-то свое, то тогда стоит сразу закладывать возможности для роста.
Для проектируемой почтовой системы были сформулировали следующие требования:
- масштабируемость (неограниченное количество обслуживаемых доменов, общий объем почтовых ящиков 100 терабайт и больше);
- отказоустойчивость (все промежуточные сервисы должны быть продублированы);
- расширяемость (добавление новых узлов в систему должно быть легким и простым).
Начали с выбора хранилища под письма...
На самом деле выбор был небольшой:
- dovecot/cyrus с хранением в файловой системе через maildir/mailbox;
- dbmail с хранением в базе данных.
После оценки количества сервисов, предоставляемых «из коробки», а также изучения нюансов использования, нами было решено остановиться на dbmail.
Вот краткий список вкусностей, которые предоставляет dbmail:
- доступ к ящикам через IMAP, POP3;
- sieve-скрипты для сортировки почты;
- прием почты через smtp и lmtp протоколы;
- администрирование через cli и SQL-запросы.
В качестве MTA был выбран postfix. Поскольку мы давно с ним работаем, с уверенностью полагаем его вполне быстрой, гибкой и легко настраиваемой программой. Тем более, что на сайте dbmail есть инструкция по настройке связки postfix+dbmail.
А балансировщиком нагрузки работает лучший прокси всех времен и народов: nginx.
Web-интерфейс к почтовым ящикам может предоставлять любая из десятков доступных программ. Для начало было решено воспользоваться на RoundCube.
В итоге начала вырисовываться следующая архитектура проекта:
1. На переднем крае у нас запущен nginx с включенным модулем Mail, он принимает от клиентов коннекты по протоколам SMTP, IMAP, POP3 и, на основании имени пользователя и пароля, проксирует коннект на нужный сервер.
2. В глубине обороны работает множество postfix и dbmail, каждый из которых обслуживает свои домены.
Для внешнего мира все это выглядит как один большой почтовый сервер.
В теории масштабируемость достигнута, теперь задача реализовать.
Каждый модуль системы будет работать в своем контейнере OpenVZ. По мере увеличения нагрузки, мы будем клонировать/переносить контейнеры на новые физические серверы.
В отдельные контейнеры положим nginx, postfix с различными фильтрами почты, dbmail и хранилище писем в MySQL базе данных разместим в одном контейнере, так как dbmail не должен сильно загружать процессор, а объемы данных, передаваемые между dbmail и mysql будут большими (дублирование данных в хранилище писем будем реализовывать через механизм MySQL репликации master-slave, организуя для каждого dbmail-модуля свой hotbackup-модуль).
Так же, для удобства, в отдельные контейнеры можно выделить веб-серверы с roundcube и панелью управления всей системой.
Все контейнеры общаются между собой по локальной сети с «серыми» адресами.
Реальные интернет адреса планировалось выдать только nginx-контейнерам.
В процессе установки и настройки nginx выяснилось, что SMTP-сессии без авторизации он проксировать не умеет. Решение данной проблемы немного изменило первоначально планируемую архитектуру проекта, что привело к повышению отказоустойчивости и расширяемости. Мы отказались от проксирования SMTP трафика через nginx, и решили, что postfix-модули будут получать его напрямую.
Все postfix-модули системы сделали одинаковыми, каждый со своим реальным IP-адресом, а определяем какому именно dbmail-модулю передавать почту через transport_maps.
В итоге любой postfix-модуль может принять почту для любого домена в системе, применить различные фильтры и доставить в нужное хранилище.
Балансироваться они будут через round-robin записи в DNS:
nginx1 IN A 1.1.2.1
nginx2 IN A 1.1.2.2
postfix1 IN A 1.1.1.1
postfix2 IN A 1.1.1.2
postfix3 IN A 1.1.1.3
mx1 IN A 1.1.1.1
IN A 1.1.1.2
IN A 1.1.1.3
mx2 IN A 1.1.1.2
IN A 1.1.1.3
IN A 1.1.1.1
mx3 IN A 1.1.1.3
IN A 1.1.1.2
IN A 1.1.1.1
imap IN A 1.1.2.1
IN A 1.1.2.2
pop3 IN A 1.1.2.1
IN A 1.1.2.2
smtp IN CNAME mx1
_spf IN TXT "v=spf1 ip4:1.1.1.1 ip4:1.1.1.2 ip4:1.1.1.3 ?all"
В домене клиента добавляются необходимые записи:
@ IN MX 10 mx1.dbmail.io.
@ IN MX 20 mx2.dbmail.io.
@ IN MX 30 mx3.dbmail.io.
@ IN TXT "v=spf1 a mx include:_spf.dbmail.io -all"
Почтовые клиенты пользователей настраиваются на прием почты с pop3.dbmail.io или imap.dbmail.io, а отправку почты через smtp.dbmail.io
Не дублированными и уникальными остались только dbmail-модули, но из напрямую интернета они не доступны, поэтому необходимости в динамическом распределении нагрузки на них пока нет.
Каждый из dbmail-модулей хранит почту для нескольких доменов, если ресурсы модуля будут заканчиваться,
часть доменов можно выселить в отдельный модуль.
А в дальнейшем есть планы перейти на хранение почты в какой-либо выделенной кластерной базе данных и унифицировать dbmail-модули.
В итоге получилась вот такая масштабируемая отказоустойчивая и расширяемая почтовая система:
Все элементы нашей почтовой системы общаются между собой по стандартным протоколам и, как наивно представлялось, — все должно было заработать сразу и без необходимости строить подпорки.
К сожалению, конструкцию пришлось допиливать напильником.
Историю настройки и отладки читайте в следующих статьях.