A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

Jó napot, Habr!

Feladat

Szervezetem levelezőszervert használ a Kerio Connect platformon; a levelezőszerverek különböző városokban vannak telepítve a felhasználók kiszolgálására. Kezdetben nem volt elosztott struktúra, mivel a domainek a harmadik szinten különböznek, jelezve a webhely városát. Minden működött és mindenki elégedett volt. Egy szép napon a vezetőség feladatot, közös tevékenységnaptárt tűzött ki az összes helyszín között!

őstörténet

Kezdetben az volt az ötlet, hogy felemeljük a Kerio Distributed Mail Domaint, és az mindent maga csinálna. Alighogy elkészült egy elosztott tartomány, de ez nem így történt, a szerver készen állt a naptárak, mappák, névjegyek szinkronizálására - ugyanazon a szerveren található tartományok között, de egyáltalán nem szándékozott szinkronizálni az adatokat több között. szerverek.

Természetesen nem számítottam ekkora fogásra, és sokáig nem hittem el, hogy hiányzik a szükséges funkció. Később okirati bizonyítékokat találtam erre a tényre. Nagyon zavart és csalódott voltam ettől.

A feladatból simán probléma lett.

Milyen lehetőségek voltak?

  • Hozzon létre két klienst különböző szervereken, amelyek kicserélik a szükséges adatokat valamilyen harmadik féltől származó szoftverrel. Meg kellett találni ezt a harmadik féltől származó szoftvert, amely megvalósítja ezt a funkciót - nem szeretem az ilyen rake-et, de úgy tűnt, hogy ez az egyetlen gyors megoldás.
  • Írjon saját szkriptet a szerverek közötti adatszinkronizáláshoz. A helyzet az, hogy a Kerio minden egyes objektumot külön fájlként tárol, így szükség volt egy szkript kidolgozására a fájlokkal való munkavégzéshez, de a kellő számú forrás miatt a feladat kissé bonyolultnak tűnt, főleg, hogy több alkalommal kellett végrehajtani. ellenőrzi az adatok helyességét, hátha valaki ugyanabban az időszakban hoz létre feladatot stb., stb.

A jövőre nézve azt mondom, hogy bár a Kerio egy objektumot külön fájlként tárol, nem olyan hülyeség, hogy minden alkalommal megkérdezze, hogyan működik a fájlrendszer, amikor hozzáférünk az objektumhoz.

Miután sok időt eltöltöttem a gondolkodással, és összeállítottam egy csomó papírt az „ellenséges terület elfoglalásának” terveivel, 6 órakor két helyes döntést hoztam:

  • Az első döntés az, hogy a saját dolgoddal foglalkozol, és nem kívülről keresel semmit.
  • A második megoldás aludni.

Már reggel egyetlen és igaz gondolatra ébredtem, ami néhány betűre redukálódott - DFS

döntés

Maga a megoldás így nézett ki

  • hozza az összes szinkronizálásban részt vevő szervert a Windows operációs rendszerre. (Része Linuxon volt. A levelek adatait másik operációs rendszerre kellett áttelepíteni)
  • Határozza meg a szinkronizálásban részt vevő könyvtárak szerkezetét – azonosaknak kell lenniük.
  • Határozza meg az összes levelezőkiszolgálót egy tartomány alatt, egyetlen DFS-területtel.
  • Készítse el a fent említett elosztott Kerio tartományt, mivel esetemben nem csak a szerverek, hanem a tartományok közötti adatszinkronizálás is szükséges, a másodikat a Kerio szerver önállóan tudja kezelni. (ellentétben az elsővel)
  • Állítsa be a szinkronizált könyvtárakat DFS-területre.
  • Találj ki valami mankót (végül is nem tudsz mankó nélkül élni)

Реализация

Példa két levelezőszerveren (talán többen)

1. Kerio elosztott tartomány

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

A Mester nem vesz részt a szinkronizálásban, de ez nem előfeltétel.

Nem írom le, hogyan kell Kerio elosztott domaint emelni, nincs benne semmi bonyolult, tanulmányozhatod a hivatalos manul

Végül a következő képet kell látnia az adminisztrációs konzolon:

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

Ezután a megosztott mappák érdekeltek, a Master szerveren a következő beállításokat adhatja meg:

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

Minden domainhez egyedi - a szerver nem szinkronizálja a nyilvános mappákat a tartományok között

Minden domainben közös - minden kiszolgáló felhagy az egyes tartományokban meglévő nyilvános mappákkal, és új egyedi mappákat hoz létre minden egyes levelezőszerveren.

Figyelem! Bár ez a beállítás módosítja a konfigurációs házirendet az összes kiszolgálón, minden szervertől külön szinkronizál (vagyis egyetlen közös terület nélkül)

A rendszergazda továbbra is megoszthatja a hozzáférést a felhasználók között.
az én esetemben mindegyik az enyém, és teljes szinkronizálásra van szükségem (A te esetedben a megoldás eltérő lehet) minden szerveren azonos tartománykészleteket kell létrehozni, amelyeket szinkronizálni kell.

2. Kerio adatkönyvtárak

Most létre kell hoznia azonos megosztott könyvtárakat, amelyeket minden kiszolgálón szinkronizálni kell. Mappák, naptárak, névjegyek.

Tanács - hozzon létre könyvtárakat angolul, ha latinul hozza létre őket, akkor a könyvtárnak valami érthetetlen kódolásban lesz neve, ez legalább kényelmetlen.

Most minden szerveren meg kell találnia a levelezési mappák fizikai elérési útját.

Minden domainben közös ~DataMailmail#publicСинхронизируемый каталог#msgs
Minden domainhez egyedi ~DataMailmail**Domain**#publicСинхронизируемый каталог#msgs

Felhívjuk figyelmét, hogy nem a teljes könyvtárat szinkronizáljuk, hanem csak a tárolót az adatokkal #üzenetek — maguk az objektumok vannak itt tárolva, minden más adatnak külön kell lennie minden szerverhez.

3.DFS

Nem írom le részletesen, hogyan kell konfigurálni a DFS-t, elegendő információ áll rendelkezésre erről a problémáról.

A DFS egy szerepkör-szolgáltatás a Windows Server rendszerben, amely lehetővé teszi a különböző kiszolgálókon található megosztott mappák kombinálását
Hivatkozás az MS DFS dokumentumhoz

Az elosztott fájlrendszer beállítása előtt le kell állítania minden olyan levelezőszervert, amely részt vesz az adatszinkronizálásban.

A telepítés befejeztével minden szinkronizált mappához a következő képet kell kapnia

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

Természetesen nem kell közzétenni a replikált mappákat.

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

A replikáció megtörténte után (és nincs semmi különös, amit replikálni kellene - a mappák üresek), a levelezőszerverek elindíthatók.

Ezután feltöltheti az egyik levelezőkiszolgálót adatokkal, és ellenőrizheti, hogy az adatok megfelelően replikálódnak-e.

4. Mankó

A tükrözés leírása

Ahogy az adatok szinkronizálásának (DFS) megkezdése után látható, ha az első szerveren hozott létre valamit, akkor valahogy semmi sem jelenik meg a második szerveren, vagy megjelenik, de valahogy nem mindig.

Ne ess kétségbe, természetesen előbb-utóbb megjelenik, de jobb előbb, mint utóbb. Mert 6-12 óra múlva már késő.

A helyzet az, hogy amint létrehoztál valamit az első szerveren, a második és az azt követő szervereken a fájl természetesen azonnal megjelenik a DFS rendszernek köszönhetően, de abban az esetben, ha ezt a levélkönyvtárat valaki már elolvasta és újra kérik, a szerver nem olvassa be újra az #msgs mappát, hanem kiköp adatokat a saját indexéből, amelyek már nem felelnek meg a valóságunknak.

A Kerio rendelkezik egy mechanizmussal az index újraolvasására, de körülbelül hat óra alatt képes működni, és ezalatt a 6 óra alatt némileg elveszhet a feladat relevanciája a naptárban.
A szinkronizálás azonnali teszteléséhez törölheti a fájlt a megfelelő szinkronizált index.fld könyvtárban, miután újra elérte a levelezőszerver mappáját, és ha ez a fájl hiányzik, a Kerio újra beolvassa a könyvtárat és az adatokat. meg fog jelenni. Úgy tűnik, ez a megoldás, törölje a fájlt, amikor az adatok megváltoznak, de ez nem minden alkalommal működik, hanem csak az első alkalommal, akkor Kerio valamiért elveszíti az index.fld érdeklődését
Elkezdi köpni is a felhasználó számára érthetetlen üzeneteket - valami indexről, és hogy ott már csinál valamit.

Van egy másik lehetőség, létrehozni valamit - egy új objektum létrehozásának pillanatában a szerver hirtelen észreveszi, hogy a fájlnév, amelyet hozzá akart rendelni, már foglalt, de hógolyózik, és ez egy zsákutca lehetőség.

Hogy lehet ez?

Ha még egyszer odafigyelünk a számunkra már ismerős képre.

A megosztott mappák, névjegyek és naptárak teljes szinkronizálása az elosztott Kerio Connect szerverek között

De egy másik síkon láthat egy nagyon érdekes gombot, amire most szükségünk van - A mappák újraindexelése

És valóban. Ha erre a gombra kattintunk egy levelezőszerveren, amely nem tudja, hogy a szinkronizált #msgs-ben már megváltozott valami, akkor stabil, gyors eredményt kapunk. Minden rejtett világossá válik.

A naplóban láthatod, hogy ez mennyi ideig tart, esetemben több ezer (15 ezer) rekordnál kb 3-4 perc.

Csak azt kell kitalálni, hogyan nyomjuk meg ezt a gombot, amikor szükségünk van rá.

Kiderült, hogy Kerio sajátjuk van API

Leírás
dokumentáció

A feladatunkat végrehajtó függvény így néz ki:
session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

A fentiek mindegyikéből egy olyan szkriptet kell írnunk, amely figyeli az érdeklődésre számot tartó mappák állapotát, és ha valami megváltozott, végrehajtja a számunkra szükséges funkciót.

Azt akarom mondani, hogy több különböző verziójú szkriptet írtam, amelyek különböző ellenőrzéseket hajtanak végre, és arra telepedtem le, amelyik a fájlok száma alapján von le minden következtetést.

Szkript megvalósítás

CMD szkript példa és leírás

Index.bat

@echo off
set dir=%~dp0
%dir:~0,2%
CD "%~dp0"
md "%CD%LOG"
md "%CD%Setup"

ECHO -Start- >> "%CD%LOG%Computername%.log"
ECHO Start -> %Computername% %Date% %Time% >> "%CD%LOG%Computername%.log"

SetLocal EnableDelayedExpansion
for /f "UseBackQ Delims=" %%A IN ("%CD%Setup%Computername%.List") do (
  set /a c+=1
  set "m!c!=%%A"
)

set d=%c%
Echo Folder = %c%
ECHO Folder = %c% >> "%CD%LOG%Computername%.log"
ECHO.
ECHO. >> "%CD%LOG%Computername%.log"

:start
cls
if %c% LSS 1 exit
set /a id=1
set R=0

:Find
REM PF-Start
if "%id%" gtr "%c%" if %R% == 1 Goto Reindex 
if "%id%" gtr "%c%" timeout 60 && Goto start

For /F "tokens=1-3" %%a IN ('Dir "!m%id%!#msgs" /-C/S/A:-D') Do Set 2DirSize!id!=!DS!& Set DS=%%c
if "2DirSize!id!" == "" set 1DirSize!id!=!2DirSize%id%!

echo %id%
ECHO !m%id%!
echo Count        [ !1DirSize%id%! -- !2DirSize%id%! ]

if "!1DirSize%id%!" == "!2DirSize%id%!" ECHO Synk

REM DEL index.fld
if "!1DirSize%id%!" NEQ "!2DirSize%id%!" del /f /q !m%id%!index.fld && del /f /q !m%id%!indexlog.fld && del /f /q !m%id%!search.fld && set R=1 && ECHO RE-index Count && ECHO RE-index Count %Date% %Time% - Delete !m%id%! >> "%CD%LOG%Computername%.log"

set 1DirSize!id!=!2DirSize%id%!

ECHO.
ECHO.

set /a id+=1
goto Find

:Reindex
ECHO. >> "%CD%LOG%Computername%.log"
ECHO --- RE-INDEX - Start - %Date% %Time% --- >> "%CD%LOG%Computername%.log"
ECHO. >> ----------------------------------- >> "%CD%LOG%Computername%.log"
call PublicFolders.py
timeout 60
goto start

exit

A szkript egy példánya minden levelezőszerveren fut (szolgáltatásként használható, nincs szükség rendszergazdai jogokra)

A szkript beolvassa a fájlt Setup%Computername%.List

Ahol a %Számítógépnév% az aktuális szerver neve (A könyvtár egyszerre tartalmazhatja az összes kiszolgáló listáját.)

A %Computername%.List fájl – a szinkronizált könyvtárak teljes elérési útját tartalmazza, minden elérési út egy új sorba kerül, és nem tartalmazhat üres sorokat.

Az első indítás után a szkript végrehajtja az indexelési eljárást, függetlenül attól, hogy szükséges-e vagy sem, és a szkript egy indexet is készít az egyes szinkronizált könyvtárakban található fájlok számáról.

A szkript célja, hogy megszámolja a megadott könyvtárban található összes fájlt.

Az egyes könyvtárak számlálása végén, ha legalább egy könyvtárban a fájlok aktuális értéke nem egyezik az előzővel, a szkript törli a fájlokat a szinkronizált levélkönyvtár gyökérkönyvtárából: index.fld, indexlog.fld, search.fld és elindítja a megosztott levelezőmappák indexelési folyamatát.

A feladat végrehajtásával kapcsolatos információk a LOG könyvtárba kerülnek.

Indexelési folyamat
Az indexelési folyamat egy Kerio API-függvény végrehajtásából áll
Session = callMethod("Domains.checkPublicFoldersIntegrity",{}, token)

Egy példa implementációt adunk meg – python
PublicFolders.py

import json
import urllib.request
import http.cookiejar
""" Cookie storage is necessary for session handling """
jar = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar))
urllib.request.install_opener(opener)
""" Hostname or ip address of your Kerio Control instance with protocol, port and credentials """

server = "http://127.0.0.1:4040"
username = "user"
password = "password"

def callMethod(method, params, token = None):
    """
    Remotely calls given method with given params.
    :param: method string with fully qualified method name
    :param: params dict with parameters of remotely called method
    :param: token CSRF token is always required except login method. Use method "Session.login" to obtain this token.
    """
    data =  {"method": method ,"id":1, "jsonrpc":"2.0", "params": params}

    req = urllib.request.Request(url = server + '/admin/api/jsonrpc/')
    req.add_header('Content-Type', 'application/json')
    if (token is not None):
        req.add_header('X-Token', token)    

    httpResponse = urllib.request.urlopen(req, json.dumps(data).encode())

    if (httpResponse.status == 200):
        body = httpResponse.read().decode()
        return json.loads(body)

session = callMethod("Session.login", {"userName":username, "password":password, "application":{"vendor":"Kerio", "name":"Control Api-Local", "version":"Python"}})
token = session["result"]["token"]
print (session)

session = callMethod("Domains.checkPublicFoldersIntegrity",{"domainId": "test2.local"}, token)
print (session)

callMethod("Session.logout",{}, token)

http://127.0.0.1:4040 hagyhatja úgy, ahogy van, de ha HTTPS-t igényel, a pythonnak megbíznia kell a Kerio tanúsítványban.

A fájlban is meg kell adni egy fiókot, amely jogosult a levelezőszerver e funkciójának végrehajtására (Adm - nyilvános levelezőmappák).

Remélem, hogy cikkem hasznos lesz a Kerio Connect rendszergazdák számára.

Forrás: will.com

Hozzászólás