TieÅ”saistes video satura ieteikumu sistÄma, pie kuras strÄdÄjam, ir slÄgta komerciÄla izstrÄde, un tehniski tÄ ir patentÄtu un atvÄrtÄ pirmkoda komponentu daudzkomponentu kopa. Å Ä« raksta rakstÄ«Å”anas mÄrÄ·is ir aprakstÄ«t dokeru spietu klasterizÄcijas sistÄmas ievieÅ”anu pieturvietai, nepÄrtraucot mÅ«su procesu izveidoto darbplÅ«smu ierobežotÄ laikÄ. JÅ«su uzmanÄ«bai piedÄvÄtais stÄstÄ«jums ir sadalÄ«ts divÄs daļÄs. PirmajÄ daÄ¼Ä ir aprakstÄ«ts CI / CD pirms docker spieta lietoÅ”anas, bet otrajÄ ir aprakstÄ«ts tÄ ievieÅ”anas process. Tie, kas nav ieinteresÄti lasÄ«t pirmo daļu, var droÅ”i pÄriet uz otro.
I daļa
TÄlÄ, tÄlÄ gadÄ bija nepiecieÅ”ams pÄc iespÄjas ÄtrÄk iestatÄ«t CI / CD procesu. Viens no nosacÄ«jumiem bija neizmantot Docker izvietoÅ”anai izstrÄdÄtas sastÄvdaļas vairÄku iemeslu dÄļ:
- uzticamÄkai un stabilÄkai ražoÅ”anas komponentu darbÄ«bai (tas ir, faktiski prasÄ«ba neizmantot virtualizÄciju)
- vadoÅ”ie izstrÄdÄtÄji nevÄlÄjÄs strÄdÄt ar Docker (dÄ«vaini, bet tÄ tas bija)
- atbilstoÅ”i pÄtniecÄ«bas un attÄ«stÄ«bas vadÄ«bas ideoloÄ£iskajiem apsvÄrumiem
MVP infrastruktÅ«ra, steks un aptuvenÄs sÄkotnÄjÄs prasÄ«bas tika parÄdÄ«tas Å”Ädi:
- 4 IntelĀ® X5650 serveri ar Debian (ir pilnÄ«bÄ izstrÄdÄta vÄl viena jaudÄ«ga iekÄrta)
- PaÅ”u pielÄgoto komponentu izstrÄde tiek veikta C ++, Python3
- Galvenie izmantotie treÅ”o puÅ”u rÄ«ki: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,ā¦
- Cauruļvadi komponentu veidoÅ”anai un testÄÅ”anai atseviŔķi atkļūdoÅ”anai un izlaiÅ”anai
Viens no pirmajiem jautÄjumiem, kas jÄatrisina sÄkotnÄjÄ posmÄ, ir tas, kÄ pielÄgotie komponenti tiks izvietoti jebkurÄ vidÄ (CI / CD).
MÄs nolÄmÄm sistÄmiski instalÄt treÅ”o puÅ”u komponentus un sistÄmiski tos atjauninÄt. PielÄgotas lietojumprogrammas, kas izstrÄdÄtas C++ vai Python, var izvietot vairÄkos veidos. Starp tiem, piemÄram: sistÄmas pakotÅu izveide, nosÅ«tÄ«Å”ana uz iebÅ«vÄto attÄlu krÄtuvi un pÄc tam instalÄÅ”ana serveros. NezinÄma iemesla dÄļ tika izvÄlÄta cita metode, proti: izmantojot CI, tiek apkopoti lietojumprogrammu izpildÄmie faili, izveidota virtuÄlÄ projekta vide, instalÄti py moduļi no faila prasÄ«bas.txt, un visi Å”ie artefakti tiek nosÅ«tÄ«ti kopÄ ar konfigurÄcijÄm, skriptiem un pavadoÅ”o lietojumprogrammu vidi serveriem. PÄc tam lietojumprogrammas tiek palaistas kÄ virtuÄls lietotÄjs bez administratora tiesÄ«bÄm.
Gitlab-CI tika izvÄlÄta kÄ CI/CD sistÄma. IegÅ«tais cauruļvads izskatÄ«jÄs apmÄram Å”Ädi:
StrukturÄli gitlab-ci.yml izskatÄ«jÄs Å”Ädi
---
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
Ir vÄrts atzÄ«mÄt, ka montÄža un testÄÅ”ana tiek veikta pÄc sava attÄla, kur jau ir instalÄtas visas nepiecieÅ”amÄs sistÄmas pakotnes un ir veikti citi iestatÄ«jumi.
Lai gan katrs no Å”iem skriptiem darbos ir savÄ ziÅÄ interesants, bet es, protams, par tiem nerunÄÅ”u. Katra no tiem apraksts prasÄ«s daudz laika un tas nav raksta mÄrÄ·is. Es tikai vÄrsÄ«Å”u jÅ«su uzmanÄ«bu uz to, ka izvietoÅ”anas posms sastÄv no skriptu izsaukÅ”anas secÄ«bas:
- Createconfig.py - izveido failu settings.ini ar komponentu iestatÄ«jumiem dažÄdÄs vidÄs turpmÄkai izvietoÅ”anai (pirmsražoÅ”ana, ražoÅ”ana, testÄÅ”ana utt.)
- install_venv.sh - izveido virtuÄlo vidi py komponentiem noteiktÄ direktorijÄ un kopÄ to attÄlos serveros
- ready_init.d.py ā sagatavo komponenta starta-stop skriptus, pamatojoties uz veidni
- deploy.py - sadala un restartÄ jaunas sastÄvdaļas
Laiks pagÄja. IestudÄjuma posms tika aizstÄts ar pirmsproducÄÅ”anu un producÄÅ”anu. Pievienots produkta atbalsts vÄl vienÄ izplatÄ«Å”anÄ (CentOS). Pievienoti 5 jaudÄ«gÄki fiziskie serveri un ducis virtuÄlo serveru. Un izstrÄdÄtÄjiem un testÄtÄjiem kļuva arvien grÅ«tÄk pÄrbaudÄ«t savus uzdevumus vidÄ, kas ir vairÄk vai mazÄk tuvu darba stÄvoklim. Å ajÄ laikÄ kļuva skaidrs, ka bez viÅa nav iespÄjams iztikt ...
II daļa
TÄtad, mÅ«su klasteris ir iespaidÄ«ga sistÄma, kas sastÄv no pÄris desmitiem atseviŔķu komponentu, kurus Dockerfiles neapraksta. To var konfigurÄt tikai izvietoÅ”anai noteiktÄ vidÄ kopumÄ. MÅ«su uzdevums ir izvietot klasteru iestudÄjuma vidÄ, lai to pÄrbaudÄ«tu pirms pirmsizlaides testÄÅ”anas.
TeorÄtiski vienlaikus var darboties vairÄkas kopas: tik daudz, cik uzdevumu ir pabeigtÄ stÄvoklÄ« vai tuvu pabeigÅ”anai. MÅ«su rÄ«cÄ«bÄ esoÅ”o serveru jaudas ļauj katrÄ serverÄ« darbinÄt vairÄkus klasterus. Katram inscenÄÅ”anas klasterim jÄbÅ«t izolÄtam (ostÄs, direktorijÄs utt. nedrÄ«kst bÅ«t krustoÅ”anÄs).
MÅ«su visvÄrtÄ«gÄkais resurss ir mÅ«su laiks, un mums tÄ nebija daudz.
Lai sÄktu ÄtrÄk, mÄs izvÄlÄjÄmies Docker Swarm tÄ vienkÄrŔības un arhitektÅ«ras elastÄ«bas dÄļ. Vispirms mÄs izveidojÄm pÄrvaldnieku un vairÄkus mezglus attÄlajos serveros:
$ 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
PÄc tam izveidojiet tÄ«klu:
$ docker network create --driver overlay --subnet 10.10.10.0/24 nw_swarm
TÄlÄk mÄs savienojÄm Gitlab-CI un Swarm mezglus, lai attÄlinÄti kontrolÄtu mezglus no CI: sertifikÄtu instalÄÅ”ana, slepeno mainÄ«go iestatÄ«Å”ana un Docker pakalpojuma iestatÄ«Å”ana vadÄ«bas serverÄ«. Å is
PÄc tam failam .gitlab-ci .yml pievienojÄm steka izveides un iznÄ«cinÄÅ”anas darbus.
.gitlab-ci .yml ir pievienoti vÄl daži darbi
## 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
No iepriekÅ” minÄtÄ koda fragmenta var redzÄt, ka konveijeriem ir pievienotas divas pogas (deploy_staging, stop_staging), kas prasa manuÄlu darbÄ«bu.
Steka nosaukums atbilst filiÄles nosaukumam, un ar Å”o unikalitÄti vajadzÄtu pietikt. Pakalpojumi stekÄ saÅem unikÄlas IP adreses un portus, direktorijus utt. bÅ«s izolÄts, bet vienÄds no steka uz steku (jo konfigurÄcijas fails visiem stekiem ir vienÄds) - ko gribÄjÄm. MÄs izvietojam steku (klasteri), izmantojot docker-compose.yml, kas raksturo mÅ«su kopu.
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
Å eit var redzÄt, ka komponenti ir savienoti ar vienu tÄ«klu (nw_swarm) un ir pieejami viens otram.
SistÄmas komponenti (pamatojoties uz redis, mysql) ir atdalÄ«ti no vispÄrÄjÄ pielÄgoto komponentu kopuma (plÄnos un pielÄgotie tiek sadalÄ«ti kÄ pakalpojumi). MÅ«su klastera izvietoÅ”anas posms izskatÄs kÄ CMD nodoÅ”ana mÅ«su vienÄ lielajÄ konfigurÄtajÄ attÄlÄ un kopumÄ praktiski neatŔķiras no izvietoÅ”anas, kas aprakstÄ«ta I daļÄ. Es izcelÅ”u atŔķirÄ«bas:
- git klons... - iegūstiet izvietoŔanai nepiecieŔamos failus (createconfig.py, install_venv.sh utt.)
- saritinÄt... && izvilkt rÄvÄjslÄdzÄju... - lejupielÄdÄjiet un izpakojiet veidoÅ”anas artefaktus (apkopotÄs utilÄ«tas)
Ir tikai viena problÄma, kas vÄl nav aprakstÄ«ta: komponenti, kuriem ir tÄ«mekļa saskarne, nav pieejami no izstrÄdÄtÄju pÄrlÅ«kprogrammÄm. MÄs atrisinÄm Å”o problÄmu, izmantojot apgriezto starpniekserveri, Å”Ädi:
FailÄ .gitlab-ci.yml pÄc klasteru steka izvietoÅ”anas mÄs pievienojam balansÄtÄja izvietoÅ”anas rindu (kas, veicot apÅemÅ”anos, tikai atjaunina tÄ konfigurÄciju (izveido jaunus nginx konfigurÄcijas failus atbilstoÅ”i veidnei: /etc/nginx/conf. d/${CI_COMMIT_REF_NAME}.conf) ā skatiet docker-compose-nginx.yml kodu)
- 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
IzstrÄdes datoros atjauniniet /etc/hosts; izrakstÄ«t vietrÄdi nginx:
10.50.173.106 staging_BRANCH-1831_cluster.dev
TÄtad ir ieviesta izolÄtu pielÄgoÅ”anas klasteru izvietoÅ”ana, un izstrÄdÄtÄji tagad var tos palaist jebkurÄ skaitÄ, kas ir pietiekams, lai pÄrbaudÄ«tu savus uzdevumus.
NÄkotnes plÄni:
- Atdaliet mÅ«su sastÄvdaļas kÄ pakalpojumus
- Ir katram Dockerfile
- AutomÄtiski noteikt mazÄk noslogotus mezglus kaudzÄ
- NorÄdiet mezglus pÄc nosaukuma modeļa (nevis izmantojiet ID, kÄ norÄdÄ«ts rakstÄ)
- Pievienojiet Äeku, ka kaudze ir iznÄ«cinÄta
- ...
ÄŖpaÅ”s paldies par
Avots: www.habr.com