Docker Swarm استعمال ڪندي ايپليڪيشنن کي ترتيب ڏيو

آن لائن وڊيو مواد جي سفارش جو نظام جنهن تي اسان ڪم ڪري رهيا آهيون اهو هڪ بند تجارتي ترقي آهي ۽ ٽيڪنيڪل طور تي مالڪي ۽ اوپن سورس حصن جو هڪ گھڻ-جزو ڪلستر آهي. هن آرٽيڪل لکڻ جو مقصد هڪ اسٽيجنگ پليٽ فارم لاءِ ڊاڪر سوارم ڪلسٽرنگ سسٽم جي نفاذ کي بيان ڪرڻ آهي، بغير محدود وقت جي حالتن هيٺ اسان جي عملن جي قائم ڪيل ڪم جي فلو کي ٽوڙڻ جي. توهان جي ڌيان ۾ پيش ڪيل داستان ٻن حصن ۾ ورهايل آهي. پهريون حصو بيان ڪري ٿو CI/CD ڊاکر سوارم استعمال ڪرڻ کان اڳ، ۽ ٻيو حصو ان کي لاڳو ڪرڻ جي عمل کي بيان ڪري ٿو. جن کي پهرين حصي پڙهڻ ۾ دلچسپي نه آهي اهي محفوظ طور تي ٻئي ڏانهن منتقل ڪري سگهن ٿا.

حصو آئون

هڪ دفعي، هڪ CI / CD پروسيس کي جلدي ممڪن طور تي قائم ڪرڻ جي ضرورت هئي. شرطن مان هڪ هو Docker استعمال نه ڪرڻ لڳائڻ لاء اجزاء ڪيترن ئي سببن لاء ترقي ڪئي وئي آهي:

  • پيداوار ۾ اجزاء جي وڌيڪ قابل اعتماد ۽ مستحڪم آپريشن لاءِ (يعني، جوهر ۾، ورچوئلائيزيشن کي استعمال نه ڪرڻ جي گهرج)
  • معروف ڊولپرز ڊاڪر سان ڪم ڪرڻ نه چاهيندا هئا (عجيب، پر اهو ڪيئن هو)
  • آر اينڊ ڊي انتظام جي نظرياتي سببن لاء

MVP لاءِ بنيادي ڍانچي، اسٽيڪ ۽ لڳ ڀڳ شروعاتي ضرورتون ھيٺيون ھيون:

  • 4 Intel® X5650 سرور ڊيبين سان (هڪ وڌيڪ طاقتور مشين مڪمل طور تي ترقي لاءِ)
  • توهان جي پنهنجي ڪسٽم اجزاء جي ترقي C++، Python3 ۾ ڪئي وئي آهي
  • مکيه ٽئين پارٽي جا اوزار استعمال ڪيا ويا: ڪافڪا، ڪلڪ هاؤس، ايئر فلو، ريڊس، گرافانا، پوسٽ گريسل، Mysql، ...
  • ڊيبگ ۽ ڇڏڻ لاءِ جدا جدا حصن جي تعمير ۽ جانچ لاءِ پائپ لائنون

پهرين سوالن مان هڪ آهي جيڪو حل ٿيڻ جي ضرورت آهي شروعاتي اسٽيج تي اهو آهي ته ڪسٽم اجزاء ڪنهن به ماحول (CI/CD) ۾ ڪيئن مقرر ڪيا ويندا.

اسان ٽئين پارٽي جي اجزاء کي سسٽم طور تي نصب ڪرڻ ۽ انهن کي سسٽم طور تي تازه ڪاري ڪرڻ جو فيصلو ڪيو. C++ يا Python ۾ ٺاهيل ڪسٽم ايپليڪيشنون ڪيترن ئي طريقن سان ترتيب ڏئي سگھجن ٿيون. انهن مان، مثال طور: سسٽم پيڪيجز ٺاهڻ، انهن کي گڏ ڪيل تصويرن جي مخزن ڏانهن موڪلڻ ۽ انهن جي بعد ۾ سرور تي تنصيب. اڳ ۾ ئي اڻڄاتل سببن لاء، هڪ ٻيو طريقو چونڊيو ويو آهي، يعني: CI استعمال ڪندي، ايپليڪيشن ايگزيڪيوٽو فائلون گڏ ڪيون وينديون آهن، هڪ ورچوئل پروجيڪٽ ماحول پيدا ڪيو ويندو آهي، py ماڊيول Requiments.txt کان انسٽال ٿيل آهن، ۽ اهي سڀئي نمونا ترتيب، اسڪرپٽ ۽ ترتيب سان گڏ موڪليا ويا آهن. سرور سان گڏ ايپليڪيشن ماحول. اڳيون، ايپليڪيشنون شروع ڪيون ويون آهن مجازي صارف کان بغير منتظم جي حقن جي.

Gitlab-CI چونڊيو ويو CI/CD سسٽم طور. نتيجي ۾ پائپ لائن ڪجهه هن طرح ڏٺو:

Docker Swarm استعمال ڪندي ايپليڪيشنن کي ترتيب ڏيو
ساخت جي طور تي، gitlab-ci.yml هن طرح ڏٺو:

---
variables:
  # минимальная версия ЦПУ на серверах, где разворачивается кластер
  CMAKE_CPUTYPE: "westmere"

  DEBIAN: "MYREGISTRY:5000/debian:latest"

before_script:
  - eval $(ssh-agent -s)
  - ssh-add <(echo "$SSH_PRIVATE_KEY")
  - mkdir -p ~/.ssh && echo -e "Host *ntStrictHostKeyChecking nonn" > ~/.ssh/config

stages:
  - build
  - testing
  - deploy

debug.debian:
  stage: build
  image: $DEBIAN
  script:
    - cd builds/release && ./build.sh
    paths:
      - bin/
      - builds/release/bin/
    when: always
release.debian:
  stage: build
  image: $DEBIAN
  script:
    - cd builds/release && ./build.sh
    paths:
      - bin/
      - builds/release/bin/
    when: always

## testing stage
tests.codestyle:
  stage: testing
  image: $DEBIAN
  dependencies:
    - release.debian
  script:
    - /bin/bash run_tests.sh -t codestyle -b "${CI_COMMIT_REF_NAME}_codestyle"
tests.debug.debian:
  stage: testing
  image: $DEBIAN
  dependencies:
    - debug.debian
  script:
    - /bin/bash run_tests.sh -e codestyle/test_pylint.py -b "${CI_COMMIT_REF_NAME}_debian_debug"
  artifacts:
    paths:
      - run_tests/username/
    when: always
    expire_in: 1 week
tests.release.debian:
  stage: testing
  image: $DEBIAN
  dependencies:
    - release.debian
  script:
    - /bin/bash run_tests.sh -e codestyle/test_pylint.py -b "${CI_COMMIT_REF_NAME}_debian_release"
  artifacts:
    paths:
      - run_tests/username/
    when: always
    expire_in: 1 week

## staging stage
deploy_staging:
  stage: deploy
  environment: staging
  image: $DEBIAN
  dependencies:
    - release.debian
  script:
    - cd scripts/deploy/ &&
        python3 createconfig.py -s $CI_ENVIRONMENT_NAME &&
        /bin/bash install_venv.sh -d -r ../../requirements.txt &&
        python3 prepare_init.d.py &&
        python3 deploy.py -s $CI_ENVIRONMENT_NAME
  when: manual

اها ڳالهه نوٽ ڪرڻ گهرجي ته اسيمبلي ۽ جاچ ان جي پنهنجي تصوير تي ڪيو ويندو آهي، جتي سڀ ضروري سسٽم پيڪيجز اڳ ۾ ئي نصب ٿيل آهن ۽ ٻيون سيٽنگون ڪيون ويون آهن.

جيتوڻيڪ نوڪريءَ ۾ انهن لکتن مان هر هڪ پنهنجي طريقي سان دلچسپ آهي، پر مان يقيناً انهن بابت نه ڳالهائيندس؛ انهن مان هر هڪ کي بيان ڪرڻ ۾ ڪافي وقت لڳندو ۽ اهو مضمون جو مقصد ناهي. مون کي صرف توهان جو ڌيان ان حقيقت ڏانهن ڇڪائڻ ڏيو ته ڊيپلائيمينٽ اسٽيج ڪالنگ اسڪرپٽس جي تسلسل تي مشتمل آهي:

  1. createconfig.py - ترتيب ڏئي ٿو settings.ini فائل مختلف ماحولن ۾ اجزاء جي سيٽنگن سان گڏ بعد ۾ مقرري لاءِ (اڳتي پيداوار، پيداوار، جاچ، ...)
  2. install_venv.sh - هڪ مخصوص ڊاريڪٽري ۾ py اجزاء لاءِ هڪ مجازي ماحول ٺاهي ٿو ۽ ان کي ريموٽ سرورز ڏانهن نقل ڪري ٿو
  3. ready_init.d.py - ٽيمپليٽ جي بنياد تي شروعاتي اسٽاپ اجزاء لاءِ اسڪرپٽ تيار ڪري ٿو
  4. deploy.py - نئين اجزاء کي ترتيب ۽ ٻيهر شروع ڪري ٿو

وقت گذري ويو. اسٽيجنگ اسٽيج کي اڳڀرائي ۽ پيداوار سان تبديل ڪيو ويو. ھڪڙي وڌيڪ تقسيم (CentOS) تي پراڊڪٽ لاءِ سپورٽ شامل ڪئي وئي آھي. ٻيا 5 طاقتور جسماني سرور ۽ هڪ درجن ورچوئل شامل ڪيا ويا. ۽ اهو ڊولپرز ۽ ٽيسٽرز لاءِ تمام گهڻو مشڪل ٿي ويو آهي انهن جي ڪمن کي جانچڻ ماحول ۾ ڪم ڪندڙ رياست جي ويجهو يا گهٽ. هن وقت اهو واضح ٿي ويو ته هن کان سواء اهو ناممڪن هو ...

حصو II

Docker Swarm استعمال ڪندي ايپليڪيشنن کي ترتيب ڏيو

تنهن ڪري، اسان جو ڪلستر هڪ شاندار نظام آهي جيڪو ڪجهه درجن جي انفرادي اجزاء جو بيان نه ڪيو ويو آهي Dockerfiles. توھان ان کي ترتيب ڏئي سگھوٿا صرف عام طور تي ھڪڙي مخصوص ماحول ۾ ترتيب ڏيڻ لاءِ. اسان جو ڪم اهو آهي ته ڪلستر کي اسٽيجنگ ماحول ۾ ترتيب ڏيو ان کي جانچڻ لاءِ پري رليز ٽيسٽنگ کان اڳ.

نظرياتي طور تي، اتي ڪيترائي ڪلستر ٿي سگهن ٿا جيڪي هڪ ئي وقت ڪم ڪري رهيا آهن: جيترا ڪم مڪمل ٿيل حالت ۾ آهن يا مڪمل ٿيڻ جي ويجهو آهن. اسان جي اختياري تي سرور جي طاقت اسان کي اجازت ڏئي ٿي ته هر سرور تي ڪيترائي ڪلستر هلائڻ. هر اسٽيجنگ ڪلستر کي الڳ ڪيو وڃي (بندرگاهن، ڊائريڪٽرن وغيره ۾ اوورليپ نه هجڻ گهرجي).

اسان جو سڀ کان قيمتي وسيلو اسان جو وقت آهي، ۽ اسان وٽ گهڻو ڪجهه نه هو.

تيز شروعات لاءِ، اسان چونڊيو ڊاڪر سوارم ان جي سادگي ۽ لچڪدار فن تعمير جي ڪري. پهرين شيء جيڪا اسان ڪئي هئي هڪ مئنيجر ۽ ڪيترن ئي نوڊس ريموٽ سرور تي ٺاهي وئي:

$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
kilqc94pi2upzvabttikrfr5d     nop-test-1     Ready               Active                                  19.03.2
jilwe56pl2zvabupryuosdj78     nop-test-2     Ready               Active                                  19.03.2
j5a4yz1kr2xke6b1ohoqlnbq5 *   nop-test-3     Ready               Active              Leader              19.03.2

اڳيون، اسان هڪ نيٽ ورڪ ٺاهيو:


$ docker network create --driver overlay --subnet 10.10.10.0/24 nw_swarm

اڳيون، اسان ڳنڍيو Gitlab-CI ۽ سوارم نوڊس جي حوالي سان نوڊس جي ريموٽ مينيجمينٽ جي لحاظ کان CI کان: سرٽيفڪيٽن کي انسٽال ڪرڻ، ڳجهي متغيرن کي ترتيب ڏيڻ، ۽ ڊاکر سروس پڻ ترتيب ڏيڻ مئنيجمينٽ سرور تي. هي هڪ هڪ مضمون اسان کي گهڻو وقت بچايو.

اڳيون، اسان .gitlab-ci .yml ۾ اسٽيڪ ٺاهڻ ۽ تباهه ڪرڻ لاءِ نوڪريون شامل ڪيون.

.gitlab-ci .yml ۾ ڪيتريون ئي نوڪريون شامل ڪيون ويون آهن

## staging stage
deploy_staging:
  stage: testing
  before_script:
    - echo "override global 'before_script'"
  image: "REGISTRY:5000/docker:latest"
  environment: staging
  dependencies: []
  variables:
    DOCKER_CERT_PATH: "/certs"
    DOCKER_HOST: tcp://10.50.173.107:2376
    DOCKER_TLS_VERIFY: 1
    CI_BIN_DEPENDENCIES_JOB: "release.centos.7"
  script:
    - mkdir -p $DOCKER_CERT_PATH
    - echo "$TLSCACERT" > $DOCKER_CERT_PATH/ca.pem
    - echo "$TLSCERT" > $DOCKER_CERT_PATH/cert.pem
    - echo "$TLSKEY" > $DOCKER_CERT_PATH/key.pem
    - docker stack deploy -c docker-compose.yml ${CI_ENVIRONMENT_NAME}_${CI_COMMIT_REF_NAME} --with-registry-auth
    - rm -rf $DOCKER_CERT_PATH
  when: manual

## stop staging stage
stop_staging:
  stage: testing
  before_script:
    - echo "override global 'before_script'"
  image: "REGISTRY:5000/docker:latest"
  environment: staging
  dependencies: []
  variables:
    DOCKER_CERT_PATH: "/certs"
    DOCKER_HOST: tcp://10.50.173.107:2376
    DOCKER_TLS_VERIFY: 1
  script:
    - mkdir -p $DOCKER_CERT_PATH
    - echo "$TLSCACERT" > $DOCKER_CERT_PATH/ca.pem
    - echo "$TLSCERT" > $DOCKER_CERT_PATH/cert.pem
    - echo "$TLSKEY" > $DOCKER_CERT_PATH/key.pem
    - docker stack rm ${CI_ENVIRONMENT_NAME}_${CI_COMMIT_REF_NAME}
    # TODO: need check that stopped
  when: manual

مٿين ڪوڊ جي ٽڪڙي مان اهو واضح ٿئي ٿو ته ٻه بٽڻ شامل ڪيا ويا آهن پائپ لائنز (deploy_staging، stop_staging) جن کي دستي عمل جي ضرورت آهي.

Docker Swarm استعمال ڪندي ايپليڪيشنن کي ترتيب ڏيو
اسٽيڪ جو نالو شاخ جي نالي سان ملندو آهي ۽ اها انفراديت ڪافي هجڻ گهرجي. اسٽيڪ ۾ خدمتون حاصل ڪن ٿيون منفرد IP پتي، ۽ بندرگاهن، ڊائريڪٽرن وغيره. الڳ ٿي ويندو، پر اسٽيڪ کان اسٽيڪ تائين ساڳيو (جيئن ته ترتيب واري فائل سڀني اسٽيڪ لاءِ ساڳي آهي) - اهو ئي آهي جيڪو اسان چاهيون ٿا. اسان استعمال ڪندي اسٽيڪ (ڪلسٽر) کي ترتيب ڏيون ٿا docker-compose.yml، جيڪو اسان جي ڪلستر کي بيان ڪري ٿو.

docker-compose.yml

---
version: '3'

services:
  userprop:
    image: redis:alpine
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:
  celery_bcd:
    image: redis:alpine
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

  schedulerdb:
    image: mariadb:latest
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_DATABASE: schedulerdb
      MYSQL_USER: ****
      MYSQL_PASSWORD: ****
    command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--explicit_defaults_for_timestamp=1']
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

  celerydb:
    image: mariadb:latest
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_DATABASE: celerydb
      MYSQL_USER: ****
      MYSQL_PASSWORD: ****
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

  cluster:
    image: $CENTOS7
    environment:
      - CENTOS
      - CI_ENVIRONMENT_NAME
      - CI_API_V4_URL
      - CI_REPOSITORY_URL
      - CI_PROJECT_ID
      - CI_PROJECT_URL
      - CI_PROJECT_PATH
      - CI_PROJECT_NAME
      - CI_COMMIT_REF_NAME
      - CI_BIN_DEPENDENCIES_JOB
    command: >
      sudo -u myusername -H /bin/bash -c ". /etc/profile &&
        mkdir -p /storage1/$CI_COMMIT_REF_NAME/$CI_PROJECT_NAME &&
        cd /storage1/$CI_COMMIT_REF_NAME/$CI_PROJECT_NAME &&
            git clone -b $CI_COMMIT_REF_NAME $CI_REPOSITORY_URL . &&
            curl $CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=$CI_BIN_DEPENDENCIES_JOB -o artifacts.zip &&
            unzip artifacts.zip ;
        cd /storage1/$CI_COMMIT_REF_NAME/$CI_PROJECT_NAME/scripts/deploy/ &&
            python3 createconfig.py -s $CI_ENVIRONMENT_NAME &&
            /bin/bash install_venv.sh -d -r ../../requirements.txt &&
            python3 prepare_init.d.py &&
            python3 deploy.py -s $CI_ENVIRONMENT_NAME"
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    tty: true
    stdin_open: true
    networks:
      nw_swarm:

networks:
  nw_swarm:
    external: true

هتي توهان ڏسي سگهو ٿا ته اجزاء هڪ نيٽ ورڪ سان ڳنڍيل آهن (nw_swarm) ۽ هڪ ٻئي تائين رسائي لائق آهن.

سسٽم جا حصا (ريڊيس، mysql جي بنياد تي) گراهڪ حصن جي عام تلاء کان جدا ڪيا ويا آهن (منصوبا، ڪسٽم اجزاء پڻ ورهايل آهن خدمتون). اسان جي ڪلسٽر جي ڊيپلائيمينٽ اسٽيج اسان جي ھڪڙي وڏي ترتيب ڏنل تصوير ڏانھن CMD کي منتقل ڪرڻ وانگر نظر اچي ٿي ۽، عام طور تي، حصو I ۾ بيان ڪيل ڊيپلائيمينٽ کان عملي طور تي مختلف ناهي. مان فرق تي زور ڏيندس:

  • گيٽ کلون... - اسان فائلون حاصل ڪندا آهيون جيڪي ترتيب ڏيڻ لاء ضروري آهن (createconfig.py، install_venv.sh، وغيره)
  • ڪرل... && unzip... - تعميراتي نمونن کي ڊائون لوڊ ۽ ان زپ ڪريو (مرتب ڪيل افاديت)

هتي صرف هڪ آهي اڃا تائين اڻ ڄاڻايل مسئلو: اجزاء جيڪي ويب انٽرفيس آهن ڊولپرز جي برائوزرن کان رسائي نه آهن. اسان هن مسئلي کي ريورس پراکسي استعمال ڪندي حل ڪيو، اهڙيء طرح:

.gitlab-ci.yml ۾، ڪلستر اسٽيڪ کي ترتيب ڏيڻ کان پوء، بيلنس کي ترتيب ڏيڻ لاء هڪ لائن شامل ڪريو (جيڪو، جڏهن انجام ڏنو ويو آهي، صرف ان جي ترتيب کي تازه ڪاري ڪري ٿو (نئين نينگڪس ترتيبن جون فائلون ٺاهي ٿو ٽيمپليٽ: /etc/nginx/conf.d) /${CI_COMMIT_REF_NAME}.conf) - ڪوڊ ڏسو docker-compose-nginx.yml)

    - docker stack deploy -c docker-compose-nginx.yml ${CI_ENVIRONMENT_NAME} --with-registry-auth

docker-compose-nginx.yml

---
version: '3'

services:
  nginx:
    image: nginx:latest
    environment:
      CI_COMMIT_REF_NAME: ${CI_COMMIT_REF_NAME}
      NGINX_CONFIG: |-
            server {
                listen 8080;
                server_name staging_${CI_COMMIT_REF_NAME}_cluster.dev;

                location / {
                    proxy_pass http://staging_${CI_COMMIT_REF_NAME}_cluster:8080;
                }
            }
            server {
                listen 5555;
                server_name staging_${CI_COMMIT_REF_NAME}_cluster.dev;

                location / {
                    proxy_pass http://staging_${CI_COMMIT_REF_NAME}_cluster:5555;
                }
            }
    volumes:
      - /tmp/staging/nginx:/etc/nginx/conf.d
    command:
      /bin/bash -c "echo -e "$$NGINX_CONFIG" > /etc/nginx/conf.d/${CI_COMMIT_REF_NAME}.conf;
        nginx -g "daemon off;";
        /etc/init.d/nginx reload"
    ports:
      - 8080:8080
      - 5555:5555
      - 3000:3000
      - 443:443
      - 80:80
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

networks:
  nw_swarm:
    external: true

ڊولپر ڪمپيوٽرن تي، تازه ڪاري /etc/hosts؛ يو آر ايل کي nginx تي سيٽ ڪريو:

10.50.173.106 staging_BRANCH-1831_cluster.dev

تنهن ڪري، الڳ ٿيل اسٽيجنگ ڪلسٽرز جي تعیناتي تي عمل ڪيو ويو آهي ۽ ڊولپرز هاڻي انهن کي ڪنهن به مقدار ۾ شروع ڪري سگهن ٿا انهن جي ڪمن کي جانچڻ لاء ڪافي.

مستقبل جا منصوبا:

  • خدمتن جي طور تي اسان جي اجزاء کي الڳ ڪريو
  • هر هڪ لاء هڪ Dockerfile ٺاهيو
  • خودڪار طور تي اسٽيڪ ۾ گهٽ لوڊ ٿيل نوڊس کي ڳوليو
  • نالي جي ٽيمپليٽ استعمال ڪندي نوڊس جي وضاحت ڪريو (مضمون ۾ آئي ڊي استعمال ڪرڻ بدران)
  • چيڪ شامل ڪريو ته اسٽيڪ تباهه ٿي ويو آهي
  • ...

لاء خاص مهرباني مضمون.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو