Serlêdan bi karanîna Docker Swarm bicîh bikin

Pergala pêşniyara naveroka vîdyoya serhêl a ku em li ser dixebitin pêşkeftinek bazirganî ya girtî ye û ji hêla teknîkî ve komek pir-pêkhatî ya hêmanên xwedan û çavkaniya vekirî ye. Armanca nivîsandina vê gotarê danasîna pêkanîna pergala komkirina swarm a docker-ê ji bo platformek qonaxê ye, bêyî ku rêça xebata damezrandî ya pêvajoyên me di bin şert û mercên demkî sînordar de têk bibe. Çîroka ku li ber çavê we hatî pêşkêş kirin, dibe du beş. Beşa yekem CI/CD-ê berî ku swarm-a docker bikar bîne rave dike, û beşa duyemîn jî pêvajoya bicihanîna wê diyar dike. Kesên ku ne eleqedar in ku beşa yekem bixwînin, dikarin bi ewlehî derbasî beşa duyemîn bibin.

Beş I

Carekê, pêdivî bû ku pêvajoyek CI/CD bi lez û bez were saz kirin. Yek ji şertan ne karanîna Docker bû ji bo belavkirinê pêkhateyên ku ji ber çend sedeman têne pêşve xistin:

  • ji bo xebitandina pêbawer û aramtir a pêkhateyan di Hilberînê de (ango, di eslê xwe de, hewcedariya ne karanîna virtualbûnê)
  • pêşdebirên pêşeng nexwest ku bi Docker re bixebitin (ecêb, lê wusa bû)
  • ji ber sedemên îdeolojîk ên rêveberiya R&D

Binesaziya, stûn û hewcedariyên destpêkê yên nêzîk ji bo MVP wiha bûn:

  • 4 serverên Intel® X5650 bi Debian re (makîneyek bihêztir bi tevahî ji bo pêşkeftinê)
  • Pêşveçûna pêkhateyên xweya xwerû di C++, Python3 de pêk tê
  • Amûrên sereke yên sêyemîn ên ku têne bikar anîn: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,…
  • Xetên lûleyên ji bo çêkirin û ceribandina pêkhateyan ji hev cuda ji bo debugkirin û berdanê

Yek ji yekem pirsên ku divê di qonaxa destpêkê de were çareser kirin ev e ku dê çawa pêkhateyên xwerû di her hawîrdorê de (CI/CD) werin bicîh kirin.

Me biryar da ku em pêkhateyên sêyemîn bi pergalî saz bikin û wan bi pergalî nûve bikin. Serlêdanên xwerû yên ku di C++ an Python de hatine pêşve xistin dikarin bi çend awayan werin bicîh kirin. Di nav wan de, mînakî: afirandina pakêtên pergalê, şandina wan ji depoya wêneyên berhevkirî û sazkirina wan a paşîn li ser serveran. Ji ber sedemek jixwe nediyar, rêbazek din hate hilbijartin, ev jî: bi karanîna CI-ê, pelên bikêrhatî yên serîlêdanê têne berhev kirin, hawîrdorek projeyek virtual tê afirandin, modulên py ji daxwazên.txt têne saz kirin, û van hemî hunerî digel mîhengan, skrîpt û nivîsan têne şandin. hawîrdora serîlêdanê ya bi pêşkêşkeran re. Dûv re, serîlêdan ji bikarhênerek virtual bêyî mafên rêveber têne destpêkirin.

Gitlab-CI wekî pergala CI/CD hate hilbijartin. Xeta boriyê ya encam tiştek wiha xuya bû:

Serlêdan bi karanîna Docker Swarm bicîh bikin
Bi strukturî, gitlab-ci.yml wiha xuya bû:

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

Hêjayî gotinê ye ku kombûn û ceribandin li ser wêneya xwe tê kirin, ku hemî pakêtên pergalê yên pêwîst jixwe hatine saz kirin û mîhengên din têne çêkirin.

Her çend her yek ji van senaryoyan di karan de bi awayê xwe balkêş be jî, bê guman ez ê qala wan nekim; danasîna her yek ji wan dê demek girîng bigire û ev ne armanca gotarê ye. Bihêle ez tenê bala we bikişînim ser vê yekê ku qonaxa bicîhkirinê ji rêzek nivîsarên bangkirinê pêk tê:

  1. createconfig.py - pelek settings.ini bi mîhengên pêkhateyên li hawîrdorên cihêreng ji bo bicîhkirina paşîn diafirîne (Pêşhilberîn, Hilberîn, Testkirin, ...)
  2. install_venv.sh - Ji bo hêmanên py di pelrêçek taybetî de jîngehek virtual diafirîne û wê li serverên dûr kopî dike
  3. amade_init.d.py - li ser bingeha şablonê ji bo hêmanên destpêk-rawestan nivîsan amade dike
  4. deploy.py - pêkhateyên nû bi cih dike û ji nû ve dest pê dike

Dem derbas bû. Qonaxa sehneyê bi pêşhilberîn û hilberînê hat guhertin. Piştgiriya hilberê li ser belavkirinek din (CentOS) hate zêdekirin. 5 serverên fizîkî yên hêzdar û bi dehan virtual lê zêde kirin. Û ji bo pêşdebiran û ceribandinan dijwartir bû ku karên xwe li hawîrdorek kêm-zêde nêzî rewşa xebatê biceribînin. Di vê demê de diyar bû ku ne gengaz e ku bêyî wî bikin ...

Beşa II

Serlêdan bi karanîna Docker Swarm bicîh bikin

Ji ber vê yekê, koma me pergalek balkêş e ku ji du dehan hêmanên kesane yên ku ji hêla Dockerfiles ve nehatine vegotin e. Hûn dikarin wê ji bo bicîhkirina li hawîrdorek taybetî tenê bi gelemperî mîheng bikin. Erka me ev e ku em komê li hawîrdorek qonaxê bi cih bikin da ku wê berî ceribandina pêş-serbestberdanê ceribandinê bikin.

Ji hêla teorîkî ve, dibe ku çend kom bi hevdemî bixebitin: Bi qasî ku di rewşek qedandî de an jî nêzîkê qedandinê de kar hene. Hêza serverên di destê me de dihêle ku em li ser her serverek çend koman bimeşînin. Pêdivî ye ku her komika qonaxê were veqetandin (divê di port, peldank, hwd. de hevûdu tunebe).

Çavkaniya me ya herî bi qîmet wextê me ye û zêde jî tunebû.

Ji bo destpêkek zûtir, me Docker Swarm ji ber sadebûn û mîmariya wê ya maqûl hilbijart. Yekem tiştê ku me kir ev bû ku li ser serverên dûr rêveberek û çend nod ava kirin:

$ 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

Piştre, me torgilokek çêkir:


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

Dûv re, me girêkên Gitlab-CI û Swarm di warê rêveberiya dûr a nodên ji CI ve girêda: sazkirina sertîfîkayan, danîna guhêrbarên veşartî, û her weha sazkirina karûbarê Docker li ser servera kontrolê. Ev yek gotara me gelek wext xilas kir.

Dûv re, me ji bo çêkirin û tunekirina stakê di .gitlab-ci .yml de kar zêde kirin.

Çend karên din li .gitlab-ci .yml hatin zêdekirin

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

Ji perçeya kodê ya jorîn diyar e ku du bişkok li Pipelines (deploy_staging, stop_staging) hatine zêdekirin ku çalakiya destan hewce dike.

Serlêdan bi karanîna Docker Swarm bicîh bikin
Navê stackê bi navê şaxê re têkildar e û divê ev yekane bes be. Karûbarên di stakê de navnîşanên IP-ê yên yekta, û port, peldank, hwd digirin. dê were veqetandin, lê heman ji stêrk heya stêrk (ji ber ku pelê vesazkirinê ji bo hemî stûnan yek e) - ya ku me dixwest ev e. Em stack (kluster) bi kar tînin docker-berhevkirin.yml, ku koma me diyar dike.

docker-berhevkirin.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

Li vir hûn dikarin bibînin ku pêkhate ji hêla yek torê ve (nw_swarm) ve girêdayî ne û bi hev re têne gihîştin.

Parçeyên pergalê (li ser bingeha redis, mysql) ji hewza giştî ya hêmanên xwerû têne veqetandin (di planan de, hêmanên xwerû jî wekî karûbar têne dabeş kirin). Qonaxa bicîhkirina koma me dişibihe veguheztina CMD-ê li yek wêneyek meya mîhengkirî ya mezin û, bi gelemperî, bi pratîkî ji bicîhkirina ku di Beşa I-ê de hatî destnîşan kirin ne cûda ye. Ez ê cûdahiyan tekez bikim:

  • git clone... - em pelên ku ji bo bicîhkirinê hewce ne digirin (createconfig.py, install_venv.sh, hwd.)
  • qul... && veke... - Berhemên çêkirinê dakêşin û vekin (karsazên berhevkirî)

Tenê yek pirsgirêkek heye ku hîn nehatiye vegotin: pêkhateyên ku xwedan navgîniya webê ne ji gerokên pêşdebiran nayên gihîştin. Em vê pirsgirêkê bi karanîna proxy berevajî çareser dikin, bi vî rengî:

Di .gitlab-ci.yml de, piştî danîna stûna komê, xêzek ji bo bicihkirina hevsengiyê lê zêde bike (ku gava ku tê kirin, tenê veavakirina xwe nûve dike (li gorî şablonê pelên veavakirina nginx-ê yên nû diafirîne: /etc/nginx/conf.d /${CI_COMMIT_REF_NAME}.conf) - li kodê binêre 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

Li ser komputerên pêşdebiran, nûvekirina /etc/hosts; url-ê li nginx saz bikin:

10.50.173.106 staging_BRANCH-1831_cluster.dev

Ji ber vê yekê, bicîhkirina komên qonaxên veqetandî hatî sepandin û pêşdebiran naha dikarin wan bi her qasê ku têra ceribandina karên xwe bikin dest pê bikin.

Planên pêşerojê:

  • Parçeyên me wekî karûbar ji hev veqetînin
  • Ji bo her yekê Dockerfile biafirînin
  • Otomatîk girêkên kêm barkirî yên di stikê de kifş bikin
  • Bi karanîna şablonek navekî girêk diyar bikin (li şûna ku wekî di gotarê de ID bikar bînin)
  • Kontrolek lê zêde bike ku stûn hatiye hilweşandin
  • ...

Spasên taybetî ji bo gotar.

Source: www.habr.com

Add a comment