TL;DR: ülevaate-artikkel rakenduste konteinerites käivitamise keskkondade võrdlemiseks. Käsitletakse Dockerit ja teisi sarnaseid süsteeme.

Veidi ajaloost, kust kõik alguse sai
Ajalugu
Esimene tuntud rakenduse isoleerimise meetod on chroot. See sama süsteemi kutsung muudab juurkatalooge - võimaldades programmil, mis seda kutsub, juurdepääsu ainult selle katalooge sisesisene failidele. Kuid kui programmile antakse superkasutaja õigused, võib see potentsiaalselt "põgeneda" chrootist ja saada juurdepääsu põhikirjale. Samuti ei piirduta juurkatalooge vahetusega teiste ressursside (mälu, protsessor) ning võrgujuurdepääsuga.
Järgmiseks meetodiks on täisfunktsionaalse operatsioonisüsteemi käitamine konteineri sees, operatsioonisüsteemi tuumamehhanismide abil. Erinevates operatsioonisüsteemides nimetatakse seda meetodit erinevalt, kuid põhimõte jääb samaks - mitme sõltumatu operatsioonisüsteemi käitamine, millest igaühel on juure tuum, millel põhikirjarežiim töötab. Siia kuuluvad FreeBSD Jails, Solaris Zones, OpenVZ ja LXC Linuxile. Tagatakse isoleeritus mitte ainult ketta ruumi, vaid ka teiste ressursside osas, eelkõige võib igal konteineril olla piirangud protsessorinõuete, mälu ja võrgu ribalaiuste osas. Võrreldes chrootiga on konteinerist väljapääsemine keerulisem, kuna konteineri superkasutajal on juurdepääs ainult konteineri sisule, kuid vajadusest hoida konteerimine ajakohasena ja kasutada vanu tuumaversioone (mis on aktuaalne Linuxile, vähem FreeBSD-le) on olemas tõenäosus "tuuma isoleerimisest läbi murda" ja saada juurdepääs põhikirjale.
Kuna allalaadimist täis operatsioonisüsteemi konteineris (käivitus süsteemi, pakettide haldamine jne) on võimalik kohe käivitada rakendusi, peamine on tagada rakendustele selliste funktsioonide olemasolu (vajalikud teegid ja muud failid). See idee sai alusena rakenduste konteinerite virtualiseerimisele, mille kõige tuntum ja laiemalt tunnustatud esindaja on Docker. Võrreldes varasemate süsteemidega võimaldasid paindlikumad isolatsioonimehhanismid koos konteinerite vahelise virtuaalsete võrkude sisseehitatud toega ja rakenduste oleku jälgimisega loobuda füüsiliste serverite käsitsi haldamisest, et luua suur hulk konteinerite keskkondi.
Docker
Docker on kõige tuntum rakenduste konteinerimise tarkvara. Kirjutatud Go keeles, kasutab see Linuxi kernel'i sisseehitatud funktsioone — cgroups, namespaces, capabilities jne., samuti failisüsteeme Aufs ja teisi sarnaseid, et säästa kettaruumi.

Allikas: wikimedia
Arhitektuur
Enne versiooni 1.11 töötas Docker ühe teenusena, mis teostas kõik konteinerite toimingud: kuvamine konteinerite pilte, konteinerite käivitamine ja API päringute töötlemine. Alates versioonist 1.11 on Docker jagatud mitmeks osaks, mis suhtlevad omavahel: containerd, et hallata konteinerite kogu elutsüklit (ketta ruumi eraldamine, piltide allalaadimine, võrgu haldamine, käivitamine, paigaldamine ja jälgimine) ja runC, konteinerite täitmise keskkond, mis põhineb cgroups'i ja teiste Linuxi kernel'i funktsioonide kasutamisel. Ise teenus docker jäi alles, kuid nüüd see teenib ainult API päringute töötlemiseks, mis edastatakse containerd.

Paigaldamine ja seadistamine
Minu lemmikviis Docker'i paigaldamiseks on docker-machine, mis mitte ainult ei paigalda ja seadista dockerit kaugtöötlusserveritesse (sealhulgas erinevatesse pilvedesse), vaid võimaldab ka töötada kaugtöötlusserverite failisüsteemidega ning käivitada erinevaid käske.
Kuid alates 2018. aastast ei ole projekt peaaegu arenenud, seega teeme paigaldamise ikka enamiku Linux i jaotuste jaoks tavapäraselt — lisame hoidla ja paigaldame vajalikud paketid.
Seda meetodit kasutatakse ka automatiseeritud installimisel, näiteks Ansible'i või teiste sarnaste süsteemide abil, kuid seda ma selles artiklis käsitlema ei hakka.
Installatsioon toimub Centos 7 peal, serverina kasutan virtuaalmasinat; piisab, kui käivitada alltoodud käsud:
# yum install -y yum-utils
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install docker-ce docker-ce-cli containerd.ioPärast installi tuleb teenus käivitada ja seadistada automaatselt käivituma:
# systemctl enable docker
# systemctl start docker
# firewall-cmd --zone=public --add-port=2377/tcp --permanentLisaks on võimalik luua docker'i grupp, mille liikmed saavad töötada dockeriga ilma sudo't kasutamata, seadistada logimist, aktiveerida API välise juurdepääsu ning mitte unustada täiendavalt seadistada tulemüür (keelatud on kõik, mis ei ole lubatud; eelnevalt ja allpool olen seda selguse huvides ajanud), kuid siin ma ei peatu.
Muud võimalused
Lisaks mainitud docker machine'ile on olemas veel docker registry, mis on konteinerite piltide salvestamise vahend, ning docker compose, mis on rakenduste konteinerites juurutamise automatiseerimise vahend, kasutades konteinerite ja muude seotud elementide (nt võrgud, püsivad failisüsteemid andmete salvestamiseks) koostamiseks ja seadistamiseks YAML-faile.
Selle abil saab korraldada ka CICD torustikke. Teine huvitav võimalus on klastrirežiimi töö, nn swarm mode (enne versiooni 1.12 tuntud kui docker swarm), mis võimaldab luua mitmest serverist ühtse infrastruktuuri konteinerite käitamiseks. Toetatakse virtuaalvõrku kõigi serverite üle, on olemas sisseehitatud koormuse tasakaalustaja ning konteineritele on toetatud saladusi.
Docker compose'i YAML-failid võivad väikeste muudatustega olla kasutatavad sellistes klasstrites, automatiseerides täielikult väikeste ja keskmise suurusega klasstrite hooldust erinevatel eesmärkidel. Suuremate klasstrite korral on eelistatud Kubernetes, kuna swarm mode'i hoolduskulud võivad ületada Kubernetes'i omad.
Töö Dockeriga
Pärast installimist ja seadistamist proovime luua klastrit, kus paigaldame GitLabi ja Docker Registry arendustiimile. Serveritena kasutan kolme virtuaalmasinat, millele paigaldan ka jaotatud failisüsteemi GlusterFS, mida kasutan docker volumes'i salvestamiseks, näiteks Docker Registry usaldusväärse versiooni käivitamiseks. Käivitamiseks vajalikud põhikomponendid: Docker Registry, Postgresql, Redis, GitLab koos GitLab Runneriga Swarmi peal. Postgresql käivitame klasterdamisega. , seega ei tohi Postgresql andmete salvestamiseks kasutada GlusterFS-i. Ülejäänud kriitilised andmed salvestatakse GlusterFS-is.
GlusterFS-i paigaldamiseks kõigile serveritele (neid kutsutakse node1, node2, node3) tuleb installida paketid, lubada tulemüüride töö ja luua vajalikud kataloogid:
# yum -y install centos-release-gluster7
# yum -y install glusterfs-server
# systemctl enable glusterd
# systemctl start glusterd
# firewall-cmd --add-service=glusterfs --permanent
# firewall-cmd --reload
# mkdir -p /srv/gluster
# mkdir -p /srv/docker
# echo "$(hostname):/docker /srv/docker glusterfs defaults,_netdev 0 0" >> /etc/fstabPärast paigaldamist tuleb GlusterFS seadistamist jätkata ühest sõlmest, näiteks node1-st:
# gluster peer probe node2
# gluster peer probe node3
# gluster volume create docker replica 3 node1:/srv/gluster node2:/srv/gluster node3:/srv/gluster force
# gluster volume start dockerSeejärel tuleb loodud volume monteerida (käsku tuleb täita kõigil serveritel):
# mount /srv/dockerSwarm mode seadistamine toimub ühel serveritest, mis saab juhi (Leader) rolli, teised peavad klastri juurde liituma, seega tuleb esimesel serveril käivitatud käsu väljundi kopeerida ja täita teistes.
Klastri esialgne seadistamine, käivitan käsu node1-l:
# docker swarm init
Swarm initialized: current node (a5jpfrh5uvo7svzz1ajduokyq) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0c5mf7mvzc7o7vjk0wngno2dy70xs95tovfxbv4tqt9280toku-863hyosdlzvd76trfptd4xnzd xx.xx.xx.xx:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
# docker swarm join-token managerKopeerime teise käsu väljundi, täidame node2-l ja node3-l:
# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.Sellega on serverite esialgne seadistamine lõppenud, alustame teenuste seadistamist, käsud täidetakse node1-l, kui ei ole teisiti märgitud.
Esiteks loome võrgud konteinerite jaoks:
# docker network create --driver=overlay etcd
# docker network create --driver=overlay pgsql
# docker network create --driver=overlay redis
# docker network create --driver=overlay traefik
# docker network create --driver=overlay gitlabSeejärel märgime serverid, see on vajalik, et siduda mõned teenused serveritega:
# docker node update --label-add nodename=node1 node1
# docker node update --label-add nodename=node2 node2
# docker node update --label-add nodename=node3 node3Järgmisena loome kataloogid andmete salvestamiseks etcd-s, KV-pood, mis on vajalik Traefikule ja Stolonile. Sarnaselt Postgresqlile on need serveritega seotud konteinerid, seega täidame selle käsu kõigil serveritel:
# mkdir -p /srv/etcdSeejärel loome etcd seadistamise faili ja rakendame selle:
00etcd.yml
versioon: '3.7'
teenused:
etcd1:
pilt: quay.io/coreos/etcd:latest
hostinimi: etcd1
käsk:
- etcd
- --name=etcd1
- --data-dir=/data.etcd
- --advertise-client-urls=http://etcd1:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-advertise-peer-urls=http://etcd1:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
- --initial-cluster-state=new
- --initial-cluster-token=etcd-cluster
võrgud:
- etcd
mahud:
- etcd1vol:/data.etcd
juhi:
koopiad: 1
paigutus:
piirangud: [node.labels.nodename == node1]
etcd2:
pilt: quay.io/coreos/etcd:latest
hostinimi: etcd2
käsk:
- etcd
- --name=etcd2
- --data-dir=/data.etcd
- --advertise-client-urls=http://etcd2:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-advertise-peer-urls=http://etcd2:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
- --initial-cluster-state=new
- --initial-cluster-token=etcd-cluster
võrgud:
- etcd
mahud:
- etcd2vol:/data.etcd
juhi:
koopiad: 1
paigutus:
piirangud: [node.labels.nodename == node2]
etcd3:
pilt: quay.io/coreos/etcd:latest
hostinimi: etcd3
käsk:
- etcd
- --name=etcd3
- --data-dir=/data.etcd
- --advertise-client-urls=http://etcd3:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-advertise-peer-urls=http://etcd3:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
- --initial-cluster-state=new
- --initial-cluster-token=etcd-cluster
võrgud:
- etcd
mahud:
- etcd3vol:/data.etcd
juhi:
koopiad: 1
paigutus:
piirangud: [node.labels.nodename == node3]
mahud:
etcd1vol:
juht: kohalik
juht_valikud:
tüüp: none
o: bind
seade: "/srv/etcd"
etcd2vol:
juht: kohalik
juht_valikud:
tüüp: none
o: bind
seade: "/srv/etcd"
etcd3vol:
juht: kohalik
juht_valikud:
tüüp: none
o: bind
seade: "/srv/etcd"
võrgud:
etcd:
väline: true# docker stack deploy --compose-file 00etcd.yml etcdMõne aja pärast kontrollime, et etcd klaster on üles tõusnud:
# docker exec $(docker ps | awk '/etcd/ {print $1}') etcdctl member list
ade526d28b1f92f7: name=etcd1 peerURLs=http://etcd1:2380 clientURLs=http://etcd1:2379 isLeader=false
bd388e7810915853: name=etcd3 peerURLs=http://etcd3:2380 clientURLs=http://etcd3:2379 isLeader=false
d282ac2ce600c1ce: name=etcd2 peerURLs=http://etcd2:2380 clientURLs=http://etcd2:2379 isLeader=true
# docker exec $(docker ps | awk '/etcd/ {print $1}') etcdctl cluster-health
member ade526d28b1f92f7 is healthy: got healthy result from http://etcd1:2379
member bd388e7810915853 is healthy: got healthy result from http://etcd3:2379
member d282ac2ce600c1ce is healthy: got healthy result from http://etcd2:2379
cluster is healthyLoome Postgresql jaoks katalooge, käsk tuleb täita kõigil serveritel:
# mkdir -p /srv/pgsqlJärgmisena loome Postgresql seadistamiseks faili:
01pgsql.yml
versioon: '3.7'
teenused:
pgsentinel:
pilt: sorintlab/stolon:master-pg10
käsk:
- gosu
- stolon
- stolon-sentinel
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
- --log-level=debug
võrgud:
- etcd
- pgsql
juurutamine:
koopiad: 3
värskenduse_config:
paralleelsus: 1
viivitus: 30s
järjekord: stop-first
tõrke_toiming: pause
pgkeeper1:
pilt: sorintlab/stolon:master-pg10
hostinimi: pgkeeper1
käsk:
- gosu
- stolon
- stolon-keeper
- --pg-listen-address=pgkeeper1
- --pg-repl-username=replica
- --uid=pgkeeper1
- --pg-su-username=postgres
- --pg-su-passwordfile=/run/secrets/pgsql
- --pg-repl-passwordfile=/run/secrets/pgsql_repl
- --data-dir=/var/lib/postgresql/data
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
võrgud:
- etcd
- pgsql
keskkond:
- PGDATA=/var/lib/postgresql/data
mahutid:
- pgkeeper1:/var/lib/postgresql/data
saladused:
- pgsql
- pgsql_repl
juurutamine:
koopiad: 1
paiknemine:
piirangud: [node.labels.nodename == node1]
pgkeeper2:
pilt: sorintlab/stolon:master-pg10
hostinimi: pgkeeper2
käsk:
- gosu
- stolon
- stolon-keeper
- --pg-listen-address=pgkeeper2
- --pg-repl-username=replica
- --uid=pgkeeper2
- --pg-su-username=postgres
- --pg-su-passwordfile=/run/secrets/pgsql
- --pg-repl-passwordfile=/run/secrets/pgsql_repl
- --data-dir=/var/lib/postgresql/data
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
võrgud:
- etcd
- pgsql
keskkond:
- PGDATA=/var/lib/postgresql/data
mahutid:
- pgkeeper2:/var/lib/postgresql/data
saladused:
- pgsql
- pgsql_repl
juurutamine:
koopiad: 1
paiknemine:
piirangud: [node.labels.nodename == node2]
pgkeeper3:
pilt: sorintlab/stolon:master-pg10
hostinimi: pgkeeper3
käsk:
- gosu
- stolon
- stolon-keeper
- --pg-listen-address=pgkeeper3
- --pg-repl-username=replica
- --uid=pgkeeper3
- --pg-su-username=postgres
- --pg-su-passwordfile=/run/secrets/pgsql
- --pg-repl-passwordfile=/run/secrets/pgsql_repl
- --data-dir=/var/lib/postgresql/data
- --cluster-name=stolon-cluster
- --store-backend=etcdv3
- --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
võrgud:
- etcd
- pgsql
keskkond:
- PGDATA=/var/lib/postgresql/data
mahutid:
- pgkeeper3:/var/lib/postgresql/data
saladused:
- pgsql
- pgsql_repl
juurutamine:
koopiad: 1
paiknemine:
piirangud: [node.labels.nodename == node3]
postgresql:
pilt: sorintlab/stolon:master-pg10
käsk: gosu stolon stolon-proxy --listen-address 0.0.0.0 --cluster-name stolon-cluster --store-backend=etcdv3 --store-endpoints http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
võrgud:
- etcd
- pgsql
juurutamine:
koopiad: 3
värskenduse_config:
paralleelsus: 1
viivitus: 30s
järjekord: stop-first
tõrke_toiming: rollback
mahutid:
pgkeeper1:
draiver: kohalik
draiver_opts:
tüüp: none
o: bind
seade: "/srv/pgsql"
pgkeeper2:
draiver: kohalik
draiver_opts:
tüüp: none
o: bind
seade: "/srv/pgsql"
pgkeeper3:
draiver: kohalik
draiver_opts:
tüüp: none
o: bind
seade: "/srv/pgsql"
saladused:
pgsql:
fail: "/srv/docker/postgres"
pgsql_repl:
fail: "/srv/docker/replica"
võrgud:
etcd:
väline: tõene
pgsql:
väline: tõeneGenereerime saladusi, rakendame faili:
# </dev/urandom tr -dc 234567890qwertyuopasdfghjkzxcvbnmQWERTYUPASDFGHKLZXCVBNM | head -c $(((RANDOM%3)+15)) > /srv/docker/replica
# </dev/urandom tr -dc 234567890qwertyuopasdfghjkzxcvbnmQWERTYUPASDFGHKLZXCVBNM | head -c $(((RANDOM%3)+15)) > /srv/docker/postgres
# docker stack deploy --compose-file 01pgsql.yml pgsqlMõne aja pärast (vaatame käsu väljundit docker service ls, et näha, et kõik teenused on üles tõusnud) käivitame Postgresql klastri:
# docker exec $(docker ps | awk '/pgkeeper/ {print $1}') stolonctl --cluster-name=stolon-cluster --store-backend=etcdv3 --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379 initKontrollime Postgresql klastri valmisolekut:
# docker exec $(docker ps | awk '/pgkeeper/ {print $1}') stolonctl --cluster-name=stolon-cluster --store-backend=etcdv3 --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379 status
=== Active sentinels ===
ID LEADER
26baa11d false
74e98768 false
a8cb002b true
=== Active proxies ===
ID
4d233826
9f562f3b
b0c79ff1
=== Keepers ===
UID HEALTHY PG LISTENADDRESS PG HEALTHY PG WANTEDGENERATION PG CURRENTGENERATION
pgkeeper1 true pgkeeper1:5432 true 2 2
pgkeeper2 true pgkeeper2:5432 true 2 2
pgkeeper3 true pgkeeper3:5432 true 3 3
=== Cluster Info ===
Master Keeper: pgkeeper3
===== Keepers/DB tree =====
pgkeeper3 (master)
├─pgkeeper2
└─pgkeeper1
Seadistame traefik'i konteinerite väljast juurdepääsu avamiseks:
03traefik.yml
version: '3.7'
services:
traefik:
image: traefik:latest
command: >
--log.level=INFO
--providers.docker=true
--entryPoints.web.address=:80
--providers.providersThrottleDuration=2
--providers.docker.watch=true
--providers.docker.swarmMode=true
--providers.docker.swarmModeRefreshSeconds=15s
--providers.docker.exposedbydefault=false
--accessLog.bufferingSize=0
--api=true
--api.dashboard=true
--api.insecure=true
networks:
- traefik
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
replicas: 3
placement:
constraints:
- node.role == manager
preferences:
- spread: node.id
labels:
- traefik.enable=true
- traefik.http.routers.traefik.rule=Host(`traefik.example.com`)
- traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.docker.network=traefik
networks:
traefik:
external: true# docker stack deploy --compose-file 03traefik.yml traefikKäivitame Redis klastrit, selleks loome kõikidesse sõlmedesse salvestuskausta:
# mkdir -p /srv/redis05redis.yml
version: '3.7'
services:
redis-master:
image: 'bitnami/redis:latest'
networks:
- redis
ports:
- '6379:6379'
environment:
- REDIS_REPLICATION_MODE=master
- REDIS_PASSWORD=xxxxxxxxxxx
deploy:
mode: global
restart_policy:
condition: any
volumes:
- 'redis:/opt/bitnami/redis/etc/'
redis-replica:
image: 'bitnami/redis:latest'
networks:
- redis
ports:
- '6379'
depends_on:
- redis-master
environment:
- REDIS_REPLICATION_MODE=slave
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PORT_NUMBER=6379
- REDIS_MASTER_PASSWORD=xxxxxxxxxxx
- REDIS_PASSWORD=xxxxxxxxxxx
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: any
redis-sentinel:
image: 'bitnami/redis:latest'
networks:
- redis
ports:
- '16379'
depends_on:
- redis-master
- redis-replica
entrypoint: |
bash -c 'bash -s <<EOF
"/bin/bash" -c "cat < /opt/bitnami/redis/etc/sentinel.conf
port 16379
dir /tmp
sentinel monitor master-node redis-master 6379 2
sentinel down-after-milliseconds master-node 5000
sentinel parallel-syncs master-node 1
sentinel failover-timeout master-node 5000
sentinel auth-pass master-node xxxxxxxxxxx
sentinel announce-ip redis-sentinel
sentinel announce-port 16379
EOF"
"/bin/bash" -c "redis-sentinel /opt/bitnami/redis/etc/sentinel.conf"
EOF'
deploy:
mode: global
restart_policy:
condition: any
volumes:
redis:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: "/srv/redis"
networks:
redis:
external: true# docker stack deploy --compose-file 05redis.yml redisLisame Docker Registry:
06registry.yml
versioon: '3.7'
teenused:
registri:
pilt: registry:2.6
võrgud:
- traefik
mahts:
- registry_data:\/var\/lib\/registry
juurutamine:
koopiad: 1
asukoht:
piirangud: [node.role == manager]
taaskäivitamispoliitika:
tingimus: on-failure
sildid:
- traefik.enable=true
- traefik.http.routers.registry.rule=Host(`registry.example.com`)
- traefik.http.services.registry.loadbalancer.server.port=5000
- traefik.docker.network=traefik
mahts:
registry_data:
draiver: kohalik
draiveri_valikud:
tüüp: none
o: bind
seade: "\/srv\/docker\/registry"
võrgud:
traefik:
väline: true# mkdir /srv/docker/registry
# docker stack deploy --compose-file 06registry.yml registryJa lõpuks — GitLab:
08gitlab-runner.yml
versioon: '3.7'
teenused:
gitlab:
pilt: gitlab\/gitlab-ce:latest
võrgud:
- pgsql
- redis
- traefik
- gitlab
portid:
- 22222:22
keskkond:
GITLAB_OMNIBUS_CONFIG: |
postgresql['enable'] = false
redis['enable'] = false
gitlab_rails['registry_enabled'] = false
gitlab_rails['db_username'] = "gitlab"
gitlab_rails['db_password'] = "XXXXXXXXXXX"
gitlab_rails['db_host'] = "postgresql"
gitlab_rails['db_port'] = "5432"
gitlab_rails['db_database'] = "gitlab"
gitlab_rails['db_adapter'] = 'postgresql'
gitlab_rails['db_encoding'] = 'utf8'
gitlab_rails['redis_host'] = 'redis-master'
gitlab_rails['redis_port'] = '6379'
gitlab_rails['redis_password'] = 'xxxxxxxxxxx'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.yandex.ru"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "noreply@example.com"
gitlab_rails['smtp_password'] = "xxxxxxxxx"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['gitlab_email_from'] = 'noreply@example.com'
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
external_url 'http:\/\/gitlab.example.com\/'
gitlab_rails['gitlab_shell_ssh_port'] = 22222
mahts:
- gitlab_conf:\/etc\/gitlab
- gitlab_logs:\/var\/log\/gitlab
- gitlab_data:\/var\/opt\/gitlab
juurutamine:
režiim: replitseeritud
koopiad: 1
asukoht:
piirangud:
- node.role == manager
sildid:
- traefik.enable=true
- traefik.http.routers.gitlab.rule=Host(`gitlab.example.com`)
- traefik.http.services.gitlab.loadbalancer.server.port=80
- traefik.docker.network=traefik
gitlab-runner:
pilt: gitlab\/gitlab-runner:latest
võrgud:
- gitlab
mahts:
- gitlab_runner_conf:\/etc\/gitlab
- \/var\/run\/docker.sock:\/var\/run\/docker.sock
juurutamine:
režiim: replitseeritud
koopiad: 1
asukoht:
piirangud:
- node.role == manager
mahts:
gitlab_conf:
draiver: kohalik
draiveri_valikud:
tüüp: none
o: bind
seade: "\/srv\/docker\/gitlab\/conf"
gitlab_logs:
draiver: kohalik
draiveri_valikud:
tüüp: none
o: bind
seade: "\/srv\/docker\/gitlab\/logs"
gitlab_data:
draiver: kohalik
draiveri_valikud:
tüüp: none
o: bind
seade: "\/srv\/docker\/gitlab\/data"
gitlab_runner_conf:
draiver: kohalik
draiveri_valikud:
tüüp: none
o: bind
seade: "\/srv\/docker\/gitlab\/runner"
võrgud:
pgsql:
väline: true
redis:
väline: true
traefik:
väline: true
gitlab:
väline: true# mkdir -p /srv/docker/gitlab/conf
# mkdir -p /srv/docker/gitlab/logs
# mkdir -p /srv/docker/gitlab/data
# mkdir -p /srv/docker/gitlab/runner
# docker stack deploy --compose-file 08gitlab-runner.yml gitlabKlastri ja teenuste lõplik olek:
# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
lef9n3m92buq etcd_etcd1 replicated 1/1 quay.io/coreos/etcd:latest
ij6uyyo792x5 etcd_etcd2 replicated 1/1 quay.io/coreos/etcd:latest
fqttqpjgp6pp etcd_etcd3 replicated 1/1 quay.io/coreos/etcd:latest
hq5iyga28w33 gitlab_gitlab replicated 1/1 gitlab/gitlab-ce:latest *:22222->22/tcp
dt7s6vs0q4qc gitlab_gitlab-runner replicated 1/1 gitlab/gitlab-runner:latest
k7uoezno0h9n pgsql_pgkeeper1 replicated 1/1 sorintlab/stolon:master-pg10
cnrwul4r4nse pgsql_pgkeeper2 replicated 1/1 sorintlab/stolon:master-pg10
frflfnpty7tr pgsql_pgkeeper3 replicated 1/1 sorintlab/stolon:master-pg10
x7pqqchi52kq pgsql_pgsentinel replicated 3/3 sorintlab/stolon:master-pg10
mwu2wl8fti4r pgsql_postgresql replicated 3/3 sorintlab/stolon:master-pg10
9hkbe2vksbzb redis_redis-master global 3/3 bitnami/redis:latest *:6379->6379/tcp
l88zn8cla7dc redis_redis-replica replicated 3/3 bitnami/redis:latest *:30003->6379/tcp
1utp309xfmsy redis_redis-sentinel global 3/3 bitnami/redis:latest *:30002->16379/tcp
oteb824ylhyp registry_registry replicated 1/1 registry:2.6
qovrah8nzzu8 traefik_traefik replicated 3/3 traefik:latest *:80->80/tcp, *:443->443/tcpMida veel saaks parandada? Oluline on seadistada Traefik konteinerite töötamine https-i kaudu, lisada TLS-krüpteerimine Postgresql-i ja Redis'e jaoks. Aga üldiselt saab seda arendajatele anda PoC-na. Vaatame nüüd Dockerile alternatiive.
Podman
Veel üks üsna tuntud mootor konteinerite käivitamiseks, mis on rühmitatud podide (pods, rühmad koos installitud konteineritest) järgi. Erinevalt Dockerist ei nõua see konteinerite käivitamiseks ühtegi teenust, kogu töö toimub läbi libpod teegi. Samuti on see kirjutatud Go-s ja vajab konteinerite käivitamiseks OCI ühilduvat käitusaja keskkonda, näiteks runC.

Töö Podmaniga sarnaneb üldiselt Dockeriga, kuni selleni, et saate teha nii (paljude proovijatena, sealhulgas käesoleva artikli autorina, on seda kinnitatud):
$ alias docker=podmanja saate jätkata töötamist. Üldiselt on olukord Podmaniga üsna huvitav, kuna varasemad Kubernetes versioonid töötasid Dockeriga, siis umbes alates 2015. aastast, pärast konteinerite maailmas standardimise (OCI - Open Container Initiative) ja Docker'i jagunemist containerd ja runC-ks, areneb Dockerile alternatiiv Kubernetes'e jaoks: CRI-O. Podman on selles suhtes Docker'i alternatiiv, mis põhineb Kubernetes'e põhimõtetel, sealhulgas konteinerite gruppides grupeerimisel, kuid projekti peamine eesmärk on käivitada konteinerid Docker'i stiilis ilma täiendavate teenusteta. Arusaadavatel põhjustel ei ole swarm mode'i, kuna arendajad ütlevad selgelt, et kui vajate klastrit - võtke Kubernetes.
Paigaldamine
CentOS 7-s seadistamiseks piisab Extras repostiivide aktiveerimisest ja seejärel paigaldada kõik käsuga:
# yum -y install podmanMuud võimalused
Podman suudab genereerida süsteemi üksuseid systemd jaoks, lahendades seeläbi konteinerite käivitamise probleemid serveri taaskäivitamisel. Lisaks on väidetud, et systemd töötab korrektselt pid 1-na konteineris. Konteinerite kokkupanekuks on olemas eraldi tööriist buildah, samuti on olemas kolmandate osapoolte tööriistad - Docker-compose'i analoogid, mis genereerivad sealhulgas Kubernetes'ega ühilduvaid konfiguratsioonifaile, nii et üleminek Podmanilt Kubernetes'ile on tehtud võimalikult lihtsaks.
Töö Podmaniga
Kuna swarm mode'i ei ole (oodatakse üleminekut Kubernetes'ile, kui on vaja klastrit) - kogume kogumise ajal eraldi konteinerite kaupa.
Installime podman-compose:
# yum -y install python3-pip
# pip3 install podman-composeTulemuseks olev konfiguratsioonifail podmani jaoks erineb veidi, näiteks tuli eraldi volume sektsioon otse teenuste sektsiooni üle viia.
gitlab-podman.yml
versioon: '3.7'
teenused:
gitlab:
pilt: gitlab/gitlab-ce:latest
domeen: gitlab.example.com
taasta: kui ei ole peatatud
keskkond:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['gitlab_shell_ssh_port'] = 22222
sadamad:
- "80:80"
- "22222:22"
mahtu:
- /srv/podman/gitlab/conf:/etc/gitlab
- /srv/podman/gitlab/data:/var/opt/gitlab
- /srv/podman/gitlab/logs:/var/log/gitlab
võrgud:
- gitlab
gitlab-runner:
pilt: gitlab/gitlab-runner:alpine
taasta: kui ei ole peatatud
sõltub:
- gitlab
mahtu:
- /srv/podman/gitlab/runner:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
võrgud:
- gitlab
võrgud:
gitlab:# podman-compose -f gitlab-runner.yml -d upTöö tulemus:
# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da53da946c01 docker.io/gitlab/gitlab-runner:alpine run --user=gitlab... About a minute ago Up About a minute ago 0.0.0.0:22222->22/tcp, 0.0.0.0:80->80/tcp root_gitlab-runner_1
781c0103c94a docker.io/gitlab/gitlab-ce:latest /assets/wrapper About a minute ago Up About a minute ago 0.0.0.0:22222->22/tcp, 0.0.0.0:80->80/tcp root_gitlab_1Vaadakem, mida ta genereerib systemd ja kubernetes'i jaoks, selleks on vaja teada poodi nime või ID-d:
# podman pod ls
POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID
71fc2b2a5c63 root Running 11 minutes ago 3 db40ab8bf84bKubernetes:
# podman generate kube 71fc2b2a5c63
# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-1.6.4
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-07-29T19:22:40Z"
labels:
app: root
name: root
spec:
containers:
- command:
- /assets/wrapper
env:
- name: PATH
value: /opt/gitlab/embedded/bin:/opt/gitlab/bin:/assets:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: HOSTNAME
value: gitlab.example.com
- name: container
value: podman
- name: GITLAB_OMNIBUS_CONFIG
value: |
gitlab_rails['gitlab_shell_ssh_port'] = 22222
- name: LANG
value: C.UTF-8
image: docker.io/gitlab/gitlab-ce:latest
name: rootgitlab1
ports:
- containerPort: 22
hostPort: 22222
protocol: TCP
- containerPort: 80
hostPort: 80
protocol: TCP
resources: {}
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /var/opt/gitlab
name: srv-podman-gitlab-data
- mountPath: /var/log/gitlab
name: srv-podman-gitlab-logs
- mountPath: /etc/gitlab
name: srv-podman-gitlab-conf
workingDir: /
- command:
- run
- --user=gitlab-runner
- --working-directory=/home/gitlab-runner
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- name: TERM
value: xterm
- name: HOSTNAME
- name: container
value: podman
image: docker.io/gitlab/gitlab-runner:alpine
name: rootgitlab-runner1
resources: {}
securityContext:
allowPrivilegeEscalation: true
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
volumeMounts:
- mountPath: /etc/gitlab-runner
name: srv-podman-gitlab-runner
- mountPath: /var/run/docker.sock
name: var-run-docker.sock
workingDir: /
volumes:
- hostPath:
path: /srv/podman/gitlab/runner
type: Directory
name: srv-podman-gitlab-runner
- hostPath:
path: /var/run/docker.sock
type: File
name: var-run-docker.sock
- hostPath:
path: /srv/podman/gitlab/data
type: Directory
name: srv-podman-gitlab-data
- hostPath:
path: /srv/podman/gitlab/logs
type: Directory
name: srv-podman-gitlab-logs
- hostPath:
path: /srv/podman/gitlab/conf
type: Directory
name: srv-podman-gitlab-conf
status: {}Systemd:
# podman generate systemd 71fc2b2a5c63
# pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020
[Unit]
Description=Podman pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
Documentation=man:podman-generate-systemd(1)
Requires=container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
Before=container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa
ExecStop=/usr/bin/podman stop -t 10 db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa/userdata/conmon.pid
[Install]
WantedBy=multi-user.target
# container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020
[Unit]
Description=Podman container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
Documentation=man:podman-generate-systemd(1)
RefuseManualStart=yes
RefuseManualStop=yes
BindsTo=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
After=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864
ExecStop=/usr/bin/podman stop -t 10 da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864/userdata/conmon.pid
[Install]
WantedBy=multi-user.target
# container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020
[Unit]
Description=Podman container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service
Documentation=man:podman-generate-systemd(1)
RefuseManualStart=yes
RefuseManualStop=yes
BindsTo=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
After=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start 781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3
ExecStop=/usr/bin/podman stop -t 10 781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3/userdata/conmon.pid
[Install]
WantedBy=multi-user.targetKahjuks, peale konteinerite käivitamise, ei tee genereeritud üksus systemd jaoks midagi muud (näiteks vanade konteinerite puhastamist sellise teenuse uuesti käivitamisel), seega sellised asjad tuleb ise juurde kirjutada.
Põhimõtteliselt on Podman piisav, et proovida, mis on konteinerid, viia üle vanad konfiguratsioonid docker-compose'ist, pärast mida liikuda Kubernetes'i suunas, kui on vaja klastrit, või saada lihtsamalt hallatav alternatiiv Docker'ile.
rkt
Projekt umbes pool aastat tagasi, kuna selle ostis RedHat, seega ma ei peatu sellel detailselt. Üldiselt jättis see üsna hea mulje, kuid võrreldes Docker'iga ja veel enam Podman'iga, näeb see välja nagu kombain. Samuti eksisteeris CoreOS jaotust, mis oli üles ehitatud rkt põhjal (kuigi neil oli algselt Docker), kuid selle tugi lõppes samuti pärast RedHat'i ostu.
Plash
Veel , mille autor soovis lihtsalt koguda ja käivitada konteinerid. Kohtu andmete ja koodi põhjal — autor ei järginud standardeid, vaid otsustas lihtsalt kirjutada oma rakenduse, mida ta põhimõtteliselt ka tegi.
Järeldused
Kubernetes'i olemasolu korral on olukord üsna huvitav: ühelt poolt saab Docker'iga koguda klastrit (swarm režiimis), millega saab isegi klientide toote keskkondi käivitada, see on eriti aktuaalne väikestele meeskondadele (3-5 inimest), või väikese üldkoormuse korral, või kui ei ole soovi süveneda Kubernetes'i seadistamise nüanssidesse, sealhulgas suurte koormustega.
Podman ei taga täit ühilduvust, kuid sellel on üks tähtis eelis — ühilduvus Kubernetesega, sealhulgas lisatööriistade (buildah jne) osas. Seetõttu lähen tööriista valikule nii: väikeste meeskondade või piiratud eelarve jaoks — Docker (võimaliku swarm mode'iga), isiklikuks arenduseks kohalikul localhost'il — Podman koos kolleegidega, ning kõigi teiste jaoks — Kubernetes.
Ma ei ole kindel, et Docker'i olukord tulevikus ei muutu; nad on ikkagi pioneerid ning samas aeglaselt standardiseeruvad. Kuid Podman'il, vaatamata kõigile oma puudustele (töö ainult Linuxil, puuduvad klasterdamise võimalused, koostamine ja muud toimingud — kolmandate osapoolte lahendustega) on tulevik selgem, seega kutsun kõiki huvilisi neid järeldusi arutama kommentaarides.
P.S. 3. augustil käivitame “”, kus saab lähemalt tutvuda selle tööga. Läbime kõik selle tööriistad: alates peamistest abstraktsioonidest kuni võrgu parameetriteni, erinevate operatsioonisüsteemide ja programmeerimiskeelte töö nüanssideni. Te tutvute tehnoloogiaga ja saate aru, kus ja kuidas on parim Dockerit kasutada. Jagame ka parimaid praktikaid ja juhtumeid.
Eelneva tellimuse hind enne väljaandmist: 5000 rubla. Videokursuse programmi saab vaadata .
Allikas: habr.com
