كيفية إطلاق خادم سحابي عن بُعد على AWS: دليل شامل للمبتدئين والمحترفين

دقائق القراءة: 10

تُعد خدمة الحوسبة السحابية من أمازون (AWS) منصة رائعة ومبتكرة، حيث تتألف من مجموعة من اللبنات الأساسية المنفصلة التي يمكن دمجها لبناء بنى تحتية معقدة للغاية. هذه المرونة والقوة تصبح واضحة بمجرد أن تتقن أساسياتها. ولكن عند البدء، قد تواجه تحديات مثل كيفية الحصول على عنوان IP الخاص بخادمك، أو أي مفتاح SSH يجب استخدامه. في هذا الدليل الشامل، سنتناول بعض المفاهيم الأساسية، ثم ننتقل إلى إطلاق خادمنا الخاص على السحابة!

أساسيات إدارة الخوادم السحابية عن بُعد على AWS

تتعدد الأسباب التي قد تدفعك للبدء في استخدام AWS. قد تكون شركتك بصدد نقل بنيتها التحتية إلى السحابة، أو ربما ترغب في بدء العمل الحر وتجنب تكاليف الخوادم الأولية الباهظة، أو ببساطة تسعى لاكتساب مهارة تقنية جديدة. لإطلاق خادم سحابي عن بُعد على AWS، من الضروري فهم بعض المصطلحات والمفاهيم الأساسية. سأستعرض هنا المصطلحات الأكثر صلة بإطلاق الخوادم عن بُعد، مع العلم أن هذه المفاهيم ذاتها تُستخدم في خدمات البنية التحتية الأكثر تعقيدًا مثل Elastic Beanstalk و Docker Swarm و Kubernetes.

خدمة الحوسبة السحابية المرنة (EC2)

تُعد مثيلات AWS EC2 بمثابة قلب القوة الحاسوبية لديك على السحابة، وهي ببساطة خوادمك الافتراضية عن بُعد. إن فهم كيفية التعامل مع مثيلات EC2 أمر بالغ الأهمية، فهي حجر الزاوية في معظم البنى التحتية السحابية وتظهر في كل مكان تقريبًا.

مجموعات الأمان (Security Groups)

تُعتبر مجموعات الأمان بمثابة جدران حماية افتراضية تتحكم في الوصول إلى خدمات AWS المختلفة، وفي حالتنا هذه، إلى مثيل EC2 الخاص بك. تحدد هذه المجموعات المنافذ المفتوحة لحركة المرور الواردة والصادرة، مما يضمن حماية مواردك.

أزواج المفاتيح (Key Pairs)

أزواج المفاتيح هي في الأساس مفاتيح SSH الخاصة بك. من الضروري جدًا تتبعها والاحتفاظ بها في مكان آمن! إذا كنت تستخدم AWS بشكل متكرر، ستبدأ في تجميع العديد من أزواج المفاتيح، لذا تأكد من منحها أسماء وصفية وواضحة بدلاً من مجرد ssh . ;-) لتسهيل إدارتها.

الشبكة الافتراضية الخاصة (VPC)

تُعد VPC موردًا معزولًا تمامًا حيث تقيم بنيتك التحتية الحاسوبية. لاستعارة فلسفة “كل شيء يشبه مكعبات الليغو”، فإن VPC هي صندوق الليغو، بينما تمثل مثيلات EC2 ومجموعات الأمان و أزواج المفاتيح (Key Pairs) مكعبات الليغو الفعلية. تتولى شبكات VPC مسؤولية جميع جوانب الشبكات الخاصة بك. عند التسجيل في حساب AWS، ستحصل على شبكة VPC افتراضية، وهي ما سنستخدمه في هذا الدليل.

كيفية إطلاق مثيل EC2

توجد طرق عديدة لإطلاق مثيل EC2، ويعتمد اختيار الطريقة الأنسب على متطلباتك الخاصة. في هذا الدليل، سنتناول استخدام كل من واجهة الويب الخاصة بـ AWS Console ومكتبة Boto3 في بايثون. كملحوظة سريعة، نظرًا لأن AWS تضم عددًا هائلاً من الخدمات، يجب عليك الدخول إلى كل خدمة على حدة لإدارتها. إذا شعرت بالضياع في أي وقت، ما عليك سوى البحث عن الخدمة المطلوبة من قائمة “الخدمات” (Services).

إطلاق مثيل EC2 باستخدام المعالج التوجيهي

أولاً، ستحتاج إلى تسجيل الدخول إلى لوحة تحكم AWS Console الخاصة بك.

البحث عن خدمة EC2 في قائمة خدمات AWS

للوصول إلى صفحة خدمات EC2، ابحث عنها ضمن قائمة “الخدمات” (Services). انقر على “الخدمات” لفتح مربع البحث، ثم اكتب اسم الخدمة التي تريدها – في هذه الحالة، EC2. انقر على اسم الخدمة من القائمة للانتقال إلى لوحة تحكم تلك الخدمة.

اختيار “إطلاق مثيل” (Launch Instance)

بمجرد وصولك إلى لوحة تحكم EC2، ستحتاج إلى النقر على زر “إطلاق مثيل” (Launch Instance) الموجود في منتصف الشاشة. سيؤدي هذا إلى بدء تشغيل معالج إطلاق AWS EC2، والذي سيرشدنا خلال عملية إعداد مثيل EC2. إذا كنت تخطط لمتابعة الجزء الثاني من هذا الدليل حيث سنقوم بإطلاق خادم EC2 برمجيًا باستخدام بايثون، فهذه فرصة ممتازة لتدوين معرف VPC الافتراضي الخاص بك!

صفحة اختيار نوع مثيل EC2 في AWS

نظرة عامة على معالج EC2

بعد اختيار “إطلاق مثيل” (Launch Instance)، سيتم توجيهك إلى معالج الإعداد. تحتوي قائمة المعالج على 7 خطوات، ويمكنك التبديل بينها بحرية لتكوين المثيل الخاص بك بالطريقة التي تفضلها.

قائمة خطوات معالج إطلاق مثيل EC2 في AWS

معالج EC2 – اختيار نوع AMI الخاص بك

هنا تبدأ العملية الأساسية!

شاشة اختيار نوع AMI في معالج إطلاق EC2

في هذه الخطوة، ستختار نوع صورة أمازون للجهاز (AMI)، والتي تحدد بشكل أساسي نظام التشغيل الذي ترغب في استخدامه. تتوفر مجموعة واسعة من صور AMI المعدة مسبقًا للعديد من حالات الاستخدام الشائعة، بما في ذلك تطبيقات التعلم الآلي، خوادم الويب، وقواعد البيانات. يمكنك استكشاف سوق AWS Marketplace للاطلاع على جميع صور AMI المتاحة. أنا شخصياً أفضل صورة Amazon Linux 2، ولكن يمكنك البحث عن أي نوع صورة آخر، بما في ذلك Ubuntu، CentOS، أو أي من صور Bitnami المتعددة.

ملاحظة جانبية سريعة: أنا معجب جدًا بصور Bitnami. إنها رائعة حقًا، وإذا كنت تتطلع إلى نشر أي نوع من تطبيقات الويب مثل Ghost، WordPress، Nginx، أو حتى تطبيقات أكثر تعقيدًا مثل Redash أو Airflow، فإنني أوصي بها بشدة.

معالج EC2 – اختيار نوع المثيل الخاص بك

في هذا الدليل، سأختار النوع المجاني (free tier) لأنني أنوي إنهاء هذا المثيل بعد التجربة، ولكن إذا كنت ستستخدم مثيل EC2 هذا لأي غرض مهم، فستحتاج إلى اختيار قوة حاسوبية أكبر. إذا كانت متطلباتك تتضمن أي شيء يتعلق بالإنترنت، مثل نقل البيانات، فتأكد من الانتباه إلى قدرات الشبكة واختيار نوع مثيل ضمن النطاق المتوسط.

شاشة اختيار نوع وحجم مثيل EC2 في AWS

مرر لأسفل واختر إما “إطلاق” (Launch) للإطلاق بالإعدادات الافتراضية، أو “تكوين مثيلك” (Configure your Instance) لإضافة تكوينات إضافية مثل تغيير حجم نظام الملفات الجذر، اختيار شبكة VPC، أو إضافة بيانات المستخدم (user data).

معالج EC2 – إضافة الوسوم (Tags)

عندما تبدأ للتو، قد لا يبدو هذا الأمر ذا أهمية كبيرة، ولكن مع تقدمك في استخدام AWS، سترغب في التأكد من أن جميع مثيلاتك تحتوي، على الأقل، على وسوم “الاسم” (Name tags). سيسمح لك هذا بالبحث عن مثيلاتك بسهولة أكبر والقيام بأشياء مفيدة مثل إنشاء مجموعات موارد لتجميع خدمات AWS الخاصة بك. في قائمة المعالج، اختر “إضافة وسوم” (Add Tags). لا تقلق، يمكنك التبديل بين خطوات المعالج بقدر ما تريد.

شاشة إضافة الوسوم (Tags) في معالج إطلاق EC2

معالج EC2 – تكوين مجموعة الأمان (Security Group)

قبل الانتهاء، سنقوم بتكوين مجموعة الأمان، وهي التي تحدد قواعد الوصول إلى المثيل. ستقوم AWS بإنشاء مجموعة أمان لك تلقائيًا، أو يمكنك اختيار مجموعة موجودة بالفعل. الإعداد الافتراضي هو فتح المنفذ 22 لبروتوكول SSH، ولكن إذا كنت ستستخدم هذا المثيل لأي تطبيقات ويب أو قواعد بيانات، فستحتاج إلى فتح تلك المنافذ أيضًا.

شاشة تكوين مجموعة الأمان في معالج إطلاق EC2

معالج EC2 – الإطلاق (LAUNCH)

الآن بعد أن حددنا لـ AWS جميع متطلباتنا، لنقم بإطلاق مثيلنا! انقر على “مراجعة وإطلاق” (Review and Launch). ستظهر لك نافذة منبثقة تسألك عن مفتاح SSH الذي ترغب في استخدامه. يمكنك أيضًا إنشاء زوج مفاتيح SSH جديد من هنا.

نافذة اختيار أو إنشاء زوج مفاتيح SSH في معالج EC2

معالج EC2 – صفحة التأكيد

بمجرد إطلاق المثيل، سيتم توجيهك إلى صفحة تأكيد تحتوي على معرف مثيل EC2 الخاص بك (EC2 Instance ID).

صفحة تأكيد إطلاق مثيل EC2 مع المعرف

لوحة تحكم EC2 – الحصول على عنوان IP الخاص بك

ها قد وصلنا! الآن كل ما تبقى هو انتظار أن يصبح مثيلنا جاهزًا ثم الاتصال به عبر SSH.

شاشة لوحة تحكم EC2 تعرض عنوان IP العام للمثيل

تمام! الآن علينا فقط الاتصال بمثيلنا عبر SSH. ستختلف التفاصيل الخاصة بهذه العملية قليلاً اعتمادًا على نوع المثيل الذي اخترته. يفترض هذا الدليل أنك قمت بتنزيل زوج المفاتيح الخاص بك الذي يحمل اسم my-remote-server.pem ونقلته إلى المسار ~/.ssh.

chmod 400 ~/.ssh/my-remote-server.pem
# Amazon linux 2 ami
ssh -i ~/.ssh/my-remote-server.pem ec2-user@PUBLIC_DNS
# Ubuntu or Bitnami
ssh -i ~/.ssh/my-remote-server.pem ubuntu@PUBLIC_DNS

هذا كل ما في الأمر! الآن أصبح لديك خادم سحابي عن بُعد جاهز للاستخدام!

إطلاق مثيل EC2 باستخدام مكتبة Boto3 في بايثون

تنويه كامل هنا: ما سنقوم به يتجاوز ما أفعله عادةً باستخدام مكتبة Boto3. لأي شيء يتجاوز مجرد إطلاق مثيل EC2، أوصي بشدة باستخدام واجهة التحكم (console) أو أداة “البنية التحتية ككود” (Infrastructure as Code) مثل CloudFormation أو Terraform. ومع ذلك، عند البدء، من المهم جدًا فهم الأساسيات. لدي أيضًا حاجة ملحة لكتابة تقارير لكل شيء تقريبًا. لا تتردد في إزالة هذا الجزء إذا لم تكن مهووسًا بالتوثيق مثلي. 😉

import boto3
import time
import json
from pprint import pprint
from select import select
import logging
from logging import Logger
from paramiko import SSHClient
import paramiko
from typing import Any
import os

logger = logging.getLogger('launch_ec2')
logger.setLevel(logging.DEBUG)

PROJECT = "my-remote-server"
KEY_PAIR = "my-remote-server"
SECURITY_GROUP= "sg-some-number" # Amazon Linux 2 AMI
AMI_ID= "ami-062f7200baf2fa504"
INSTANCE_TYPE= "t3a.medium"

report_data = {
    'name' : PROJECT,
    'computer_name' : KEY_PAIR,
}

def initialize_dir():
    """
    Initialize a directory to write out our keypair and reports
    """
    if not os.path.exists(KEY_PAIR):
        os.mkdir(KEY_PAIR)

def create_key_pair():
    ec2_client = boto3.client('ec2')
    key_pair_response = ec2_client.create_key_pair(KeyName=KEY_PAIR)
    report_data['ssh_key'] = {}
    report_data['ssh_key']['id'] = key_pair_response['KeyPairId']
    report_data['ssh_key']['name'] = key_pair_response['KeyName']
    report_data['ssh_key']['key'] = key_pair_response['KeyMaterial']
    report_data['ssh_key']['key_file'] = os.path.abspath(os.path.join(KEY_PAIR, 'keypair.pem'))
    logger.info('Successfully created ssh key')

def write_key_file():
    """
    Write out the .pem ssh key file
    :return:
    """
    f = open(os.path.join(KEY_PAIR, 'keypair.pem'), 'w+')
    f.write(report_data['ssh_key']['key'])
    f.close()
    os.chmod(os.path.join(KEY_PAIR, 'keypair.pem'), 0o400)
    logger.info('Wrote out ssh key file to {keypair}'.format(
        keypair=os.path.abspath(os.path.join(KEY_PAIR, 'keypair.pem'))
    ))

def create_instance():
    ec2 = boto3.resource('ec2')
    instance = ec2.create_instances(
        SecurityGroupIds=[SECURITY_GROUP],
        ImageId=AMI_ID,
        MinCount=1,
        MaxCount=1,
        InstanceType=INSTANCE_TYPE,
        KeyName=KEY_PAIR,
        TagSpecifications=[
            {
                'ResourceType': 'instance',
                'Tags': [
                    {
                        'Key': 'Name',
                        'Value': PROJECT
                    },
                ]
            },
        ],
    )
    report_data['ec2'] = {}
    report_data['ec2']['id'] = instance[0].id
    report_data['ec2']['PublicIP'] = None

def get_public_ip():
    print('Waiting for instance to initialize with public IP address...')
    print('This may take some time...')
    time.sleep(10)
    ec2 = boto3.resource('ec2')
    running_instances = ec2.instances.filter(Filters=[
        {
            'Name': 'instance-state-name',
            'Values': ['running']
        },
        {
            'Name': 'instance-id',
            'Values': [report_data['ec2']['id']]
        }
    ])
    for instance in running_instances:
        # Add instance info to a dictionary
        report_data['ec2'] = {
            'instance_id': report_data['ec2']['id'],
            'Type': instance.instance_type,
            'State': instance.state['Name'],
            'PrivateIP': instance.private_ip_address,
            'PublicIP': instance.public_ip_address,
            'LaunchTime': str(instance.launch_time)
        }

def write_report():
    """
    Write out a JSON file with all of the IDs and things we need
    """
    logger.info('Writing report to {}'.format(
        os.path.abspath(os.path.join(KEY_PAIR, 'report.json'))
    ))
    f = open(os.path.abspath(os.path.join(KEY_PAIR, 'report.json')) , 'w+')
    json.dump(report_data, f, ensure_ascii=False, indent=4)
    f.close()

def print_helper_commands():
    """
    Print some helper commands for ssh and rsync to the screen
    """
    rsync_command = "rsync -av --progress -e 'ssh -i {key_file}' HOST_DIR ec2-user@{public_id}:/home/ec2-user/efs".format(
        key_file=report_data['ssh_key']['key_file'],
        public_id=report_data['ec2']['PublicIP']
    )
    ssh_command = "ssh -i {key_file} ec2-user@{public_ip}".format(
        key_file=report_data['ssh_key']['key_file'],
        public_ip=report_data['ec2']['PublicIP']
    )
    report_data['ssh_command'] = ssh_command
    report_data['rsync_command'] = rsync_command
    print('Some helpful commands!')
    print('###################################')
    print('# SSH to the instance with: ')
    print(ssh_command)
    print('###################################')
    print('###################################')
    print('# Rsync data to the instance with: ')
    print(rsync_command)
    print('###################################')

def print_end_message():
    print('##################################')
    print('Finished!')
    print('See {dir}/report.json for details'.format(dir=KEY_PAIR))

initialize_dir()
create_key_pair()
write_key_file()
create_instance()
while report_data['ec2']['PublicIP'] is None:
    get_public_ip()
print_helper_commands()
write_report()
print_end_message()

يتألف هذا السكريبت من عدة دوال أساسية تعمل معًا لإطلاق مثيل EC2 وتوفير معلومات الاتصال به:

  • initialize_dir(): تقوم هذه الدالة بتهيئة مجلد محلي لتخزين زوج المفاتيح والتقارير الناتجة.
  • create_key_pair(): تنشئ زوج مفاتيح SSH جديدًا على AWS وتحفظ تفاصيله في بيانات التقرير.
  • write_key_file(): تكتب المفتاح الخاص (.pem) الذي تم إنشاؤه إلى ملف داخل المجلد المهيأ، وتضبط أذوناته لضمان الأمان.
  • create_instance(): تطلق مثيل EC2 جديدًا، مع تحديد مجموعة الأمان، صورة AMI، نوع المثيل، واسم زوج المفاتيح.
  • get_public_ip(): تنتظر حتى يصبح المثيل قيد التشغيل ويحصل على عنوان IP عام، ثم تقوم بتحديث بيانات التقرير بهذا العنوان.
  • write_report(): تكتب جميع البيانات المجمعة حول المثيل وزوج المفاتيح في ملف JSON لسهولة الرجوع إليها.
  • print_helper_commands(): تطبع أوامر مساعدة جاهزة للاتصال بالمثيل عبر SSH ومزامنة الملفات باستخدام Rsync.
  • print_end_message(): تعرض رسالة ختامية تشير إلى اكتمال العملية ومكان حفظ التقرير.

بعد تعريف هذه الدوال، يقوم السكريبت بتسلسل تنفيذها لإنشاء المثيل، انتظار جاهزيته، ثم عرض المعلومات اللازمة للاتصال به.

الخلاصة التقنية

لقد غطينا في هذا الدليل الشامل كيفية إطلاق خادم سحابي عن بُعد على منصة AWS، بدءًا من المفاهيم الأساسية مثل EC2 و VPC ومجموعات الأمان، وصولاً إلى التنفيذ العملي عبر واجهة الويب ومعالج الإطلاق، وكذلك برمجيًا باستخدام مكتبة Boto3 في بايثون. إن القدرة على نشر وإدارة الخوادم السحابية بكفاءة هي مهارة أساسية في عالم الحوسبة السحابية المتطور. تكمن القيمة الحقيقية لـ AWS في مرونتها وقابليتها للتوسع، مما يتيح للمطورين والشركات بناء حلول قوية وموثوقة. سواء كنت تنوي استضافة موقع ويب، أو تشغيل تطبيقات تعلم آلي، أو بناء بنية تحتية معقدة، فإن فهم هذه الأساسيات سيضعك على المسار الصحيح لاستغلال الإمكانيات الهائلة للسحابة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *