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:
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:
- createconfig.py - yn creu ffeil settings.ini gyda gosodiadau ar gyfer cydrannau mewn gwahanol amgylcheddau i'w defnyddio wedyn (Cyn-gynhyrchu, Cynhyrchu, Profi, ...)
- gosod_venv.sh — yn creu amgylchedd rhithwir ar gyfer cydrannau py mewn cyfeiriadur penodol ac yn ei gopïo i weinyddion pell
- paratoi_init.d.py — paratoi sgriptiau ar gyfer cydrannau cychwyn yn seiliedig ar y templed
- 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
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
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.
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
- ...