Sambaza programu kwa kutumia Docker Swarm

Mfumo wa mapendekezo ya maudhui ya video mtandaoni tunaofanyia kazi ni uendelezaji wa kibiashara uliofungwa na kitaalamu ni kundi la vipengele vingi vya vipengele vya wamiliki na chanzo huria. Madhumuni ya kuandika makala haya ni kuelezea utekelezaji wa mfumo wa kuunganisha makundi ya docker kwa jukwaa la jukwaa, bila kutatiza utendakazi uliowekwa wa michakato yetu chini ya hali ya muda mfupi. Simulizi inayowasilishwa kwako imegawanywa katika sehemu mbili. Sehemu ya kwanza inaelezea CI/CD kabla ya kutumia kundi la docker, na sehemu ya pili inaelezea mchakato wa kuitekeleza. Wale ambao hawana nia ya kusoma sehemu ya kwanza wanaweza kuendelea kwa usalama hadi ya pili.

Iасть Mimi

Hapo zamani za kale, kulikuwa na haja ya kuanzisha mchakato wa CI/CD haraka iwezekanavyo. Moja ya masharti ilikuwa kutotumia Docker kwa ajili ya kupelekwa Vipengele vinatengenezwa kwa sababu kadhaa:

  • kwa uendeshaji wa kuaminika zaidi na thabiti wa vipengele katika Uzalishaji (yaani, kimsingi, hitaji la kutotumia uboreshaji)
  • watengenezaji wakuu hawakutaka kufanya kazi na Docker (ya kushangaza, lakini ndivyo ilivyokuwa)
  • kwa sababu za kiitikadi za usimamizi wa R&D

Miundombinu, rundo na makadirio ya mahitaji ya awali ya MVP yalikuwa kama ifuatavyo:

  • Seva 4 za Intel® X5650 zilizo na Debian (mashine moja yenye nguvu zaidi kwa maendeleo)
  • Ukuzaji wa vifaa vyako mwenyewe hufanywa katika C++, Python3
  • Zana kuu za wahusika wengine zilizotumika: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql, ...
  • Mabomba ya kujenga na kupima vipengele tofauti kwa utatuzi na kutolewa

Moja ya maswali ya kwanza ambayo yanahitaji kutatuliwa katika hatua ya awali ni jinsi vipengele maalum vitatumika katika mazingira yoyote (CI/CD).

Tuliamua kusakinisha vipengele vya wahusika wengine kimfumo na kusasisha kimfumo. Programu maalum zilizotengenezwa katika C++ au Python zinaweza kutumwa kwa njia kadhaa. Miongoni mwao, kwa mfano: kuunda vifurushi vya mfumo, kuwapeleka kwenye hifadhi ya picha zilizokusanywa na ufungaji wao wa baadaye kwenye seva. Kwa sababu ambayo tayari haijulikani, njia nyingine ilichaguliwa, ambayo ni: kwa kutumia CI, faili zinazoweza kutekelezeka za programu zinakusanywa, mazingira ya mradi yanaundwa, moduli za py kutoka kwa mahitaji.txt husakinishwa, na mabaki haya yote hutumwa pamoja na usanidi, hati na. mazingira ya maombi yanayoambatana na seva. Kisha, programu zinazinduliwa kutoka kwa mtumiaji pepe bila haki za msimamizi.

Gitlab-CI ilichaguliwa kama mfumo wa CI/CD. Bomba lililosababisha lilionekana kama hii:

Sambaza programu kwa kutumia Docker Swarm
Kimuundo, gitlab-ci.yml ilionekana kama hii:

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

Inastahili kuzingatia kwamba mkusanyiko na upimaji unafanywa kwa picha yake mwenyewe, ambapo vifurushi vyote muhimu vya mfumo tayari vimewekwa na mipangilio mingine inafanywa.

Ingawa kila moja ya maandishi haya kwenye kazi yanavutia kwa njia yake mwenyewe, hakika sitazungumza juu yao; kuelezea kila mmoja wao kutachukua muda mwingi na hii sio kusudi la kifungu hicho. Acha nitoe mawazo yako kwa ukweli kwamba hatua ya kupeleka ina mlolongo wa hati za kupiga simu:

  1. createconfig.py — huunda faili ya settings.ini yenye mipangilio ya vijenzi katika mazingira tofauti kwa ajili ya utumaji unaofuata (Uzalishaji wa awali, Uzalishaji, Majaribio, ...)
  2. install_venv.sh - huunda mazingira ya kawaida ya vifaa vya py kwenye saraka maalum na kuinakili kwa seva za mbali
  3. kuandaa_init.d.py - huandaa hati za vijenzi vya kusimamisha-kuanzisha kulingana na kiolezo
  4. deploy.py - Huweka na kuanzisha upya vipengele vipya

Muda ulipita. Hatua ya hatua ilibadilishwa na utayarishaji na uzalishaji. Usaidizi wa bidhaa umeongezwa kwenye usambazaji mmoja zaidi (CentOS). Seva zingine 5 zenye nguvu na dazeni za mtandao ziliongezwa. Na ilizidi kuwa vigumu kwa wasanidi programu na wanaojaribu kujaribu kazi zao katika mazingira karibu zaidi au chini ya hali ya kazi. Kwa wakati huu ikawa wazi kuwa haiwezekani kufanya bila yeye ...

Sehemu ya II

Sambaza programu kwa kutumia Docker Swarm

Kwa hivyo, nguzo yetu ni mfumo wa kuvutia wa vipengee kadhaa vya watu binafsi ambavyo havijaelezewa na Dockerfiles. Unaweza kuisanidi kwa kupelekwa kwa mazingira maalum kwa jumla tu. Jukumu letu ni kusambaza nguzo katika mazingira ya jukwaa ili kuijaribu kabla ya majaribio ya kabla ya kutolewa.

Kinadharia, kunaweza kuwa na vikundi kadhaa vinavyofanya kazi kwa wakati mmoja: kadiri kuna kazi katika hali iliyokamilika au karibu kukamilika. Nguvu za seva tulizo nazo huturuhusu kuendesha vikundi kadhaa kwenye kila seva. Kila nguzo ya jukwaa lazima itengwe (haipaswi kuwa na mwingiliano katika bandari, saraka, n.k.).

Rasilimali yetu muhimu zaidi ni wakati wetu, na hatukuwa na mengi yake.

Kwa kuanza haraka, tulichagua Docker Swarm kwa sababu ya unyenyekevu wake na usanifu rahisi. Jambo la kwanza tulifanya ni kuunda meneja na nodi kadhaa kwenye seva za mbali:

$ 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

Ifuatayo, tuliunda mtandao:


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

Kisha, tuliunganisha nodes za Gitlab-CI na Swarm kwa suala la usimamizi wa kijijini wa nodes kutoka kwa CI: vyeti vya kufunga, kuweka vigezo vya siri, na pia kuanzisha huduma ya Docker kwenye seva ya udhibiti. Huyu makala ilituokoa muda mwingi.

Kisha, tuliongeza kazi za kuunda na kuharibu safu katika .gitlab-ci .yml.

Kazi nyingi zaidi zimeongezwa kwenye .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

Kutoka kwa kipande cha msimbo hapo juu ni wazi kwamba vifungo viwili vimeongezwa kwa Pipelines (deploy_staging, stop_staging) ambayo yanahitaji hatua ya mwongozo.

Sambaza programu kwa kutumia Docker Swarm
Jina la rafu linalingana na jina la tawi na upekee huu unapaswa kutosha. Huduma katika rafu hupokea anwani za kipekee za IP, na bandari, saraka, n.k. itatengwa, lakini sawa kutoka kwa stack hadi stack (kwani faili ya usanidi ni sawa kwa rafu zote) - ndivyo tulivyotaka. Tunapeleka stack (nguzo) kwa kutumia docker-compose.yml, ambayo inaelezea nguzo yetu.

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

Hapa unaweza kuona kwamba vipengele vinaunganishwa na mtandao mmoja (nw_swarm) na vinapatikana kwa kila mmoja.

Vipengee vya mfumo (kulingana na redis, mysql) vinatenganishwa na dimbwi la jumla la vifaa maalum (katika mipango, vifaa maalum pia vimegawanywa kama huduma). Hatua ya uwekaji wa nguzo yetu inaonekana kama kuhamisha CMD hadi kwenye picha yetu moja kubwa iliyosanidiwa na, kwa ujumla, haina tofauti na uwekaji uliofafanuliwa katika Sehemu ya I. Nitasisitiza tofauti hizo:

  • git clone... - tunapata faili zinazohitajika kutekeleza utumaji (createconfig.py, install_venv.sh, n.k.)
  • pinda... && ufungue... - pakua na ufungue mabaki ya ujenzi (huduma zilizokusanywa)

Kuna tatizo moja tu ambalo bado halijaelezewa: vipengele vilivyo na kiolesura cha wavuti havipatikani kutoka kwa vivinjari vya wasanidi programu. Tunasuluhisha shida hii kwa kutumia wakala wa nyuma, kwa hivyo:

Katika .gitlab-ci.yml, baada ya kupeleka mrundikano wa nguzo, ongeza mstari wa kupeleka sawazisha (ambayo, inapojitolea, inasasisha tu usanidi wake (huunda faili mpya za usanidi wa nginx kulingana na kiolezo: /etc/nginx/conf.d /${CI_COMMIT_REF_NAME}.conf) - tazama msimbo 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

Kwenye kompyuta za wasanidi programu, sasisha /etc/hosts; weka url kwa nginx:

10.50.173.106 staging_BRANCH-1831_cluster.dev

Kwa hivyo, utumaji wa nguzo za hatua zilizotengwa umetekelezwa na wasanidi programu sasa wanaweza kuzizindua kwa idadi yoyote ya kutosha ili kujaribu majukumu yao.

Mipango ya siku zijazo:

  • Tenganisha vipengele vyetu kama huduma
  • Unda faili ya Docker kwa kila moja
  • Gundua kiotomatiki nodi zilizopakiwa kidogo kwenye rafu
  • Bainisha nodi kwa kutumia kiolezo cha jina (badala ya kutumia kitambulisho kama ilivyo kwenye kifungu)
  • Ongeza hundi kwamba rafu imeharibiwa
  • ...

Shukrani za pekee kwa nakala.

Chanzo: mapenzi.com

Kuongeza maoni