TL; DR: Мақолаи мухтасар - дастур оид ба муқоисаи муҳитҳо барои иҷрои барномаҳо дар контейнерҳо. Имкониятҳои Docker ва дигар системаҳои шабеҳ баррасӣ карда мешаванд.
Таърихи каме дар бораи он ки ҳама аз куҷо пайдо шудааст
ҳикояи
Аввалин роҳи маъруфи ҷудо кардани барнома chroot мебошад. Даъвати системавӣ бо ҳамон ном тағиротро ба директорияи реша таъмин мекунад - ҳамин тавр дастрасӣ ба барномае, ки онро даъват кардааст, дастрасиро танҳо ба файлҳои дохили ин директория таъмин мекунад. Аммо агар ба барнома дар дохили он ҳуқуқҳои суперкорбарӣ дода шавад, он метавонад эҳтимолан аз chroot "гурехтан" шавад ва ба системаи асосии оператсионӣ дастрасӣ пайдо кунад. Ғайр аз он, ба ғайр аз тағир додани феҳристи реша, захираҳои дигар (RAM, протсессор), инчунин дастрасӣ ба шабака маҳдуд нестанд.
Роҳи дигар ин ба кор андохтани системаи оператсионии мукаммал дар дохили контейнер бо истифода аз механизмҳои ядрои системаи оператсионӣ мебошад. Ин усулро дар системаҳои оператсионии гуногун ба таври гуногун меноманд, аммо моҳият як аст - кор кардани якчанд системаи оператсионии мустақил, ки ҳар яки онҳо дар як ядрое, ки системаи оператсионии асосиро идора мекунад, кор мекунад. Ба ин зиндонҳои FreeBSD, Solaris Zones, OpenVZ ва LXC барои Linux дохил мешаванд. Изолятсия на танҳо барои фазои диск, балки барои дигар захираҳо пешбинӣ шудааст, аз ҷумла, ҳар як контейнер метавонад дар вақти протсессор, RAM, фарохмаҷрои шабака маҳдудият дошта бошад. Дар муқоиса бо chroot, тарк кардани контейнер мушкилтар аст, зеро суперистифодабарандаи контейнер танҳо ба дохили контейнер дастрасӣ дорад, аммо аз сабаби зарурати нигоҳ доштани системаи амалиётии дохили контейнер ва истифодаи ядрои кӯҳна версияҳои (барои Linux, ба андозаи камтар FreeBSD мувофиқ аст), эҳтимолияти шикастани системаи изолятсияи ядро ва дастрасӣ ба системаи асосии амалиётӣ ба сифр баробар нест.
Ба ҷои ба кор андохтани системаи оператсионии мукаммал дар контейнер (бо системаи ибтидоӣ, мудири баста ва ғайра) барномаҳоро фавран оғоз кардан мумкин аст, чизи асосӣ ин аст, ки барномаҳо бо ин имконият (мавҷудияти китобхонаҳои зарурӣ ва файлҳои дигар). Ин идея ҳамчун асос барои виртуализатсияи барномаҳои контейнерӣ хидмат кард, ки намояндаи барҷастатарин ва маъруфи он Docker мебошад. Дар муқоиса бо системаҳои қаблӣ, механизмҳои изолятсияи фасењтар, дар якҷоягӣ бо дастгирии дарунсохт барои шабакаҳои виртуалӣ байни контейнерҳо ва ҳолати барнома дар дохили контейнер, ба қобилияти сохтани муҳити ягонаи ягона аз шумораи зиёди серверҳои физикӣ барои идора кардани контейнерҳо оварда расонд - бе зарурати идоракунии захираҳои дастӣ.
Доктор
Docker маъруфтарин нармафзори контейнерсозии барномаҳо мебошад. Он бо забони Go навишта шудааст, ки имкониятҳои муқаррарии ядрои Linux - гурӯҳҳо, фазоҳои номҳо, қобилиятҳо ва ғайра, инчунин системаҳои файлии Aufs ва дигарҳоро барои сарфаи фазои диск истифода мебарад.
Манбаъ: wikimedia
меъморӣ
Пеш аз версияи 1.11, Docker ҳамчун хидмати ягона кор мекард, ки ҳама амалиётҳоро бо контейнерҳо иҷро мекард: зеркашии тасвирҳо барои контейнерҳо, кушодани контейнерҳо, коркарди дархостҳои API. Аз версияи 1.11, Docker ба якчанд қисмҳо тақсим шудааст, ки бо ҳамдигар ҳамкорӣ мекунанд: контейнер, барои коркарди тамоми давраи ҳаёти контейнерҳо (тақсимоти фазои диск, зеркашии тасвирҳо, шабака, оғоз, насб ва мониторинги ҳолати контейнерҳо) ва runC , вақтҳои кори контейнер, ки дар асоси истифодаи гурӯҳҳо ва дигар хусусиятҳои ядрои Linux. Худи хидмати докер боқӣ мемонад, аммо ҳоло он танҳо барои коркарди дархостҳои API, ки ба контейнер пахш мешавад, хидмат мекунад.
Насб ва танзимот
Роҳи дӯстдоштаи ман барои насб кардани docker docker-machine мебошад, ки ба ғайр аз мустақиман насб кардан ва танзим кардани докер дар серверҳои дурдаст (аз ҷумла абрҳои гуногун) ба шумо имкон медиҳад, ки бо системаҳои файлии серверҳои дурдаст кор кунед ва инчунин метавонад фармонҳои гуногунро иҷро кунед.
Аммо, аз соли 2018 инҷониб лоиҳа базӯр таҳия карда нашудааст, аз ин рӯ мо онро бо роҳи муқаррарии аксари дистрибюторҳои Linux насб мекунем - бо илова кардани анбор ва насб кардани бастаҳои зарурӣ.
Ин усул инчунин барои насби автоматӣ истифода мешавад, масалан, бо истифода аз Ansible ё дигар системаҳои шабеҳ, аммо ман онро дар ин мақола баррасӣ намекунам.
Насбкунӣ дар Centos 7 анҷом дода мешавад, ман як мошини виртуалиро ҳамчун сервер истифода мекунам, барои насб кардан танҳо фармонҳои зерро иҷро кунед:
# 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.io
Пас аз насб, шумо бояд хидматро оғоз кунед, онро ба худкор бор кунед:
# systemctl enable docker
# systemctl start docker
# firewall-cmd --zone=public --add-port=2377/tcp --permanent
Илова бар ин, шумо метавонед як гурӯҳи докер эҷод кунед, ки корбарони онҳо метавонанд бо докер бидуни sudo кор кунанд, сабти номро танзим кунанд, дастрасӣ ба APIро аз берун фаъол созанд, танзим кардани брандмауэрро фаромӯш накунед (ҳар чизе ки иҷозат дода намешавад дар мисолҳои дар боло ва дар поён овардашуда манъ аст - Ман инро барои содда ва визуализатсия сарфи назар кардам), аммо ман дар ин ҷо тафсилоти бештар нахоҳам дод.
Дигар хусусиятҳо
Илова ба мошини дар боло зикршуда, инчунин реестри докер мавҷуд аст, асбоб барои нигоҳ доштани тасвирҳо барои контейнерҳо, инчунин docker compose - асбоб барои автоматикунонии ҷойгиркунии замимаҳо дар контейнерҳо, файлҳои YAML барои сохтан ва танзим кардани контейнерҳо истифода мешаванд ва дигар чизҳои алоқаманд (масалан, шабакаҳо, системаҳои файлии доимӣ барои нигоҳ доштани маълумот).
Он инчунин метавонад барои ташкили қубурҳо барои CICD истифода шавад. Хусусияти дигари ҷолиб ин кор дар реҷаи кластерӣ мебошад, ки ба истилоҳ режими тӯда (пеш аз версияи 1.12 он ҳамчун тӯдаи докер маълум буд), ки ба шумо имкон медиҳад инфрасохтори ягонаро аз якчанд серверҳо барои идора кардани контейнерҳо ҷамъ кунед. Дар болои ҳама серверҳо дастгирии шабакаи виртуалӣ мавҷуд аст, мувозинати дарунсохташуда ва инчунин дастгирии асрор барои контейнерҳо мавҷуд аст.
Файлҳои YAML аз docker compose метавонанд барои чунин кластерҳо бо тағироти ночиз истифода шаванд, ки нигоҳдории кластерҳои хурд ва миёнаро барои мақсадҳои гуногун пурра автоматӣ мекунанд. Барои кластерҳои калон, Kubernetes афзалтар аст, зеро хароҷоти нигоҳдории режими тӯда метавонад аз ҳисоби Kubernetes зиёдтар бошад. Илова ба runC, ҳамчун муҳити иҷро барои контейнерҳо, шумо метавонед, масалан, насб кунед
Кор бо Docker
Пас аз насб ва конфигуратсия, мо кӯшиш мекунем, ки кластер созем, ки дар он мо GitLab ва Реестри Docker-ро барои дастаи таҳиякунанда ҷойгир кунем. Ҳамчун серверҳо ман се мошини маҷозӣ истифода хоҳам кард, ки дар онҳо ман ба таври иловагӣ FS-и тақсимшудаи GlusterFS -ро ҷойгир мекунам ва онро ҳамчун анбори ҳаҷмҳои докер истифода хоҳам кард, масалан, барои иҷро кардани версияи аз хатогии реестри докер. Ҷузъҳои калидии иҷрошаванда: Registry Docker, Postgresql, Redis, GitLab бо дастгирии GitLab Runner дар болои Swarm. Postgresql бо кластерсозӣ оғоз карда мешавад
Барои ҷойгиркунии GlusterFS дар ҳама серверҳо (онҳо node1, node2, node3 номида мешаванд), шумо бояд бастаҳоро насб кунед, брандмауэрро фаъол созед, директорияҳои заруриро эҷод кунед:
# 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/fstab
Пас аз насб, кор оид ба конфигуратсияи GlusterFS бояд аз як гиреҳ идома дода шавад, масалан node1:
# 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 docker
Пас шумо бояд ҳаҷми ҳосилшударо насб кунед (фармон бояд дар ҳама серверҳо иҷро карда шавад):
# mount /srv/docker
Ҳолати тӯда дар яке аз серверҳо танзим шудааст, ки пешво хоҳад буд, боқимондаҳо бояд ба кластер ҳамроҳ шаванд, аз ин рӯ натиҷаи иҷро кардани фармон дар сервери аввал бояд дар боқимонда нусхабардорӣ ва иҷро карда шавад.
Танзимоти ибтидоии кластер, ман фармонро дар node1 иҷро мекунам:
# 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 manager
Натиҷаи фармони дуюмро нусхабардорӣ кунед, дар node2 ва node3 иҷро кунед:
# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.
Ин конфигуратсияи пешакии серверҳоро ба анҷом мерасонад, биёед ба танзимоти хидматҳо шурӯъ кунем, фармонҳои иҷрошаванда аз node1 оғоз карда мешаванд, агар тартиби дигаре пешбинӣ нашуда бошад.
Пеш аз ҳама, биёед шабакаҳоро барои контейнерҳо созем:
# 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 gitlab
Сипас мо серверҳоро қайд мекунем, ин барои пайваст кардани баъзе хидматҳо ба серверҳо зарур аст:
# docker node update --label-add nodename=node1 node1
# docker node update --label-add nodename=node2 node2
# docker node update --label-add nodename=node3 node3
Минбаъд, мо директорияҳоро барои нигоҳ доштани маълумотҳои ғайра, анбори КВ, ки Traefik ва Stolon лозиманд, эҷод мекунем. Ба монанди Postgresql, инҳо контейнерҳои ба серверҳо пайвастшуда хоҳанд буд, аз ин рӯ мо ин фармонро дар ҳама серверҳо иҷро мекунем:
# mkdir -p /srv/etcd
Баъдан, файлеро барои танзим кардани etcd эҷод кунед ва онро татбиқ кунед:
00etcd.yml
version: '3.7'
services:
etcd1:
image: quay.io/coreos/etcd:latest
hostname: etcd1
command:
- 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
networks:
- etcd
volumes:
- etcd1vol:/data.etcd
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node1]
etcd2:
image: quay.io/coreos/etcd:latest
hostname: etcd2
command:
- 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
networks:
- etcd
volumes:
- etcd2vol:/data.etcd
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node2]
etcd3:
image: quay.io/coreos/etcd:latest
hostname: etcd3
command:
- 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
networks:
- etcd
volumes:
- etcd3vol:/data.etcd
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node3]
volumes:
etcd1vol:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/etcd"
etcd2vol:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/etcd"
etcd3vol:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/etcd"
networks:
etcd:
external: true
# docker stack deploy --compose-file 00etcd.yml etcd
Пас аз чанде, мо тафтиш мекунем, ки кластери etcd боло рафтааст:
# 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 healthy
Барои Postgresql феҳристҳо эҷод кунед, фармонро дар ҳама серверҳо иҷро кунед:
# mkdir -p /srv/pgsql
Баъдан, барои танзими Postgresql файл эҷод кунед:
01pgsql.yml
version: '3.7'
services:
pgsentinel:
image: sorintlab/stolon:master-pg10
command:
- 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
networks:
- etcd
- pgsql
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 30s
order: stop-first
failure_action: pause
pgkeeper1:
image: sorintlab/stolon:master-pg10
hostname: pgkeeper1
command:
- 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
networks:
- etcd
- pgsql
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- pgkeeper1:/var/lib/postgresql/data
secrets:
- pgsql
- pgsql_repl
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node1]
pgkeeper2:
image: sorintlab/stolon:master-pg10
hostname: pgkeeper2
command:
- 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
networks:
- etcd
- pgsql
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- pgkeeper2:/var/lib/postgresql/data
secrets:
- pgsql
- pgsql_repl
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node2]
pgkeeper3:
image: sorintlab/stolon:master-pg10
hostname: pgkeeper3
command:
- 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
networks:
- etcd
- pgsql
environment:
- PGDATA=/var/lib/postgresql/data
volumes:
- pgkeeper3:/var/lib/postgresql/data
secrets:
- pgsql
- pgsql_repl
deploy:
replicas: 1
placement:
constraints: [node.labels.nodename == node3]
postgresql:
image: sorintlab/stolon:master-pg10
command: 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
networks:
- etcd
- pgsql
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 30s
order: stop-first
failure_action: rollback
volumes:
pgkeeper1:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/pgsql"
pgkeeper2:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/pgsql"
pgkeeper3:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/pgsql"
secrets:
pgsql:
file: "/srv/docker/postgres"
pgsql_repl:
file: "/srv/docker/replica"
networks:
etcd:
external: true
pgsql:
external: true
Мо сирро тавлид мекунем, файлро татбиқ мекунем:
# </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 pgsql
Пас аз чанде (ба натиҷаи фармон нигаред хадамоти docker lsки ҳама хидматҳо баланд шуданд) кластери Postgresql-ро оғоз кунед:
# 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 init
Санҷиши омодагии кластери Postgresql:
# 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
Мо traefik-ро барои кушодани дастрасӣ ба контейнерҳо аз берун танзим мекунем:
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 traefik
Мо Redis Cluster-ро оғоз мекунем, барои ин мо дар ҳама гиреҳҳо феҳристи нигоҳдорӣ эҷод мекунем:
# mkdir -p /srv/redis
05redis.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 <<EOF > /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 redis
Иловаи Феҳристи Docker:
06registry.yml
version: '3.7'
services:
registry:
image: registry:2.6
networks:
- traefik
volumes:
- registry_data:/var/lib/registry
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
restart_policy:
condition: on-failure
labels:
- traefik.enable=true
- traefik.http.routers.registry.rule=Host(`registry.example.com`)
- traefik.http.services.registry.loadbalancer.server.port=5000
- traefik.docker.network=traefik
volumes:
registry_data:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/registry"
networks:
traefik:
external: true
# mkdir /srv/docker/registry
# docker stack deploy --compose-file 06registry.yml registry
Ва ниҳоят - GitLab:
08gitlab-runner.yml
version: '3.7'
services:
gitlab:
image: gitlab/gitlab-ce:latest
networks:
- pgsql
- redis
- traefik
- gitlab
ports:
- 22222:22
environment:
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'] = "[email protected]"
gitlab_rails['smtp_password'] = "xxxxxxxxx"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['gitlab_email_from'] = '[email protected]'
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
volumes:
- gitlab_conf:/etc/gitlab
- gitlab_logs:/var/log/gitlab
- gitlab_data:/var/opt/gitlab
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- 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:
image: gitlab/gitlab-runner:latest
networks:
- gitlab
volumes:
- gitlab_runner_conf:/etc/gitlab
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
volumes:
gitlab_conf:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/conf"
gitlab_logs:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/logs"
gitlab_data:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/data"
gitlab_runner_conf:
driver: local
driver_opts:
type: none
o: bind
device: "/srv/docker/gitlab/runner"
networks:
pgsql:
external: true
redis:
external: true
traefik:
external: true
gitlab:
external: 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 gitlab
Ҳолати ниҳоии кластер ва хидматҳо:
# 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/tcp
Боз чиро бехтар кардан мумкин аст? Боварӣ ҳосил кунед, ки Traefik-ро барои кор бо контейнерҳои https танзим кунед, рамзгузории tls барои Postgresql ва Redis илова кунед. Аммо дар маҷмӯъ, шумо метавонед онро аллакай ба таҳиягарон ҳамчун PoC диҳед. Биёед ҳоло алтернативаҳоро ба Docker дида бароем.
Подман
Боз як муҳаррики хеле маъруф барои кор кардани контейнерҳо, ки аз рӯи қуттиҳо гурӯҳбандӣ шудаанд (подҳо, гурӯҳҳои контейнерҳои якҷоя ҷойгиршуда). Баръакси Docker, он барои идора кардани контейнерҳо ягон хидмат талаб намекунад, ҳама корҳо тавассути китобхонаи libpod анҷом дода мешаванд. Инчунин дар Go навишта шудааст, барои иҷрои контейнерҳо ба монанди runC вақти кории мувофиқи OCI лозим аст.
Кор бо Подман дар маҷмӯъ ба кори Docker шабоҳат дорад, то он даме, ки шумо ин корро карда метавонед (аз ҷониби бисёре аз онҳое, ки онро озмудаанд, аз ҷумла муаллифи ин мақола даъво доранд):
$ alias docker=podman
ва шумо метавонед корро давом диҳед. Дар маҷмӯъ, вазъият бо Подман хеле ҷолиб аст, зеро агар версияҳои аввали Kubernetes бо Docker кор мекарданд, пас аз соли 2015 пас аз стандартизатсияи ҷаҳони контейнер (OCI - Ташаббуси Open Container) ва тақсим кардани Docker ба контейнер ва runC, алтернативаи Docker барои кор дар Kubernetes таҳия карда мешавад: CRI-O. Подман дар ин замина алтернатива ба Docker аст, ки дар асоси принсипҳои Kubernetes, аз ҷумла гурӯҳбандии контейнерҳо сохта шудааст, аммо ҳадафи асосии лоиҳа ба кор андохтани контейнерҳои услуби Docker бидуни хидматҳои иловагӣ мебошад. Бо сабабҳои маълум, режими тӯда вуҷуд надорад, зеро таҳиягарон ба таври возеҳ мегӯянд, ки агар ба шумо кластер лозим бошад, Kubernetes-ро гиред.
параметр
Барои насб кардан дар Centos 7, танҳо анбори Extras -ро фаъол кунед ва ҳама чизро бо фармон насб кунед:
# yum -y install podman
Дигар хусусиятҳо
Подман метавонад воҳидҳоро барои systemd тавлид кунад ва ба ин васила мушкилоти оғоз кардани контейнерҳоро пас аз бозоғозкунии сервер ҳал кунад. Илова бар ин, systemd ҳамчун pid 1 дар контейнер дуруст кор мекунад. Барои сохтани контейнерҳо як асбоби алоҳидаи сохтмон мавҷуд аст, инчунин асбобҳои тарафи сеюм мавҷуданд - аналогҳои docker-compose, ки инчунин файлҳои конфигуратсияи бо Kubernetes мувофиқро тавлид мекунанд, аз ин рӯ гузариш аз Podman ба Kubernetes то ҳадди имкон содда аст.
Кор бо Подман
Азбаски режими тӯда вуҷуд надорад (агар кластер лозим бошад, он бояд ба Kubernetes гузарад), мо онро дар контейнерҳои алоҳида ҷамъ мекунем.
Насб кардани podman-compose:
# yum -y install python3-pip
# pip3 install podman-compose
Файли конфигуратсияи натиҷавӣ барои podman каме фарқ мекунад, зеро масалан, мо маҷбур шудем, ки қисмати алоҳидаи ҳаҷмҳоро мустақиман ба бахши хидматҳо гузаронем.
gitlab-podman.yml
version: '3.7'
services:
gitlab:
image: gitlab/gitlab-ce:latest
hostname: gitlab.example.com
restart: unless-stopped
environment:
GITLAB_OMNIBUS_CONFIG: |
gitlab_rails['gitlab_shell_ssh_port'] = 22222
ports:
- "80:80"
- "22222:22"
volumes:
- /srv/podman/gitlab/conf:/etc/gitlab
- /srv/podman/gitlab/data:/var/opt/gitlab
- /srv/podman/gitlab/logs:/var/log/gitlab
networks:
- gitlab
gitlab-runner:
image: gitlab/gitlab-runner:alpine
restart: unless-stopped
depends_on:
- gitlab
volumes:
- /srv/podman/gitlab/runner:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
networks:
- gitlab
networks:
gitlab:
# podman-compose -f gitlab-runner.yml -d up
Натиҷаи кор:
# 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_1
Биёед бубинем, ки он барои systemd ва kubernetes чӣ тавлид мекунад, барои ин ба мо лозим аст, ки ном ё идентификати подкро фаҳмем:
# podman pod ls
POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID
71fc2b2a5c63 root Running 11 minutes ago 3 db40ab8bf84b
Кубернетес:
# 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: {}
система:
# 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.target
Мутаассифона, ба ҷуз аз кор кардани контейнерҳо, воҳиди тавлидшуда барои systemd дигар коре намекунад (масалан, тоза кардани контейнерҳои кӯҳна ҳангоми аз нав оғоз кардани чунин хидмат), аз ин рӯ шумо бояд чунин чизҳоро худатон илова кунед.
Аслан, Подман барои санҷидани контейнерҳо, интиқол додани конфигуратсияҳои кӯҳна барои docker-compose кифоя аст ва сипас ба сӯи Кубернетес, агар лозим бошад, дар кластер равед ё алтернативаи истифодаи осонтар ба Docker гиред.
кт
Лоиҳа
Плас
Бештар
натиҷаҳои
Вазъият бо Кубернетес хеле ҷолиб аст: аз як тараф, бо Docker шумо метавонед кластерро ҷамъ кунед (дар ҳолати тӯда), ки бо он шумо ҳатто муҳити истеҳсолиро барои муштариён идора карда метавонед, ин махсусан барои дастаҳои хурд (3-5 нафар) дуруст аст. ), ё бо сарбории умумии хурд ё набудани хоҳиши фаҳмидани нозукиҳои таъсиси Kubernetes, аз ҷумла барои бори баланд.
Подман мутобиқати пурраро таъмин намекунад, аммо он як бартарии муҳим дорад - мутобиқат бо Kubernetes, аз ҷумла асбобҳои иловагӣ (buildah ва дигарон). Аз ин рӯ, ман ба интихоби асбоб барои кор чунин муносибат хоҳам кард: барои дастаҳои хурд ё бо буҷаи маҳдуд - Docker (бо режими эҳтимолии тӯда), барои таҳияи худ дар ҳости шахсии худ - рафиқон Подман ва барои ҳама - Кубернетес.
Ман боварӣ надорам, ки вазъият бо Docker дар оянда тағир намеёбад, охир онҳо пешраванд ва инчунин оҳиста-оҳиста қадам ба қадам стандартизатсия мекунанд, аммо Подман бо ҳама камбудиҳояш (танҳо дар Linux кор мекунад, кластер нест, монтаж ва дигар амалҳо қарорҳои тарафи сеюм мебошанд) оянда равшантар аст, бинобар ин ман ҳамаро даъват мекунам, ки ин бозёфтҳоро дар шарҳҳо муҳокима кунанд.
PS 3 август мо оғоз мекунем "
Нархи фармоиши пеш аз баровардан: 5000 рубл. Барномаи "Docker Video Course" -ро пайдо кардан мумкин аст
Манбаъ: will.com