הגירה לענן: מ-On-Premise ובין ספקים
שרת ייצור עם היסטוריה של 8 שנים: שלושה דורות של מפתחים, ללא תיעוד, crontab -l מציג 47 משימות, שמחציתן לא ברורות. MySQL 5.6, סוף החיים לפני יותר משנתיים. PHP 7.2. חבורה של סקריפטים ב-/opt/scripts/ ללא git. המשימה היא להעביר את זה ל-Yandex Cloud תוך חודשיים ללא הפסקת שירות. כאן אנחנו מתחילים.
ביקורת לפני הגירה: מה באמת חי על השרת
הדבר הראשון שאנחנו עושים הוא מלאי מלא. לא מהזיכרון של מנהל הצוות, אלא עם כלים.
# Что запущено и слушает порты ss -tlnp # Все процессы с их cmdline ps auxf # Cron всех пользователей for user in $(cut -f1 -d: /etc/passwd); do echo "=== $user ==="; crontab -u $user -l 2>/dev/null; done # Зависимости PHP-приложения composer show --installed # Установленные пакеты с датой dpkg-query -W -f='${Package} ${Version} ${Status}\n' | grep installed # Хардкод localhost в конфигах grep -r "127.0.0.1\|localhost" /etc/app/ /var/www/ --include='*.{php,yml,conf,env}' יחידות Systemd, סקריפטים של initd, קונפיגורציות של supervisor, מארחים וירטואליים של nginx — הכל מתועד. נקודה לא מובנת מאליה: # Что запущено и слушает порты ss -tlnp # Все процессы с их cmdline ps auxf # Cron всех пользователей for user in $(cut -f1 -d: /etc/passwd); do echo "=== $user ==="; crontab -u $user -l 2>/dev/null; done # Зависимости PHP-приложения composer show --installed # Установленные пакеты с датой dpkg-query -W -f='${Package} ${Version} ${Status}\n' | grep installed # Хардкод localhost в конфигах grep -r "127.0.0.1\|localhost" /etc/app/ /var/www/ --include='*.{php,yml,conf,env}' מציג לעתים קרובות שירותים שאף אחד בצוות לא יודע עליהם. Memcached על פורט לא סטנדרטי, שרת מדדים פנימי של HTTP, Zookeeper ישן. כל שירות כזה הוא תלות שחייבת להיות מועברת או מכובה בכוונה.
פרופיל עומס. אנחנו מתעניינים בערכי שיא ב-90 הימים האחרונים — לא ממוצעים. אם Grafana או Zabbix לא מוגדרים, אנחנו מסתכלים על ss -tlnp (אם sysstat מותקן), sar, /var/log/mysql/slow_query.log בזמן עומס שיא. בלי הבנת שיאים, אי אפשר לבחור את הגודל הנכון של מופעי ענן.
תלות בין שירותים. על שרתים מונוליטיים, הכל מחובר ישירות דרך vmstat 1 60. בענן, שירותים יהיו פרוסים על פני כתובות IP שונות — אנחנו צריכים דיאגרמה: מי מתחבר למי, אילו פורטים, האם יש localhost מקודדים בקונפיגורציות. 127.0.0.1 מוצא את זה במהירות, אבל צריך גם לבדוק קבצי env, grep -r, ו-config/*.php.
איך לבחור אסטרטגיית הגירה?
שתי גישות עיקריות — lift-and-shift ו-re-platform. הבחירה ביניהן היא החלטה ארכיטקטונית, לא טכנית.
Lift-and-shift — לקחת מה שיש ולהעביר אותו "כמו שהוא" למכונות וירטואליות בענן. מהיר, סיכון נמוך, שינויי קוד מינימליים. התוצאה היא אותו מונולית, רק בענן. אין autoscaling, שירותים מנוהלים, תמחור אלסטי. מוצדק אם: לוח הזמנים צפוף, הקוד לא השתנה שנים, הצוות קטן.
Re-platform — בשלב ההגירה, לעבור מרכיבים מנוהלים עצמית לשירותים מנוהלים. MySQL 5.6 → Yandex Managed PostgreSQL 15. Redis על VM → Yandex Managed Redis. אחסון קבצים → Object Storage. זה לוקח יותר זמן, אבל התוצאה היא ארכיטקטורת ענן אמיתית. סיכון: אי-תאימות בעת שינוי מסדי נתונים, שינויי קוד שצריך לבדוק.
אפשרות שלישית — re-architect (קונטיינריזציה, מיקרוסרביסים) — לא מומלצת במסגרת הגירה. זה פרויקט נפרד. שילוב הגירה לענן עם שכתוב ארכיטקטורה הוא דרך ישירה לכישלון של שניהם.
השוואת גישות:
| קריטריון | Lift-and-shift | Re-platform |
|---|---|---|
| זמן ביצוע | 2-3 שבועות | 4-8 שבועות |
| שינויי קוד | מינימליים | בינוניים (שינויי דרייבר DB, נתיבי קבצים) |
| סיכונים | נמוכים | בינוניים (אי-תאימות DB) |
| תועלת ענן | נמוכה (אותן VM) | גבוהה (שירותים מנוהלים, autoscaling) |
| חיסכון אופייני | 10-20% | 30-50% על תשתית |
תבניות הגירת נתונים
זה החלק הקשה ביותר. נתונים הם הדבר היחיד שאי אפשר להחזיר לאחור.
Strangler Fig להעברה הדרגתית
תבנית Strangler Fig (מתוארת בספרו של מרטין פאולר "Patterns of Enterprise Application Architecture"): בקשות חדשות מופנות בהדרגה לתשתית החדשה, בעוד הישנה פועלת במקביל. מאזן עומסים (nginx, HAProxy) מפנה חלק מהתעבורה לשרתים חדשים, חלק לישנים. היחס משתנה ככל שהפונקציונליות מאומתת.
upstream backend_old { server 192.168.1.100:8080 weight=9; } upstream backend_new { server 10.0.1.50:8080 weight=1; } # canary: 10% на новый, 90% на старый split_clients "${remote_addr}${date_gmt}" $backend { 10% backend_new; * backend_old; } עבור שירותים חסרי מצב זה עובד היטב. עבור שירותים עם מצב — יש צורך בשכפול נתונים דו-כיווני בתקופת הפעולה המקבילה.
MySQL → Managed PostgreSQL: מלכודות אמיתיות
Dump ישיר לא עובד בין DBMS שונים. כלים: application.yml, AWS Schema Conversion Tool (עובד גם מחוץ ל-AWS), המרת DDL ידנית.
upstream backend_old { server 192.168.1.100:8080 weight=9; } upstream backend_new { server 10.0.1.50:8080 weight=1; } # canary: 10% на новый, 90% на старый split_clients "${remote_addr}${date_gmt}" $backend { 10% backend_new; * backend_old; } יכול לקרוא מ-MySQL ולכתוב ל-PostgreSQL ישירות:
LOAD DATABASE FROM mysql://user:pass@old-server/mydb INTO postgresql://user:pass@new-server/mydb WITH include drop, create tables, create indexes, reset sequences, foreign keys SET MySQL PARAMETERS net_read_timeout = '120', net_write_timeout = '120' CAST type bigint to bigint drop typemod, type varchar to text; אבל pgloader לא מטפל בפרטים הספציפיים של MySQL שאינם תואמים ל-PostgreSQL:
-
pgloaderב-MySQL מומר ל-LOAD DATABASE FROM mysql://user:pass@old-server/mydb INTO postgresql://user:pass@new-server/mydb WITH include drop, create tables, create indexes, reset sequences, foreign keys SET MySQL PARAMETERS net_read_timeout = '120', net_write_timeout = '120' CAST type bigint to bigint drop typemod, type varchar to text;או טיפוס מותאם אישית — יש להחליט לפני ההגירה - פונקציות ספציפיות ל-MySQL בפרוצדורות שמורות (
pgloader,ENUM,TEXT) — לשכתב ידנית למקבילות PostgreSQL -
GROUP_CONCATב-MySQL =IFNULLב-PostgreSQL (PostgreSQL תמיד משתמש ב-UTF-8 של 4 בתים), אבל יש להגדירDATE_FORMATבמפורש - שדות Auto-increment: ב-PostgreSQL זה
utf8mb4אוutf8— אחרי הייבוא, לאפס רצפים דרךCOLLATION
בדיקה לאחר הגירה: SERIAL עבור כל טבלה בשני השרתים, השוואת hashes של רשומות מפתח. אי-התאמה של שורה אחת מתוך מיליון היא קטסטרופה אם זו הזמנה או עסקה.
סנכרון בזמן אמת במהלך Cut-Over
Cut-over הוא הרגע של מעבר DNS/מאזן עומסים מהשרת הישן לחדש. מטרה: למזער את החלון שבו נתונים בשרת הישן משתנים ולא מגיעים לחדש.
עבור MySQL → MySQL (lift-and-shift): להגדיר שכפול old-master → new-slave במהלך ההגירה. Cut-over:
- הפעלת מצב תחזוקה באפליקציה (או מעבר מאזן עומסים לדף "עבודות טכניות")
- לחכות עד ש-
GENERATED ALWAYS AS IDENTITYבשרת החדש מציגsetval - בשרת הישן:
SELECT COUNT(*) FROM - לבדוק
SHOW SLAVE STATUS— מיקום לוג - בשרת החדש:
Seconds_Behind_Master: 0לאחר הגעה לאותו מיקום - לשנות מחרוזת חיבור באפליקציה → restart
-
FLUSH TABLES WITH READ LOCKבשרת הישן - להעביר DNS/מאזן עומסים
חלון נעילת קריאה — שניות, לא דקות. אם יותר — משהו השתבש, rollback.
הגירת קבצים ואחסון אובייקטים
קבצים סטטיים, העלאות משתמשים, גיבויים — בדרך כלל ג'יגה או טרה-בייטים. SHOW MASTER STATUS עם התקדמות ובדיקת checksum:
rsync -avz --checksum --progress \ --exclude='*.tmp' \ /var/www/uploads/ \ user@new-server:/var/www/uploads/ עבור נפחי טרה-בייט — STOP SLAVE עם UNLOCK TABLES כדי לא לרוות את הערוץ של השרת הישן במהלך פעולה. הריצה הראשונה נעשית מראש (יום או יומיים לפני cut-over), השנייה — ממש לפני המעבר, רק דלתא.
כשעוברים ל-Object Storage, השתמשו ב-rsync עם 16 זרמים מקבילים. אחרי ההעברה — CDN מול Object Storage. Yandex Cloud CDN מוגדר עם ה-bucket כמקור. כתובת ה-URL הציבורית של האפליקציה משתנה: rsync -avz --checksum --progress \ --exclude='*.tmp' \ /var/www/uploads/ \ user@new-server:/var/www/uploads/ במקום rsync. זה שינוי קוד שצריך לבדוק.
איך להגר בין ספקי ענן?
מעבר מ-AWS ל-Hetzner או בין ספקים רוסיים הוא תרחיש נפרד. עומסי Kubernetes נעים בצורה נקייה יחסית: ייצוא manifests דרך --bwlimit, החלפת annotations ספציפיים לענן (StorageClass, LoadBalancer annotations), פריסה ל-cluster החדש.
Velero לגיבוי+שחזור של משאבי Kubernetes:
# Backup на источнике velero backup create full-backup \ --include-namespaces=production,staging \ --storage-location=aws-s3 # Restore на целевом кластере velero restore create --from-backup full-backup \ --namespace-mappings "production:production" PersistentVolumes — מסובך יותר. Velero עושה snapshot של volumes דרך דרייבר CSI, אבל snapshots הם ספציפיים לספק. בין ספקים: עצירת pods, העתקת נתונים דרך pod rsync זמני, יצירת PVC ב-cluster החדש, שחזור נתונים, הפעלת pods.
שירותים מנוהלים (RDS, ElastiCache, Kafka מנוהל) בעת החלפת ספק הופכים למנוהלים עצמית או למקבילים מנוהלים אחרים. זו לא משימה טכנית — זו החלטה ארכיטקטונית עם ניתוח שוויון תכונות.
למה תוכנית Rollback היא חובה?
כל הגירה ללא תוכנית rollback היא הרפתקה. תוכנית ה-rollback נכתבת לפני תחילת העבודה, לא במהלכה.
תוכנית rollback מינימלית:
- תנאי rollback: מה בדיוק חייב להישבר כדי להפעיל rollback
- נקודת אל-חזור: אחרי אילו פעולות rollback בלתי אפשרי או עולה יותר מתיקון הבעיה
- פקודות ספציפיות לחזרה לשרת הישן
- אחראי על החלטת rollback
- מגבלת זמן: אם אחרי X שעות הבעיה לא נפתרה — rollback אוטומטי
דוגמה לרשימת בדיקה ל-cut-over
- [ ] גיבוי נתונים מלא (DB dump + קבצים) לפני התחלה
- [ ] בדיקת שכפול:
rclone sync - [ ] הפעלת דף תחזוקה
- [ ] ביצוע
https://cdn.example.com/uploads/file.jpg - [ ] רישום מיקום binlog
- [ ] החלפת מחרוזת חיבור באפליקציה
- [ ] שחרור נעילת קריאה
- [ ] החלפת DNS TTL ל-60 שניות (מראש)
- [ ] אימות פונקציונליות בשרת החדש (smoke test)
- [ ] ניתוק השרת הישן מהרשת (לא כיבוי, אלא בידוד)
- [ ] ניטור למשך 24 שעות
לוחות זמנים אופייניים
| סוג הגירה | היקף | לוח זמנים |
|---|---|---|
| Lift-and-shift, 1-3 שירותים | קטן (< 50 GB נתונים) | 2-3 שבועות |
| Re-platform, שינוי DB | בינוני (50-500 GB) | 4-8 שבועות |
| תשתית מלאה עם Kubernetes | גדול | 2-4 חודשים |
| הגירה בין ספקי ענן | כל היקף | +30-50% לבסיס |
העלות מוערכת לאחר ביקורת של התשתית הנוכחית. גורמי מפתח: נפח נתונים, מספר תלויות, חלון השבתה מותר, ודרישות rollback.
מה כלול בעבודה
- ביקורת מפורטת של התשתית הנוכחית עם תיעוד כל התלויות
- בחירת אסטרטגיית הגירה (lift-and-shift או re-platform) עם נימוקים
- העברת נתונים בשלבים עם אימות שלמות
- הגדרת שירותים מנוהלים (DBMS, Redis, Object Storage, CDN)
- עדכון מחרוזות חיבור, קבצי env, ו-CI/CD pipelines
- פיתוח ובדיקת תוכנית rollback
- ניטור לאחר cut-over למשך 48 שעות
- תיעוד התשתית החדשה (דיאגרמות, runbook)
- הכשרת צוות הלקוח לעבודה עם שירותי ענן
הניסיון והערבויות שלנו
הגירות מטופלות על ידי מהנדסים עם הסמכות AWS Solutions Architect, CKA ו-Terraform Associate. ניסיון ממוצע בתשתיות ענן — 7+ שנים. בחמש השנים האחרונות, השלמנו בהצלחה יותר מ-60 העברות, כולל פרויקטים עם סובלנות תקלות של 99.99%. אנחנו מבטיחים:
- שלמות נתונים בכל שלב (checksums, אימות hash)
- השבתה שלא תעלה על החלון המוסכם (בדרך כלל 15–30 דקות)
- תמיכה מלאה למשך שבועיים לאחר סיום ההגירה
נעריך את הפרויקט שלכם — שלחו לנו תיאור של התשתית הנוכחית שלכם, ואנחנו נציע אסטרטגיה עם לוחות זמנים משוערים.
הזמינו ביקורת של התשתית הנוכחית שלכם — נזהה את כל התלויות הנסתרות ונכין תוכנית הגירה מפורטת לענן. קבלו ייעוץ על בחירת ספק ואסטרטגיה.







