خادم اختبار لفريق التطوير

مرحبا يا هبر! في هذه المقالة ، أريد مشاركة تجربة نشر خادم اختبار لفريق التطوير. باختصار جوهر المشكلة - هناك فريق تطوير والعديد من المشاريع في PHP. بينما كنا صغارًا وكان المشروع في الأساس واحدًا ، استخدمنا خادمًا تجريبيًا واحدًا ولإظهار المهمة للعميل ، قام المطور بإعداد "عمود" الخادم لفترة معينة. إذا لم تكن هناك "نوافذ" في الوقت المناسب ، فعلينا الانتظار. مع مرور الوقت ، زاد الفريق وتعقيد المهام ، على التوالي ، وزاد وقت التحقق وازدحام خادم الاختبار ، مما أثر سلبًا على المهلة والمكافأة. لذلك ، كان علي أن أبحث عن حل وهو تحت القطع.

تمهيدي


ماذا كان:

  1. خادم اختبار واحد
  2. Gitlab و redmine على خادم آخر
  3. الرغبة في حل مشكلة

جميع الخوادم في شبكتنا المحلية ، ولا يمكن الوصول إلى خادم الاختبار من الخارج.

ما هو المطلوب:

  1. القدرة على اختبار مشاريع / فروع متعددة في نفس الوقت
  2. يمكن للمطور الذهاب إلى الخادم وإعداده وعدم فصل أي شيء عن الآخرين
  3. يجب أن يكون كل شيء مناسبًا قدر الإمكان وأن يتم على زر واحد ، ويفضل أن يكون من gitlab (CI / CD).

خيارات القرار


1. خادم واحد ، العديد من المضيفين


الخيار الأسهل. نستخدم نفس خادم الاختبار ، يحتاج المطور فقط إلى إنشاء مضيف لكل فرع / مشروع وإضافته إلى تكوين nginx / apache2.

الإيجابيات:

  1. بسرعة ويفهم الجميع
  2. يمكن أتمتة

السلبيات:

  1. لا يتم استيفاء البند 2 من المتطلبات - يمكن للمطور بدء تحديث قاعدة البيانات ، وفي بعض الظروف ، وضع كل شيء في (Hi Andrey!)
  2. أتمتة معقدة للغاية مع مجموعة من ملفات التكوين

2. لكل مطور على الخادم!


خصص لكل خادم والمطور مسؤول عن اقتصاده.

الإيجابيات:

  1. يمكن للمطور تخصيص الخادم بالكامل لمشروعك

السلبيات:

  1. لم يتم استيفاء البند 2 من المتطلبات
  2. يمكن أن تكون الموارد باهظة الثمن والموارد مكتوفة الأيدي أثناء التطوير ، وليس الاختبار
  3. الأتمتة أكثر تعقيدًا مما كانت عليه في النقطة 1 بسبب الخوادم المختلفة

3. حاويات - الرصيف ، kubernetes


هذه التكنولوجيا تخترق حياتنا بشكل متزايد. في المنزل ، كنت أستخدم عامل الرصيف لمشاريعي لفترة طويلة.
Docker - برنامج لأتمتة نشر وإدارة التطبيقات في بيئة افتراضية على مستوى نظام التشغيل. يتيح لك "حزم" التطبيق مع كل ما يحيط به وتبعياته في حاوية يمكن نقلها إلى أي نظام Linux مع دعم cgroups في النواة ، كما يوفر بيئة لإدارة الحاوية.
الإيجابيات:

  1. يتم استخدام خادم واحد
  2. تم استيفاء جميع المتطلبات.

السلبيات:

  1. تستهلك الصور والحاويات أحيانًا مساحة كبيرة ، عليك تنظيف التيجان القديمة بالفعل لتوفير مساحة.

تنفيذ عامل الميناء


عند استخدام gitlab ، AutoDevOps ، كانت إعدادات kubernetes تلفت انتباهي كثيرًا. بالإضافة إلى ذلك ، فإن الرجال الملتحين في لقاءات مختلفة يخبرون كم هم رائعون مع kubernetes. لذلك ، تقرر محاولة نشر المجموعة في منشآتها ، تم طلب الخادم (ولا يمكنك لمس الاختبار ، الناس يختبرون هناك) وبدأ!

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

وكيل عكسي


لكي لا أعيد اختراع العجلة ، بدأت في البحث عن حلول جاهزة. وقد وجد - هذا ترافيك .

Træfik هو بروكسي عكسي حديث وموازن تحميل يبسط نشر الخدمات الصغيرة. يتكامل Træfik مع مكونات البنية التحتية الموجودة (Docker ، وضع Swarm ، Kubernetes ، Marathon ، Consul ، Etcd ، Rancher ، Amazon ECS ، ...) ويتم تكوينه تلقائيًا وديناميكيًا. للعمل مع عامل الإرساء ، ما عليك سوى تحديد مأخذ التوصيل وهذا كل شيء ، ثم يجد Træfik نفسه جميع الحاويات والتوجيه إليها (لمزيد من التفاصيل ، راجع "تطبيقات التعبئة في عامل الإرساء").

تكوين حاوية Træfik
أقوم بتشغيله من خلال docker-compose.yml

version: '3' services: traefik: image: traefik:latest # The official Traefik docker image command: --api --docker # Enables the web UI and tells Træfik to listen to docker ports: - 443:443 - 80:80 # The HTTP port - 8080:8080 # The Web UI (enabled by --api) volumes: - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events - /opt/traefik/traefik.toml:/traefik.toml - /opt/traefik/certs/:/certs/ networks: - proxy container_name: traefik restart: always networks: proxy: external: true 


هنا نبلغ الوكيل أننا بحاجة للاستماع إلى المنافذ 80،443 و 8080 (واجهة الويب الخاصة بالوكيل) ، وتركيب مقبس عامل الميناء ، وملف التكوين ومجلد الشهادة. من أجل راحة تسمية مواقع الاختبار ، قررنا إجراء اختبار المجال المحلي * .test. عند الوصول إلى أي موقع عليه ، يصل المستخدم إلى خادم الاختبار لدينا. لذلك ، فإن الشهادات في مجلد traefik موقعة ذاتيًا ، ولكنها تدعم Let's Encrypt.

إنشاء الشهادة

 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout domain.key -out domain.crt 

قبل البدء ، تحتاج إلى إنشاء شبكة وكيل في عامل الإرساء (يمكنك تسميتها بنفسك).

 docker network create proxy 

ستكون هذه هي شبكة ربط traefik بحاويات مواقع php. لذلك ، نحدده في معلمة الشبكات الخاصة بالخدمة وفي شبكات الملف بأكمله عن طريق تحديد المعلمة الخارجية: صحيح.

ملف Traefik.toml
 debug = false logLevel = "DEBUG" defaultEntryPoints = ["https","http"] #  insecureSkipVerify = true #   [entryPoints] [entryPoints.http] address = ":80" [entryPoints.https] address = ":443" [entryPoints.https.tls] [docker] endpoint = "unix:///var/run/docker.sock" domain = "docker.localhost" watch = true exposedbydefault = false 


كل شيء بسيط للغاية هنا - نحدد نقاط الدخول لحركة http و https ، ولا تنس تعيين insecureSkipVerify = true إذا كانت الشهادات محلية. في قسم entryPoints.https.tls ، لا يمكنك تحديد الشهادات ، ثم يستبدل traefik شهادته.

يمكنك بدء الخدمة

 docker-compose up -d 

إذا انتقلت إلى site.test ، فستتلقى خطأ 404 ، نظرًا لأن هذا النطاق غير مرتبط بأي حاوية.

نحن حزمة التطبيقات في عامل ميناء


الآن تحتاج إلى تكوين الحاوية مع التطبيق ، وهي:

1. تحديد شبكة وكيل في الشبكات
2. إضافة ملصقات مع تكوين traefik

فيما يلي تكوين أحد التطبيقات

تطبيقات docker-compose.yml
 version: '3' services: app: build: data/docker/php #   restart: always working_dir: /var/www/html/public volumes: - ./:/var/www/html #    - /home/develop/site-files/f:/var/www/html/public/f #       links: - mailcatcher - memcached - mysql labels: - traefik.enabled=true - traefik.frontend.rule=Host:TEST_DOMAIN,crm.TEST_DOMAIN,bonus.TEST_DOMAIN - traefik.docker.network=proxy - traefik.port=443 - traefik.protocol=https networks: - proxy - default mailcatcher: image: schickling/mailcatcher:latest restart: always memcached: image: memcached restart: always mysql: image: mysql:5.7 restart: always command: --max_allowed_packet=902505856 --sql-mode="" environment: MYSQL_ROOT_PASSWORD: 12345 MYSQL_DATABASE: site volumes: - ./data/cache/mysql-db:/var/lib/mysql #      phpmyadmin: image: phpmyadmin/phpmyadmin restart: always links: - mysql environment: MYSQL_USERNAME: root MYSQL_ROOT_PASSWORD: 12345 PMA_ARBITRARY: 1 PMA_HOST: mysql_1 labels: - traefik.enabled=true - traefik.frontend.rule=Host:pma.TEST_DOMAIN - traefik.docker.network=proxy - traefik.port=80 - traefik.default.protocol=http networks: - proxy - default networks: proxy: external: true 


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

بعد ذلك ، قم بتكوين التسميات

  - traefik.enabled=true # traefik    - traefik.frontend.rule=Host:TEST_DOMAIN,crm.TEST_DOMAIN,bonus.TEST_DOMAIN #    traefik     - traefik.docker.network=proxy #   - traefik.port=443 #,     ssl   80   http - traefik.protocol=https #  #  phpmyadmin   http  

في قسم الشبكات العامة ، حدد الخارجية: صواب

يجب استبدال ثابت TEST_DOMAIN بمجال ، على سبيل المثال ، site.test

قم بتشغيل التطبيق

 docker-compose up -d 

الآن إذا ذهبت إلى المجالات site.test ، crm.site.test ، bonus.site.test ، يمكنك رؤية موقع العمل. وعلى المجال pma.site.test سيكون هناك phpmyadmin للعمل المريح مع قاعدة البيانات.

تكوين GitLab


نقوم بإنشاء معالج مهام ، لذلك ندير

 gitlab-runner register 

نحدد عنوان url gitlab ، الرمز المميز ، والذي سيتم من خلاله تنفيذ المهمة (المنفذين). نظرًا لأن اختباري و gitlab موجودان على خوادم مختلفة ، فحدد منفذ ssh. ستحتاج إلى تحديد عنوان الخادم وكلمة المرور / تسجيل الدخول للاتصال عبر ssh.

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

.gitlab-ci.yml
 stages: - build - clear #  develop build_develop: stage: build #   build tags: #     - ssh-develop environment: # ,       -   name: review/$CI_BUILD_REF_NAME #  url: https://site$CI_PIPELINE_ID.test #url     on_stop: clear when: manual script: - cd ../ && cp -r $CI_PROJECT_NAME $CI_PIPELINE_ID && cd $CI_PIPELINE_ID #     - cp -r /home/develop/site-files/.ssh data/docker/php/.ssh #  ssh - sed -i -e "s/TEST_DOMAIN/site$CI_PIPELINE_ID.test/g" docker-compose.yml #   - docker-compose down #   - docker-compose up -d --build #  - script -q -c "docker exec -it ${CI_PIPELINE_ID}_app_1 bash -c \"cd ../ && php composer.phar install --prefer-dist \"" #   - script -q -c "docker exec -it ${CI_PIPELINE_ID}_app_1 bash -c \"cd ../ && php composer.phar first-install $CI_PIPELINE_ID\"" #     #  production build_prod: stage: build tags: - ssh-develop environment: name: review/$CI_BUILD_REF_NAME url: https://site$CI_PIPELINE_ID.test on_stop: clear when: manual script: - cd ../ && cp -r $CI_PROJECT_NAME $CI_PIPELINE_ID && cd $CI_PIPELINE_ID - cp -r /home/develop/site-files/.ssh data/docker/php/.ssh #  ssh - docker-compose down - docker-compose up -d --build - script -q -c "docker exec -it ${CI_PIPELINE_ID}_app_1 bash -c \"cd ../ && php composer.phar install --prefer-dist --no-dev\"" - script -q -c "docker exec -it ${CI_PIPELINE_ID}_app_1 bash -c \"cd ../ && php composer.phar first-install $CI_PIPELINE_ID\"" clear: stage: clear tags: - ssh-develop environment: name: review/$CI_BUILD_REF_NAME action: stop script: - cd ../ && cd $CI_PIPELINE_ID && docker-compose down && cd ../ && echo password | sudo -S rm -rf $CI_PIPELINE_ID #       when: manual 


في هذا التكوين ، تم وصف مرحلتين - البناء والوضوح. تتضمن مرحلة الإنشاء خيارين - build_develop و build_prod



يقوم Gitlab بإنشاء مخطط تدفق عملية يمكن فهمه. في المثال الخاص بي ، تبدأ جميع العمليات يدويًا (عندما: المعلمة اليدوية). يتم ذلك حتى يتمكن المطور ، بعد نشر موقع الاختبار ، من سحب تعديلاته في الحاوية دون إعادة بناء الحاوية بأكملها. سبب آخر هو اسم المجال - الموقع $ CI_PIPELINE_ID.test ، حيث CI_PIPELINE_ID هو رقم العملية التي بدأت التجميع. أي أنهم قدموا الموقع باستخدام النطاق site123.test للتحقق ، ومن أجل إجراء تعديلات ساخنة ، يتم صب التغييرات على الفور في الحاوية من قبل المطور.

ميزة صغيرة لمنفذ ssh. عند الاتصال بالخادم ، يتم إنشاء مجلد من النموذج.

 /home//builds/_runner/0/_/_ 

لذلك ، تمت إضافة خط

 cd ../ && cp -r $CI_PROJECT_NAME $CI_PIPELINE_ID && cd $CI_PIPELINE_ID 

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

تقوم المرحلة الواضحة بإيقاف الحاويات وحذف المجلد ، وقد تحتاج إلى امتيازات الجذر ، لذلك نستخدم كلمة مرور الصدى | sudo -S rm حيث كلمة المرور هي كلمة مرورك.

جمع القمامة


من وقت لآخر ، تحتاج إلى إزالة الحاويات غير المستخدمة حتى لا تشغل مساحة ، لأن هذا النص المكتوب بمثل هذا المحتوى معلق في التاج

 #!/bin/bash #   : docker ps --filter status=dead --filter status=exited -aq | xargs -r docker rm -v #   : yes | docker container prune #    : yes | docker image prune #    : yes | docker volume prune 

يؤدى مرة واحدة في اليوم.

الخلاصة


ساعدنا هذا الحل في تحسين الاختبار وإصدار الميزات الجديدة بشكل كبير. على استعداد للإجابة على الأسئلة ، يتم قبول النقد البناء.

مكافأة


لكي لا تجمع الصور من ملف Dockerfile في كل مرة ، يمكنك تخزينها في سجل عامل الميناء المحلي.

ملف docker-compose.yml
 registry: restart: always image: registry:2 ports: - 5000:5000 volumes: - /opt/docker-registry/data:/var/lib/registry #     


لا يستخدم هذا الخيار المصادقة ، فهذه ليست طريقة آمنة (!!!) ، ولكنها مناسبة لتخزين الصور غير الهامة.

يمكنك تكوين gitlab للعرض

  gitlab_rails['registry_enabled'] = true gitlab_rails['registry_host'] = "registry.test" gitlab_rails['registry_port'] = "5000" 

بعد ذلك ، تظهر قائمة بالصور في gitlab

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


All Articles