Defnyddio cymwysiadau gan ddefnyddio Docker Swarm

Mae'r system argymell cynnwys fideo ar-lein yr ydym yn gweithio arni yn ddatblygiad masnachol caeedig ac yn dechnegol mae'n glwstwr aml-gydran o gydrannau perchnogol a ffynhonnell agored. Pwrpas ysgrifennu'r erthygl hon yw disgrifio gweithrediad y system clystyru heidiau docwyr ar gyfer llwyfan llwyfannu, heb amharu ar lif gwaith sefydledig ein prosesau o dan amodau amser cyfyngedig. Mae'r naratif a gyflwynir i'ch sylw wedi'i rannu'n ddwy ran. Mae'r rhan gyntaf yn disgrifio CI/CD cyn defnyddio haid docwr, ac mae'r ail ran yn disgrifio'r broses o'i weithredu. Gall y rhai nad oes ganddynt ddiddordeb mewn darllen y rhan gyntaf symud ymlaen yn ddiogel i'r ail.

Rhan I.

Un tro, roedd angen sefydlu proses CI/CD cyn gynted â phosibl. Un o'r amodau oedd peidio â defnyddio Docker ar gyfer lleoli cydrannau yn cael eu datblygu am sawl rheswm:

  • ar gyfer gweithrediad mwy dibynadwy a sefydlog o gydrannau mewn Cynhyrchu (h.y., yn ei hanfod, y gofyniad i beidio â defnyddio rhithwiroli)
  • nid oedd datblygwyr blaenllaw eisiau gweithio gyda Docker (rhyfedd, ond dyna fel y bu)
  • am resymau ideolegol o reoli ymchwil a datblygu

Roedd y seilwaith, y stac a’r gofynion cychwynnol bras ar gyfer yr MVP fel a ganlyn:

  • 4 gweinydd Intel® X5650 gyda Debian (un peiriant mwy pwerus yn gyfan gwbl i'w ddatblygu)
  • Mae datblygiad eich cydrannau personol eich hun yn cael ei wneud yn C++, Python3
  • Prif offer trydydd parti a ddefnyddir: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,…
  • Piblinellau ar gyfer adeiladu a phrofi cydrannau ar wahân ar gyfer dadfygio a rhyddhau

Un o'r cwestiynau cyntaf y mae angen ei ddatrys yn y cam cychwynnol yw sut y bydd cydrannau arfer yn cael eu defnyddio mewn unrhyw amgylchedd (CI/CD).

Fe wnaethom benderfynu gosod cydrannau trydydd parti yn systematig a'u diweddaru'n systematig. Gellir defnyddio cymwysiadau personol a ddatblygwyd yn C ++ neu Python mewn sawl ffordd. Yn eu plith, er enghraifft: creu pecynnau system, eu hanfon i'r storfa o ddelweddau a gasglwyd a'u gosod wedyn ar weinyddion. Am reswm sydd eisoes yn anhysbys, dewiswyd dull arall, sef: defnyddio CI, mae ffeiliau gweithredadwy cymhwysiad yn cael eu llunio, mae amgylchedd prosiect rhithwir yn cael ei greu, mae modiwlau py o requirements.txt yn cael eu gosod, ac mae'r holl arteffactau hyn yn cael eu hanfon ynghyd â chyfluniadau, sgriptiau a yr amgylchedd cais sy'n cyd-fynd â'r gweinyddwyr. Nesaf, mae cymwysiadau'n cael eu lansio gan ddefnyddiwr rhithwir heb hawliau gweinyddwr.

Dewiswyd Gitlab-CI fel y system CI/CD. Roedd y biblinell ganlyniadol yn edrych fel hyn:

Defnyddio cymwysiadau gan ddefnyddio Docker Swarm
Yn strwythurol, roedd gitlab-ci.yml yn edrych fel hyn:

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

Mae'n werth nodi bod cydosod a phrofi yn cael ei wneud ar ei ddelwedd ei hun, lle mae'r holl becynnau system angenrheidiol eisoes wedi'u gosod a gosodiadau eraill yn cael eu gwneud.

Er bod pob un o'r sgriptiau hyn mewn swyddi yn ddiddorol yn ei ffordd ei hun, yn sicr ni fyddaf yn siarad amdanynt; bydd disgrifio pob un ohonynt yn cymryd cryn amser ac nid dyma bwrpas yr erthygl. Gadewch i mi dynnu eich sylw at y ffaith bod y cam lleoli yn cynnwys dilyniant o alw sgriptiau:

  1. createconfig.py - yn creu ffeil settings.ini gyda gosodiadau ar gyfer cydrannau mewn gwahanol amgylcheddau i'w defnyddio wedyn (Cyn-gynhyrchu, Cynhyrchu, Profi, ...)
  2. gosod_venv.sh — yn creu amgylchedd rhithwir ar gyfer cydrannau py mewn cyfeiriadur penodol ac yn ei gopïo i weinyddion pell
  3. paratoi_init.d.py — paratoi sgriptiau ar gyfer cydrannau cychwyn yn seiliedig ar y templed
  4. defnyddio.py - yn defnyddio ac yn ailgychwyn cydrannau newydd

Aeth amser heibio. Disodlwyd y cam llwyfannu gan raggynhyrchu a chynhyrchu. Mae cefnogaeth i'r cynnyrch wedi'i ychwanegu ar un dosbarthiad arall (CentOS). Ychwanegwyd 5 gweinydd corfforol pwerus arall a dwsin o rai rhithwir. A daeth yn fwyfwy anodd i ddatblygwyr a phrofwyr brofi eu tasgau mewn amgylchedd sydd fwy neu lai yn agos at y cyflwr gweithio. Ar yr adeg hon daeth yn amlwg ei bod yn amhosibl gwneud hebddo ...

Rhan II

Defnyddio cymwysiadau gan ddefnyddio Docker Swarm

Felly, mae ein clwstwr yn system ysblennydd o ddau ddwsin o gydrannau unigol nas disgrifiwyd gan Dockerfiles. Gallwch ei ffurfweddu i'w ddefnyddio i amgylchedd penodol yn gyffredinol yn unig. Ein tasg ni yw lleoli'r clwstwr mewn amgylchedd llwyfannu i'w brofi cyn ei brofi cyn rhyddhau.

Yn ddamcaniaethol, gall fod sawl clwstwr yn gweithio ar yr un pryd: cymaint ag y mae tasgau sydd wedi'u cwblhau neu'n agos at gael eu cwblhau. Mae pŵer y gweinyddwyr sydd ar gael inni yn ein galluogi i redeg sawl clwstwr ar bob gweinydd. Rhaid i bob clwstwr llwyfannu fod yn ynysig (ni ddylai fod unrhyw orgyffwrdd mewn porthladdoedd, cyfeiriaduron, ac ati).

Ein hadnodd mwyaf gwerthfawr yw ein hamser, ac nid oedd gennym lawer ohono.

I gael cychwyn cyflymach, fe wnaethom ddewis Docker Swarm oherwydd ei symlrwydd a'i bensaernïaeth hyblyg. Y peth cyntaf a wnaethom oedd creu rheolwr a sawl nod ar weinyddion anghysbell:

$ 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

Nesaf, rydym wedi creu rhwydwaith:


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

Nesaf, gwnaethom gysylltu nodau Gitlab-CI a Swarm o ran rheoli nodau o CI o bell: gosod tystysgrifau, gosod newidynnau cyfrinachol, a hefyd sefydlu'r gwasanaeth Docker ar y gweinydd rheoli. Yr un yma erthygl arbed llawer o amser inni.

Nesaf, fe wnaethom ychwanegu swyddi ar gyfer creu a dinistrio'r pentwr yn .gitlab-ci .yml.

Mae sawl swydd arall wedi'u hychwanegu at .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

O'r darn cod uchod mae'n amlwg bod dau fotwm wedi'u hychwanegu at Piblinellau (deploy_staging, stop_staging) sy'n gofyn am weithredu â llaw.

Defnyddio cymwysiadau gan ddefnyddio Docker Swarm
Mae enw'r pentwr yn cyfateb i enw'r gangen a dylai'r unigrywiaeth hon fod yn ddigon. Mae gwasanaethau yn y pentwr yn derbyn cyfeiriadau IP unigryw, a phorthladdoedd, cyfeiriaduron, ac ati. yn cael ei ynysu, ond yr un peth o stac i bentwr (gan fod y ffeil ffurfweddu yr un peth ar gyfer pob pentwr) - dyna beth roedden ni ei eisiau. Rydym yn defnyddio'r pentwr (clwstwr). docker-compose.yml, sy’n disgrifio ein clwstwr.

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

Yma gallwch weld bod y cydrannau wedi'u cysylltu gan un rhwydwaith (nw_swarm) a'u bod yn hygyrch i'w gilydd.

Mae cydrannau system (yn seiliedig ar redis, mysql) wedi'u gwahanu oddi wrth y gronfa gyffredinol o gydrannau arfer (mewn cynlluniau, mae cydrannau arfer hefyd yn cael eu rhannu fel gwasanaethau). Mae cam defnyddio ein clwstwr yn edrych fel trosglwyddo CMD i'n un ddelwedd fawr wedi'i ffurfweddu ac, yn gyffredinol, nid yw bron yn wahanol i'r defnydd a ddisgrifir yn Rhan I. Pwysleisiaf y gwahaniaethau:

  • clôn git... - rydym yn cael y ffeiliau angenrheidiol i gyflawni'r defnydd (createconfig.py, install_venv.sh, ac ati)
  • cyrlio... && dadsipio... - lawrlwytho a dadsipio'r arteffactau adeiladu (cyfleustodau wedi'u crynhoi)

Dim ond un broblem sydd heb ei disgrifio eto: nid yw cydrannau sydd â rhyngwyneb gwe yn hygyrch o borwyr y datblygwyr. Rydym yn datrys y broblem hon gan ddefnyddio dirprwy, felly:

Yn .gitlab-ci.yml, ar ôl defnyddio'r pentwr clwstwr, ychwanegwch linell ar gyfer defnyddio'r balancer (sydd, ar ôl ymrwymo, ond yn diweddaru ei ffurfweddiad (yn creu ffeiliau cyfluniad nginx newydd yn ôl y templed: /etc/nginx/conf.d /${CI_COMMIT_REF_NAME}.conf) - gweler y cod docker-compose-nginx.yml)

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

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

Ar gyfrifiaduron datblygwyr, diweddaru /etc/hosts; gosod yr url i nginx:

10.50.173.106 staging_BRANCH-1831_cluster.dev

Felly, mae'r defnydd o glystyrau llwyfannu ynysig wedi'i roi ar waith a gall datblygwyr nawr eu lansio mewn unrhyw swm digonol i brofi eu tasgau.

Cynlluniau ar gyfer y dyfodol:

  • Gwahanwch ein cydrannau fel gwasanaethau
  • Creu Dockerfile ar gyfer pob un
  • Canfod nodau llai llwythog yn y pentwr yn awtomatig
  • Nodwch nodau gan ddefnyddio templed enw (yn hytrach na defnyddio id fel yn yr erthygl)
  • Ychwanegwch siec bod y pentwr wedi'i ddinistrio
  • ...

Diolch arbennig am erthygl.

Ffynhonnell: hab.com

Ychwanegu sylw