Біз жұмыс істеп жатқан онлайн бейне мазмұнын ұсыну жүйесі жабық коммерциялық әзірлеме болып табылады және техникалық жағынан меншікті және ашық бастапқы компоненттердің көп құрамды кластері болып табылады. Бұл мақаланы жазудың мақсаты - шектеулі уақыт ішінде біздің процестеріміздің белгіленген жұмыс процесін бұзбай, кезеңдік торап үшін докер тобын кластерлеу жүйесін енгізуді сипаттау. Назарларыңызға ұсынылған әңгіме екі бөлікке бөлінген. Бірінші бөлімде докер тобын қолданбас бұрын CI/CD сипатталады, ал екіншісі оны жүзеге асыру процесін сипаттайды. Бірінші бөлімді оқуға қызығушылық танытпайтындар екіншісіне қауіпсіз өтуі мүмкін.
I бөлім
Алыс, алыс жылы CI / CD процесін мүмкіндігінше тез орнату қажет болды. Шарттардың бірі Docker қолданбау болды орналастыру үшін компоненттер бірнеше себептерге байланысты әзірленді:
- Өндірісте компоненттердің сенімді және тұрақты жұмыс істеуі үшін (яғни виртуализацияны қолданбау талабы)
- жетекші әзірлеушілер Docker-пен жұмыс істегісі келмеді (біртүрлі, бірақ солай болды)
- ҒЗТКЖ басшылығының идеологиялық ойларына сәйкес
MVP үшін инфрақұрылым, стек және шамамен бастапқы талаптар келесідей ұсынылды:
- Debian бар 4 Intel® X5650 сервері (тағы бір қуатты машина толығымен әзірленген)
- Жеке теңшелетін компоненттерді әзірлеу C ++, Python3 тілдерінде жүзеге асырылады
- Қолданылатын негізгі үшінші тарап құралдары: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,…
- Түзету және шығару үшін құрамдастарды бөлек құрастыруға және сынауға арналған құбырлар
Бастапқы кезеңде шешілуі қажет бірінші сұрақтардың бірі - реттелетін құрамдастардың кез келген ортада (CI/CD) қалай орналастырылатыны.
Біз үшінші тарап компоненттерін жүйелі түрде орнатуды және оларды жүйелі түрде жаңартуды шештік. C++ немесе Python тілінде әзірленген қолданбалы қолданбаларды бірнеше жолмен орналастыруға болады. Олардың ішінде, мысалы: жүйелік пакеттерді жасау, оларды құрастырылған кескіндердің репозиторийіне жіберу, содан кейін оларды серверлерге орнату. Белгісіз себеппен басқа әдіс таңдалды, атап айтқанда: CI көмегімен қолданбаның орындалатын файлдары құрастырылады, виртуалды жоба ортасы жасалады, py модульдері талаптар.txt файлынан орнатылады және барлық осы артефактілер конфигурациялармен, сценарийлермен және файлдармен бірге жіберіледі. серверлерге қолданбалы ортаны ілеспе. Содан кейін қолданбалар әкімші құқықтарынсыз виртуалды пайдаланушы ретінде іске қосылады.
CI/CD жүйесі ретінде Gitlab-CI таңдалды. Алынған құбыр келесідей болды:
Құрылымдық жағынан 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
Айта кету керек, құрастыру және тестілеу барлық қажетті жүйелік пакеттер орнатылған және басқа параметрлер жасалған жеке кескінде жүзеге асырылады.
Жұмыстағы осы сценарийлердің әрқайсысы өзінше қызықты болса да, бірақ мен олар туралы айтпаймын, олардың әрқайсысының сипаттамасы көп уақытты алады және бұл мақаланың мақсаты емес. Мен сіздің назарыңызды орналастыру кезеңі шақыру сценарийлерінің тізбегінен тұратынына ғана аударамын:
- createconfig.py - кейіннен орналастыру үшін әртүрлі орталарда құрамдас параметрлері бар settings.ini файлын жасайды (алдын ала өндіру, өндіру, сынақтан өткізу, ...)
- install_venv.sh - белгілі бір каталогта py компоненттері үшін виртуалды орта жасайды және оны қашықтағы серверлерге көшіреді
- Preparat_init.d.py — шаблон негізінде компонент үшін старт-стоп сценарийлерін дайындайды
- deploy.py - жаңа компоненттерді ыдыратады және қайта іске қосады
Уақыт өтті. Сахналық кезең алдын ала және өндіріске ауыстырылды. Тағы бір дистрибутивке (CentOS) өнімге қолдау қосылды. Тағы 5 күшті физикалық сервер және ондаған виртуалды сервер қосылды. Әзірлеушілер мен тестерлер үшін жұмыс күйіне азды-көпті жақын ортада өз тапсырмаларын тексеру қиындай түсті. Бұл кезде онсыз істеу мүмкін емес екені белгілі болды ...
II бөлім
Сонымен, біздің кластер Dockerfiles сипаттамаған бірнеше ондаған жеке құрамдастардың керемет жүйесі. Сіз оны тек жалпы белгілі бір ортаға орналастыру үшін теңшей аласыз. Біздің міндетіміз – шығарылым алдындағы тестілеуден бұрын оны тексеру үшін кластерді кезеңдік ортаға орналастыру.
Теориялық тұрғыдан, бір уақытта іске қосылған бірнеше кластер болуы мүмкін: орындалған күйде немесе аяқталуға жақын тапсырмалардың саны сонша. Біздің қолымыздағы серверлердің мүмкіндіктері әр серверде бірнеше кластерлерді іске қосуға мүмкіндік береді. Әрбір кезеңдік кластер оқшауланған болуы керек (порттарда, каталогтарда және т.б. қиылысулар болмауы керек).
Біздің ең құнды ресурс - бұл біздің уақыт, және бізде оның көп бөлігі болмады.
Жылдамырақ бастау үшін біз 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
Содан кейін біз Gitlab-CI және Swarm түйіндерін CI түйіндерін қашықтан басқару тұрғысынан байланыстырдық: сертификаттарды орнату, құпия айнымалы мәндерді орнату және басқару серверінде 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
Жоғарыдағы код үзіндісінен қолмен әрекетті қажет ететін екі түйменің (deploy_staging, stop_staging) Құбырларға қосылғанын көруге болады.
Стек атауы филиал атауына сәйкес келеді және бұл бірегейлік жеткілікті болуы керек. Стектегі қызметтер бірегей 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
Мұнда сіз құрамдастардың бір желімен (nw_swarm) қосылғанын және бір-біріне қол жетімді екенін көре аласыз.
Жүйе құрамдастары (redis, mysql негізінде) теңшелетін құрамдастардың жалпы пулынан (жоспарларда және теңшелетіндер қызметтер ретінде бөлінеді) бөлінген. Біздің кластерді орналастыру кезеңі CMD-ді біздің бір үлкен конфигурацияланған кескінге беру сияқты көрінеді және жалпы алғанда, I бөлімде сипатталған орналастырудан іс жүзінде еш айырмашылығы жоқ. Мен айырмашылықтарды бөліп көрсетемін:
- git клон... - орналастыруға қажетті файлдарды алу (createconfig.py, install_venv.sh және т.б.)
- бұйралау... && разрядты ашу... - құрастыру артефактілерін жүктеп алыңыз және ашыңыз (құрастырылған утилиталар)
Тек бір ғана әлі сипатталмаған мәселе бар: веб-интерфейсі бар құрамдастарға әзірлеушілердің браузерлерінен қол жеткізу мүмкін емес. Біз бұл мәселені кері прокси арқылы шешеміз, осылайша:
.gitlab-ci.yml ішінде кластер стегін орналастырғаннан кейін теңгерімді қолдану жолын қосамыз (ол орындалған кезде оның конфигурациясын ғана жаңартады (үлгіге сәйкес жаңа nginx конфигурация файлдарын жасайды: /etc/nginx/conf. 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
Сонымен, оқшауланған кезеңдік кластерлерді орналастыру жүзеге асырылды және әзірлеушілер енді оларды тапсырмаларын тексеру үшін жеткілікті кез келген санда іске қоса алады.
Болашақ жоспарлар:
- Біздің құрамдастарды қызметтер ретінде бөліңіз
- Әрбір Docker файлы үшін бар
- Стектегі аз жүктелген түйіндерді автоматты түрде анықтау
- Түйіндерді атау үлгісі бойынша көрсетіңіз (мақаладағыдай идентификаторды пайдаланудың орнына)
- Стек жойылғанын тексеруді қосыңыз
- ...
Арнайы рахмет
Ақпарат көзі: www.habr.com