GitLab شل عداء. إطلاق تنافسي لخدمات الاختبار باستخدام Docker Compose


سيكون هذا المقال ذا أهمية لكل من المختبرين والمطورين ، ولكنه يستهدف بشكل أكبر شركات التشغيل التي تواجه مشكلة تكوين GitLab CI / CD لاختبار التكامل في ظروف موارد البنية التحتية غير الكافية و / أو عدم وجود نظام أساسي لتنسيق الحاوية. سوف أخبرك بكيفية تكوين نشر بيئات الاختبار باستخدام عامل التشغيل الذي يتم إنشاؤه على عداء GitLab shell واحد وعند نشر بيئات متعددة ، لا تتداخل الخدمات التي يتم إطلاقها مع بعضها البعض.



محتوى




الشروط


  1. في ممارستي ، غالبًا ما حدث "شفاء" اختبار التكامل في المشروعات. وغالبًا ما تكون المشكلة الأولى والأكثر أهمية هي خط أنابيب CI ، حيث يتم إجراء اختبار تكامل للخدمة (الخدمات) المتقدمة في بيئة تطوير / مرحلة. تسبب هذا في عدد غير قليل من المشاكل:


    • نظرًا لوجود عيوب في خدمة معينة أثناء اختبار التكامل ، قد تتلف دائرة الاختبار بسبب البيانات المعطلة. كانت هناك حالات عند إرسال طلب بتنسيق JSON مقطوع ، علقت إحدى الخدمات ، الأمر الذي أدى إلى توقف تشغيل الحامل تمامًا.
    • تباطؤ حلقة الاختبار مع نمو بيانات الاختبار. أعتقد أنه لا معنى لوصف مثال مع تنظيف / استعادة قاعدة بيانات. في ممارستي ، لم أر مشروعًا تمت فيه هذه العملية بسلاسة.
    • خطر تعطيل أداء دائرة الاختبار عند اختبار إعدادات النظام العامة. على سبيل المثال ، سياسة المستخدم / المجموعة / كلمة المرور / التطبيق.
    • تمنع بيانات الاختبار من الاختبارات الذاتية من العيش في الاختبار.

    سيقول شخص ما إن الاختبارات التلقائية الجيدة يجب أن تنظف البيانات بعدها. لدي حجج ضد:


    • المدرجات الديناميكية مريحة للغاية للاستخدام.
    • لا يمكن حذف كل كائن من النظام من خلال API. على سبيل المثال ، لم يتم تنفيذ استدعاء لحذف كائن ، لأنه يتعارض مع منطق العمل.
    • عند إنشاء كائن من خلال واجهة برمجة التطبيقات ، يمكن إنشاء كمية هائلة من البيانات التعريفية ، مما يصعب حذفه.
    • إذا كانت الاختبارات مترابطة ، فإن عملية تنظيف البيانات بعد الانتهاء من الاختبارات تتحول إلى صداع.
    • مكالمات إضافية (وفي رأيي غير مبررة) إلى واجهة برمجة التطبيقات.
    • والحجة الرئيسية: عندما تبدأ بيانات الاختبار في التنظيف مباشرة من قاعدة البيانات. يتحول إلى سيرك PK / FK حقيقي! من المطورين يكون مسموعًا: "لقد قمت فقط بإضافة / حذف / إعادة تسمية اللوحة ، لماذا فشل اختبار التكامل 100500؟"

    في رأيي ، الحل الأمثل هو بيئة ديناميكية.


  2. يستخدم العديد من الأشخاص عامل إنشاء عامل الإرساء لتشغيل بيئة اختبار ، ولكن عددًا قليلًا من المستخدمين يستخدم تكوين عامل ربط عند إجراء اختبار التكامل في CI / CD. وهنا لا تأخذ في الاعتبار kubernetes والسرب وغيرها من منصات تزامن الحاويات. ليس كل شركة لديها. سيكون من الرائع لو كان عامل الإرساء - compose.yml عالميًا.
  3. حتى إذا كان لدينا عداء ضمان الجودة الخاص بنا ، كيف يمكننا التأكد من أن الخدمات التي يتم إطلاقها من خلال عامل الإرساء لا تتداخل مع بعضها البعض؟
  4. كيفية جمع سجلات الخدمات المختبرة؟
  5. كيفية تنظيف عداء؟

لديّ عداء GitLab الخاص بمشاريعي وقد صادفت هذه المشكلات عند تطوير عميل Java لـ TestRail . أو بالأحرى ، عند إجراء اختبارات التكامل. فيما يلي ، سنحل هذه المشكلات بأمثلة من هذا المشروع.


إلى المحتوى



Gitlab قذيفة عداء


بالنسبة للعداء ، أوصي بجهاز Linux ظاهري يحتوي على 4 وحدات تحكم في وحدة المعالجة المركزية (VCPU) وذاكرة وصول عشوائي (RAM) سعة 4 جيجابايت و 50 جيجابايت محرك أقراص ثابتة.
على الإنترنت ، الكثير من المعلومات حول تكوين gitlab-runner ، وذلك باختصار:


  • نذهب إلى الجهاز على SSH
  • إذا كان لديك أقل من 8 جيجابايت من ذاكرة الوصول العشوائي ، فإنني أوصي بإجراء مبادلة قدرها 10 جيجابايت حتى لا يأتي قاتل OOM ولا يقتلنا بسبب نقص ذاكرة الوصول العشوائي. يمكن أن يحدث هذا عندما يتم تشغيل أكثر من 5 مهام في وقت واحد. المهام ستكون أبطأ ، لكنها مستقرة.


    مثال قاتل OOM

    إذا رأيت bash: line 82: 26474 Killed في سجلات المهام ، ثم قم بتشغيل sudo dmesg | grep 26474 sudo dmesg | grep 26474


     [26474] 1002 26474 1061935 123806 339 0 0 java Out of memory: Kill process 26474 (java) score 127 or sacrifice child Killed process 26474 (java) total-vm:4247740kB, anon-rss:495224kB, file-rss:0kB, shmem-rss:0kB 

    وإذا كانت الصورة تبدو مثل هذا ، فقم إما بإضافة مبادلة أو إسقاط RAM.




  • تثبيت gitlab- عداء ، عامل ميناء ، عامل ميناء الإنشاء ، وجعل.
  • أضف gitlab-runner user to gitlab-runner group
     sudo groupadd docker sudo usermod -aG docker gitlab-runner 
  • تسجيل gitlab عداء.
  • فتح للتحرير / /etc/gitlab-runner/config.toml / /etc/gitlab-runner/config.toml / /etc/gitlab-runner/config.toml وإضافة


     concurrent=20 [[runners]] request_concurrency = 10 

    سيتيح لك ذلك تشغيل مهام متوازية على عداء واحد. اقرأ المزيد هنا .
    إذا كان جهازك أكثر قوة ، على سبيل المثال ، 8 vCPU ، 16 جيجابايت من ذاكرة الوصول العشوائي ، يمكن جعل هذه الأرقام أكبر مرتين على الأقل. لكن كل هذا يتوقف على ما سيتم إطلاقه بالضبط على هذا العداء وبأي كمية.



هذا يكفي.


إلى المحتوى



إعداد عامل ميناء compose.yml


المهمة الرئيسية هي docker-compose.yml ، والتي سيتم استخدامها محليا وفي خط أنابيب CI.


سيتم استخدام المتغير COMPOSE_PROJECT_NAME لبدء عدة مثيلات للبيئة (راجع ملف التعريف).


مثال لبلدي عامل ميناء compose.yml


 version: "3" #    web (php)  fmt , #      . #   ,   /var/www/testrail volumes: static-content: services: db: image: mysql:5.7.22 environment: MYSQL_HOST: db MYSQL_DATABASE: mydb MYSQL_ROOT_PASSWORD: 1234 SKIP_GRANT_TABLES: 1 SKIP_NETWORKING: 1 SERVICE_TAGS: dev SERVICE_NAME: mysql migration: image: registry.gitlab.com/touchbit/image/testrail/migration:latest links: - db depends_on: - db fpm: image: registry.gitlab.com/touchbit/image/testrail/fpm:latest container_name: "testrail-fpm-${CI_JOB_ID:-local}" volumes: - static-content:/var/www/testrail links: - db web: image: registry.gitlab.com/touchbit/image/testrail/web:latest #   TR_HTTP_PORT  TR_HTTPS_PORTS  , #     80  443  . ports: - ${TR_HTTP_PORT:-80}:80 - ${TR_HTTPS_PORT:-443}:443 volumes: - static-content:/var/www/testrail links: - db - fpm 

إلى المحتوى



إعداد Makefile


يمكنني استخدام Makefile ، لأنه مناسب جدًا لكل من الإدارة المحلية للبيئة وفي CI.


مزيد من التعليقات مضمنة


 #           `.indirect`, #     `docker-compose.yml` #  bash   pipefail # pipefail -   ,      SHELL=/bin/bash -o pipefail #   CI_JOB_ID   ifeq ($(CI_JOB_ID),) #   local CI_JOB_ID := local endif #    export COMPOSE_PROJECT_NAME = $(CI_JOB_ID)-testrail #    , , volumes docker-down: docker-compose -f .indirect/docker-compose.yml down #   docker-down () docker-up: docker-down #     docker-registry docker-compose -f .indirect/docker-compose.yml pull #   # force-recreate -    # renew-anon-volumes -   volumes   docker-compose -f .indirect/docker-compose.yml up --force-recreate --renew-anon-volumes -d #  ,   ,           docker ps #    docker-logs: mkdir -p ./logs docker logs $${COMPOSE_PROJECT_NAME}_web_1 >& logs/testrail-web.log || true docker logs $${COMPOSE_PROJECT_NAME}_fpm_1 >& logs/testrail-fpm.log || true docker logs $${COMPOSE_PROJECT_NAME}_migration_1 >& logs/testrail-migration.log || true docker logs $${COMPOSE_PROJECT_NAME}_db_1 >& logs/testrail-mysql.log || true #   docker-clean: @echo   testrail- docker kill $$(docker ps --filter=name=testrail -q) || true @echo    docker rm -f $$(docker ps -a -f --filter=name=testrail status=exited -q) || true @echo  dangling  docker rmi -f $$(docker images -f "dangling=true" -q) || true @echo  testrail  docker rmi -f $$(docker images --filter=reference='registry.gitlab.com/touchbit/image/testrail/*' -q) || true @echo    volume docker volume rm -f $$(docker volume ls -q) || true @echo   testrail  docker network rm $(docker network ls --filter=name=testrail -q) || true docker ps 

تحقق الاطلاق المحلي
 $ make docker-up docker-compose -f .indirect/docker-compose.yml pull Pulling db ... done Pulling migration ... done Pulling fpm ... done Pulling web ... done docker-compose -f .indirect/docker-compose.yml up --force-recreate --renew-anon-volumes -d Creating network "local-testrail_default" with the default driver Recreating local-testrail_db_1 ... done Recreating local-testrail_migration_1 ... done Recreating local-testrail_fpm_1 ... done Recreating local-testrail_web_1 ... done docker ps CONTAINER ID NAMES 3b8f9d4af29c local-testrail_web_1 5622c7d742d5 local-testrail_fpm_1 b580e3392038 local-testrail_migration_1 e467630bd3a5 local-testrail_db_1 

التحقق من إطلاق CI
 $ export CI_JOB_ID=123456789 $ make docker-up docker-compose -f .indirect/docker-compose.yml pull Pulling db ... done Pulling migration ... done Pulling fpm ... done Pulling web ... done docker-compose -f .indirect/docker-compose.yml up --force-recreate --renew-anon-volumes -d Creating network "123456789-testrail_default" with the default driver Creating volume "123456789-testrail_static-content" with default driver Creating 123456789-testrail_db_1 ... done Creating 123456789-testrail_fpm_1 ... done Creating 123456789-testrail_migration_1 ... done Creating 123456789-testrail_web_1 ... done docker ps CONTAINER ID NAMES ccf1ad33d0e8 123456789-testrail_web_1 bc079964f681 123456789-testrail_fpm_1 10dc9d4d8f2a 123456789-testrail_migration_1 fe98d43c380e 123456789-testrail_db_1 

تحقق جمع السجل
 $ make docker-logs mkdir -p ./logs docker logs ${COMPOSE_PROJECT_NAME}_web_1 >& logs/testrail-web.log || true docker logs ${COMPOSE_PROJECT_NAME}_fpm_1 >& logs/testrail-fpm.log || true docker logs ${COMPOSE_PROJECT_NAME}_migration_1 >& logs/testrail-migration.log || true docker logs ${COMPOSE_PROJECT_NAME}_db_1 >& logs/testrail-mysql.log || true 


إلى المحتوى



إعداد .gitlab-ci.yml



تشغيل اختبارات التكامل


 Integration: stage: test tags: - my-shell-runner before_script: #   registry - docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY} #   TR_HTTP_PORT  TR_HTTPS_PORT - export TR_HTTP_PORT=$(shuf -i10000-60000 -n1) - export TR_HTTPS_PORT=$(shuf -i10000-60000 -n1) script: #    - make docker-up #    jar (  ) - java -jar itest.jar --http-port ${TR_HTTP_PORT} --https-port ${TR_HTTPS_PORT} #    - docker run --network=testrail-network-${CI_JOB_ID:-local} --rm itest after_script: #   - make docker-logs #   - make docker-down artifacts: #   when: always paths: - logs expire_in: 30 days 

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



إلى المحتوى



عداء التنظيف


سيتم تشغيل المهمة فقط في الموعد المحدد.


 stages: - clean - build - test Clean runner: stage: clean only: - schedules tags: - my-shell-runner script: - make docker-clean 

بعد ذلك ، انتقل إلى مشروع GitLab الخاص بنا -> CI / CD -> الجداول -> جدول جديد وإضافة جدول جديد



إلى المحتوى



يؤدي


تشغيل 4 مهام في GitLab CI


في سجلات المهمة الأخيرة مع اختبارات التكامل ، نرى حاويات من مهام مختلفة


 CONTAINER ID NAMES c6b76f9135ed 204645172-testrail-web_1 01d303262d8e 204645172-testrail-fpm_1 2cdab1edbf6a 204645172-testrail-migration_1 826aaf7c0a29 204645172-testrail-mysql_1 6dbb3fae0322 204645084-testrail-web_1 3540f8d448ce 204645084-testrail-fpm_1 70fea72aa10d 204645084-testrail-mysql_1 d8aa24b2892d 204644881-testrail-web_1 6d4ccd910fad 204644881-testrail-fpm_1 685d8023a3ec 204644881-testrail-mysql_1 1cdfc692003a 204644793-testrail-web_1 6f26dfb2683e 204644793-testrail-fpm_1 029e16b26201 204644793-testrail-mysql_1 c10443222ac6 204567103-testrail-web_1 04339229397e 204567103-testrail-fpm_1 6ae0accab28d 204567103-testrail-mysql_1 b66b60d79e43 204553690-testrail-web_1 033b1f46afa9 204553690-testrail-fpm_1 a8879c5ef941 204553690-testrail-mysql_1 069954ba6010 204553539-testrail-web_1 ed6b17d911a5 204553539-testrail-fpm_1 1a1eed057ea0 204553539-testrail-mysql_1 

سجل أكثر تفصيلا
 $ docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY} WARNING! Using --password via the CLI is insecure. Use --password-stdin. WARNING! Your password will be stored unencrypted in /home/gitlab-runner/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded $ export TR_HTTP_PORT=$(shuf -i10000-60000 -n1) $ export TR_HTTPS_PORT=$(shuf -i10000-60000 -n1) $ mkdir ${CI_JOB_ID} $ cp .indirect/docker-compose.yml ${CI_JOB_ID}/docker-compose.yml $ make docker-up docker-compose -f ${CI_JOB_ID:-.indirect}/docker-compose.yml kill docker network rm testrail-network-${CI_JOB_ID:-local} || true Error: No such network: testrail-network-204645172 docker network create testrail-network-${CI_JOB_ID:-local} 0a59552b4464b8ab484de6ae5054f3d5752902910bacb0a7b5eca698766d0331 docker-compose -f ${CI_JOB_ID:-.indirect}/docker-compose.yml pull Pulling web ... done Pulling fpm ... done Pulling migration ... done Pulling db ... done docker-compose -f ${CI_JOB_ID:-.indirect}/docker-compose.yml up --force-recreate --renew-anon-volumes -d Creating volume "204645172-testrail_static-content" with default driver Creating 204645172-testrail-mysql_1 ... Creating 204645172-testrail-mysql_1 ... done Creating 204645172-testrail-migration_1 ... done Creating 204645172-testrail-fpm_1 ... done Creating 204645172-testrail-web_1 ... done docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c6b76f9135ed registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" 13 seconds ago Up 1 second 0.0.0.0:51148->80/tcp, 0.0.0.0:25426->443/tcp 204645172-testrail-web_1 01d303262d8e registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" 16 seconds ago Up 13 seconds 9000/tcp 204645172-testrail-fpm_1 2cdab1edbf6a registry.gitlab.com/touchbit/image/testrail/migration:latest "docker-entrypoint.s…" 16 seconds ago Up 13 seconds 3306/tcp, 33060/tcp 204645172-testrail-migration_1 826aaf7c0a29 mysql:5.7.22 "docker-entrypoint.s…" 18 seconds ago Up 16 seconds 3306/tcp 204645172-testrail-mysql_1 6dbb3fae0322 registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" 36 seconds ago Up 22 seconds 0.0.0.0:44202->80/tcp, 0.0.0.0:20151->443/tcp 204645084-testrail-web_1 3540f8d448ce registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" 38 seconds ago Up 35 seconds 9000/tcp 204645084-testrail-fpm_1 70fea72aa10d mysql:5.7.22 "docker-entrypoint.s…" 40 seconds ago Up 37 seconds 3306/tcp 204645084-testrail-mysql_1 d8aa24b2892d registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" About a minute ago Up 53 seconds 0.0.0.0:31103->80/tcp, 0.0.0.0:43872->443/tcp 204644881-testrail-web_1 6d4ccd910fad registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" About a minute ago Up About a minute 9000/tcp 204644881-testrail-fpm_1 685d8023a3ec mysql:5.7.22 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp 204644881-testrail-mysql_1 1cdfc692003a registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:44752->80/tcp, 0.0.0.0:23540->443/tcp 204644793-testrail-web_1 6f26dfb2683e registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" About a minute ago Up About a minute 9000/tcp 204644793-testrail-fpm_1 029e16b26201 mysql:5.7.22 "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp 204644793-testrail-mysql_1 c10443222ac6 registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" 5 hours ago Up 5 hours 0.0.0.0:57123->80/tcp, 0.0.0.0:31657->443/tcp 204567103-testrail-web_1 04339229397e registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" 5 hours ago Up 5 hours 9000/tcp 204567103-testrail-fpm_1 6ae0accab28d mysql:5.7.22 "docker-entrypoint.s…" 5 hours ago Up 5 hours 3306/tcp 204567103-testrail-mysql_1 b66b60d79e43 registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" 5 hours ago Up 5 hours 0.0.0.0:56321->80/tcp, 0.0.0.0:58749->443/tcp 204553690-testrail-web_1 033b1f46afa9 registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" 5 hours ago Up 5 hours 9000/tcp 204553690-testrail-fpm_1 a8879c5ef941 mysql:5.7.22 "docker-entrypoint.s…" 5 hours ago Up 5 hours 3306/tcp 204553690-testrail-mysql_1 069954ba6010 registry.gitlab.com/touchbit/image/testrail/web:latest "nginx -g 'daemon of…" 5 hours ago Up 5 hours 0.0.0.0:32869->80/tcp, 0.0.0.0:16066->443/tcp 204553539-testrail-web_1 ed6b17d911a5 registry.gitlab.com/touchbit/image/testrail/fpm:latest "docker-php-entrypoi…" 5 hours ago Up 5 hours 9000/tcp 204553539-testrail-fpm_1 1a1eed057ea0 mysql:5.7.22 "docker-entrypoint.s…" 5 hours ago Up 5 hours 3306/tcp 204553539-testrail-mysql_1 

تم إنجاز جميع المهام بنجاح

التحف المهمة تحتوي على سجلات الخدمة والاختبار



يبدو أن كل شيء جميل ، ولكن هناك فارق بسيط. يمكن إلغاء خط الأنابيب قسراً أثناء تنفيذ اختبارات التكامل ، وفي هذه الحالة لن يتم إيقاف تشغيل الحاويات قيد التشغيل. من وقت لآخر تحتاج إلى تنظيف العداء. لسوء الحظ ، لا تزال مهمة المراجعة في GitLab CE في حالة فتح


لكننا أضفنا إطلاق المهمة المجدولة ، ولا أحد يمنعنا من بدء التشغيل يدويًا.
انتقل إلى مشروعنا -> CI / CD -> جداول وقم بتشغيل المهمة Clean runner



المجموع:


  • لدينا عداء قذيفة واحد.
  • لا توجد تعارضات بين المهام والبيئة.
  • لدينا إطلاق مواز للمهام مع اختبارات التكامل.
  • يمكنك تشغيل اختبارات التكامل محليًا وفي الحاوية.
  • يتم جمع سجلات الخدمات والاختبارات وإرفاقها بمهمة خط الأنابيب.
  • من الممكن تنظيف العداء من صور عامل الميناء القديمة.

وقت الإعداد هو ~ 2 ساعة.
هذا ، في الواقع ، هو كل شيء. سوف أكون سعيدا لردود الفعل.


PS
شكر خاص ل freeseacher vvasilenok ivanych . تعليقاتكم كانت قيمة للغاية في سياق المنشور.


إلى المحتوى

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


All Articles