Տեղադրեք հավելվածները Docker Swarm-ի հետ

Առցանց տեսաբովանդակության առաջարկությունների համակարգը, որի վրա մենք աշխատում ենք, փակ առևտրային մշակում է և տեխնիկապես սեփական և բաց կոդով բաղադրիչների բազմաբաղադրիչ կլաստեր է: Այս հոդվածը գրելու նպատակն է նկարագրել դոկերային ոհմակի կլաստերավորման համակարգի ներդրումը փուլային տեղամասի համար՝ առանց սահմանափակ ժամանակում մեր գործընթացների հաստատված աշխատանքային հոսքը խաթարելու: Ձեր ուշադրությանը ներկայացված պատմվածքը բաժանված է երկու մասի. Առաջին մասը նկարագրում է CI / CD-ն նախքան docker swarm-ը օգտագործելը, իսկ երկրորդը նկարագրում է դրա իրականացման գործընթացը: Նրանք, ովքեր չեն հետաքրքրվում առաջին մասի ընթերցմամբ, կարող են հանգիստ անցնել երկրորդին:

Մաս I

Դեռ հեռավոր, հեռավոր տարում անհրաժեշտ էր հնարավորինս արագ կարգավորել CI / CD գործընթացը: Պայմաններից մեկը Docker-ը չօգտագործելն էր տեղակայման համար մշակված բաղադրիչները մի քանի պատճառներով.

  • Արտադրության մեջ բաղադրիչների ավելի հուսալի և կայուն շահագործման համար (այսինքն, ըստ էության, վիրտուալացում չօգտագործելու պահանջն է)
  • առաջատար մշակողները չէին ցանկանում աշխատել Docker-ի հետ (տարօրինակ է, բայց դա այդպես էր)
  • համաձայն R&D ղեկավարության գաղափարական նկատառումների

Ենթակառուցվածքը, կույտը և MVP-ի մոտավոր նախնական պահանջները ներկայացվել են հետևյալ կերպ.

  • 4 Intel® X5650 սերվեր Debian-ով (ևս մեկ հզոր մեքենա լիովին մշակված է)
  • Սեփական մաքսային բաղադրիչների մշակումն իրականացվում է C ++, Python3-ում
  • Օգտագործված հիմնական երրորդ կողմի գործիքները՝ Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,…
  • Խողովակաշարեր՝ առանձին բաղադրիչների կառուցման և փորձարկման համար վրիպազերծման և թողարկման համար

Առաջին հարցերից մեկը, որը պետք է լուծվի սկզբնական փուլում, այն է, թե ինչպես են մաքսային բաղադրիչները տեղակայվելու ցանկացած միջավայրում (CI/CD):

Մենք որոշեցինք համակարգային կերպով տեղադրել երրորդ կողմի բաղադրիչները և թարմացնել դրանք համակարգային: C++ կամ Python-ով մշակված անհատական ​​հավելվածները կարող են տեղակայվել մի քանի ձևով: Դրանցից, օրինակ՝ համակարգային փաթեթների ստեղծում, դրանք կառուցված պատկերների շտեմարան ուղարկելու և այնուհետև սերվերների վրա տեղադրում: Անհայտ պատճառով ընտրվել է մեկ այլ մեթոդ, այն է՝ օգտագործելով CI, հավելվածի գործարկվող ֆայլերը կազմվում են, ստեղծվում է վիրտուալ նախագծի միջավայր, py մոդուլները տեղադրվում են request.txt-ից, և այս բոլոր արտեֆակտներն ուղարկվում են կոնֆիգուրների, սկրիպտների և ուղեկցող կիրառական միջավայր սերվերներին: Հաջորդը, հավելվածները գործարկվում են որպես վիրտուալ օգտվող՝ առանց ադմինիստրատորի իրավունքների:

Որպես CI/CD համակարգ ընտրվել է Gitlab-CI: Ստացված խողովակաշարն այսպիսի տեսք ուներ.

Տեղադրեք հավելվածները 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. prede_init.d.py — կաղապարի հիման վրա բաղադրիչի համար պատրաստում է start-stop սկրիպտներ
  4. deploy.py - քայքայվում և վերագործարկում է նոր բաղադրիչները

Ժամանակն անցավ։ Բեմական փուլը փոխարինվեց նախաարտադրությամբ և արտադրությամբ։ Ավելացվեց արտադրանքի աջակցությունը ևս մեկ բաշխման վրա (CentOS): Ավելացվեց ևս 5 հզոր ֆիզիկական սերվեր և մեկ տասնյակ վիրտուալ: Եվ ծրագրավորողների և փորձարկողների համար ավելի ու ավելի դժվար էր դառնում իրենց առաջադրանքները փորձարկել աշխատանքային վիճակին քիչ թե շատ մոտ միջավայրում։ Այս պահին պարզ դարձավ, որ անհնար է անել առանց նրա ...

Մաս II

Տեղադրեք հավելվածները Docker Swarm-ի հետ

Այսպիսով, մեր կլաստերը մի քանի տասնյակ առանձին բաղադրիչներից բաղկացած տպավորիչ համակարգ է, որոնք նկարագրված չեն Dockerfiles-ի կողմից: Դուք կարող եք կարգավորել այն միայն ընդհանուր առմամբ որոշակի միջավայրում տեղակայման համար: Մեր խնդիրն է կլաստերը տեղակայել բեմական միջավայրում, որպեսզի փորձարկենք այն նախքան թողարկումից առաջ փորձարկումը:

Տեսականորեն կարող են լինել մի քանի կլաստերներ, որոնք աշխատում են միաժամանակ՝ այնքան, որքան առաջադրանք կա ավարտված վիճակում կամ ավարտին մոտ: Մեր տրամադրության տակ գտնվող սերվերների հնարավորությունները մեզ թույլ են տալիս գործարկել մի քանի կլաստերներ յուրաքանչյուր սերվերի վրա: Յուրաքանչյուր բեմական կլաստեր պետք է մեկուսացված լինի (նավահանգիստներում, դիրեկտորիաներում և այլն խաչմերուկ չպետք է լինի):

Մեր ամենաարժեքավոր ռեսուրսը մեր ժամանակն է, և մենք դրանից շատ բան չունեինք:

Ավելի արագ մեկնարկի համար մենք ընտրեցինք Docker Swarm-ը՝ շնորհիվ իր պարզության և ճարտարապետության ճկունության: Առաջին բանը, որ մենք արեցինք, մենեջեր և մի քանի հանգույցներ ստեղծելն էր հեռավոր սերվերների վրա.

$ 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 և Swarm հանգույցները CI-ից հանգույցների հեռակառավարման առումով՝ սերտիֆիկատների տեղադրում, գաղտնի փոփոխականների տեղադրում և հսկիչ սերվերի վրա Docker ծառայության կարգավորում: Այս մեկը հոդված մեզ շատ ժամանակ խնայեց:

Հաջորդը, մենք ավելացրեցինք stack-ի ստեղծման և ոչնչացման աշխատանքները .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) ավելացվել են Pipelines-ին, որոնք պահանջում են ձեռքով գործողություն:

Տեղադրեք հավելվածները Docker Swarm-ի հետ
Կույտի անունը համապատասխանում է մասնաճյուղի անվանմանը, և այս եզակիությունը պետք է բավարար լինի: Ծառայությունները փաթեթում ստանում են եզակի ip հասցեներ և նավահանգիստներ, դիրեկտորիաներ և այլն: կլինի մեկուսացված, բայց նույնը բուրգից բուրգ (քանի որ կազմաձևման ֆայլը նույնն է բոլոր կույտերի համար) - այն, ինչ մենք ուզում էինք: Մենք տեղակայում ենք ստեկը (կլաստերը)՝ օգտագործելով դոկտոր-կոմպոզ.իմլ, որը նկարագրում է մեր կլաստերը:

դոկտոր-կոմպոզ.իմլ

---
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) և հասանելի են միմյանց։

Համակարգի բաղադրիչները (հիմնված redis, mysql-ի վրա) առանձնացված են մաքսային բաղադրիչների ընդհանուր լողավազանից (պլաններում և մաքսայինները բաժանվում են որպես ծառայություններ): Մեր կլաստերի տեղակայման փուլը նման է CMD-ի փոխանցմանը մեր մեկ մեծ կազմաձևված պատկերին և, ընդհանուր առմամբ, գործնականում չի տարբերվում I մասում նկարագրված տեղակայումից: Ես ընդգծեմ տարբերությունները.

  • git clone... - ստացեք տեղակայման համար անհրաժեշտ ֆայլերը (createconfig.py, install_venv.sh և այլն)
  • ոլորել... && unzip... - ներբեռնեք և բացեք շինարարական արտեֆակտները (կազմված կոմունալ ծառայություններ)

Կա միայն մեկ, դեռ չնկարագրված խնդիր. վեբ ինտերֆեյս ունեցող բաղադրիչները հասանելի չեն մշակողների բրաուզերներից: Մենք լուծում ենք այս խնդիրը՝ օգտագործելով հակադարձ պրոքսի, այսպիսով.

.gitlab-ci.yml-ում, կլաստերի կույտը տեղակայելուց հետո, մենք ավելացնում ենք հավասարակշռողի տեղակայման գիծը (որը, երբ կատարում է, թարմացնում է միայն դրա կազմաձևումը (ստեղծում է նոր nginx կազմաձևման ֆայլեր ըստ ձևանմուշի. /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; նշանակել url-ը nginx-ին.

10.50.173.106 staging_BRANCH-1831_cluster.dev

Այսպիսով, մեկուսացված բեմական կլաստերների տեղակայումն իրականացվել է, և մշակողները այժմ կարող են դրանք գործարկել ցանկացած քանակությամբ, որը բավարար է իրենց առաջադրանքները ստուգելու համար:

Ապագա պլաններ:

  • Առանձնացրեք մեր բաղադրիչները որպես ծառայություններ
  • Ունենալ յուրաքանչյուր Dockerfile-ի համար
  • Ավտոմատ կերպով հայտնաբերել ավելի քիչ բեռնված հանգույցները կույտում
  • Նշեք հանգույցները ըստ անվան օրինակի (այլ ոչ թե օգտագործել id, ինչպես հոդվածում)
  • Ավելացրեք ստուգում, որ բուրգը ոչնչացված է
  • ...

Հատուկ շնորհակալություն статью.

Source: www.habr.com

Добавить комментарий