مرحبا يا هبر! في هذه المقالة ، أريد مشاركة تجربة نشر خادم اختبار لفريق التطوير. باختصار جوهر المشكلة - هناك فريق تطوير والعديد من المشاريع في PHP. بينما كنا صغارًا وكان المشروع في الأساس واحدًا ، استخدمنا خادمًا تجريبيًا واحدًا ولإظهار المهمة للعميل ، قام المطور بإعداد "عمود" الخادم لفترة معينة. إذا لم تكن هناك "نوافذ" في الوقت المناسب ، فعلينا الانتظار. مع مرور الوقت ، زاد الفريق وتعقيد المهام ، على التوالي ، وزاد وقت التحقق وازدحام خادم الاختبار ، مما أثر سلبًا على المهلة والمكافأة. لذلك ، كان علي أن أبحث عن حل وهو تحت القطع.
تمهيدي
ماذا كان:
- خادم اختبار واحد
- Gitlab و redmine على خادم آخر
- الرغبة في حل مشكلة
جميع الخوادم في شبكتنا المحلية ، ولا يمكن الوصول إلى خادم الاختبار من الخارج.
ما هو المطلوب:
- القدرة على اختبار مشاريع / فروع متعددة في نفس الوقت
- يمكن للمطور الذهاب إلى الخادم وإعداده وعدم فصل أي شيء عن الآخرين
- يجب أن يكون كل شيء مناسبًا قدر الإمكان وأن يتم على زر واحد ، ويفضل أن يكون من gitlab (CI / CD).
خيارات القرار
1. خادم واحد ، العديد من المضيفين
الخيار الأسهل. نستخدم نفس خادم الاختبار ، يحتاج المطور فقط إلى إنشاء مضيف لكل فرع / مشروع وإضافته إلى تكوين nginx / apache2.
الإيجابيات:
- بسرعة ويفهم الجميع
- يمكن أتمتة
السلبيات:
- لا يتم استيفاء البند 2 من المتطلبات - يمكن للمطور بدء تحديث قاعدة البيانات ، وفي بعض الظروف ، وضع كل شيء في (Hi Andrey!)
- أتمتة معقدة للغاية مع مجموعة من ملفات التكوين
2. لكل مطور على الخادم!
خصص لكل خادم والمطور مسؤول عن اقتصاده.
الإيجابيات:
- يمكن للمطور تخصيص الخادم بالكامل لمشروعك
السلبيات:
- لم يتم استيفاء البند 2 من المتطلبات
- يمكن أن تكون الموارد باهظة الثمن والموارد مكتوفة الأيدي أثناء التطوير ، وليس الاختبار
- الأتمتة أكثر تعقيدًا مما كانت عليه في النقطة 1 بسبب الخوادم المختلفة
3. حاويات - الرصيف ، kubernetes
هذه التكنولوجيا تخترق حياتنا بشكل متزايد. في المنزل ، كنت أستخدم عامل الرصيف لمشاريعي لفترة طويلة.
Docker - برنامج لأتمتة نشر وإدارة التطبيقات في بيئة افتراضية على مستوى نظام التشغيل. يتيح لك "حزم" التطبيق مع كل ما يحيط به وتبعياته في حاوية يمكن نقلها إلى أي نظام Linux مع دعم cgroups في النواة ، كما يوفر بيئة لإدارة الحاوية.
الإيجابيات:
- يتم استخدام خادم واحد
- تم استيفاء جميع المتطلبات.
السلبيات:
- تستهلك الصور والحاويات أحيانًا مساحة كبيرة ، عليك تنظيف التيجان القديمة بالفعل لتوفير مساحة.
تنفيذ عامل الميناء
عند استخدام 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 docker-compose.yml # - docker-compose down # - docker-compose up -d --build # - script -q -c cd ../ && php composer.phar install --prefer-dist \ # - script -q -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 cd ../ && php composer.phar install --prefer-dist --no-dev\ - script -q -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 حيث كلمة المرور هي كلمة مرورك.
جمع القمامة
من وقت لآخر ، تحتاج إلى إزالة الحاويات غير المستخدمة حتى لا تشغل مساحة ، لأن هذا النص المكتوب بمثل هذا المحتوى معلق في التاج
يؤدى مرة واحدة في اليوم.
الخلاصة
ساعدنا هذا الحل في تحسين الاختبار وإصدار الميزات الجديدة بشكل كبير. على استعداد للإجابة على الأسئلة ، يتم قبول النقد البناء.
مكافأة
لكي لا تجمع الصور من ملف 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
