Примените апликације помоћу Доцкер Сварм-а

Систем за препоруку видео садржаја на мрежи на којем радимо је затворен комерцијални развој и технички је вишекомпонентни кластер власничких и компоненти отвореног кода. Сврха писања овог чланка је да се опише имплементација система груписања доцкер роја за локацију за постављање без ометања успостављеног тока рада наших процеса у ограниченом времену. Наратив који је представљен вашој пажњи подељен је на два дела. Први део описује ЦИ/ЦД пре употребе доцкер роја, а други описује процес његове имплементације. Они који нису заинтересовани за читање првог дела могу безбедно да пређу на други.

И део

Још далеке, далеке године, било је неопходно што брже поставити ЦИ/ЦД процес. Један од услова је био да се не користи Доцкер за распоређивање развијене компоненте из неколико разлога:

  • за поузданији и стабилнији рад компоненти у Продукцији (односно, у ствари, услов да се не користи виртуелизација)
  • водећи програмери нису желели да раде са Доцкер-ом (чудно, али тако је било)
  • према идеолошким промишљањима менаџмента Р&Д

Инфраструктура, стек и приближни почетни захтеви за МВП су представљени на следећи начин:

  • 4 Интел® Кс5650 сервера са Дебиан-ом (једна моћнија машина је потпуно развијена)
  • Развој сопствених компоненти се врши у Ц++, Питхон3
  • Главни коришћени алати треће стране: Кафка, Цлицкхоусе, Аирфлов, Редис, Графана, Постгрескл, Мискл,…
  • Цевоводи за изградњу и тестирање компоненти одвојено за отклањање грешака и ослобађање

Једно од првих питања које треба да се реши у почетној фази је како ће прилагођене компоненте бити распоређене у било ком окружењу (ЦИ / ЦД).

Одлучили смо да системски инсталирамо компоненте треће стране и системски их ажурирамо. Прилагођене апликације развијене у Ц++ или Питхон-у могу се применити на неколико начина. Међу њима, на пример: креирање системских пакета, њихово слање у спремиште изграђених слика и затим њихово инсталирање на сервере. Из непознатог разлога, изабран је други метод, а то је: коришћењем ЦИ-ја се компајлирају извршни фајлови апликације, креира се виртуелно пројектно окружење, инсталирају се пи модули из рекуирементс.ткт, а сви ови артефакти се шаљу заједно са конфигурацијама, скриптама и пратеће окружење апликације на сервере. Затим се апликације покрећу као виртуелни корисник без администраторских права.

Гитлаб-ЦИ је изабран као ЦИ/ЦД систем. Добијени цевовод је изгледао отприлике овако:

Примените апликације помоћу Доцкер Сварм-а
Структурно, гитлаб-ци.имл је изгледао овако

---
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. цреатецонфиг.пи - креира датотеку сеттингс.ини са подешавањима компоненти у различитим окружењима за накнадну примену (препродукција, производња, тестирање, ...)
  2. инсталл_венв.сх - креира виртуелно окружење за пи компоненте у одређеном директоријуму и копира га на удаљене сервере
  3. припреми_инит.д.пи — припрема старт-стоп скрипте за компоненту на основу шаблона
  4. деплои.пи - разлаже и поново покреће нове компоненте

Време је пролазило. Сценска фаза је замењена предпродукцијом и продукцијом. Додата подршка за производ на још једној дистрибуцији (ЦентОС). Додато 5 моћнијих физичких сервера и десетак виртуелних. А програмерима и тестерима је постајало све теже да тестирају своје задатке у окружењу које је мање-више блиско радном стању. У овом тренутку постало је јасно да је немогуће без њега ...

ИИ део

Примените апликације помоћу Доцкер Сварм-а

Дакле, наш кластер је спектакуларан систем од неколико десетина одвојених компоненти које Доцкерфилес не описује. Можете га конфигурисати само за примену у одређеном окружењу уопште. Наш задатак је да поставимо кластер у окружење за провођење да бисмо га тестирали пре тестирања пре издања.

Теоретски, може постојати неколико кластера који раде истовремено: онолико колико има задатака у завршеном стању или близу завршетка. Капацитети сервера којима располажемо омогућавају нам да покренемо неколико кластера на сваком серверу. Сваки стагинг кластер мора бити изолован (не сме бити укрштања портова, директоријума итд.).

Наш највреднији ресурс је наше време, а нисмо га имали много.

За бржи почетак, изабрали смо Доцкер Сварм због његове једноставности и флексибилности архитектуре. Прва ствар коју смо урадили је креирање менаџера и неколико чворова на удаљеним серверима:

$ 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

Затим смо повезали Гитлаб-ЦИ и Сварм чворове у смислу даљинске контроле чворова из ЦИ: инсталирање сертификата, постављање тајних варијабли и подешавање Доцкер сервиса на контролном серверу. Овај чланак уштедели смо много времена.

Затим смо додали послове креирања и уништавања стекова у .гитлаб-ци .имл.

Још неколико послова је додато у .гитлаб-ци .имл

## 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

Из горњег исечка кода, можете видети да су два дугмета (деплои_стагинг, стоп_стагинг) додата у цевоводе, што захтева ручну акцију.

Примените апликације помоћу Доцкер Сварм-а
Име стека одговара имену гране и ова јединственост би требала бити довољна. Услуге у стеку добијају јединствене ИП адресе, портове, директоријуме итд. биће изоловани, али исти од стека до стека (јер је конфигурациони фајл исти за све стекове) - оно што смо желели. Ми постављамо стек (кластер) користећи доцкер-цомпосе.имл, који описује наш кластер.

доцкер-цомпосе.имл

---
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

Овде можете видети да су компоненте повезане једном мрежом (нв_сварм) и доступне су једна другој.

Системске компоненте (засноване на редис, мискл) су одвојене од општег скупа прилагођених компоненти (у плановима и прилагођене су подељене као услуге). Фаза имплементације нашег кластера изгледа као преношење ЦМД-а у нашу једну велику конфигурисану слику и, уопштено гледано, практично се не разликује од примене описане у првом делу. Истакнућу разлике:

  • гит клон... - набавите датотеке потребне за примену (цреатецонфиг.пи, инсталл_венв.сх, итд.)
  • увити... && раскопчати... - преузмите и распакујте артефакте изградње (састављени услужни програми)

Постоји само један још неописан проблем: компоненте које имају веб интерфејс нису доступне из претраживача програмера. Овај проблем решавамо коришћењем обрнутог проксија, на следећи начин:

У .гитлаб-ци.имл, након постављања стека кластера, додајемо линију за постављање балансера (који, када се урезује, само ажурира своју конфигурацију (креира нове нгинк конфигурационе датотеке према шаблону: /етц/нгинк/цонф. д/${ЦИ_ЦОММИТ_РЕФ_НАМЕ}.цонф) – погледајте код доцкер-цомпосе-нгинк.имл)

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

доцкер-цомпосе-нгинк.имл

---
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

На рачунарима за развој, ажурирајте /етц/хостс; преписати урл за нгинк:

10.50.173.106 staging_BRANCH-1831_cluster.dev

Дакле, имплементација изолованих сценских кластера је имплементирана и програмери сада могу да их покрену у било ком броју довољном да провере своје задатке.

Планови за будућност:

  • Одвојите наше компоненте као услуге
  • Имајте за сваки Доцкерфиле
  • Аутоматски откријте мање оптерећене чворове у стеку
  • Одредите чворове према обрасцу имена (уместо да користите ИД као у чланку)
  • Додајте проверу да је стек уништен
  • ...

Посебно хвала за статью.

Извор: ввв.хабр.цом

Додај коментар