TL;DR: шолу мақаласы – контейнерлердегі қолданбаларды іске қосу үшін орталарды салыстыруға арналған нұсқаулық. Docker және басқа ұқсас жүйелердің мүмкіндіктері қарастырылады.
Мұның бәрі қайдан шыққаны туралы шағын тарих
История
Қолданбаны оқшаулаудың бірінші белгілі тәсілі - chroot. Бір аттас жүйелік шақыру түбірлік каталогты өзгертуді қамтамасыз етеді - осылайша оны шақырған бағдарламаға қол жеткізуді қамтамасыз етеді, тек осы каталогтың ішіндегі файлдарға қол жеткізу. Бірақ егер бағдарлама ішінде суперпайдаланушы құқығы берілсе, ол chroot-тан «қашып» және негізгі операциялық жүйеге қол жеткізе алады. Сондай-ақ, түбірлік каталогты өзгертуден басқа, басқа ресурстар (RAM, процессор), сондай-ақ желіге кіру шектелмейді.
Келесі жол – операциялық жүйе ядросының механизмдерін пайдалана отырып, контейнер ішінде толыққанды операциялық жүйені іске қосу. Бұл әдіс әртүрлі операциялық жүйелерде әртүрлі деп аталады, бірақ мәні бір - әрқайсысы негізгі операциялық жүйені басқаратын бір ядрода жұмыс істейтін бірнеше тәуелсіз операциялық жүйелерді іске қосу. Бұған Linux үшін FreeBSD Jails, Solaris Zones, OpenVZ және LXC кіреді. Оқшаулау тек дискілік кеңістік үшін ғана емес, сонымен қатар басқа ресурстар үшін де қарастырылған, атап айтқанда, әрбір контейнерде процессор уақытына, жедел жадқа, желі өткізу қабілетіне шектеулер болуы мүмкін. Chroot-пен салыстырғанда, контейнерден шығу қиынырақ, өйткені контейнердегі суперпайдаланушы тек контейнердің ішкі жағына қол жеткізе алады, алайда контейнер ішіндегі операциялық жүйені жаңарту қажеттілігіне және ескі ядро пайдалануына байланысты. нұсқаларында (Linux үшін, аз дәрежеде FreeBSD) ядроны оқшаулау жүйесін «жарып өту» және негізгі операциялық жүйеге қол жеткізу ықтималдығы нөлге тең емес.
Контейнерде толыққанды операциялық жүйені іске қосудың орнына (инициализация жүйесімен, пакет менеджері және т. басқа файлдар). Бұл идея контейнерлік қолданбаларды виртуалдандыру үшін негіз болды, оның ең көрнекті және танымал өкілі Docker болып табылады. Алдыңғы жүйелермен салыстырғанда, икемді оқшаулау механизмдері, контейнерлер арасындағы виртуалды желілерді және контейнер ішіндегі қолданба күйін қолдаумен бірге, көптеген физикалық серверлерден контейнерлерді іске қосу үшін біртұтас ортаны құру мүмкіндігіне әкелді. ресурстарды қолмен басқару қажеттілігі.
Докер
Docker - қолданбаларды контейнерлеудің ең танымал бағдарламалық құралы. Go тілінде жазылған ол Linux ядросының тұрақты мүмкіндіктерін – топтарды, аттар кеңістігін, мүмкіндіктерді және т.б., сондай-ақ Aufs файлдық жүйелерін және дискілік кеңістікті үнемдеу үшін ұқсас басқаларды пайдаланады.
Дереккөз: wikimedia
сәулет
1.11 нұсқасына дейін Docker контейнерлермен барлық операцияларды орындайтын бір қызмет ретінде жұмыс істеді: контейнерлерге суреттерді жүктеп алу, контейнерлерді іске қосу, API сұрауларын өңдеу. 1.11 нұсқасынан бастап Docker бір-бірімен өзара әрекеттесетін бірнеше бөліктерге бөлінді: контейнерлер, контейнерлердің бүкіл өмірлік циклін өңдеу үшін (дискілік кеңістікті бөлу, кескіндерді жүктеу, желіні құру, іске қосу, орнату және контейнерлердің күйін бақылау) және runC , топтарды және Linux ядросының басқа мүмкіндіктерін пайдалануға негізделген контейнердің орындалу уақыты. Докер қызметінің өзі қалады, бірақ қазір ол тек контейнерге таратылатын API сұрауларын өңдеуге қызмет етеді.
Орнату және конфигурация
Доккерді орнатудың менің сүйікті тәсілі - қашықтағы серверлерде (соның ішінде әртүрлі бұлттарда) докерді тікелей орнату және конфигурациялаумен қатар, қашықтағы серверлердің файлдық жүйелерімен жұмыс істеуге мүмкіндік беретін, сонымен қатар әртүрлі пәрмендерді іске қоса алатын докер-машинасы.
Дегенмен, 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-ге сырттан қол жеткізуді қоса алады, брандмауэрді дәл баптауды ұмытпаңыз (рұқсат етілмеген барлық нәрсе жоғарыдағы және төменде келтірілген мысалдарда тыйым салынған - мен мұны қарапайымдылық пен визуализация үшін өткізіп жібердім), бірақ мен мұнда толығырақ тоқталмаймын.
Басқа мүмкіндіктер
Жоғарыда аталған докерлік машинадан басқа, докер тізілімі, контейнерлерге арналған кескіндерді сақтауға арналған құрал, сонымен қатар докер құрастыру - контейнерлерде қолданбаларды орналастыруды автоматтандыру құралы, YAML файлдары контейнерлерді құру және конфигурациялау үшін қолданылады және басқа байланысты нәрселер (мысалы, желілер, деректерді сақтауға арналған тұрақты файлдық жүйелер).
Оны CICD үшін құбырларды ұйымдастыру үшін де пайдалануға болады. Тағы бір қызықты мүмкіндік - кластерлік режимде жұмыс істейді, бұл контейнерлерді іске қосу үшін бірнеше серверлерден бір инфрақұрылымды жинауға мүмкіндік беретін үйір режимі (1.12 нұсқасына дейін ол докер тобы ретінде белгілі болды). Барлық серверлердің үстінде виртуалды желіге қолдау бар, кірістірілген жүктеме балансы бар, сонымен қатар контейнерлерге арналған құпияларды қолдау бар.
Docker compose YAML файлдарын әртүрлі мақсаттар үшін шағын және орта кластерлерге техникалық қызмет көрсетуді толығымен автоматтандыратын шағын модификациялары бар осындай кластерлер үшін пайдалануға болады. Үлкен кластерлер үшін Kubernetes жақсырақ, өйткені үйір режиміне қызмет көрсету шығындары Kubernetes-тен асып түсуі мүмкін. Контейнерлер үшін орындау ортасы ретінде runC-ге қосымша, мысалы, орнатуға болады
Docker-пен жұмыс
Орнату мен конфигурациялаудан кейін біз әзірлеу тобы үшін GitLab және Docker тізілімін орналастыратын кластерді құруға тырысамыз. Серверлер ретінде мен үш виртуалды машинаны қолданамын, оларда GlusterFS таратылған FS қосымша орналастырамын, мен оны докер томдарының қоймасы ретінде пайдаланамын, мысалы, докер тізілімінің қатесіз нұсқасын іске қосу үшін. Іске қосылатын негізгі компоненттер: Docker Registry, Postgresql, Redis, GitLab Swarm жоғарғы жағындағы GitLab Runner қолдауымен. Postgresql кластерлеу арқылы іске қосылады
GlusterFS-ті барлық серверлерде орналастыру үшін (олар түйін1, түйін2, түйін3 деп аталады) бумаларды орнату, брандмауэрді қосу, қажетті каталогтарды жасау керек:
# 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 конфигурациялау жұмысын бір түйіннен жалғастыру керек, мысалы, 1 түйін:
# 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
Swarm режимі серверлердің бірінде конфигурацияланған, ол Лидер болады, қалғандары кластерге қосылуы керек, сондықтан бірінші серверде пәрменді іске қосу нәтижесі қалғандарында көшіріліп, орындалуы керек.
Бастапқы кластерді орнату, мен 1 node пәрменін іске қосамын:
# 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
Екінші пәрменнің нәтижесін көшіріп, 2 және 3 түйінінде орындаңыз:
# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.
Бұл серверлердің алдын ала конфигурациясын аяқтайды, қызметтерді конфигурациялауды бастайық, егер басқаша көрсетілмесе, орындалатын пәрмендер 1 түйіннен іске қосылады.
Ең алдымен контейнерлер үшін желілерді құрайық:
# 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 қажет KV қоймасы, etcd деректерін сақтауға арналған каталогтарды жасаймыз. 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
Біраз уақыттан кейін (пәрменнің нәтижесін қараңыз докер қызметі 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 кластерін бастаймыз, ол үшін барлық түйіндерде сақтау каталогын жасаймыз:
# 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 контейнерлерімен жұмыс істеу үшін конфигурациялауды ұмытпаңыз, Postgresql және Redis үшін tls шифрлауын қосыңыз. Бірақ жалпы алғанда, сіз оны әзірлеушілерге PoC ретінде бере аласыз. Енді Docker баламаларын қарастырайық.
Подман
Тұтқалар бойынша топтастырылған контейнерлерді іске қосуға арналған тағы бір танымал қозғалтқыш (подтар, бірге орналастырылған контейнерлер топтары). Docker-тен айырмашылығы, ол контейнерлерді іске қосу үшін ешқандай қызметті қажет етпейді, барлық жұмыс libpod кітапханасы арқылы орындалады. Сондай-ақ Go бағдарламасында жазылған, runC сияқты контейнерлерді іске қосу үшін OCI үйлесімді жұмыс уақыты қажет.
Жалпы Подманмен жұмыс істеу Docker жұмысына ұқсайды, сондықтан сіз мұны осылай жасай аласыз (оны қолданып көргендердің көпшілігі, соның ішінде осы мақаланың авторы мәлімдеген):
$ alias docker=podman
және сіз жұмысты жалғастыра аласыз. Жалпы алғанда, Подманмен жағдай өте қызықты, өйткені егер Kubernetes-тің алғашқы нұсқалары Docker-пен жұмыс істеген болса, шамамен 2015 жылдан бастап, контейнер әлемін стандарттағаннан кейін (OCI - Open Container Initiative) және Docker-ді контейнерге және runC-ге бөлгеннен кейін балама Docker Kubernetes: CRI-O жүйесінде жұмыс істеу үшін әзірленуде. Осыған байланысты Подман Кубернетес қағидаттарына негізделген, оның ішінде контейнерлерді топтастыруға негізделген Docker-ке балама болып табылады, бірақ жобаның негізгі мақсаты - қосымша қызметтерсіз Docker стиліндегі контейнерлерді іске қосу. Белгілі себептерге байланысты үйір режимі жоқ, өйткені әзірлеушілер егер сізге кластер қажет болса, Kubernetes алыңыз деп нақты айтады.
параметр
Centos 7 жүйесіне орнату үшін Extras репозиторийін белсендіріңіз, содан кейін барлығын пәрменмен орнатыңыз:
# yum -y install podman
Басқа мүмкіндіктер
Podman systemd үшін бірліктерді жасай алады, осылайша серверді қайта жүктегеннен кейін контейнерлерді іске қосу мәселесін шешеді. Сонымен қатар, systemd контейнердегі pid 1 ретінде дұрыс жұмыс істейтіні жарияланды. Контейнерлерді құрастыру үшін бөлек құрастыру құралы бар, сонымен қатар үшінші тарап құралдары бар - Docker-compose аналогтары, олар да Kubernetes-үйлесімді конфигурация файлдарын жасайды, сондықтан Podman-дан Kubernetes-ке өту мүмкіндігінше қарапайым.
Подманмен жұмыс
Үйір режимі болмағандықтан (кластер қажет болса, ол Кубернетеске ауысуы керек), біз оны бөлек контейнерлерге жинаймыз.
podman-compose орнату:
# yum -y install python3-pip
# pip3 install podman-compose
Подман үшін алынған конфигурация файлы сәл өзгеше, мысалы, біз бөлек томдар бөлімін тікелей қызметтер бөліміне жылжытуға тура келді.
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 үшін жасалған құрылғы басқа ештеңе жасамайды (мысалы, мұндай қызмет қайта іске қосылғанда ескі контейнерлерді тазалау), сондықтан мұндай нәрселерді өзіңіз қосуға тура келеді.
Негізінде, Podman контейнерлердің не екенін сынап көру, докер құрастыру үшін ескі конфигурацияларды тасымалдау, содан кейін қажет болса, кластерде Кубернетеске бару немесе Docker-ке оңайырақ балама алу үшін жеткілікті.
rkt
Жоба
Плас
көбірек
қорытындылар
Кубернетеспен жағдай өте қызықты: бір жағынан, Docker көмегімен сіз тіпті клиенттер үшін өндірістік орталарды іске қоса аласыз, кластерді жинай аласыз (3-5 адам), бұл әсіресе шағын командаларға қатысты (XNUMX-XNUMX адам). ) немесе шағын жалпы жүктемемен немесе Kubernetes орнатудың қыр-сырын түсінуге деген құлшынысының болмауы, соның ішінде жоғары жүктемелер үшін.
Podman толық үйлесімділікті қамтамасыз етпейді, бірақ оның бір маңызды артықшылығы бар - Kubernetes-пен үйлесімділік, соның ішінде қосымша құралдар (buildah және басқалар). Сондықтан мен жұмыс құралын таңдауға келесідей қараймын: шағын командалар үшін немесе бюджеті шектеулі - Docker (мүмкін үйір режимі бар), жеке локалхостта өзім үшін әзірлеу үшін - Подман жолдастар және басқалар үшін - Кубернетес.
Мен Docker жағдайының болашақта өзгермейтініне сенімді емеспін, өйткені олар пионерлер, сонымен қатар біртіндеп біртіндеп стандарттауда, бірақ Подман барлық кемшіліктерімен (тек Linux-та жұмыс істейді, кластерлеу жоқ, құрастыру және басқа әрекеттер үшінші тарап шешімдері болып табылады) болашақ айқынырақ, сондықтан мен барлығын осы тұжырымдарды түсініктемелерде талқылауға шақырамын.
PS 3 тамызда біз іске қосамыз»
Шығаруға дейін алдын ала тапсырыс құны: 5000 рубль. «Docker Video Course» бағдарламасын табуға болады
Ақпарат көзі: www.habr.com