Serverless CI / CD على AWS



سيكون من الرائع أن يكون نشر نسخ اللصق شيئًا من الماضي ، ولكن ، للأسف ، كانت الأمور مختلفة. يحدث أن المطورين يفضلون طريقة التسليم هذه. على الرغم من الآن اكتب مقالًا عن سبب عدم هذا الأمر ، لكنك تعرف كل شيء بدوني. مع الاتجاه نحو هندسة بدون خادم ، تلعب خطوط أنابيب CI / CD دورًا مهمًا في تسليم التطبيق. كتبت أيضًا عنهم في المقال " 3 أفضل النصائح لمشروعك بدون خادم التالي ."


لقد كنت مهتمًا بموضوع CI و CD منذ فترة طويلة ، ولأول مرة التقيت به منذ عدة سنوات - بفضل TeamCity. حاليًا ، لا يزال TeamCity يستخدم لمعظم خطوط أنابيب CI / CD الخاصة بنا. TeamCity يعمل بشكل رائع ، ليس لدي أي شيء ضده ، لكنني دائماً أسعى لتحسين العمل. على سبيل المثال ، سيكون من الجيد جمع خطوط أنابيب في شكل كود - وهذا أحد المجالات التي ليست فيها TeamCity جيدة.


لقد تعلمت أدوات التكامل والتسليم في AWS منذ بعض الوقت ، وعلى الرغم من أننا نستخدم CodeDeploy لمشروع آخر يعمل على EC2 ، إلا أنني لم أقم بنشر مشروع بدون خادم معهم. بعد مراجعة الأدوات مرة أخرى ، لاحظت هذا: الآن هناك وظيفة تكامل مضمنة لنشر CloudFormation و Lambda ، بناءً على SAM AWS ؛ نستخدم إطار عمل بدون خادم - يقوم بإنشاء قوالب CloudFormation ، لكنه لا يعمل خارج الصندوق باستخدام أدوات AWS.


التحضير


يمكنني استخدام خدمات AWS التالية: EC2 ، Docker ، ECR ، S3 ، IAM ، CodeBuild ، CodePipeline ، CloudWatch ، CloudTrail. من أجل مواكبة ذلك ، عليك أن تفهم على الأقل مستوى أساسي ما تقوم به كل من هذه الخدمات.


بشكل أساسي ، أكتب الرمز الجانبي للخادم في .NET ، ويعتمد هذا الدليل أيضًا على هذا النظام الأساسي. لا تحتوي أي من صور CodeBuild مسبقة الصنع على وقت تشغيل .NET و NodeJS في نفس الوقت (هناك حاجة إلى NodeJS لإطار عمل بدون خادم). إذا كانت وظائف Lambda مكتوبة في NodeJS ، فإن تكوين خط أنابيب النشر أبسط بكثير ، لأن هذه هي بيئة التشغيل الوحيدة المطلوبة للتثبيت في صورة Docker (إذا كانت قضيتك ، لا تتردد في تخطي معظم الدليل). للمرة الثانية ، كانت هذه أول تجربة لي مع الحاويات ، وأنا سعيد بتعلم شيء جديد.


أجرؤ على افتراض أن الرمز الخاص بك في مستودع معين ، على سبيل المثال ، بوابة. للحصول على إرشادات ، نقوم ببساطة بتحميل ملف يحتوي على حزمة من التعليمات البرمجية للنشر إلى S3 ؛ كيف تحصل عليه الأمر متروك لك. بأخذ عملي كأساس ، يمكنك دائمًا المضي قدمًا من خلال توصيل خط الأنابيب الخاص بك بمستودعات مثل github أو CodeCommit.


1. إنشاء مثيل EC2 وتثبيت Docker


قم بتشغيل مثيل قياسي لـ AWS Linux 2 EC2 - يجب أن يكون هذا واضحًا دون توضيح. تسجيل الدخول وتثبيت Docker باستخدام الأوامر:


sudo yum update -y sudo amazon-linux-extras install docker sudo service docker start 

تحتاج أيضًا إلى إضافة ec2 للمستخدم إلى مجموعة عامل ميناء لتنفيذ أوامر Docker دون استخدام sudo:


 sudo usermod -a -G docker ec2-user 

عند اكتمال الأمر ، قم بتسجيل الخروج ثم تسجيل الدخول مرة أخرى إلى مثيل EC2 الخاص بك بحيث يتلقى مستخدم ec2 أذونات جديدة. تأكد من قيام مستخدم ec2 بتشغيل أوامر Docker دون sudo:


 docker info 


docker info إخراج docker info


2. إنشاء صورة عامل الميناء ووضعه في ECR


افترض أن الخطوة السابقة ناجحة ؛ الخطوة التالية هي إنشاء صورة Docker تناسبها في ECR. تقدم AWS الصور الأساسية لـ CodeBuild على github ، وهذا يجعل من السهل إنشاء صورتك الخاصة.


لقد نشرت الصورة أيضًا على github - في حالة عدم رغبتك في اتباع هذه الخطوات لإنشاء الخاصة بك: https://github.com/effectivedigital/serverless-deployment-image


انسخ الصور وانتقل إلى دليل .NET Core 2.1:


 git clone https://github.com/aws/aws-codebuild-docker-images.git cd aws-codebuild-docker-images cd ubuntu/dot-net/core-2.1/ 

افتح Dockerfile في محرر النصوص المفضل لديك:


 nano Dockerfile 

أضف الأوامر لتثبيت NodeJS والإطار بدون خادم في نهاية الأوامر الأخرى المتوفرة بالفعل في Dockerfile. حصلت على معظم هذه الأوامر من صورة NodeJS Docker في نفس مستودع AWS:


 # Install Node Dependencies ENV NODE_VERSION="10.14.1" # gpg keys listed at https://github.com/nodejs/node#release-team RUN set -ex \ && for key in \ 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ B9AE9905FFD7803F25714661B63B535A4C206CA9 \ 77984A986EBC2AA786BC0F66B01FBB92821C587A \ 56730D5401028683275BD23C23EFEFE93C4CFFFE \ 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ FD3A5288F042B6850C66B31F09FE44734EB7990E \ 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \ C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ 4ED778F539E3634C779C87C6D7062848A1AB005C \ A48C2BEE680E841632CD4E44F07496B3EB3C1762 \ ; do \ gpg - keyserver hkp://p80.pool.sks-keyservers.net:80 - recv-keys "$key" || \ gpg - keyserver hkp://ipv4.pool.sks-keyservers.net - recv-keys "$key" || \ gpg - keyserver hkp://pgp.mit.edu:80 - recv-keys "$key" ; \ done RUN set -ex \ && wget "https://nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" -O node-v$NODE_VER$ && wget "https://nodejs.org/download/release/v$NODE_VERSION/SHASUMS256.txt.asc" -O SHASUMS256.txt.asc \ && gpg - batch - decrypt - output SHASUMS256.txt SHASUMS256.txt.asc \ && grep " node-v$NODE_VERSION-linux-x64.tar.gz\$" SHASUMS256.txt | sha256sum -c - \ && tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local - strip-components=1 \ && rm "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc SHASUMS256.txt \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ && rm -fr /var/lib/apt/lists/* /tmp/* /var/tmp/* RUN npm set unsafe-perm true CMD [ "node" ] # Install Serverless Framework RUN set -ex \ && npm install -g serverless 

الآن نقوم بجمع وتمييز الصورة:


 docker build -t aws/codebuild/dot-net . 

بعد الانتهاء من التجميع ، قم بتشغيل الصورة - تأكد من أن كل شيء يعمل وأنه تم تثبيت الإطار بدون خادم بشكل صحيح:


 docker run -it --entrypoint sh aws/codebuild/dot-net -c bash sls -v 


تشغيل sls -v داخل حاوية جديدة


ثم قم بإنشاء المستودع في ECR باستخدام AWS CLI. بعد تشغيل الأمر ، سيتم عرض مستودع التخزين الجديد في وحدة التحكم AWS:


 aws ecr create-repository --repository-name codebuild-dotnet-node 


استجابة AWS CLI لإنشاء مستودع في ECR



الآن قم بتمييز صورة aws / codebuild / dot-net التي تم إنشاؤها سابقًا باستخدام repositoryUri من الخطوة السابقة:


 docker tag aws/codebuild/dot-net <ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com/codebuild-dotnet-node 

قم بتشغيل الأمر get-login للحصول على سطر أوامر مصادقة تسجيل الدخول إلى عامل ميناء سجل الحاوية:


 aws ecr get-login --no-include-email 


قم بتشغيل أمر تسجيل دخول عامل ميناء صادر عن الأمر get-login أثناء الخطوة الأخيرة.


 docker login -u AWS -p eyJwYXlsb2FkIjoiNGZnd0dSaXM1L2svWWRLMmhJT1c0WWpOZEcxamJFeFJOK2VvT0Y5[...] https://<ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com 

إذا نجح تسجيل الدخول ، فضع صورة عامل النقل في المستودع الذي تم إنشاؤه في ECR. قد يستغرق هذا عدة دقائق (حسب حجم الصورة المكتملة).


 docker push <ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com/codebuild-dotnet-node 


عامل الميناء على EC2 يخلق صورتنا



صورة عامل الميناء في ECR


ثم يمكننا فتح الوصول إلى الصورة من ECR لأي شخص. يجب حظر الإذن في بيئة العمل ، ولكن في هذا المثال سنفتحه. انتقل إلى علامة تبويب الأذونات في وحدة التحكم AWS ، حدد "تغيير سياسة JSON" وأدخل العنصر التالي في السياسة:


 { "Version": "2008-10-17", "Statement": [ { "Sid": "EnableAccountAccess", "Effect": "Allow", "Principal": "*", "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:DescribeImages", "ecr:DescribeRepositories", "ecr:GetAuthorizationToken", "ecr:GetDownloadUrlForLayer", "ecr:GetRepositoryPolicy", "ecr:ListImages" ] } ] } 

3. إنشاء خط أنابيب


لقد حان الوقت لجمع الأنابيب. لتبسيط العملية ، وجعلها متعددة النشر ، والتمسك بالشكل الكارثي للهندسة المعمارية بدون خادم ، قمت ببناء خط أنابيب باستخدام إطار عمل بدون خادم. يمكنك تحقيق نفس النتيجة من خلال البناء في CloudFormation.


لن أنسخ المصدر بالكامل من ملف serverless.yml - انسخه من github: https://github.com/effectivedigital/serverless-deployment-pipeline


تحقق من القالب بدون خادم لمعرفة ما الذي ستفعله بالضبط ، ولكن باختصار ، يقوم بإعداد العناصر التالية:


  • 3 شرائح S3
  • سياسة الجزء 1
  • 3 أدوار IAM
  • 1 مشروع CodeBuild
  • 1 خط أنابيب CodePipeline
  • حدث CloudWatch واحد
  • 1 تتبع CloudTrail

ثم قم بتحديث DockerImageArn لصورتك في ECR. إذا كنت ترغب في إنشاء حزم نشر باسم غير Deployment.zip ، فعليك أيضًا تحديث DeploymentFilename :


 DockerImageArn: <ACCOUNTID>.dkr.ecr.ap-southeast-2.amazonaws.com/codebuild-dotnet-node:latest DeploymentFilename: Deployment.zip 

هذا كل شيء ، خط الأنابيب جاهز للنشر. قم بتشغيل أمر النشر بدون خادم وانتظر حتى يتم تكوينه:


 sls deploy -v 


خلق إطار serverless كومة CloudFormation



التي أنشأتها خادم خط أنابيب الإطار CodePipeline



التي أنشأتها مشروع إطار serverless مشروع CodeBuild


4. إضافة buildSpec.yml إلى التطبيق الخاص بك


عندما يكتشف CodePipeline تغييرًا في ملف النشر في S3 ، فإنه يخبر CodeBuild أن يبدأ ويحاول إنشاء التطبيق ونشره. ومع ذلك ، يجب أن يعرف CodeBuild أيضًا الأوامر التي يجب تنفيذها لإنشاء التطبيق ونشره ، ويحتوي buildSpec.yml على إرشادات سيتبعها CodeBuild.


لقد قمت بإنشاء تطبيق "Hello world" بسيط للغاية يتضمن مثالاً على ملف buildSpec.yml الذي يمكنك استخدامه: https://github.com/effectivedigital/serverless-deployment-app
أو قم بإنشاء ملف buildSpec.yml في التطبيقات الحالية واملأه وفقًا للتعليمات التالية:


 version: 0.2 phases: pre_build: commands: - chmod a+x * build: commands: - ./build.sh post_build: commands: - sls deploy -v -s $STAGE 

5. فحص خطوط الأنابيب


كل شيء جاهز الآن للإطلاق الأول لخط الأنابيب الخاص بك. قم بإنشاء حزمة تسمى Deployment.zip ، ويجب أن تتضمن جميع الملفات الخاصة بالتطبيق بدون خادم وملف buildSpec.yml.


بعد لحظات قليلة ، يجب على CloudTrail تسجيل حدث PutObject وتنشيط قاعدة حدث CloudWatch ، التي تقوم بعد ذلك بتنشيط مشغل CodePipeline.



تم نشر Deployment.zip في S3



أطلقت CodePipeline ، بناء على


إذا انتقلنا إلى تفاصيل خطوة AWS CodeBuild ، فيمكننا رؤية عملية الإنشاء والنشر:



ستتلقى CodeBuild الإخراج من البنية ونشر صورة Docker



نشر ناجح!


يظهر التطبيق الجديد الذي تم نشره بواسطة خط الأنابيب لدينا في CloudFormation:



يمكنك اختبار نقطة نهاية واجهة برمجة التطبيقات التي تم إنشاؤها في تطبيقنا البسيط (عنوان URL في إخراج CodeBuild أو في واجهة برمجة تطبيقات البوابة) والتأكد من أن التطبيق يعمل بنجاح:



ساعي البريد للاتصال API


استنتاجات موجزة


يسمح لك CodePipeline بإنشاء خط أنابيب CI / CD قابل للتطوير ومرن وغير مكلف ، ويساعد في حل بعض المشكلات المرتبطة بخطوط الأنابيب التقليدية التي تم إنشاؤها على الخوادم.
أرغب في المضي قدمًا وإضافة اختبار الوحدة بعد النشر إلى المزيج ، لكن الموضوع يستحق مقالة منفصلة - وهذه مناسبة لقراءتنا في المستقبل!

Source: https://habr.com/ru/post/ar440756/


All Articles