Docker Swarm көмегімен қолданбаларды орналастырыңыз

Біз жұмыс істеп жатқан онлайн бейне мазмұнын ұсыну жүйесі жабық коммерциялық әзірлеме болып табылады және техникалық жағынан меншікті және ашық бастапқы компоненттердің көп құрамды кластері болып табылады. Бұл мақаланы жазудың мақсаты - шектеулі уақыт ішінде біздің процестеріміздің белгіленген жұмыс процесін бұзбай, кезеңдік торап үшін докер тобын кластерлеу жүйесін енгізуді сипаттау. Назарларыңызға ұсынылған әңгіме екі бөлікке бөлінген. Бірінші бөлімде докер тобын қолданбас бұрын CI/CD сипатталады, ал екіншісі оны жүзеге асыру процесін сипаттайды. Бірінші бөлімді оқуға қызығушылық танытпайтындар екіншісіне қауіпсіз өтуі мүмкін.

I бөлім

Алыс, алыс жылы CI / CD процесін мүмкіндігінше тез орнату қажет болды. Шарттардың бірі Docker қолданбау болды орналастыру үшін компоненттер бірнеше себептерге байланысты әзірленді:

  • Өндірісте компоненттердің сенімді және тұрақты жұмыс істеуі үшін (яғни виртуализацияны қолданбау талабы)
  • жетекші әзірлеушілер Docker-пен жұмыс істегісі келмеді (біртүрлі, бірақ солай болды)
  • ҒЗТКЖ басшылығының идеологиялық ойларына сәйкес

MVP үшін инфрақұрылым, стек және шамамен бастапқы талаптар келесідей ұсынылды:

  • Debian бар 4 Intel® X5650 сервері (тағы бір қуатты машина толығымен әзірленген)
  • Жеке теңшелетін компоненттерді әзірлеу C ++, Python3 тілдерінде жүзеге асырылады
  • Қолданылатын негізгі үшінші тарап құралдары: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,…
  • Түзету және шығару үшін құрамдастарды бөлек құрастыруға және сынауға арналған құбырлар

Бастапқы кезеңде шешілуі қажет бірінші сұрақтардың бірі - реттелетін құрамдастардың кез келген ортада (CI/CD) қалай орналастырылатыны.

Біз үшінші тарап компоненттерін жүйелі түрде орнатуды және оларды жүйелі түрде жаңартуды шештік. C++ немесе Python тілінде әзірленген қолданбалы қолданбаларды бірнеше жолмен орналастыруға болады. Олардың ішінде, мысалы: жүйелік пакеттерді жасау, оларды құрастырылған кескіндердің репозиторийіне жіберу, содан кейін оларды серверлерге орнату. Белгісіз себеппен басқа әдіс таңдалды, атап айтқанда: CI көмегімен қолданбаның орындалатын файлдары құрастырылады, виртуалды жоба ортасы жасалады, py модульдері талаптар.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. Preparat_init.d.py — шаблон негізінде компонент үшін старт-стоп сценарийлерін дайындайды
  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 қызметін орнату. Бұл мақала көп уақытымызды үнемдеді.

Содан кейін .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) қосылғанын және бір-біріне қол жетімді екенін көре аласыз.

Жүйе құрамдастары (redis, mysql негізінде) теңшелетін құрамдастардың жалпы пулынан (жоспарларда және теңшелетіндер қызметтер ретінде бөлінеді) бөлінген. Біздің кластерді орналастыру кезеңі CMD-ді біздің бір үлкен конфигурацияланған кескінге беру сияқты көрінеді және жалпы алғанда, I бөлімде сипатталған орналастырудан іс жүзінде еш айырмашылығы жоқ. Мен айырмашылықтарды бөліп көрсетемін:

  • git клон... - орналастыруға қажетті файлдарды алу (createconfig.py, install_venv.sh және т.б.)
  • бұйралау... && разрядты ашу... - құрастыру артефактілерін жүктеп алыңыз және ашыңыз (құрастырылған утилиталар)

Тек бір ғана әлі сипатталмаған мәселе бар: веб-интерфейсі бар құрамдастарға әзірлеушілердің браузерлерінен қол жеткізу мүмкін емес. Біз бұл мәселені кері прокси арқылы шешеміз, осылайша:

.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; nginx үшін url тағайындаңыз:

10.50.173.106 staging_BRANCH-1831_cluster.dev

Сонымен, оқшауланған кезеңдік кластерлерді орналастыру жүзеге асырылды және әзірлеушілер енді оларды тапсырмаларын тексеру үшін жеткілікті кез келген санда іске қоса алады.

Болашақ жоспарлар:

  • Біздің құрамдастарды қызметтер ретінде бөліңіз
  • Әрбір Docker файлы үшін бар
  • Стектегі аз жүктелген түйіндерді автоматты түрде анықтау
  • Түйіндерді атау үлгісі бойынша көрсетіңіз (мақаладағыдай идентификаторды пайдаланудың орнына)
  • Стек жойылғанын тексеруді қосыңыз
  • ...

Арнайы рахмет мақала.

Ақпарат көзі: www.habr.com

пікір қалдыру