Lantzen ari garen lineako bideo-edukiak gomendatzeko sistema garapen komertzial itxi bat da eta teknikoki osagai anitzeko kluster bat da, jabedun eta kode irekiko osagaiez. Artikulu hau idaztearen helburua da docker swarm clustering sistemaren ezarpena deskribatzea eszenatze gune baterako, gure prozesuetan ezarritako lan-fluxua denbora mugatu batean eten gabe. Arretara aurkezten den kontakizuna bi zatitan banatuta dago. Lehen zatiak CI / CD deskribatzen du docker swarm erabili aurretik, eta bigarrenak bere ezarpenaren prozesua deskribatzen du. Lehenengo zatia irakurtzeko interesik ez dutenek segurtasunez pasa dezakete bigarrenera.
I. zatia
Urruneko urte urrunean, beharrezkoa zen CI / CD prozesua ahalik eta azkarren konfiguratzea. Baldintzetako bat Docker ez erabiltzea zen zabaltzeko osagaiak garatu dira hainbat arrazoirengatik:
- Produkzioan osagaien funtzionamendu fidagarriagoa eta egonkorragoa lortzeko (hau da, hain zuzen, birtualizazioa ez erabiltzeko eskakizuna)
- Garatzaile nagusiek ez zuten Dockerrekin lan egin nahi (arraroa, baina horrela zen)
- I+G kudeaketaren gogoeta ideologikoen arabera
MVPrako azpiegitura, pila eta gutxi gorabeherako hasierako eskakizunak honela aurkeztu ziren:
- 4 Intel® X5650 zerbitzari Debian-ekin (makina indartsuago bat guztiz garatuta dago)
- Osagai pertsonalizatuen garapena C ++, Python3-n egiten da
- Erabilitako hirugarrenen tresna nagusiak: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql, ...
- Osagaiak bereizita eraikitzeko eta probatzeko kanalizazioak arazketa eta askatzeko
Hasierako fasean landu beharreko lehen galderetako bat osagai pertsonalizatuak nola zabalduko diren edozein ingurunetan (CI / CD).
Hirugarrenen osagaiak sistematikoki instalatzea eta sistematikoki eguneratzea erabaki genuen. C++ edo Python-en garatutako aplikazio pertsonalizatuak hainbat modutara zabaldu daitezke. Horien artean, adibidez: sistema paketeak sortzea, eraikitako irudien biltegira bidali eta gero zerbitzarietan instalatzea. Arrazoi ezezagun batengatik, beste metodo bat aukeratu zen, hau da: CI erabiliz, aplikazioaren fitxategi exekutagarriak konpilatzen dira, proiektuaren ingurune birtual bat sortzen da, py moduluak requirements.txt-etik instalatzen dira eta artefaktu hauek guztiak konfigurazio, script eta scriptekin batera bidaltzen dira. aplikazio-ingurunearekin batera zerbitzarietara. Ondoren, aplikazioak erabiltzaile birtual gisa abiarazten dira administratzaile eskubiderik gabe.
Gitlab-CI aukeratu zuten CI/CD sistema gisa. Ondorioz, hodiak honelako itxura zuen:
Egitura aldetik, gitlab-ci.yml itxura hau zuen
---
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
Azpimarratzekoa da muntaia eta probak bere irudian egiten direla, beharrezko sistema pakete guztiak dagoeneko instalatuta dauden eta beste ezarpen batzuk egin diren.
Lanpostuetan gidoi hauetako bakoitza bere erara interesgarria bada ere, baina noski ez dut horietaz hitz egingo.Bakoitzaren deskribapenak denbora asko beharko du eta ez da hau artikuluaren helburua. Inplementazio-fasea dei-scripten sekuentziaz osatuta dagoela bakarrik jarriko dizut arreta:
- createconfig.py - settings.ini fitxategi bat sortzen du osagaien ezarpenekin hainbat ingurunetan gero zabaltzeko (aurreprodukzioa, ekoizpena, probak, ...)
- install_venv.sh - py osagaientzako ingurune birtual bat sortzen du direktorio zehatz batean eta urruneko zerbitzarietan kopiatzen du
- prestatu_init.d.py — txantiloian oinarritutako osagaiaren hasiera-gelditzeko scriptak prestatzen ditu
- zabaldu.py - osagai berriak deskonposatu eta berrabiarazi egiten ditu
Denbora pasa zen. Eszenaratzea aurreprodukzioa eta ekoizpena ordezkatu zuten. Produkturako laguntza gehitu da beste banaketa batean (CentOS). 5 zerbitzari fisiko indartsuago eta dozena bat birtual gehitu dira. Eta gero eta zailagoa zen garatzaile eta probatzaileentzat beren zereginak probatzea lan-egoeratik gutxi gorabehera hurbileko ingurune batean. Une honetan, argi geratu zen ezinezkoa zela hura gabe egin ...
II. zatia
Beraz, gure klusterra Dockerfiles-ek deskribatzen ez dituen dozena pare bat osagaiz osatutako sistema ikusgarria da. Orokorrean ingurune zehatz batean hedatzeko soilik konfigura dezakezu. Gure zeregina klusterra fase-ingurune batean zabaltzea da, kaleratu aurretiko probak probatzeko.
Teorian, hainbat kluster egon daitezke aldi berean exekutatzen: amaitutako egoeran edo amaitzetik gertu dauden zereginak adina. Eskura ditugun zerbitzarien ahalmenek zerbitzari bakoitzean hainbat kluster exekutatzeko aukera ematen dute. Eszenatze-kluster bakoitza isolatuta egon behar da (ez da gurutzaketarik egon behar portuetan, direktorioetan, etab.).
Gure baliabiderik baliotsuena gure denbora da, eta ez genuen askorik.
Azkarrago hasteko, Docker Swarm aukeratu dugu bere sinpletasunagatik eta arkitektura malgutasunagatik. Egin genuen lehenengo gauza kudeatzailea eta hainbat nodo sortzea izan zen urruneko zerbitzarietan:
$ 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
Ondoren, sortu sare bat:
$ docker network create --driver overlay --subnet 10.10.10.0/24 nw_swarm
Ondoren, Gitlab-CI eta Swarm nodoak konektatu genituen CI-tik nodoen urruneko kontrolari dagokionez: ziurtagiriak instalatu, aldagai sekretuak ezarri eta Docker zerbitzua kontrol zerbitzarian konfiguratu. Hau
Ondoren, pila sortzeko eta suntsitzeko lanak gehitu genituen .gitlab-ci .yml-era.
Lan batzuk gehiago gehitu dira .gitlab-ci .yml-era
## 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
Goiko kode zatitik, bi botoi (deploy_staging, stop_staging) Pipelines-en gehitu direla ikus dezakezu, eskuzko ekintzak behar direla.
Pila-izena adar-izenarekin bat dator eta berezitasun hori nahikoa izan beharko litzateke. Pilako zerbitzuek ip helbide bereziak eta atakak, direktorioak eta abar jasotzen dituzte. isolatuta egongo da, baina berdin pila batetik bestera (konfigurazio fitxategia pila guztietan berdina baita) - nahi genuena. Pila (kluster) erabiliz zabaltzen dugu Docker-compose.yml, gure klusterra deskribatzen duena.
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
Hemen ikus dezakezu osagaiak sare batek (nw_swarm) konektatuta daudela eta elkarren eskura daudela.
Sistemaren osagaiak (redis, mysql oinarritutakoak) osagai pertsonalizatuen multzo orokorretik bereizten dira (planetan eta pertsonalizatuak zerbitzu gisa banatzen dira). Gure klusterraren inplementazio-etapa CMD gure konfiguratutako irudi handi bakarrera pasatzen dela dirudi eta, oro har, ez du ia desberdintzen I. zatian deskribatutako inplementaziotik. Desberdintasunak nabarmenduko ditut:
- git klona... - Lortu hedatzeko beharrezkoak diren fitxategiak (createconfig.py, install_venv.sh, etab.)
- kizkurtu... && deskonprimitu... - Deskargatu eta deskonprimitu eraikuntza artifaktuak (konpilatutako utilitateak)
Oraindik deskribatu gabeko arazo bakarra dago: web-interfazea duten osagaiak ez dira garatzaileen arakatzaileetatik eskuragarri. Arazo hau alderantzizko proxy erabiliz konpontzen dugu, honela:
.gitlab-ci.yml-en, cluster pila zabaldu ondoren, orekatzailea inplementatzeko lerroa gehitzen dugu (konpromisatzen denean, bere konfigurazioa soilik eguneratzen du (nginx konfigurazio fitxategi berriak sortzen ditu txantiloiaren arabera: /etc/nginx/conf. d/${CI_COMMIT_REF_NAME}.conf) - ikusi docker-compose-nginx.yml kodea)
- 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
Garapen-ordenagailuetan, eguneratu /etc/hosts; agindu URL nginx-i:
10.50.173.106 staging_BRANCH-1831_cluster.dev
Beraz, eszenatze-kluster isolatuen hedapena inplementatu da eta garatzaileek orain exekutatu ditzakete beren zereginak egiaztatzeko nahikoa den kopurutan.
Etorkizuneko planak:
- Bereizi gure osagaiak zerbitzu gisa
- Dockerfile bakoitzerako izan
- Detektatu automatikoki pilako kargatu gutxiagoko nodoak
- Zehaztu nodoak izen ereduaren arabera (artikuluan bezala id erabili beharrean)
- Gehitu pila suntsitu dela egiaztatzea
- ...
Esker bereziak
Iturria: www.habr.com