ื“ื•ืงืจ ื•ื”ื›ืœ, ื”ื›ืœ, ื”ื›ืœ

TL;DR: ืžืืžืจ ืกืงื™ืจื” - ืžื“ืจื™ืš ืœื”ืฉื•ื•ืืช ืกื‘ื™ื‘ื•ืช ืœื”ืคืขืœืช ื™ื™ืฉื•ืžื™ื ื‘ืงื•ื ื˜ื™ื™ื ืจื™ื. ื”ืืคืฉืจื•ื™ื•ืช ืฉืœ Docker ื•ืžืขืจื›ื•ืช ื“ื•ืžื•ืช ืื—ืจื•ืช ื™ื™ื—ืฉื‘ื•.

ื“ื•ืงืจ ื•ื”ื›ืœ, ื”ื›ืœ, ื”ื›ืœ

ืงืฆืช ื”ื™ืกื˜ื•ืจื™ื” ืžืื™ืคื” ื”ื›ืœ ื”ื’ื™ืข

ื›ืชื‘ื”

ื”ื“ืจืš ื”ื™ื“ื•ืขื” ื”ืจืืฉื•ื ื” ืœื‘ื•ื“ื“ ืืคืœื™ืงืฆื™ื” ื”ื™ื chroot. ืงืจื™ืืช ื”ืžืขืจื›ืช ื‘ืื•ืชื• ืฉื ืžืกืคืงืช ืฉื™ื ื•ื™ ืœืกืคืจื™ื™ืช ื”ืฉื•ืจืฉ - ื•ื‘ื›ืš ืžืกืคืงืช ื’ื™ืฉื” ืœืชื•ื›ื ื™ืช ืฉืงืจืื” ืœื”, ื’ื™ืฉื” ืจืง ืœืงื‘ืฆื™ื ื‘ืชื•ืš ืกืคืจื™ื™ื” ื–ื•. ืื‘ืœ ืื ืœืชื•ื›ื ื™ืช ื ื™ืชื ื•ืช ื–ื›ื•ื™ื•ืช ืžืฉืชืžืฉ-ืขืœ ื‘ืคื ื™ื, ื”ื™ื ืขืฉื•ื™ื” "ืœื‘ืจื•ื—" ืžื”-chroot ื•ืœืงื‘ืœ ื’ื™ืฉื” ืœืžืขืจื›ืช ื”ื”ืคืขืœื” ื”ืจืืฉื™ืช. ื›ืžื• ื›ืŸ, ื‘ื ื•ืกืฃ ืœืฉื™ื ื•ื™ ืกืคืจื™ื™ืช ื”ืฉื•ืจืฉ, ืžืฉืื‘ื™ื ืื—ืจื™ื (RAM, ืžืขื‘ื“), ื›ืžื• ื’ื ื’ื™ืฉื” ืœืจืฉืช, ืื™ื ื ืžื•ื’ื‘ืœื™ื.

ื”ื“ืจืš ื”ื‘ืื” ื”ื™ื ืœื”ืคืขื™ืœ ืžืขืจื›ืช ื”ืคืขืœื” ืžืœืื” ื‘ืชื•ืš ื”ืงื•ื ื˜ื™ื™ื ืจ, ืชื•ืš ืฉื™ืžื•ืฉ ื‘ืžื ื’ื ื•ื ื™ื ืฉืœ ืœื™ื‘ืช ืžืขืจื›ืช ื”ื”ืคืขืœื”. ืฉื™ื˜ื” ื–ื• ื ืงืจืืช ืื—ืจืช ื‘ืžืขืจื›ื•ืช ื”ืคืขืœื” ืฉื•ื ื•ืช, ืืš ื”ืžื”ื•ืช ื–ื”ื” - ื”ืคืขืœืช ืžืกืคืจ ืžืขืจื›ื•ืช ื”ืคืขืœื” ืขืฆืžืื™ื•ืช, ืฉื›ืœ ืื—ืช ืžื”ืŸ ืคื•ืขืœืช ืขืœ ืื•ืชื• ืœื™ื‘ื” ืฉืžืคืขื™ืœื” ืืช ืžืขืจื›ืช ื”ื”ืคืขืœื” ื”ืจืืฉื™ืช. ื–ื” ื›ื•ืœืœ ื›ืœื FreeBSD, Solaris Zones, OpenVZ ื•-LXC ืขื‘ื•ืจ ืœื™ื ื•ืงืก. ื‘ื™ื“ื•ื“ ืžืกื•ืคืง ืœื ืจืง ืขื‘ื•ืจ ืฉื˜ื— ื“ื™ืกืง, ืืœื ื’ื ืขื‘ื•ืจ ืžืฉืื‘ื™ื ืื—ืจื™ื, ื‘ืคืจื˜, ืœื›ืœ ืžื™ื›ืœ ื™ื›ื•ืœื•ืช ืœื”ื™ื•ืช ื”ื’ื‘ืœื•ืช ืขืœ ื–ืžืŸ ืžืขื‘ื“, ื–ื™ื›ืจื•ืŸ RAM, ืจื•ื—ื‘ ืคืก ืจืฉืช. ื‘ื”ืฉื•ื•ืื” ืœ-chroot, ื”ื™ืฆื™ืื” ืžื”ืงื•ื ื˜ื™ื™ื ืจ ืงืฉื” ื™ื•ืชืจ, ืžืื—ืจ ื•ืœืžืฉืชืžืฉ-ืขืœ ื‘ืงื•ื ื˜ื™ื™ื ืจ ื™ืฉ ื’ื™ืฉื” ืจืง ืœื—ืœืง ื”ืคื ื™ืžื™ ืฉืœ ื”ืงื•ื ื˜ื™ื™ื ืจ, ืœืขื•ืžืช ื–ืืช, ื‘ืฉืœ ื”ืฆื•ืจืš ืœืขื“ื›ืŸ ืืช ืžืขืจื›ืช ื”ื”ืคืขืœื” ื‘ืชื•ืš ื”ืงื•ื ื˜ื™ื™ื ืจ ื•ืฉื™ืžื•ืฉ ื‘ืงืจื ืœ ื™ืฉืŸ. ื’ืจืกืื•ืช (ืจืœื•ื•ื ื˜ื™ื•ืช ืœืœื™ื ื•ืงืก, ื‘ืžื™ื“ื” ืคื—ื•ืชื” FreeBSD), ื™ืฉ ืกื™ื›ื•ื™ ืœื ืืคืกื™ ืœืคืจื•ืฅ ืืช ืžืขืจื›ืช ื‘ื™ื“ื•ื“ ื”ืงืจื ืœ ื•ืœืงื‘ืœ ื’ื™ืฉื” ืœืžืขืจื›ืช ื”ื”ืคืขืœื” ื”ืจืืฉื™ืช.

ื‘ืžืงื•ื ืœื”ืคืขื™ืœ ืžืขืจื›ืช ื”ืคืขืœื” ืžืœืื” ื‘ืงื•ื ื˜ื™ื™ื ืจ (ืขื ืžืขืจื›ืช ืืชื—ื•ืœ, ืžื ื”ืœ ื—ื‘ื™ืœื•ืช ื•ื›ื•'), ื ื™ืชืŸ ืœื”ืคืขื™ืœ ืืคืœื™ืงืฆื™ื•ืช ื‘ืื•ืคืŸ ืžื™ื™ื“ื™, ื”ืขื™ืงืจ ืœืกืคืง ืœืืคืœื™ืงืฆื™ื•ืช ืืช ื”ื”ื–ื“ืžื ื•ืช ื”ื–ื• (ื ื•ื›ื—ื•ืช ื”ืกืคืจื™ื•ืช ื”ื“ืจื•ืฉื•ืช ื• ืงื‘ืฆื™ื ืื—ืจื™ื). ืจืขื™ื•ืŸ ื–ื” ืฉื™ืžืฉ ื‘ืกื™ืก ืœื•ื•ื™ืจื˜ื•ืืœื™ื–ืฆื™ื” ืฉืœ ืืคืœื™ืงืฆื™ื•ืช ืžื›ื•ืœื•ืช, ืฉื”ื ืฆื™ื’ ื”ื‘ื•ืœื˜ ื•ื”ืžื•ื›ืจ ืฉืœื” ื”ื•ื Docker. ื‘ื”ืฉื•ื•ืื” ืœืžืขืจื›ื•ืช ืงื•ื“ืžื•ืช, ืžื ื’ื ื•ื ื™ ื‘ื™ื“ื•ื“ ื’ืžื™ืฉื™ื ื™ื•ืชืจ, ื™ื—ื“ ืขื ืชืžื™ื›ื” ืžื•ื‘ื ื™ืช ื‘ืจืฉืชื•ืช ื•ื™ืจื˜ื•ืืœื™ื•ืช ื‘ื™ืŸ ืงื•ื ื˜ื™ื™ื ืจื™ื ื•ืžืฆื‘ ื™ื™ืฉื•ืžื™ื ื‘ืชื•ืš ืงื•ื ื˜ื™ื™ื ืจ, ื”ื‘ื™ืื• ืœื™ื›ื•ืœืช ืœื‘ื ื•ืช ืกื‘ื™ื‘ื” ื”ื•ืœื™ืกื˜ื™ืช ืื—ืช ืžืžืกืคืจ ืจื‘ ืฉืœ ืฉืจืชื™ื ืคื™ื–ื™ื™ื ืœื”ืคืขืœืช ืงื•ื ื˜ื™ื™ื ืจื™ื - ืœืœื ื”ืฆื•ืจืš ื‘ื ื™ื”ื•ืœ ืžืฉืื‘ื™ื ื™ื“ื ื™.

ืกึทื•ึธืจ

Docker ื”ื™ื ืชื•ื›ื ืช ืžื™ื›ืœ ื”ื™ื™ืฉื•ืžื™ื ื”ืžื•ื›ืจืช ื‘ื™ื•ืชืจ. ื›ืชื•ื‘ ื‘ืฉืคืช Go, ื”ื•ื ืžืฉืชืžืฉ ื‘ื™ื›ื•ืœื•ืช ื”ืจื’ื™ืœื•ืช ืฉืœ ืœื™ื‘ืช ืœื™ื ื•ืงืก - cgroups, ืžืจื—ื‘ื™ ืฉืžื•ืช, ื™ื›ื•ืœื•ืช ื•ื›ื•', ื›ืžื• ื’ื ืžืขืจื›ื•ืช ืงื‘ืฆื™ื Aufs ื•ืื—ืจื•ืช ื“ื•ืžื•ืช ืœื—ื™ืกื›ื•ืŸ ื‘ืฉื˜ื— ื“ื™ืกืง.

ื“ื•ืงืจ ื•ื”ื›ืœ, ื”ื›ืœ, ื”ื›ืœ
ืžืงื•ืจ: ื•ื™ืงื™ืžื“ื™ื”

ืื“ืจื™ื›ืœื•ืช

ืœืคื ื™ ื’ืจืกื” 1.11, Docker ืขื‘ื“ ื›ืฉื™ืจื•ืช ื™ื—ื™ื“ ืฉื‘ื™ืฆืข ืืช ื›ืœ ื”ืคืขื•ืœื•ืช ืขื ืงื•ื ื˜ื™ื™ื ืจื™ื: ื”ื•ืจื“ืช ืชืžื•ื ื•ืช ืœืงื•ื ื˜ื™ื™ื ืจื™ื, ื”ืฉืงืช ืงื•ื ื˜ื™ื™ื ืจื™ื, ืขื™ื‘ื•ื“ ื‘ืงืฉื•ืช API. ืžืื– ื’ืจืกื” 1.11, Docker ืคื•ืฆืœ ืœืžืกืคืจ ื—ืœืงื™ื ื”ืžืงื™ื™ืžื™ื ืื™ื ื˜ืจืืงืฆื™ื” ื–ื” ืขื ื–ื”: containerd, ืœื˜ื™ืคื•ืœ ื‘ื›ืœ ืžื—ื–ื•ืจ ื”ื—ื™ื™ื ืฉืœ ืงื•ื ื˜ื™ื™ื ืจื™ื (ื”ืงืฆืืช ืฉื˜ื— ื“ื™ืกืง, ื”ื•ืจื“ืช ืชืžื•ื ื•ืช, ื™ืฆื™ืจืช ืจืฉืชื•ืช, ื”ืฉืงื”, ื”ืชืงื ื” ื•ื ื™ื˜ื•ืจ ืžืฆื‘ ื”ืงื•ื ื˜ื™ื™ื ืจื™ื) ื•-runC , ื–ืžื ื™ ืจื™ืฆื” ืฉืœ ืžื™ื›ืœ, ื”ืžื‘ื•ืกืกื™ื ืขืœ ื”ืฉื™ืžื•ืฉ ื‘-cgroups ื•ืชื›ื•ื ื•ืช ืื—ืจื•ืช ืฉืœ ืœื™ื‘ืช ืœื™ื ื•ืงืก. ืฉื™ืจื•ืช docker ืขืฆืžื• ื ืฉืืจ, ืืš ื›ืขืช ื”ื•ื ืžืฉืžืฉ ืจืง ืœืขื™ื‘ื•ื“ ื‘ืงืฉื•ืช API ื”ืžืฉื•ื“ืจื•ืช ืœ-containerd.

ื“ื•ืงืจ ื•ื”ื›ืœ, ื”ื›ืœ, ื”ื›ืœ

ื”ืชืงื ื” ื•ืชืฆื•ืจื”

ื”ื“ืจืš ื”ืžื•ืขื“ืคืช ืขืœื™ื™ ืœื”ืชืงื™ืŸ docker ื”ื™ื docker-machine, ืฉืžืœื‘ื“ ื”ืชืงื ื” ื•ื”ื’ื“ืจื” ื™ืฉื™ืจื” ืฉืœ docker ื‘ืฉืจืชื™ื ืžืจื•ื—ืงื™ื (ื›ื•ืœืœ ืขื ื ื™ื ืฉื•ื ื™ื), ืžืืคืฉืจืช ืœืขื‘ื•ื“ ืขื ืžืขืจื›ื•ืช ื”ืงื‘ืฆื™ื ืฉืœ ืฉืจืชื™ื ืžืจื•ื—ืงื™ื, ื•ื™ื›ื•ืœื” ื’ื ืœื”ืจื™ืฅ ืคืงื•ื“ื•ืช ืฉื•ื ื•ืช.

ืขื ื–ืืช, ืžืื– 2018, ื”ืคืจื•ื™ืงื˜ ื›ืžืขื˜ ื•ืœื ืคื•ืชื—, ื•ืœื›ืŸ ื ืชืงื™ืŸ ืื•ืชื• ื‘ื“ืจืš ื”ืจื’ื™ืœื” ืขื‘ื•ืจ ืจื•ื‘ ื”ื”ืคืฆื•ืช ืฉืœ ืœื™ื ื•ืงืก โ€“ ืขืœ ื™ื“ื™ ื”ื•ืกืคืช ืžืื’ืจ ื•ื”ืชืงื ืช ื”ื—ื‘ื™ืœื•ืช ื”ื“ืจื•ืฉื•ืช.

ืฉื™ื˜ื” ื–ื• ืžืฉืžืฉืช ื’ื ืœื”ืชืงื ื” ืื•ื˜ื•ืžื˜ื™ืช, ืœืžืฉืœ, ื‘ืืžืฆืขื•ืช 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

ื‘ื ื•ืกืฃ, ื ื™ืชืŸ ืœื™ืฆื•ืจ ืงื‘ื•ืฆืช docker, ืฉื”ืžืฉืชืžืฉื™ื ืฉืœื” ื™ื•ื›ืœื• ืœืขื‘ื•ื“ ืขื docker ืœืœื sudo, ืœื”ื’ื“ื™ืจ ืจื™ืฉื•ื, ืœืืคืฉืจ ื’ื™ืฉื” ืœ-API ืžื‘ื—ื•ืฅ, ืœื ืœืฉื›ื•ื— ืœื›ื•ื•ื ืŸ ืืช ื—ื•ืžืช ื”ืืฉ (ื›ืœ ืžื” ืฉืœื ืžื•ืชืจ ื”ื•ื ืืกื•ืจ ื‘ื“ื•ื’ืžืื•ืช ืœืžืขืœื” ื•ืœืžื˜ื” - ื”ืฉืžื˜ืชื™ ื–ืืช ืœืฉื ื”ืคืฉื˜ื•ืช ื•ื”ื”ื“ืžื™ื”), ืืš ืœื ืืคืจื˜ ื›ืืŸ.

ืชื›ื•ื ื•ืช ืื—ืจื•ืช

ื‘ื ื•ืกืฃ ืœืžื›ื•ื ืช docker ื”ื "ืœ, ื™ืฉื ื• ื’ื docker registry, ื›ืœื™ ืœืื—ืกื•ืŸ ืชืžื•ื ื•ืช ืœืงื•ื ื˜ื™ื™ื ืจื™ื ื•ื›ืŸ docker compose - ื›ืœื™ ืœืื•ื˜ื•ืžืฆื™ื” ืฉืœ ืคืจื™ืกืช ืืคืœื™ืงืฆื™ื•ืช ื‘ืงื•ื ื˜ื™ื™ื ืจื™ื, ืงื‘ืฆื™ YAML ืžืฉืžืฉื™ื ืœื‘ื ื™ื™ื” ื•ืงื•ื ืคื™ื’ื•ืจืฆื™ื” ืฉืœ ืงื•ื ื˜ื™ื™ื ืจื™ื ื• ื“ื‘ืจื™ื ืงืฉื•ืจื™ื ืื—ืจื™ื (ืœื“ื•ื’ืžื”, ืจืฉืชื•ืช, ืžืขืจื›ื•ืช ืงื‘ืฆื™ื ืงื‘ื•ืขื•ืช ืœืื—ืกื•ืŸ ื ืชื•ื ื™ื).

ื–ื” ื™ื›ื•ืœ ืœืฉืžืฉ ื’ื ืœืืจื’ื•ืŸ ืฆื™ื ื•ืจื•ืช ืขื‘ื•ืจ CICD. ืชื›ื•ื ื” ืžืขื ื™ื™ื ืช ื ื•ืกืคืช ื”ื™ื ืขื‘ื•ื“ื” ื‘ืžืฆื‘ cluster, ืžื” ืฉื ืงืจื swarm mode (ืœืคื ื™ ื’ืจืกื” 1.12 ื”ื•ื ื”ื™ื” ื™ื“ื•ืข ื‘ืฉื docker swarm), ื”ืžืืคืฉืจ ืœื”ืจื›ื™ื‘ ืชืฉืชื™ืช ื‘ื•ื“ื“ืช ืžืžืกืคืจ ืฉืจืชื™ื ืœื”ืคืขืœืช ืงื•ื ื˜ื™ื™ื ืจื™ื. ื™ืฉื ื” ืชืžื™ื›ื” ื‘ืจืฉืช ื•ื™ืจื˜ื•ืืœื™ืช ืขืœ ื’ื‘ื™ ื›ืœ ื”ืฉืจืชื™ื, ื™ืฉื ื• ืื™ื–ื•ืŸ ืขื•ืžืกื™ื ืžื•ื‘ื ื” ื•ื›ืŸ ืชืžื™ื›ื” ื‘ืกื•ื“ื•ืช ืœืงื•ื ื˜ื™ื™ื ืจื™ื.

ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ืงื‘ืฆื™ ื”-YAML ืฉืœ docker compose ืขื‘ื•ืจ ืืฉื›ื•ืœื•ืช ื›ืืœื” ืขื ืฉื™ื ื•ื™ื™ื ืงืœื™ื, ืชื•ืš ืื•ื˜ื•ืžืฆื™ื” ืžืœืื” ืฉืœ ื”ืชื—ื–ื•ืงื” ืฉืœ ืืฉื›ื•ืœื•ืช ืงื˜ื ื™ื ื•ื‘ื™ื ื•ื ื™ื™ื ืœืžื˜ืจื•ืช ืฉื•ื ื•ืช. ืขื‘ื•ืจ ืืฉื›ื•ืœื•ืช ื’ื“ื•ืœื™ื, Kubernetes ืขื“ื™ืฃ ืžื›ื™ื•ื•ืŸ ืฉืขืœื•ื™ื•ืช ื”ืชื—ื–ื•ืงื” ืฉืœ ืžืฆื‘ ื ื—ื™ืœ ื™ื›ื•ืœื•ืช ืœืขืœื•ืช ืขืœ ืืœื• ืฉืœ Kubernetes. ื‘ื ื•ืกืฃ ืœ-runC, ื›ืกื‘ื™ื‘ืช ื‘ื™ืฆื•ืข ืœืงื•ื ื˜ื™ื™ื ืจื™ื, ื ื™ืชืŸ ืœื”ืชืงื™ืŸ, ืœืžืฉืœ ืžื™ื›ืœื™ ืงืื˜ื”

ืขื‘ื•ื“ื” ืขื Docker

ืœืื—ืจ ื”ื”ืชืงื ื” ื•ื”ื”ื’ื“ืจื”, ื ื ืกื” ืœื‘ื ื•ืช ืืฉื›ื•ืœ ื‘ื• ื ืคืจื•ืก ืืช GitLab ื•-Docker Registry ืขื‘ื•ืจ ืฆื•ื•ืช ื”ืคื™ืชื•ื—. ื‘ืชื•ืจ ืฉืจืชื™ื, ืืฉืชืžืฉ ื‘ืฉืœื•ืฉื” ืžื›ื•ื ื•ืช ื•ื™ืจื˜ื•ืืœื™ื•ืช, ืฉืขืœื™ื”ืŸ ืืคืจื•ืก ื‘ื ื•ืกืฃ ืืช ื”-FS ื”ืžื‘ื•ื–ืจ ืฉืœ GlusterFS, ืื ื™ ืืฉืชืžืฉ ื‘ื• ื›ืื—ืกื•ืŸ ื ืคื—ื™ docker, ืœืžืฉืœ, ื›ื“ื™ ืœื”ืคืขื™ืœ ื’ืจืกื” ื‘ื˜ื•ื—ื” ืœื›ืฉืœื™ื ืฉืœ ื”ืจื™ืฉื•ื ืฉืœ docker. ืจื›ื™ื‘ื™ ืžืคืชื— ืœื”ืคืขืœื”: Docker Registry, Postgresql, Redis, GitLab ืขื ืชืžื™ื›ื” ื‘-GitLab Runner ืขืœ ื’ื‘ื™ Swarm. Postgresql ื™ื•ืฉืง ืขื clustering ืกื˜ื•ืœื•ืŸ, ื›ืš ืฉืื™ื ืš ืฆืจื™ืš ืœื”ืฉืชืžืฉ ื‘-GlusterFS ื›ื“ื™ ืœืื—ืกืŸ ื ืชื•ื ื™ Postgresql. ืฉืืจ ื”ื ืชื•ื ื™ื ื”ืงืจื™ื˜ื™ื™ื ื™ืื•ื—ืกื ื• ื‘- GlusterFS.

ื›ื“ื™ ืœืคืจื•ืก ืืช 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

ืžืฆื‘ Swarm ืžื•ื’ื“ืจ ื‘ืื—ื“ ื”ืฉืจืชื™ื, ืฉื™ื”ื™ื” Leader, ื”ืฉืืจ ื™ืฆื˜ืจื›ื• ืœื”ืฆื˜ืจืฃ ืœืืฉื›ื•ืœ, ื›ืš ืฉืชืฆื˜ืจื›ื• ืœื”ืขืชื™ืง ืืช ื”ืชื•ืฆืื” ืฉืœ ื”ืคืขืœืช ื”ืคืงื•ื“ื” ื‘ืฉืจืช ื”ืจืืฉื•ืŸ ื•ืœื‘ืฆืข ื‘ืฉืืจ.

ื”ื’ื“ืจื” ืจืืฉื•ื ื™ืช ืฉืœ ืืฉื›ื•ืœ, ืื ื™ ืžืจื™ืฅ ืืช ื”ืคืงื•ื“ื” ื‘-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

ืœืื—ืจ ืžื›ืŸ, ืื ื• ื™ื•ืฆืจื™ื ืกืคืจื™ื•ืช ืœืื—ืกื•ืŸ ื ืชื•ื ื™ื ื•ื›ื•', ืื—ืกื•ืŸ ื”-KV ืฉ-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

ื”ื•ืกืฃ ืืช ื”ื“ื•ืงืจ ืจื™ืฉื•ื:

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, ืฆืจื™ืš ื–ืžืŸ ืจื™ืฆื” ืชื•ืื OCI ื›ื“ื™ ืœื”ืคืขื™ืœ ืงื•ื ื˜ื™ื™ื ืจื™ื ื›ืžื• runC.

ื“ื•ืงืจ ื•ื”ื›ืœ, ื”ื›ืœ, ื”ื›ืœ

ื”ืขื‘ื•ื“ื” ืขื ืคื•ื“ืžืŸ ื‘ืื•ืคืŸ ื›ืœืœื™ ื“ื•ืžื” ืœื–ื• ืฉืœ Docker, ื‘ืžื™ื“ื” ืฉืืชื” ื™ื›ื•ืœ ืœืขืฉื•ืช ื–ืืช ื›ืš (ืœื˜ืขื ืช ืจื‘ื™ื ืฉื ื™ืกื• ื–ืืช, ื›ื•ืœืœ ืžื—ื‘ืจ ื”ืžืืžืจ ื”ื–ื”):

$ alias docker=podman

ื•ืืชื” ื™ื›ื•ืœ ืœื”ืžืฉื™ืš ืœืขื‘ื•ื“. ื‘ืื•ืคืŸ ื›ืœืœื™, ื”ืžืฆื‘ ืขื ืคื•ื“ืžืŸ ืžืขื ื™ื™ืŸ ืžืื•ื“, ื›ื™ ืื ื”ื’ืจืกืื•ืช ื”ืžื•ืงื“ืžื•ืช ืฉืœ Kubernetes ืขื‘ื“ื• ืขื Docker, ืื– ืžืื– 2015 ื‘ืขืจืš, ืœืื—ืจ ืกื˜ื ื“ืจื˜ื™ื–ืฆื™ื” ืฉืœ ืขื•ืœื ื”ืงื•ื ื˜ื™ื™ื ืจื™ื (OCI - Open Container Initiative) ื•ืคื™ืฆื•ืœ Docker ืœ-containerd ื•-runC, ื—ืœื•ืคื” ืœ-containerd ื•-runC. Docker ืคื•ืชื— ืœื”ืคืขืœื” ื‘-Kubernetes: CRI-O. Podman ื‘ื”ืงืฉืจ ื–ื” ืžื”ื•ื•ื” ืืœื˜ืจื ื˜ื™ื‘ื” ืœ-Docker, ื”ื‘ื ื•ื™ื” ืขืœ ืขืงืจื•ื ื•ืช Kubernetes, ื›ื•ืœืœ ืงื™ื‘ื•ืฅ ืงื•ื ื˜ื™ื™ื ืจื™ื, ืืš ื”ืžื˜ืจื” ื”ืขื™ืงืจื™ืช ืฉืœ ื”ืคืจื•ื™ืงื˜ ื”ื™ื ืœื”ืคืขื™ืœ ืงื•ื ื˜ื™ื™ื ืจื™ื ื‘ืกื’ื ื•ืŸ Docker ืœืœื ืฉื™ืจื•ืชื™ื ื ื•ืกืคื™ื. ืžืกื™ื‘ื•ืช ื‘ืจื•ืจื•ืช, ืื™ืŸ ืžืฆื‘ ื ื—ื™ืœ, ืžื›ื™ื•ื•ืŸ ืฉื”ืžืคืชื—ื™ื ืื•ืžืจื™ื ื‘ื‘ื™ืจื•ืจ ืฉืื ืืชื” ืฆืจื™ืš ืืฉื›ื•ืœ, ืงื— Kubernetes.

ื”ืชืงื ื”

ื›ื“ื™ ืœื”ืชืงื™ืŸ ืขืœ Centos 7, ืคืฉื•ื˜ ื”ืคืขืœ ืืช ืžืื’ืจ ื”ืชื•ืกืคื•ืช, ื•ืœืื—ืจ ืžื›ืŸ ื”ืชืงืŸ ื”ื›ืœ ืขื ื”ืคืงื•ื“ื”:

# yum -y install podman

ืชื›ื•ื ื•ืช ืื—ืจื•ืช

Podman ื™ื›ื•ืœ ืœื™ื™ืฆืจ ื™ื—ื™ื“ื•ืช ืขื‘ื•ืจ systemd, ื•ื‘ื›ืš ืœืคืชื•ืจ ืืช ื‘ืขื™ื™ืช ื”ืชื—ืœืช ืงื•ื ื˜ื™ื™ื ืจื™ื ืœืื—ืจ ืืชื—ื•ืœ ืžื—ื“ืฉ ืฉืœ ื”ืฉืจืช. ื‘ื ื•ืกืฃ, ื”ืฆื”ืจืช systemd ืคื•ืขืœืช ื›ื”ืœื›ื” ื‘ืชื•ืจ pid 1 ื‘ืžื™ื›ืœ. ื›ื“ื™ ืœื‘ื ื•ืช ืงื•ื ื˜ื™ื™ื ืจื™ื, ื™ืฉ ื›ืœื™ buildah ื ืคืจื“, ื™ืฉ ื’ื ื›ืœื™ื ืฉืœ ืฆื“ ืฉืœื™ืฉื™ - ืื ืœื•ื’ื™ื ืฉืœ docker-compose, ืฉื’ื ืžื™ื™ืฆืจื™ื ืงื‘ืฆื™ ืชืฆื•ืจื” ืชื•ืืžื™ื ืœ-Kubernetes, ื›ืš ืฉื”ืžืขื‘ืจ ืžืคื•ื“ืžืŸ ืœ-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

Kubernetes:

# 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.target

ืœืžืจื‘ื” ื”ืฆืขืจ, ืžืœื‘ื“ ื”ืคืขืœืช ืงื•ื ื˜ื™ื™ื ืจื™ื, ื”ื™ื—ื™ื“ื” ืฉื ื•ืฆืจื” ืขื‘ื•ืจ systemd ืœื ืขื•ืฉื” ืฉื•ื ื“ื‘ืจ ืื—ืจ (ืœื“ื•ื’ืžื”, ื ื™ืงื•ื™ ืงื•ื ื˜ื™ื™ื ืจื™ื ื™ืฉื ื™ื ื›ืืฉืจ ืฉื™ืจื•ืช ื›ื–ื” ืžื•ืคืขืœ ืžื—ื“ืฉ), ืื– ืชืฆื˜ืจื›ื• ืœื”ื•ืกื™ืฃ ื“ื‘ืจื™ื ื›ืืœื” ื‘ืขืฆืžื›ื.

ื‘ืื•ืคืŸ ืขืงืจื•ื ื™, Podman ืžืกืคื™ืง ื›ื“ื™ ืœื ืกื•ืช ืžื” ื–ื” ืงื•ื ื˜ื™ื™ื ืจื™ื, ืœื”ืขื‘ื™ืจ ืชืฆื•ืจื•ืช ื™ืฉื ื•ืช ืขื‘ื•ืจ docker-compose, ื•ืื– ืœืœื›ืช ืœื›ื™ื•ื•ืŸ Kubernetes, ื‘ืžื™ื“ืช ื”ืฆื•ืจืš, ืขืœ ืืฉื›ื•ืœ, ืื• ืœืงื‘ืœ ืืœื˜ืจื ื˜ื™ื‘ื” ืงืœื” ื™ื•ืชืจ ืœืฉื™ืžื•ืฉ ืœ-Docker.

rkt

ืคืจื•ื™ืงื˜ ื”ืœืš ืœืืจื›ื™ื•ืŸ ืœืคื ื™ ื›ื—ืฆื™ ืฉื ื” ื‘ืฉืœ ื”ืขื•ื‘ื“ื” ืฉ-RedHat ืงื ืชื” ืื•ืชื•, ืื– ืœื ืืชืขื›ื‘ ืขืœ ื–ื” ื‘ื™ืชืจ ืคื™ืจื•ื˜. ื‘ืื•ืคืŸ ื›ืœืœื™ ื–ื” ื”ืฉืื™ืจ ืจื•ืฉื ื˜ื•ื‘ ืžืื•ื“, ืื‘ืœ ื‘ื”ืฉื•ื•ืื” ืœื“ื•ืงืจ, ื•ืขื•ื“ ื™ื•ืชืจ ืœืคื•ื“ืžืŸ, ื–ื” ื ืจืื” ื›ืžื• ืงื•ืžื‘ื™ื ื”. ื”ื™ื™ืชื” ื’ื ื”ืคืฆืช CoreOS ืฉื ื‘ื ืชื” ืขืœ ื’ื‘ื™ rkt (ืœืžืจื•ืช ืฉื‘ืžืงื•ืจ ื”ื™ื” ืœื”ื Docker), ืื‘ืœ ื–ื” ื’ื ื ื’ืžืจ ืœืื—ืจ ืจื›ื™ืฉืช RedHat.

ืคืœืืฉ

ื™ื•ืชืจ ืคืจื•ื™ืงื˜ ืื—ื“, ืฉื”ื›ื•ืชื‘ ืฉืœื• ืจืง ืจืฆื” ืœื‘ื ื•ืช ื•ืœื”ืคืขื™ืœ ืงื•ื ื˜ื™ื™ื ืจื™ื. ืื ืœืฉืคื•ื˜ ืœืคื™ ื”ืชื™ืขื•ื“ ื•ื”ืงื•ื“, ื”ืžื—ื‘ืจ ืœื ืคืขืœ ืœืคื™ ื”ืกื˜ื ื“ืจื˜ื™ื, ืืœื ืคืฉื•ื˜ ื”ื—ืœื™ื˜ ืœื›ืชื•ื‘ ืืช ื”ื™ื™ืฉื•ื ืฉืœื•, ืžื” ืฉืขืงืจื•ื ื™ืช ื”ื•ื ืขืฉื”.

ืžืžืฆืื™ื

ื”ืžืฆื‘ ืขื Kubernetes ืžืื•ื“ ืžืขื ื™ื™ืŸ: ืžืฆื“ ืื—ื“, ืขื Docker, ืืคืฉืจ ืœื”ืจื›ื™ื‘ ืืฉื›ื•ืœ (ื‘ืžืฆื‘ ื ื—ื™ืœ), ืื™ืชื• ืืคืฉืจ ืืคื™ืœื• ืœื”ืจื™ืฅ ืกื‘ื™ื‘ื•ืช ื™ื™ืฆื•ืจ ืขื‘ื•ืจ ืœืงื•ื—ื•ืช, ื–ื” ื ื›ื•ืŸ ื‘ืžื™ื•ื—ื“ ืขื‘ื•ืจ ืฆื•ื•ืชื™ื ืงื˜ื ื™ื (3-5 ืื ืฉื™ื) ), ืื• ืขื ืขื•ืžืก ื›ืœืœื™ ืงื˜ืŸ , ืื• ื—ื•ืกืจ ื”ืจืฆื•ืŸ ืœื”ื‘ื™ืŸ ืืช ื”ืžื•ืจื›ื‘ื•ืช ืฉืœ ื”ื’ื“ืจืช Kubernetes, ื›ื•ืœืœ ืœืขื•ืžืกื™ื ื’ื‘ื•ื”ื™ื.

Podman ืœื ืžืกืคืง ืชืื™ืžื•ืช ืžืœืื”, ืื‘ืœ ื™ืฉ ืœื• ื™ืชืจื•ืŸ ืื—ื“ ื—ืฉื•ื‘ - ืชืื™ืžื•ืช ืขื Kubernetes, ื›ื•ืœืœ ื›ืœื™ื ื ื•ืกืคื™ื (buildah ื•ืื—ืจื™ื). ืœื›ืŸ, ืื ื™ ื ื™ื’ืฉ ืœื‘ื—ื™ืจืช ื”ื›ืœื™ ืœืขื‘ื•ื“ื” ื‘ืื•ืคืŸ ื”ื‘ื: ืœืฆื•ื•ืชื™ื ืงื˜ื ื™ื, ืื• ืขื ืชืงืฆื™ื‘ ืžื•ื’ื‘ืœ - ื“ื•ืงืจ (ืขื ืžืฆื‘ ื ื—ื™ืœ ืืคืฉืจื™), ืœืคื™ืชื•ื— ืœืขืฆืžื™ ื‘ืžืืจื— ืžืงื•ืžื™ ืื™ืฉื™ - ื—ื‘ืจื™ ืคื•ื“ืžืŸ, ื•ืœื›ืœ ื”ืฉืืจ. - Kubernetes.

ืื ื™ ืœื ื‘ื˜ื•ื— ืฉื”ืžืฆื‘ ืขื Docker ืœื ื™ืฉืชื ื” ื‘ืขืชื™ื“, ื”ืจื™ ื”ื ื—ืœื•ืฆื™ื, ื•ื’ื ืžืชืงื ื™ื ืœืื˜ ืœืื˜ ืฉืœื‘ ืื—ืจ ืฉืœื‘, ืื‘ืœ ืคื•ื“ืžืŸ ืขื ื›ืœ ื”ื—ืกืจื•ื ื•ืช ืฉืœื• (ืขื•ื‘ื“ ืจืง ื‘ืœื™ื ื•ืงืก, ืœืœื ืืฉื›ื•ืœื•ืช, ื”ืจื›ื‘ื” ื•ืคืขื•ืœื•ืช ืื—ืจื•ืช ื”ืŸ ื”ื—ืœื˜ื•ืช ืฉืœ ืฆื“ ืฉืœื™ืฉื™) ื”ืขืชื™ื“ ื‘ืจื•ืจ ื™ื•ืชืจ, ืื– ืื ื™ ืžื–ืžื™ืŸ ืืช ื›ื•ืœื ืœื“ื•ืŸ ื‘ืžืžืฆืื™ื ืืœื” ื‘ื”ืขืจื•ืช.

ื .ื‘. ื‘-3 ื‘ืื•ื’ื•ืกื˜ ืื ื—ื ื• ืžืฉื™ืงื™ื ืืช "ืงื•ืจืก ื•ื™ื“ืื• ืฉืœ ื“ื•ืงืจืฉื‘ื• ืชื•ื›ืœ ืœืœืžื•ื“ ืขื•ื“ ืขืœ ืขื‘ื•ื“ืชื•. ื ื ืชื— ืืช ื›ืœ ื”ื›ืœื™ื ืฉืœื•: ืžื”ืคืฉื˜ื•ืช ื‘ืกื™ืกื™ื•ืช ื•ืขื“ ืœืคืจืžื˜ืจื™ื ืฉืœ ืจืฉืช, ื ื™ื•ืื ืกื™ื ืฉืœ ืขื‘ื•ื“ื” ืขื ืžืขืจื›ื•ืช ื”ืคืขืœื” ืฉื•ื ื•ืช ื•ืฉืคื•ืช ืชื›ื ื•ืช. ืชื•ื›ืœื• ืœื”ื›ื™ืจ ืืช ื”ื˜ื›ื ื•ืœื•ื’ื™ื” ื•ืœื”ื‘ื™ืŸ ื”ื™ื›ืŸ ื•ื›ื™ืฆื“ ื”ื›ื™ ื›ื“ืื™ ืœื”ืฉืชืžืฉ ื‘-Docker. ื ืฉืชืฃ ื’ื ืžืงืจื™ื ืฉืœ ืฉื™ื˜ื•ืช ืขื‘ื•ื“ื” ืžื•ืžืœืฆื•ืช.

ืขืœื•ืช ื”ื–ืžื ื” ืžืจืืฉ ืœืคื ื™ ื”ืฉื—ืจื•ืจ: 5000 ืจื•ื‘ืœ. ื ื™ืชืŸ ืœืžืฆื•ื ืืช ื”ืชื•ื›ื ื™ืช "ืงื•ืจืก ื•ื™ื“ืื• ื“ื•ืงืจ". ื‘ืขืžื•ื“ ื”ืงื•ืจืก.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”