ضمن تجربة قمت بها لإنشاء خادم ويب موزع بين جهازين أو أكثر، كانت واحدة من أهم الخطوات للوصول للهدف هو أن تكون محتويات مسار /var/www/html متزامنة بين الخوادم. يعود السبب في ذلك إلى أن الموقع يقدم خدمات كرفع الملفات واستعراضها، بالتالي فوجود نسخة متطابقة على جميع الخوادم خطوة أساسية للحصول على النتيجة. بالطبع هناك طرق بديلة لهذه المعضلة كاستخدام NFS أو رفع هذه الملفات على خدمة خارجية مثل Amazon S3، لكن هذه الحلول لم تكن متاحة في البيئة التي عملت عليها.
مشروع Unison لطيف جدًا ويفي بجميع الشروط التي أبحث عنها. من أهم هذه الشروط هو أنه في حال حدوث تغيير على ملف في أي من الخادمين، فإن التغيير يتم بثه إلى الخادم الآخر “Bi-Directional” وليس محددًا من مصدر واحد. عبر يونيسون تستطيع تحديد أي من الخادمين هو من يقوم بعملية الفحص والتأكيد على وجود ملفات بحاجة للمزامنة. إذا كانت لديك عشرة خوادم على سبيل المثال، فتستطيع وضع سيرفر واحد كخادم أساسي، وتسعة خوادم ثانوية ترتبط معه وتقوم بعملية المزامنة (وهو ماسنقوم به في هذه التدوينة). طريقة أخرى تستطيع القيام بها هو أن يقوم الخادم رقم عشرة بالمزامنة من الخادم التاسع، والتاسع من الثامن، وهكذا حتى يكون الخادم الثاني مرتبط مع الخادم الأول الأساسي. تسمية “أساسي” في هذه التدوينة لا تعني سوى أن الخادم الأساسي لا يقوم بنفسه بالاتصال بالخوادم الأخرى للمزامنة والمقارنة، بل ينتظر الاتصال من الخوادم الأخرى للمزامنة، وتستطيع القيام بالمزامنة دون تنصيب يونيسون عليه أصلًا. بالمناسبة، يحتوى مشروع يونيسون على مميزات أخرى منها دعمه لأنظمة ويندوز أو أي مختلف نكهات *nix، وبإمكانك الاطلاع على المزيد من هنا.
إعداد يونيسون
الخطوات التالية ستشرح كيفية إعداد يونيسون بين خادمين لمزامنة ملفات أباتشي على مسار /var/www/html. سنقوم بتسمية الخادمين بالخادم الأساسي والثانوي.
قبل أن نبدأ
يونيسون يعمل عبر بروتوكول SSH، بالتالي فأنت بحاجة لاستخدام المفاتيح “SSH Keys” بين الخادم الثانوي والأساسي، بمعنى أنك تستطيع الوصول للخادم الأساسي من الخادم الثانوي بدون كلمة مرور “Passwordless Access”. إذا كنت تقوم بتنفيذ هذه الفكرة على أكثر من خادمين، فستحتاج للقيام بنفس الخطوات على جميع السيرفرات الثانوية. ستكون خوادمنا كالتالي:
- Primary: 192.168.1.100
- Secondary: 192.168.1.200
كما ذكرنا، سنبدأ بإنشاء SSH Key بين الخادم الثانوي والأساسي. بداية علينا أن ننشئ المفتاح الخاص بالخادم الثانوي:
[root@secondary ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
49:eb:2f:cd:d7:ee:c6:71:3d:b4:a7:77:c2:03:80:ec root@secondary
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| ... |
| .oo. . |
| .S . . o|
| .E . .o+|
| .o = +o|
| ..o . O o|
| ... +o+.|
+-----------------+
الخطوة التالية هي بنسخ المفتاح من الخادم الثانوي للخادم الأساسي:
[root@secondary ~]# ssh-copy-id root@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
RSA key fingerprint is 5b:3c:06:49:97:ca:3d:7e:29:00:45:7f:dd:cf:79:b0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.100' (RSA) to the list of known hosts.
root@192.168.1.100's password:
Now try logging into the machine, with "ssh 'root@192.168.1.100'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
أخيرًا، لنقم بتجربة الدخول من الخادم الثانوي للخادم الأساسي:
[root@secondary ~]# ssh root@192.168.1.100
Last login: Sun Jan 15 22:27:40 2017 from 192.168.1.200
[root@primary ~]# echo "Hello from `hostname`"
Hello from primary
[root@primary ~]#
ممتاز. سنقوم الآن بتنصيب حزمة Unison، وهي متوفرة عبر المستودعات مثل apt أو yum. إذا كنت على أنظمة سينتوس\ريدهات فستحتاج إلى تنصيب حزمة epel-release قبل تنصيب يونيسون
[root@secondary ~]# yum install unison
[root@ubuntu ~]# apt-get install unison
الخطوة التالية هي لتأكيد الوصول بين الخادمين من خلال يونيسون، وفيها نحدد المصدر أولًا وهو الخادم الأساسي:
[root@secondary ~]# unison -testServer ssh://192.168.1.100//var/www/html /var/www/html
Contacting server...
Connected [//primary//var/www/html -> //secondary//var/www/html]
ممتاز جدًا، الوصول بين الخادمين يعمل بالشكل المطلوب. سأقوم بخطوة إضافية وهي تخصيص البروفايل الخاص بيونيسون. الفكرة من البروفايل هو تحديد صلاحيات يونيسون بمنعها من نسخ مجلدات معينة مثلًا، أو منع تغيير المالك أو الصلاحيات الخاصة بالملفات، وغيرها من الأمور. سنقوم بإنشاء ملف البروفايل في المسار التالي: /root/.unison/default.prf
سنضع الآن هذه الاعدادات داخل الملف. لاحظ السطر الأخير والذي يمنع مزامنة مجلد .git والذي يتواجد داخل مجلد html:
# Unison preferences file
root = /var/www/html
root = ssh://192.168.1.100//var/www/html
batch=true
prefer=newer
times=true
group=false
owner=false
log=false
ignore = Path .git
لتجربة المزامنة، سنقوم بإنشاء ملفين فارغين داخل مسار /var/www/html على كلى الخادمين، وذلك للتأكد من أن المزامنة تتم بالإتجاهين:
[root@primary ~]# touch /var/www/html/primaryfile.txt
[root@secondary ~]# touch /var/www/html/secondaryfile.txt
ملاحظة: إذا حاولت مزامنة مجلدين أحدهما فارغ، فسيرفض Unison ذلك بسبب أنه لا يعلم هل تريد تفريغ ذاك المجلد أم نسخ الملفات إلى هذا المجلد؟ لذا فإنشاء ملفات فارغة للتأكد من المزامنة أمر مستحب.
ثم قم بتنفيذ الأمر التالي من الخادم الثانوي:
[root@secondary ~]# unison -auto -batch -fastcheck true -perms 0
ستكون النتيجة كالتالي:
Contacting server...
Connected [//primary//var/www/html -> //secondary//var/www/html]
Looking for changes
Waiting for changes from server
Reconciling changes
<---- new file primaryfile.txt
new file ----> secondaryfile.txt
Propagating updates
UNISON 2.40.102 started propagating changes at 22:55:26.15 on 15 Jan 2017
[BGN] Copying primaryfile.txt from //primary//var/www/html to /var/www/html
[BGN] Copying secondaryfile.txt from /var/www/html to //primary//var/www/html
[END] Copying primaryfile.txt
[END] Copying secondaryfile.txt
UNISON 2.40.102 finished propagating changes at 22:55:26.16 on 15 Jan 2017
Saving synchronizer state
Synchronization complete at 22:55:26 (2 items transferred, 0 skipped, 0 failed)
يبدو أن العملية نجحت، للتأكيد سنقوم بعرض الملفات داخل المجلد من الخادمين:
[root@primary ~]# ls -ltr
-rw-r--r-- 1 root root 0 Jan 15 22:55 secondaryfile.txt
-rw-r--r-- 1 root root 0 Jan 15 22:55 primaryfile.txt
[root@secondary ~]# ls -ltr
-rw-r--r-- 1 root root 0 Jan 15 22:55 secondaryfile.txt
-rw-r--r-- 1 root root 0 Jan 15 22:55 primaryfile.txt
تمت العملية بنجاح. لاتنسى أن يونيسون يعمل بشكل عكسي إيضًا، فلو قمت بحذف أحد الملفين من أي من الخوادم وقمت بالمزامنة مرة أخرى فسيتم حذفه من الخادم الآخر.
تتبقى الآن الخطوة الأخيرة وهي أتمتة المزامنة بين الخادمين، وسنستعين بصديقنا cron للقيام بهذه العملية. قم بالتعديل على قائمة الأوامر المجدولة في الخادم الثانوي فقط باستخدام الأمر التالي:
[root@secondary ~]# crontab -e
وأضف فيه السطر التالي، سأقوم بجعل المزامنة تتم كل خمس دقائق، وتستطيع تعديلها بمايناسبك:
*/5 * * * * /usr/bin/unison -auto -batch -fastcheck true -perms 0
انتهينا! استمتع بما تبقى في كوب قهوتك 🙂