✕ סגור 
צור קשר
תודה על ההתעניינות .

Thank you! Your submission has been received!

Oops! Something went wrong while submitting the form

יש לכם שרתי פיתוח בענן? כבו אותם (אוטומטית) אחרי שעות העבודה

יש לכם שרתי פיתוח בענן? כבו אותם (אוטומטית) אחרי שעות העבודה
אבי קינן
|
קלה
|
Apr 18, 2018
alt="facebook"alt="linkedin"להרשמה לניוזלטר

כיום, ספקי הענן הגדולים מחייבים עבור שימוש בשרתים ביחידות זמן של שניה (שרתי לינוקס באמזון וגוגל), ושעה (בשרתי Windows). הגמישות שבשירות מאפשרת לנו לצמצם עלויות ולשלם רק עבור הצריכה בפועל.

אחת הדרכים לצמצם את עלויות חשבון הענן בארגון, היא באמצעות כיבוי והדלקת שרתי הפיתוח רק בשעות העבודה. בדרך זו, אנחנו יכולים לצמצם עלות ה-Compute של שרתים אלו בעד 75%.

לדוגמא: בחישוב שנתי, ללא חגים, בחודש ממוצע יש כ-730 שעות וכ-180 שעות עבודה, אם נפעיל את שרתי הפיתוח רק בשעות העבודה, נחסוך כ-550 שעות. אם בארגון עובדים עם שרתי m5.large, העלות החודשית של השרת היא 70.08$, לאחר שנטמיע את הפתרון, העלות החודשית תרד ל-17.28$. חיסכון של 52.8$ לשרת בחודש.

איך עושים את זה?

כדי לכבות את השרתים בצורה אוטומטית, כתבתי סקריפט Python שרץ ב-Lambda (פתרון ה-Serverless של אמזון), ה-Lambda סוקרת את המכונות בכל ה-Regions במקביל ומחפשת מכונות עם תג של TurnOn או TurnOff, במידה והזמן שבתג זהה לזמן כעת, Lambda תדליק ותכבה את השרת, בהתאם לדרישה.

שאלות נפוצות: ״רגע, אבל האייפי מתחלף כשמדליקים את האינסטנס״

נכון, כשמכבים ומדליקים את מכונות כתובת האייפי של השרת תתחלף, אבל יש לכך כמה פתרונות:

בחינם:

1. שימוש ב-Service discovery כמו Consul ובאמצעותו להתחבר לשרתים.

2. שימוש Bastion over ssh בסביבה ואז ניתן לעבוד עם כתובת האייפי הפנימית של השרת שנשארת קבועה..

בתשלום:

1. הצמידו כתובת קבועה (Elastic IP) למכונה. ב-N. Virginia/Ireland תשלמו 2.75$ לחודש פר מכונה עבור השעות שבהן השרת כבוי.

2. הקימו Site to Site VPN בין הרשת בארגון לבין ה-VPC ועבדו עם כתובות האייפי הפנימיות של השרתים.

״וכשהשרת מכובה, על מה אני משלם?״

כשהשרת מכובה, אמזון ימשיכו לחייב אותנו עבור דיסק ה-EBS של המכונה ובמידה ויש לשרת כתובת אייפי קבועה, גם עליה נשלם (2.75$ לחודש). אין תשלום נוסף על המכונה (ולא משנה מהו סוג ה-Instance Type). במידה ויש ב-VPC מוצרים נוספים כמו VPC VPN, או Nat Gateway, החיוב עבורם ימשיך כרגיל.  

״אבל לאמזון יש כבר פתרון כזה, מה ההבדל?״

נכון, לאמזון יש את AWS Instance scheduler, מוצר מתקדם שמציע המון אפשרויות,

יחד עם זאת, אני מאמין שהפתרון שהצגתי אפקטיבי יותר עבור חשבונות פיתוח, הגמישות של תיוג מכונות באמצעות תג TurnOn / TurnOff עם שעת הדלקה/כיבוי הרבה יותר אפקטיבי לטעמי לעומת ניהול לוח זמנים ב-DynamoDB והצמדת תג של לוח זמנים לשרתים.

מעבר לכך, הרשאות ה-IAM שאיתן אנו מריצים את הלמדה הרבה יותר ספציפיות לעומת הפתרון של AWS, הלמדה שלנו לא תוכל לבצע פעולות על המכונות שאינן מתויגות בתג כיבוי/הדלקה.

״קנינו Reservation עבור שרתי הפיתוח, מה עושים במצב כזה?״

במידה ורכשתם Reservation, כשהמכונה מכובת תמשיכו לשלם עליה, אלא אם יש מכונות נוספות מאותה משפחה (m5 לדוגמא) בחשבון או בארגון שהן לא Reserved ואמזון יחילו את ההנחה על מכונה אחרת.

איך מטמיעים את הפתרון?

ניתן להוריד את הסקריפט, lambda_function.py מהפרוייקט בגיטהאב ולהתקין אותו ידנית, או לחלופין, אפשר להשתמש ב-terraform הזה.

איך מתקינים:

בדף ה-IAM ניגש ל-Roles, ונלחץ על Create role כדי ליצור IAM Role חדש.

● נבחר בשירות שאנו מעוניינים לאפשר להריץ את ה-Iam Role, נלחץ על Next, נמשיך ללחוץ Next ונדלג על דף ה-Permissions (את ההרשאות נצרף בשלב הבא) וגם על דף ה-Add tags.

● בשלב ה-Review, ניתן ל-IAM Role שם (לדוגמא: lambda_ec2_turnonoff) ותיאור קצר ונלחץ על Create role.

● לאחר שיצרנו את ה-Role, נלחץ על הקישור המוביל לדף ההגדרות של ה-Role.

● בדף הגדרות ה-Role, נלחץ על  Add inline policy.

נבחר בעמודת ה-JSON ונטמיע את קטע ה-json הבא:

{

  "Version":"2012-10-17",

  "Statement":[

     {

        "Effect":"Allow",

        "Action":[

           "logs:CreateLogGroup",

           "logs:CreateLogStream",

           "logs:PutLogEvents"

        ],

        "Resource":"arn:aws:logs:*:*:*"

     },

     {

        "Effect":"Allow",

        "Action":[

           "ec2:DescribeRegions",

           "ec2:DescribeInstances"

        ],

        "Resource":"*"

     },

     {

        "Sid":"VisualEditor0",

        "Effect":"Allow",

        "Action":[

           "ec2:StartInstances"

        ],

        "Resource":"*",

        "Condition":{

           "StringLike":{

              "ec2:ResourceTag/TurnOn":"*"

           }

        }

     },

     {

        "Sid":"VisualEditor1",

        "Effect":"Allow",

        "Action":[

           "ec2:StopInstances"

        ],

        "Resource":"*",

        "Condition":{

           "StringLike":{

              "ec2:ResourceTag/TurnOff":"*"

           }

        }

     }

  ]

}

להורדת הסקריפט לחץ כאן

הערה: קטע ה-json מציין הרשאות המאפשרות ללמדה לכתוב ללוג ב-CloudWatch, לראות את כלל ה-regions וכל המכונות שבחשבון. הלמדה תוכל להדליק מכונות רק במידה ויש להן תג "TurnOn״ ולכבות מכונות רק במידה ויש להן תג "TurnOff״.

כך במידה ומשהו ישתבש, ה-lambda לא תוכל להשפיע על מכונות ללא התיוג הרלוונטי.

● נשמור את הפוליסי ונקרא לה: lambda_ec2_turnonoff_policy

Type image caption here (optional)

● כעת, נעבור ל-Lambda וניצור פונקצית למדה חדשה

● נגדיר את הלמדה:

1. נקרא ללמדה בשם: EC2_TurnOnOff.

2. בסביבת ה-Runtime של הפונקציה, נבחר ב-Python 3.7.

3. נלחץ על טאב ה-Permissions, תחת Execution role נבחר ב-Use an existing role ונבחר את ה-IAM Role שיצרנו קודם

4. נלחץ על כפתור ״Create Function״

● כדי שהלמדה תופעל אוטומטית, עלינו להשתמש ב-CloudWatch event, נגדיר חוק שיגדיר ל-CloudWatch להפעיל את הלמדה.

● נגדיר את החוק

1. ב-Rule, נבחר ב-Create a new rule.

2. נתן שם ל-Event: ״lambda_ec2_turnonoff״

3. נכתוב תיאור שמסביר את המטרה של החוק: ״Invoke lambda every half an hour״.

4. ב-Rule Type נבחר ב-Schedule expression ובתיבה נגדיר: cron(0/30 * * * ? *)

5. נלחץ על Add.

● כעת נוסיף את הקוד של הפונקציה ונגדיר משתני סביבה בלמדה:

1. נלחץ על שם הפונקציה שבמרכז המסך כדי להגיע לעורך הטקסט של הפונקציה

● נעתיק את קטע הקוד הבא ונדביק אותו בעורך הטקסט של הפונקציה

● כדי שהלמדה לא תדליק את השרתים במהלך הסופ״ש, נוכל להוסיף Environment Variable בשם workweek_tag עם היום שבו מתחיל אנו מתחילים לעבוד (Sunday עבור ישראל, Monday עבור כל השאר).

לאחר מכן נגלול למטה, ובתיבת Environment variables נוסיף משתנה בשם workweek_tag,

במשתנה זה נגדיר את היום הראשון בשבוע שלנו, לדוגמא: בישראל, נכתוב Sunday ב-Key. עבור ארה״ב, נכתוב Monday.

● נגלול למטה לתיבת ה-Basic settings, ונגדיל את זמן ה-Timeout של למדה מ-3 שניות ל-15 דקות (הזמן המקסימלי שהפונקציה יכולה לרוץ)

כעת נלחץ על כפתור ה-Save, נתייג את השרתים הרלוונטים וזהו. הלמדה תדאג להדליק ולכבות את המכונות, במידה ונרצה לעקוב אחרי הפעולות שלמדה ביצעה, נוכל לראות את הלוגים ב-Cloudwatch.

איך מתייגים מכונה:

1. ניגש ל-EC2 Console ונבחר באחת המכונות שאנו רוצים לתייג.

2. באפשרויות שבתחתית הדף, נבחר בעמודת ה-Tags ונלחץ על הכפתור Add/Edit Tags.

3. נלחץ פעמיים על כפתור Create Tag.

4.בעמודת ה-Key, נרשום TurnOn ובעמודת ה-Value נכתוב את זמן הדלקת השרת, לדוגמא עבור 10 בבוקר נכתוב "10:00".

5.בעמודת ה-Key, נרשום TurnOff ובעמודת ה-Value נכתוב את זמן הדלקת השרת, לדוגמא עבור 4 בצהריים נכתוב "16:00".

6.לשמירת השינויים נלחץ על Save.

הערה: אם אתם מעוניינים לתייג מספר גדול של מכונות בבת אחת, אפשר להשתמש ב-Tag manager שב-EC2 Console.

למעבר ל- GitHub repo

מאת: אבי קינן, עד לאחרונה עבד כ-Devops בחברת איירון סורס וכיום עובד כ-Customer reliability engineer בחברת DoIT International.

כיום, ספקי הענן הגדולים מחייבים עבור שימוש בשרתים ביחידות זמן של שניה (שרתי לינוקס באמזון וגוגל), ושעה (בשרתי Windows). הגמישות שבשירות מאפשרת לנו לצמצם עלויות ולשלם רק עבור הצריכה בפועל.

אחת הדרכים לצמצם את עלויות חשבון הענן בארגון, היא באמצעות כיבוי והדלקת שרתי הפיתוח רק בשעות העבודה. בדרך זו, אנחנו יכולים לצמצם עלות ה-Compute של שרתים אלו בעד 75%.

לדוגמא: בחישוב שנתי, ללא חגים, בחודש ממוצע יש כ-730 שעות וכ-180 שעות עבודה, אם נפעיל את שרתי הפיתוח רק בשעות העבודה, נחסוך כ-550 שעות. אם בארגון עובדים עם שרתי m5.large, העלות החודשית של השרת היא 70.08$, לאחר שנטמיע את הפתרון, העלות החודשית תרד ל-17.28$. חיסכון של 52.8$ לשרת בחודש.

איך עושים את זה?

כדי לכבות את השרתים בצורה אוטומטית, כתבתי סקריפט Python שרץ ב-Lambda (פתרון ה-Serverless של אמזון), ה-Lambda סוקרת את המכונות בכל ה-Regions במקביל ומחפשת מכונות עם תג של TurnOn או TurnOff, במידה והזמן שבתג זהה לזמן כעת, Lambda תדליק ותכבה את השרת, בהתאם לדרישה.

שאלות נפוצות: ״רגע, אבל האייפי מתחלף כשמדליקים את האינסטנס״

נכון, כשמכבים ומדליקים את מכונות כתובת האייפי של השרת תתחלף, אבל יש לכך כמה פתרונות:

בחינם:

1. שימוש ב-Service discovery כמו Consul ובאמצעותו להתחבר לשרתים.

2. שימוש Bastion over ssh בסביבה ואז ניתן לעבוד עם כתובת האייפי הפנימית של השרת שנשארת קבועה..

בתשלום:

1. הצמידו כתובת קבועה (Elastic IP) למכונה. ב-N. Virginia/Ireland תשלמו 2.75$ לחודש פר מכונה עבור השעות שבהן השרת כבוי.

2. הקימו Site to Site VPN בין הרשת בארגון לבין ה-VPC ועבדו עם כתובות האייפי הפנימיות של השרתים.

״וכשהשרת מכובה, על מה אני משלם?״

כשהשרת מכובה, אמזון ימשיכו לחייב אותנו עבור דיסק ה-EBS של המכונה ובמידה ויש לשרת כתובת אייפי קבועה, גם עליה נשלם (2.75$ לחודש). אין תשלום נוסף על המכונה (ולא משנה מהו סוג ה-Instance Type). במידה ויש ב-VPC מוצרים נוספים כמו VPC VPN, או Nat Gateway, החיוב עבורם ימשיך כרגיל.  

״אבל לאמזון יש כבר פתרון כזה, מה ההבדל?״

נכון, לאמזון יש את AWS Instance scheduler, מוצר מתקדם שמציע המון אפשרויות,

יחד עם זאת, אני מאמין שהפתרון שהצגתי אפקטיבי יותר עבור חשבונות פיתוח, הגמישות של תיוג מכונות באמצעות תג TurnOn / TurnOff עם שעת הדלקה/כיבוי הרבה יותר אפקטיבי לטעמי לעומת ניהול לוח זמנים ב-DynamoDB והצמדת תג של לוח זמנים לשרתים.

מעבר לכך, הרשאות ה-IAM שאיתן אנו מריצים את הלמדה הרבה יותר ספציפיות לעומת הפתרון של AWS, הלמדה שלנו לא תוכל לבצע פעולות על המכונות שאינן מתויגות בתג כיבוי/הדלקה.

״קנינו Reservation עבור שרתי הפיתוח, מה עושים במצב כזה?״

במידה ורכשתם Reservation, כשהמכונה מכובת תמשיכו לשלם עליה, אלא אם יש מכונות נוספות מאותה משפחה (m5 לדוגמא) בחשבון או בארגון שהן לא Reserved ואמזון יחילו את ההנחה על מכונה אחרת.

איך מטמיעים את הפתרון?

ניתן להוריד את הסקריפט, lambda_function.py מהפרוייקט בגיטהאב ולהתקין אותו ידנית, או לחלופין, אפשר להשתמש ב-terraform הזה.

איך מתקינים:

בדף ה-IAM ניגש ל-Roles, ונלחץ על Create role כדי ליצור IAM Role חדש.

● נבחר בשירות שאנו מעוניינים לאפשר להריץ את ה-Iam Role, נלחץ על Next, נמשיך ללחוץ Next ונדלג על דף ה-Permissions (את ההרשאות נצרף בשלב הבא) וגם על דף ה-Add tags.

● בשלב ה-Review, ניתן ל-IAM Role שם (לדוגמא: lambda_ec2_turnonoff) ותיאור קצר ונלחץ על Create role.

● לאחר שיצרנו את ה-Role, נלחץ על הקישור המוביל לדף ההגדרות של ה-Role.

● בדף הגדרות ה-Role, נלחץ על  Add inline policy.

נבחר בעמודת ה-JSON ונטמיע את קטע ה-json הבא:

{

  "Version":"2012-10-17",

  "Statement":[

     {

        "Effect":"Allow",

        "Action":[

           "logs:CreateLogGroup",

           "logs:CreateLogStream",

           "logs:PutLogEvents"

        ],

        "Resource":"arn:aws:logs:*:*:*"

     },

     {

        "Effect":"Allow",

        "Action":[

           "ec2:DescribeRegions",

           "ec2:DescribeInstances"

        ],

        "Resource":"*"

     },

     {

        "Sid":"VisualEditor0",

        "Effect":"Allow",

        "Action":[

           "ec2:StartInstances"

        ],

        "Resource":"*",

        "Condition":{

           "StringLike":{

              "ec2:ResourceTag/TurnOn":"*"

           }

        }

     },

     {

        "Sid":"VisualEditor1",

        "Effect":"Allow",

        "Action":[

           "ec2:StopInstances"

        ],

        "Resource":"*",

        "Condition":{

           "StringLike":{

              "ec2:ResourceTag/TurnOff":"*"

           }

        }

     }

  ]

}

להורדת הסקריפט לחץ כאן

הערה: קטע ה-json מציין הרשאות המאפשרות ללמדה לכתוב ללוג ב-CloudWatch, לראות את כלל ה-regions וכל המכונות שבחשבון. הלמדה תוכל להדליק מכונות רק במידה ויש להן תג "TurnOn״ ולכבות מכונות רק במידה ויש להן תג "TurnOff״.

כך במידה ומשהו ישתבש, ה-lambda לא תוכל להשפיע על מכונות ללא התיוג הרלוונטי.

● נשמור את הפוליסי ונקרא לה: lambda_ec2_turnonoff_policy

Type image caption here (optional)

● כעת, נעבור ל-Lambda וניצור פונקצית למדה חדשה

● נגדיר את הלמדה:

1. נקרא ללמדה בשם: EC2_TurnOnOff.

2. בסביבת ה-Runtime של הפונקציה, נבחר ב-Python 3.7.

3. נלחץ על טאב ה-Permissions, תחת Execution role נבחר ב-Use an existing role ונבחר את ה-IAM Role שיצרנו קודם

4. נלחץ על כפתור ״Create Function״

● כדי שהלמדה תופעל אוטומטית, עלינו להשתמש ב-CloudWatch event, נגדיר חוק שיגדיר ל-CloudWatch להפעיל את הלמדה.

● נגדיר את החוק

1. ב-Rule, נבחר ב-Create a new rule.

2. נתן שם ל-Event: ״lambda_ec2_turnonoff״

3. נכתוב תיאור שמסביר את המטרה של החוק: ״Invoke lambda every half an hour״.

4. ב-Rule Type נבחר ב-Schedule expression ובתיבה נגדיר: cron(0/30 * * * ? *)

5. נלחץ על Add.

● כעת נוסיף את הקוד של הפונקציה ונגדיר משתני סביבה בלמדה:

1. נלחץ על שם הפונקציה שבמרכז המסך כדי להגיע לעורך הטקסט של הפונקציה

● נעתיק את קטע הקוד הבא ונדביק אותו בעורך הטקסט של הפונקציה

● כדי שהלמדה לא תדליק את השרתים במהלך הסופ״ש, נוכל להוסיף Environment Variable בשם workweek_tag עם היום שבו מתחיל אנו מתחילים לעבוד (Sunday עבור ישראל, Monday עבור כל השאר).

לאחר מכן נגלול למטה, ובתיבת Environment variables נוסיף משתנה בשם workweek_tag,

במשתנה זה נגדיר את היום הראשון בשבוע שלנו, לדוגמא: בישראל, נכתוב Sunday ב-Key. עבור ארה״ב, נכתוב Monday.

● נגלול למטה לתיבת ה-Basic settings, ונגדיל את זמן ה-Timeout של למדה מ-3 שניות ל-15 דקות (הזמן המקסימלי שהפונקציה יכולה לרוץ)

כעת נלחץ על כפתור ה-Save, נתייג את השרתים הרלוונטים וזהו. הלמדה תדאג להדליק ולכבות את המכונות, במידה ונרצה לעקוב אחרי הפעולות שלמדה ביצעה, נוכל לראות את הלוגים ב-Cloudwatch.

איך מתייגים מכונה:

1. ניגש ל-EC2 Console ונבחר באחת המכונות שאנו רוצים לתייג.

2. באפשרויות שבתחתית הדף, נבחר בעמודת ה-Tags ונלחץ על הכפתור Add/Edit Tags.

3. נלחץ פעמיים על כפתור Create Tag.

4.בעמודת ה-Key, נרשום TurnOn ובעמודת ה-Value נכתוב את זמן הדלקת השרת, לדוגמא עבור 10 בבוקר נכתוב "10:00".

5.בעמודת ה-Key, נרשום TurnOff ובעמודת ה-Value נכתוב את זמן הדלקת השרת, לדוגמא עבור 4 בצהריים נכתוב "16:00".

6.לשמירת השינויים נלחץ על Save.

הערה: אם אתם מעוניינים לתייג מספר גדול של מכונות בבת אחת, אפשר להשתמש ב-Tag manager שב-EC2 Console.

למעבר ל- GitHub repo

מאת: אבי קינן, עד לאחרונה עבד כ-Devops בחברת איירון סורס וכיום עובד כ-Customer reliability engineer בחברת DoIT International.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
אבי קינן
בואו נעבוד ביחד
support@israelclouds.com
צרו קשר