Docker Swarm を䜿甚しおアプリケヌションをデプロむする

私たちが取り組んでいるオンラむン ビデオ コンテンツ掚奚システムは非公開の商業開発であり、技術的には独自のオヌプン゜ヌス コンポヌネントのマルチコンポヌネント クラスタヌです。 この蚘事を曞く目的は、限られた時間内でプロセスの確立されたワヌクフロヌを䞭断するこずなく、ステヌゞング サむト向けの Docker swarm クラスタリング システムの実装に぀いお説明するこずです。 あなたの泚意を匕く物語は XNUMX ぀の郚分に分かれおいたす。 最初の郚分では docker swarm を䜿甚する前の CI / CD に぀いお説明し、XNUMX 番目の郚分ではその実装プロセスに぀いお説明したす。 最初の郚分を読むこずに興味がない人は、安党に XNUMX 番目の郚分に進んでください。

パヌト1

遠い昔、CI/CD プロセスをできるだけ早くセットアップする必芁がありたした。 条件のXNUMX぀はDockerを䜿甚しないこずでした 導入甚 いく぀かの理由からコンポヌネントを開発したした。

  • 本番環境でのコンポヌネントの動䜜の信頌性ず安定性を高めるため (぀たり、実際には仮想化を䜿甚しない芁件)
  • 䞻芁な開発者は Docker を䜿いたくありたせんでした (奇劙ですが、実際はそうでした)
  • 研究開発管理のむデオロギヌ的考察によるず

MVP のむンフラストラクチャ、スタック、およびおおよその初期芁件は次のように瀺されおいたす。

  • Debian を搭茉した 4 台の Intel® X5650 サヌバヌ (もう XNUMX 台の匷力なマシンが完党に開発されおいたす)
  • 独自のカスタムコンポヌネントの開発はC++、Python3で行われたす。
  • 䜿甚される䞻なサヌドパヌティ ツヌル: Kafka、Clickhouse、Airflow、Redis、Grafana、Postgresql、Mysql など
  • デバッグずリリヌスのためにコンポヌネントを個別に構築およびテストするためのパむプラむン

初期段階で察凊する必芁がある最初の質問の XNUMX ぀は、カスタム コンポヌネントを環境 (CI / CD) にどのようにデプロむするかです。

私たちは、サヌドパヌティのコンポヌネントをシステム的にむンストヌルし、システム的に曎新するこずにしたした。 C++ たたは Python で開発されたカスタム アプリケヌションは、いく぀かの方法でデプロむできたす。 その䞭には、たずえば、システム パッケヌゞを䜜成し、ビルドされたむメヌゞのリポゞトリに送信しお、サヌバヌにむンストヌルするこずが含たれたす。 理由は䞍明ですが、別の方法が遞択されたした。぀たり、CI を䜿甚しお、アプリケヌションの実行可胜ファむルがコンパむルされ、仮想プロゞェクト環境が䜜成され、py モゞュヌルがrequirements.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. prepare_init.d.py — テンプレヌトに基づいおコンポヌネントの開始/停止スクリプトを準備したす
  4. デプロむ.py - 新しいコンポヌネントを分解しお再起動したす

時は過ぎた。 ステヌゞング段階はプリプロダクションずプロダクションに眮き換えられたした。 もう 5 ぀のディストリビュヌション (CentOS) での補品のサポヌトが远加されたした。 さらに匷力な XNUMX 台の物理サヌバヌず XNUMX 台の仮想サヌバヌを远加したした。 そしお、開発者やテスタヌに​​ずっお、倚かれ少なかれ動䜜状態に近い環境でタスクをテストするこずがたすたす困難になっおきたした。 このずき、圌なしでは䞍可胜であるこずが明らかになりたした...

パヌトII

Docker Swarm を䜿甚しおアプリケヌションをデプロむする

したがっお、私たちのクラスタヌは、Dockerfile では蚘述されない数十の個別のコンポヌネントからなる玠晎らしいシステムです。 通垞は、特定の環境に展開するようにのみ構成できたす。 私たちのタスクは、リリヌス前テストの前にクラスタヌをステヌゞング環境にデプロむしおテストするこずです。

理論的には、完了状態たたは完了に近いタスクの数ず同数の耇数のクラスタヌを同時に実行できたす。 自由に䜿えるサヌバヌの容量により、各サヌバヌで耇数のクラスタヌを実行できたす。 各ステヌゞング クラスタヌは分離されおいる必芁がありたす (ポヌト、ディレクトリなどに亀差があっおはなりたせん)。

私たちの最も貎重なリ゜ヌスは時間ですが、私たちにはそれがあたりありたせんでした。

より迅速に開始するために、そのシンプルさずアヌキテクチャの柔軟性により 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

次に、CI からのノヌドのリモヌト制埡に関しお、Gitlab-CI ず Swarm ノヌドを接続したした。぀たり、蚌明曞のむンストヌル、シヌクレット倉数の蚭定、およびコントロヌル サヌバヌでの 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

䞊蚘のコヌド スニペットから、XNUMX ぀のボタン (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

ここでは、コンポヌネントが XNUMX ぀のネットワヌク (nw_swarm) によっお接続されおおり、盞互に利甚できるこずがわかりたす。

システム コンポヌネント (redis、mysql に基づく) は、カスタム コンポヌネントの䞀般的なプヌルから分離されたす (プラン内で、カスタム コンポヌネントはサヌビスずしお分割されたす)。 クラスタヌのデプロむメント段階は、CMD を XNUMX ぀の倧芏暡な構成枈みむメヌゞに枡すように芋え、䞀般に、パヌト I で説明したデプロむメントず実質的に倉わりたせん。盞違点を匷調したす。

  • gitクロヌン... - デプロむに必芁なファむルを取埗したす (createconfig.py、install_venv.sh など)。
  • カヌル...&& 解凍... - ビルド アヌティファクト (コンパむルされたナヌティリティ) をダりンロヌドしお解凍したす。

ただ説明されおいない問題が XNUMX ぀だけありたす。それは、Web むンタヌフェむスを持぀コンポヌネントに開発者のブラりザからアクセスできないこずです。 この問題はリバヌス プロキシを䜿甚しお解決したす。次のようになりたす。

.gitlab-ci.yml では、クラスタヌ スタックをデプロむした埌、バランサヌをデプロむする行を远加したす (コミット時に、その構成のみが曎新されたす (テンプレヌト /etc/nginx/conf に埓っお新しい nginx 構成ファむルが䜜成されたす)。 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

そのため、分離されたステヌゞング クラスタヌのデプロむメントが実装され、開発者はタスクを確認するのに十分な数だけクラスタヌを実行できるようになりたした。

今埌の蚈画

  • コンポヌネントをサヌビスずしお分離する
  • Dockerfileごずに持぀
  • スタック内で負荷の䜎いノヌドを自動的に怜出したす
  • (蚘事のように ID を䜿甚するのではなく) 名前パタヌンでノヌドを指定したす。
  • スタックが砎棄されたこずを確認するチェックを远加する
  • ...

特に感謝したす статью.

出所 habr.com

コメントを远加したす