TL;DR: Superrigarda artikolo - gvidilo por kompari mediojn por ruli aplikaĵojn en ujoj. La eblecoj de Docker kaj aliaj similaj sistemoj estos konsiderataj.
Eta historio de kie ĉio venis
История
La unua konata maniero izoli aplikaĵon estas chroot. La samnoma sistemvoko disponigas ŝanĝon al la radika dosierujo - tiel havigante aliron al la programo kiu vokis ĝin, aliron nur al dosieroj ene de ĉi tiu dosierujo. Sed se la programo ricevas superuzantrajtojn interne, ĝi eble povas "eskapi" de la chroot kaj akiri aliron al la ĉefa operaciumo. Ankaŭ, krom ŝanĝi la radikan dosierujon, aliaj rimedoj (RAM, procesoro), same kiel aliro al la reto, ne estas limigitaj.
La sekva maniero estas lanĉi plenan operaciumon ene de la ujo, uzante la mekanismojn de la operaciumo-kerno. Ĉi tiu metodo nomiĝas malsame en malsamaj operaciumoj, sed la esenco estas la sama - kurante plurajn sendependajn operaciumojn, ĉiu el kiuj funkcias per la sama kerno, kiu funkcias la ĉefan operaciumon. Ĉi tio inkluzivas FreeBSD Jails, Solaris Zones, OpenVZ kaj LXC por Linukso. Izolaĵo estas provizita ne nur por diskospaco, sed ankaŭ por aliaj rimedoj, precipe ĉiu ujo povas havi limigojn pri procesora tempo, RAM, reta bendolarĝo. Kompare kun chroot, lasi la ujo estas pli malfacila, ĉar la superuzanto en la ujo havas aliron nur al la interno de la ujo, tamen pro la bezono teni la operaciumon ene de la ujo ĝisdatigita kaj la uzo de malnova kerno. versioj (gravaj por Linukso, en pli malgranda mezuro FreeBSD), estas ne-nula la probableco trarompi la kernan izoligan sistemon kaj akiri aliron al la ĉefa operaciumo.
Anstataŭ lanĉi plenan operaciumon en ujo (kun komenca sistemo, pakaĵadministranto ktp.), aplikaĵoj povas esti lanĉitaj tuj, la ĉefa afero estas provizi aplikojn kun ĉi tiu ŝanco (la ĉeesto de la necesaj bibliotekoj kaj aliaj dosieroj). Ĉi tiu ideo servis kiel bazo por kontenerigita aplikaĵvirtualigo, kies plej elstara kaj konata reprezentanto estas Docker. Kompare kun antaŭaj sistemoj, pli flekseblaj izolaj mekanismoj, kune kun enkonstruita subteno por virtualaj retoj inter ujoj kaj aplikaĵa stato ene de ujo, rezultigis la kapablon konstrui ununuran holistikan medion de granda nombro da fizikaj serviloj por ruli ujojn - sen la bezono de mana rimedadministrado.
Docker
Docker estas la plej konata aplikaĵa konteneriga programaro. Skribita en la Go-lingvo, ĝi uzas la regulajn kapablojn de la Linukso-kerno - cgroups, nomspacoj, kapabloj, ktp., same kiel Aufs-dosiersistemojn kaj aliajn similajn por ŝpari diskospacon.
Fonto: vikimedio
arkitekturo
Antaŭ versio 1.11, Docker funkciis kiel ununura servo, kiu plenumis ĉiujn operaciojn kun ujoj: elŝuti bildojn por ujoj, lanĉi ujojn, prilabori API-petojn. Ekde versio 1.11, Docker estis dividita en plurajn partojn, kiuj interagas unu kun la alia: containerd, por pritrakti la tutan vivociklon de ujoj (asigno de diskospaco, elŝutado de bildoj, interkonektado, lanĉo, instalo kaj monitorado de la stato de ujoj) kaj runC. , konteneraj rultempoj, surbaze de la uzo de cgroups kaj aliaj funkcioj de la Linukso-kerno. La docker-servo mem restas, sed nun ĝi nur servas por prilabori API-petojn elsenditajn al containerd.
Instalado kaj agordo
Mia plej ŝatata maniero instali docker estas docker-machine, kiu, krom rekte instali kaj agordi docker sur foraj serviloj (inkluzive de diversaj nuboj), permesas vin labori kun la dosiersistemoj de foraj serviloj, kaj ankaŭ povas ruli diversajn komandojn.
Tamen, ekde 2018, la projekto apenaŭ disvolviĝis, do ni instalos ĝin laŭ la kutima maniero por la plej multaj Linuksaj distribuoj - aldonante deponejon kaj instalante la necesajn pakaĵojn.
Ĉi tiu metodo ankaŭ estas uzata por aŭtomata instalado, ekzemple, uzante Ansible aŭ aliajn similajn sistemojn, sed mi ne konsideros ĝin en ĉi tiu artikolo.
Instalado estos farita sur Centos 7, mi uzos virtualan maŝinon kiel servilon, por instali, nur rulu la subajn komandojn:
# 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
Post instalado, vi devas komenci la servon, meti ĝin en aŭtomatan ŝarĝon:
# systemctl enable docker
# systemctl start docker
# firewall-cmd --zone=public --add-port=2377/tcp --permanent
Aldone, vi povas krei docker-grupon, kies uzantoj povos labori kun docker sen sudo, agordi ensalutadon, ebligi aliron al la API de ekstere, ne forgesu agordi la fajroŝirmilon (ĉio, kio ne estas permesita, estas malpermesite en la supraj kaj malsupraj ekzemploj - mi preterlasis tion por simpleco kaj bildigo), sed mi ne eniros pli detale ĉi tie.
Aliaj trajtoj
Krom ĉi-supra docker-maŝino, ekzistas ankaŭ docker-registro, ilo por stoki bildojn por ujoj, kaj ankaŭ docker-komponadon - ilo por aŭtomatigi la disfaldiĝon de aplikoj en ujoj, YAML-dosieroj estas uzataj por konstrui kaj agordi ujojn kaj aliaj rilataj aferoj (ekzemple, retoj, persistaj dosiersistemoj por konservi datumojn).
Ĝi ankaŭ povas esti uzata por organizi duktojn por CICD. Alia interesa trajto funkcias en cluster-reĝimo, la tielnomita svarma reĝimo (antaŭ versio 1.12 ĝi estis konata kiel docker-svarmo), kiu ebligas al vi kunmeti ununuran infrastrukturon de pluraj serviloj por ruli ujojn. Estas subteno por virtuala reto aldone al ĉiuj serviloj, ekzistas enkonstruita ŝarĝbalancilo, kaj ankaŭ subteno por sekretoj por ujoj.
La YAML-dosieroj de docker compose povas esti uzataj por tiaj aretoj kun malgrandaj modifoj, plene aŭtomatigante la prizorgadon de malgrandaj kaj mezaj aretoj por diversaj celoj. Por grandaj aretoj, Kubernetes estas preferinda ĉar la kostoj pri bontenado de svarmanoj povas superi tiujn de Kubernetes. Krom runC, kiel ekzekutmedio por ujoj, vi povas instali, ekzemple
Laborante kun Docker
Post instalado kaj agordo, ni provos konstrui areton en kiu ni disfaldiĝos GitLab kaj Docker Registry por la evolua teamo. Kiel serviloj, mi uzos tri virtualajn maŝinojn, sur kiuj mi aldone deplojos la distribuitan FS de GlusterFS, mi uzos ĝin kiel stokado de docker-volumoj, ekzemple, por ruli sekuran version de la docker-registro. Ŝlosilaj komponantoj por ruli: Docker Registry, Postgresql, Redis, GitLab kun subteno por GitLab Runner supre de Swarm. Postgresql estos lanĉita kun clustering
Por deploji GlusterFS sur ĉiuj serviloj (ili nomiĝas nodo1, nodo2, nodo3), vi devas instali pakaĵojn, ebligi la fajroŝirmilon, krei la necesajn dosierujojn:
# 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
Post instalado, laboro pri agordo de GlusterFS devas esti daŭrigita de unu nodo, ekzemple nodo1:
# 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
Tiam vi devas munti la rezultan volumon (la komando devas esti rulita sur ĉiuj serviloj):
# mount /srv/docker
Svarma reĝimo estas agordita sur unu el la serviloj, kiu estos Ĉefo, la resto devos aliĝi al la areto, do la rezulto de rulado de la komando sur la unua servilo devos esti kopiita kaj ekzekutita sur la resto.
Komenca agordo de grapolo, mi rulas la komandon sur nodo1:
# 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
Kopiu la rezulton de la dua komando, ekzekutu sur nodo2 kaj nodo3:
# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.
Ĉi tio kompletigas la antaŭan agordon de la serviloj, ni komencu agordi la servojn, la ekzekutotaj komandoj estos lanĉitaj de nodo1, krom se alie specifita.
Antaŭ ĉio, ni kreu retojn por ujoj:
# 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
Tiam ni markas la servilojn, ĉi tio estas necesa por ligi iujn servojn al la serviloj:
# docker node update --label-add nodename=node1 node1
# docker node update --label-add nodename=node2 node2
# docker node update --label-add nodename=node3 node3
Poste ni kreas dosierujojn por stoki etcd-datumojn, la KV-stokadon, kiun bezonas Traefik kaj Stolon. Simile al Postgresql, ĉi tiuj estos ujoj ligitaj al serviloj, do ni plenumas ĉi tiun komandon en ĉiuj serviloj:
# mkdir -p /srv/etcd
Poste, kreu dosieron por agordi etcd kaj apliki ĝin:
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
Post iom da tempo, ni kontrolas, ke la etcd-areto altiĝis:
# 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
Kreu dosierujojn por Postgresql, faru la komandon en ĉiuj serviloj:
# mkdir -p /srv/pgsql
Poste, kreu dosieron por agordi 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
Ni generas sekretojn, aplikas la dosieron:
# </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
Iom da tempo poste (rigardu la eligon de la komando docker servo lske ĉiuj servoj altiĝis) pravalorigu la Postgresql-grupon:
# 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
Kontrolante la pretecon de la Postgresql-grupo:
# 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
Ni agordas traefik por malfermi aliron al ujoj de ekstere:
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
Ni komencas Redis Cluster, por tio ni kreas stokan dosierujon sur ĉiuj nodoj:
# 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
Aldonu Docker-Registron:
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
Kaj finfine - 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
La fina stato de la areto kaj servoj:
# 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
Kion alian oni povas plibonigi? Nepre agordu Traefik por labori kun https-ujoj, aldonu tls-ĉifradon por Postgresql kaj Redis. Sed ĝenerale, vi jam povas doni ĝin al programistoj kiel PoC. Ni nun rigardu alternativojn al Docker.
podman
Alia sufiĉe konata motoro por prizorgi ujojn grupigitajn laŭ balgoj (pods, grupoj da ujoj deplojitaj kune). Male al Docker, ĝi ne postulas ajnan servon por ruli ujojn, ĉiu laboro estas farita per la libpod-biblioteko. Ankaŭ skribita en Go, bezonas OCI-konforman rultempon por ruli ujojn kiel runC.
Labori kun Podman ĝenerale similas al tiu de Docker, tiom kiom vi povas fari ĝin tiel (postulita de multaj, kiuj provis ĝin, inkluzive de la aŭtoro de ĉi tiu artikolo):
$ alias docker=podman
kaj vi povas plu labori. Ĝenerale, la situacio kun Podman estas tre interesa, ĉar se la fruaj versioj de Kubernetes funkciis kun Docker, tiam ekde proksimume 2015, post normigado de la kontenera mondo (OCI - Open Container Initiative) kaj dividi Docker en containerd kaj runC, alternativo al Docker estas disvolvita por funkcii en Kubernetes: CRI-O. Podman ĉi-rilate estas alternativo al Docker, konstruita sur la principoj de Kubernetes, inkluzive de kontenera grupigo, sed la ĉefa celo de la projekto estas ruli Docker-stilaj ujoj sen aldonaj servoj. Pro evidentaj kialoj, ne ekzistas svarma reĝimo, ĉar la programistoj klare diras, ke se vi bezonas areton, prenu Kubernetes.
fikso
Por instali sur Centos 7, simple aktivigu la deponejon de Kromaĵoj, kaj poste instalu ĉion per la komando:
# yum -y install podman
Aliaj trajtoj
Podman povas generi unuojn por systemd, tiel solvante la problemon de lanĉado de ujoj post servila rekomenco. Aldone, systemd estas deklarita funkcii ĝuste kiel pid 1 en la ujo. Por konstrui ujojn, ekzistas aparta buildah-ilo, ekzistas ankaŭ triaj iloj - analogoj de docker-compose, kiu ankaŭ generas Kubernetes-kongruajn agordajn dosierojn, do la transiro de Podman al Kubernetes estas kiel eble plej simpla.
Laborante kun Podman
Ĉar ne ekzistas svarma reĝimo (ĝi devas ŝanĝi al Kubernetes se bezonata areto), ni kunvenos ĝin en apartaj ujoj.
Instalu podman-compose:
# yum -y install python3-pip
# pip3 install podman-compose
La rezulta agordosiero por podman estas iomete malsama, ĉar ekzemple ni devis movi apartan sekcion de volumoj rekte al la sekcio de servoj.
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
Rezulto de laboro:
# 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
Ni vidu, kion ĝi generos por systemd kaj kubernetes, por tio ni devas eltrovi la nomon aŭ identigilon de la pod:
# 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
Bedaŭrinde, krom ruli ujojn, la generita unuo por systemd faras nenion alian (ekzemple, purigi malnovajn ujojn kiam tia servo estas rekomencita), do vi devos aldoni tiajn aferojn mem.
En principo, Podman sufiĉas por provi kio estas ujoj, translokigi malnovajn agordojn por docker-compose, kaj tiam iri al Kubernetes, se necese, sur areto, aŭ akiri pli facile uzeblan alternativon al Docker.
rkt
La projekto
Ekbrilo
Pli
trovoj
La situacio kun Kubernetes estas tre interesa: unuflanke, kun Docker, vi povas kunveni grapolon (en svarma reĝimo), per kiu vi eĉ povas funkciigi produktadmediojn por klientoj, ĉi tio validas precipe por malgrandaj teamoj (3-5 homoj). ), aŭ kun malgranda ĝenerala ŝarĝo , aŭ la manko de deziro kompreni la komplikaĵojn de agordo de Kubernetes, inkluzive por altaj ŝarĝoj.
Podman ne provizas plenan kongruon, sed ĝi havas unu gravan avantaĝon - kongruon kun Kubernetes, inkluzive de pliaj iloj (buildah kaj aliaj). Tial mi traktos la elekton de ilo por laboro jene: por malgrandaj teamoj, aŭ kun limigita buĝeto - Docker (kun ebla svarma reĝimo), por disvolvi por mi mem sur persona loka gastiganto - Podman-kamaradoj, kaj por ĉiuj aliaj. - Kubernetes.
Mi ne certas, ke la situacio kun Docker ne ŝanĝiĝos estonte, ja ili estas pioniroj, kaj ankaŭ malrapide normigas paŝon post paŝo, sed Podman, kun ĉiuj ĝiaj mankoj (funkcias nur en Linukso, sen clustering, asembleo). kaj aliaj agoj estas triaj decidoj) la estonteco estas pli klara, do mi invitas ĉiujn diskuti ĉi tiujn rezultojn en la komentoj.
PS La 3-an de aŭgusto ni lanĉas "
Antaŭmendo kosto antaŭ liberigo: 5000 rubloj. La programo "Docker Video Kurso" troviĝas
fonto: www.habr.com