Docker iyo dhammaan, dhammaan, dhammaan

TL;DR: Maqaal guud - hagaha isbarbardhigga jawiga codsiyada ku jira weelasha. Fursadaha Docker iyo nidaamyada kale ee la midka ah ayaa la tixgelin doonaa.

Docker iyo dhammaan, dhammaan, dhammaan

Taariikh yar oo meeshay ka timid

Π˜ΡΡ‚ΠΎΡ€ΠΈΡ

Habka ugu horreeya ee si fiican loo yaqaan ee lagu karantiilo codsiga waa chroot. Wicitaanka nidaamka ee magaca isku midka ah wuxuu bixiyaa isbeddel ku yimaada tusaha xididka - sidaas darteed bixinta helitaanka barnaamijka loo yaqaan, helitaanka kaliya faylasha gudaha tusahan. Laakin haddii barnaamijka lagu siiyo xuquuqaha superuser gudaha, waxa laga yaabaa in uu "ka baxsado" chroot oo uu galo nidaamka hawlgalka ee ugu muhiimsan. Sidoo kale, marka lagu daro beddelka tusaha xididka, agabyada kale (RAM, processor), iyo sidoo kale gelitaanka shabakadda, kuma koobna.

Habka soo socda waa in la bilaabo nidaamka hawlgalka buuxa ee gudaha weelka, iyada oo la adeegsanayo hababka kernel nidaamka hawlgalka. Habkan waxaa loogu yeeraa si ka duwan hababka kala duwan ee hawlgalka, laakiin nuxurku waa isku mid - wuxuu ku shaqeeyaa dhowr nidaamyo hawleed oo madaxbannaan, kuwaas oo mid kastaa uu ku socdo isla kernel kaas oo ku shaqeeya nidaamka ugu muhiimsan. Tan waxaa ku jira Xabsiyada FreeBSD, Aagagga Solaris, OpenVZ, iyo LXC ee Linux. Go'doominta ma aha oo kaliya booska diskka, laakiin sidoo kale kheyraadka kale, gaar ahaan, weel kasta wuxuu yeelan karaa xaddidaad ku saabsan waqtiga processor-ka, RAM, bandwidth network. Marka la barbardhigo chroot, ka tagista weelka aad ayey u adag tahay, maadaama superuser-ka ku jira weelka uu geli karo oo keliya gudaha weelka, si kastaba ha ahaatee, baahida loo qabo in nidaamka qalliinka ee gudaha weelka lagu hayo mid casri ah iyo isticmaalka kernel duug ah. Noocyo (kuxiran Linux, ilaa xad FreeBSD), ma jirto wax aan eber ahayn suurtagalnimada "jabinta" nidaamka go'doominta kernel iyo helitaanka nidaamka hawlgalka ee ugu weyn.

Halkii laga bilaabi lahaa nidaam hawleed buuxa oo weel ah (oo leh nidaamka bilowga, maareeyaha xirmada, iwm.), codsiyada waa la bilaabi karaa isla markiiba, waxa ugu muhiimsan waa in la siiyo codsiyada fursadan (joogitaanka maktabadaha lagama maarmaanka ah iyo faylasha kale). Fikirkani waxa uu u adeegay asaas u ah habaynta codsiga weel ku jira, wakiilka ugu caansan uguna caansan kaas oo ah Docker. Marka la barbardhigo nidaamyadii hore, habab go'doomin badan oo dabacsan, oo ay weheliso taageerada gudaha ee shabakadaha farsamada ee u dhexeeya weelasha iyo codsiga caddaynta gudaha weelka, waxay keentay awoodda lagu dhisayo jawi keli ah oo ka yimaada tiro badan oo ah server-yada jireed si ay u socodsiiyaan weelasha - iyada oo aan lahayn baahida loo qabo maareynta kheyraadka gacanta.

Docker

Docker waa software-ka weecinta codsiyada ee ugu caansan. Waxaa lagu qoray luqadda Go, waxay isticmaashaa awoodaha caadiga ah ee kernel Linux - kooxo, magacyo, awood, iwm, iyo sidoo kale nidaamyada faylka Aufs iyo kuwa kale oo la mid ah si loo badbaadiyo booska diskka.

Docker iyo dhammaan, dhammaan, dhammaan
Xigasho: wikimedia

naqshadaha

Kahor nooca 1.11, Docker wuxuu u shaqeeyay sidii hal adeeg oo ku fuliyay dhammaan hawlgallada weelasha: soo dejinta sawirada weelasha, bilaabista weelasha, socodsiinta codsiyada API. Laga soo bilaabo nooca 1.11, Docker waxaa loo kala qaybiyay dhowr qaybood oo is-dhex gala midba midka kale: weel, si uu u maareeyo dhammaan wareegga nolosha ee weelasha ( qoondaynta booska diskka, soo dejinta sawirada, isku xirka, bilaabista, rakibidda iyo la socodka xaaladda weelasha) iyo runC , runtimes weelka, oo ku salaysan isticmaalka kooxaha iyo sifooyinka kale ee kernel Linux. Adeegga dockerka laftiisa ayaa weli ah, laakiin hadda waxa uu u adeegaa oo kaliya in lagu socodsiiyo codsiyada API ee lagu sii daayo weelka.

Docker iyo dhammaan, dhammaan, dhammaan

Rakibaadda iyo qaabeynta

Habka aan ugu jecelahay ee lagu rakibo docker-machine, kaas oo, marka lagu daro si toos ah u rakibidda iyo habeynta docker ee server-yada fog (oo ay ku jiraan daruuro kala duwan), waxay kuu ogolaaneysaa inaad la shaqeyso nidaamyada faylka ee server-yada fog, iyo sidoo kale socodsiin kara amarro kala duwan.

Si kastaba ha noqotee, tan iyo 2018, mashruuca si dhib leh looma horumarin, markaa waxaan ku rakibi doonaa habka caadiga ah ee inta badan qaybinta Linux - adoo ku daraya kayd iyo rakibidda xirmooyinka lagama maarmaanka ah.

Habkan waxaa sidoo kale loo isticmaalaa rakibaadda otomatiga ah, tusaale ahaan, iyadoo la adeegsanayo nidaamyo macquul ah ama kuwo kale oo la mid ah, laakiin ma tixgelin doono qodobkan.

Rakibaadda waxaa lagu fulin doonaa Centos 7, Waxaan u isticmaali doonaa mashiinka farsamada sida server ahaan, si loo rakibo, kaliya ku socodsii amarrada hoose:

# 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

Ka dib markii la rakibo, waxaad u baahan tahay inaad bilowdo adeegga, ku rid autoload:

# systemctl enable docker
# systemctl start docker
# firewall-cmd --zone=public --add-port=2377/tcp --permanent

Intaa waxaa dheer, waxaad abuuri kartaa koox docker ah, kuwaas oo isticmaaleyaashooda ay awoodi doonaan inay la shaqeeyaan docker iyaga oo aan lahayn sudo, dejiyaan gooyn, awood u hel API-ga bannaanka, ha ilaawin inaad hagaajiso dabka (wax kasta oo aan la oggolayn waa Mamnuuc tusaalooyinka sare iyo hoose - Tan waxaan uga tagay fududaan iyo muuqaal), laakiin halkan kuma sii faahfaahin doono.

Tilmaamo kale

Marka lagu daro mishiinka kor ku xusan, waxaa sidoo kale jira diiwaanka docker, qalab lagu kaydiyo sawirada weelasha, iyo sidoo kale qalabaynta - qalab loogu talagalay soo dejinta codsiyada ku jira weelasha, faylasha YAML waxaa loo isticmaalaa si loo dhiso loona habeeyo weelasha iyo waxyaabaha kale ee la xidhiidha (tusaale ahaan, shabakadaha, nidaamyada faylka joogtada ah ee kaydinta xogta).

Waxa kale oo loo isticmaali karaa in lagu habeeyo dhuumaha CICD. Muuqaal kale oo xiiso leh ayaa ka shaqeynaya qaabka kooxeed, waxa loogu yeero qaabka swarm (kahor nooca 1.12 waxaa loo yaqaanay docker swarm), kaas oo kuu ogolaanaya inaad ka soo ururiso hal kaabayaal dhowr ah si aad u socodsiiso weelasha. Waxaa jira taageero loogu talagalay shabakad muuqaal ah oo ku saabsan dhammaan server-yada, waxaa jira isku-dheellitirka culeyska, iyo sidoo kale taageerada sirta ah ee weelasha.

Faylasha YAML ee ka soo baxa docker-ka waxa loo isticmaali karaa kooxahan oo kale oo leh wax ka bedel yar, iyaga oo si buuxda u toosiya dayactirka kooxaha yaryar iyo kuwa dhexe ujeedooyin kala duwan. Kooxaha waaweyn, Kubernetes ayaa la door bidayaa sababtoo ah kharashka dayactirka qaabka raxanku wuxuu ka miisaan badnaan karaa kuwa Kubernetes. Marka lagu daro runC, sida deegaanka fulinta ee weelasha, waxaad ku rakibi kartaa, tusaale ahaan weelasha Kata

La shaqaynta Docker

Ka dib rakibidda iyo qaabeynta, waxaan isku dayi doonaa inaan dhisno koox kaaso aan geyn doono GitLab iyo Docker Registry kooxda horumarinta. Adeegayaal ahaan, waxaan isticmaali doonaa seddex mashiin oo dalwad ah, kuwaas oo aan sidoo kale geyn doono GlusterFS qaybinta FS, waxaan u isticmaali doonaa kaydinta mugga docker, tusaale ahaan, si aan u socodsiiyo nooca nabdoonaanta ah ee diiwaanka docker. Qaybaha muhiimka ah ee la wado: Diiwaanka Docker, Postgresql, Redis, GitLab oo taageero u ah GitLab Runner oo ku yaal dusha sare ee Swarm. Postgresql waxa lagu bilaabi doonaa kooxaysi Stolon, markaa uma baahnid inaad isticmaasho GlusterFS si aad u kaydiso xogta Postgresql. Inta kale ee xogta muhiimka ah waxa lagu kaydin doonaa GlusterFS.

Si loo geeyo GlusterFS dhammaan server-yada (waxaa loo yaqaan node1, node2, node3), waxaad u baahan tahay inaad rakibto baakadaha, karti u geliso dabka, samee hagaha lagama maarmaanka ah:

# 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

Ka dib marka la rakibo, shaqada habaynta GlusterFS waa in laga sii wadaa hal noode, tusaale ahaan 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

Markaa waxaad u baahan tahay inaad kor u qaaddo mugga natiijada (amarka waa inuu ku shaqeeyaa dhammaan server-yada):

# mount /srv/docker

Habka Swarm waxaa lagu habeeyay mid ka mid ah server-yada, kaas oo noqon doona Hogaamiye, inta soo hartay waa inay ku biiraan kooxda, markaa natiijada ku socodsiinta amarka server-ka ugu horreeya waxay u baahan doontaa in la koobiyeeyo oo la fuliyo inta soo hartay.

Habaynta kooxda ugu horeysa, waxaan ku socodsiiyaa amarka 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

Nuqul ka samee natiijada amarka labaad, ku samee node2 iyo node3:

# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.

Tani waxay dhamaystiraysaa qaabeynta hordhaca ah ee server-yada, aynu bilowno habaynta adeegyada, amarrada la fulinayo waxaa laga bilaabi doonaa node1, haddii aan si kale loo cayimin.

Marka hore, aynu abuurno shabakado weel:

# 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

Kadib waxaan calaamadeynaa server-yada, tani waxay lagama maarmaan u tahay in lagu xiro adeegyada qaar ka mid ah server-yada:

# docker node update --label-add nodename=node1 node1
# docker node update --label-add nodename=node2 node2
# docker node update --label-add nodename=node3 node3

Marka xigta, waxaanu abuurnaa hagayaal lagu kaydiyo xogta iwm, kaydinta KV ee Traefik iyo Stolon u baahan yihiin. Si la mid ah Postgresql, kuwani waxay noqon doonaan weel ku xidhan server-yada, markaa waxaanu amarkan ku fulinaa dhammaan adeegayaasha:

# mkdir -p /srv/etcd

Marka xigta, samee fayl si aad u habayso etcd oo ku dabaq:

00iwm.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

Muddo ka dib, waxaan hubineynaa in kooxda iwm ay kor u kacday:

# 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

U samee hagaha Postgresql, ku fuli amarka dhammaan server-yada:

# mkdir -p /srv/pgsql

Marka xigta, samee fayl si aad u habayso 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

Waxaan abuurnaa siraha, isticmaal faylka:

# </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

Waqti ka dib (fiiri wax soo saarka amarka adeega docker lsin dhammaan adeegyadu kor u kaceen) bilow kooxda 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

Hubinta u diyaarsanaanta kooxda 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

Waxaan u habaynaynaa traefik si ay u furto gelitaanka weelasha dibadda:

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

Waxaan ku bilownay Kooxda Redis, tan awgeed waxaan u abuurnaa hagaha kaydinta dhammaan noodaha:

# 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

Kudar Diiwaanka Docker:

06diwaanka.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

Ugu dambeyntiina - GitLab:

08gitlab-orodyahan.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

Xaaladda ugu dambeysa ee kooxda iyo adeegyada:

# 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

Maxaa kale oo la hagaajin karaa? Hubi inaad habayso Traefik si uu ula shaqeeyo https weelasha, ku dar tls encryption Postgresql iyo Redis. Laakiin guud ahaan, waxaad horeyba u siin kartaa horumariyeyaal ahaan PoC ahaan. Aynu hadda eegno beddelka Docker.

podman

Matoor kale oo si cadaalad ah loo yaqano oo loogu talagalay weelasha orda ee ay kooxuhu u qaybsan yihiin (pods, kooxaha weelasha la wada geeyo). Si ka duwan Docker, uma baahna wax adeeg ah si loo socodsiiyo weelasha, dhammaan shaqada waxaa lagu sameeyaa maktabadda libpod. Sidoo kale ku qoran Go, waxay u baahan tahay OCI-da wakhtiga runtime si ay u socodsiiso weelasha sida runC.

Docker iyo dhammaan, dhammaan, dhammaan

La shaqaynta Podman guud ahaan waxay la mid tahay tii Docker, ilaa xadka aad sidan ku samayn karto (ay sheegteen dad badan oo isku dayay, oo uu ku jiro qoraaga maqaalkan):

$ alias docker=podman

waadna sii wadan kartaa shaqada. Guud ahaan, xaaladda Podman waa mid aad u xiiso badan, sababtoo ah haddii noocyada hore ee Kubernetes ay la shaqeeyeen Docker, ka dibna ilaa 2015, ka dib markii la jaangooyo adduunka weelka (OCI - Open Container Initiative) iyo kala qaybinta Docker weel iyo runC, beddelka Docker waxaa loo soo saaray inuu ku shaqeeyo Kubernetes: CRI-O. Podman marka la eego arrintani waa beddelka Docker, oo lagu dhisay mabaadi'da Kubernetes, oo ay ku jiraan kooxaynta weelasha, laakiin ujeedada ugu weyn ee mashruuca waa in la socodsiiyo weelasha qaabka Docker iyada oo aan lahayn adeegyo dheeraad ah. Sababo muuqda dartood, ma jiro qaab raxan ah, maadaama horumariyayaashu si cad u sheegaan in haddii aad u baahan tahay koox, qaado Kubernetes.

Ku rakibida

Si aad ugu rakibto Centos 7, kaliya dhaqaaji bakhaarka Extras, ka dibna wax walba ku rakib amarka:

# yum -y install podman

Tilmaamo kale

Podman wuxuu soo saari karaa cutubyo loogu talagalay nidaamka, sidaas darteed xallinta dhibaatada bilaabista weelasha ka dib dib-u-kicinta server-ka. Intaa waxaa dheer, systemd ayaa lagu dhawaaqay inuu si sax ah ugu shaqeeyo sida pid 1 ee weelka ku jira. Si loo dhiso weelasha, waxaa jira qalab dhisme gaar ah, sidoo kale waxaa jira qalab dhinac saddexaad ah - analogues of docker-compose, kaas oo sidoo kale soo saara Kubernetes faylasha qaabeynta ku habboon, sidaas awgeed u gudubka Podman ilaa Kubernetes waa sida ugu fudud ee suurtogalka ah.

La shaqaynta Podman

Maadaama aysan jirin qaab raxan ah (waa in loo beddelaa Kubernetes haddii koox loo baahdo), waxaan ku soo ururin doonnaa weelal kala duwan.

Ku rakib podman-compose:

# yum -y install python3-pip
# pip3 install podman-compose

Faylka qaabeynta ee podman wax yar ayuu ka duwan yahay, tusaale ahaan waxaan ku qasbanaay inaan u dhaqaaqno qayb mug gaar ah si toos ah qaybta adeegyada.

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

Natiijada shaqada:

# 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

Aynu aragno waxa ay u dhalin doonto systemd iyo kubernetes, tan waxaan u baahanahay inaan ogaano magaca ama id ee podska:

# 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: {}

habaysan:

# 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

Nasiib darro, marka laga reebo furista weelasha, unugga la soo saaray ee systemd ma jiraan wax kale (tusaale, nadiifinta weelasha duugga ah marka adeeggan dib loo bilaabo), markaa waa inaad adigu ku darto waxyaabahan oo kale.

Mabda 'ahaan, Podman ayaa ku filan inuu tijaabiyo waxa weelku yahay, u wareejinta hababkii hore ee docker-compose, ka dibna aado dhanka Kubernetes, haddii loo baahdo, koox, ama aad hesho beddelka sahlan ee loo isticmaali karo Docker.

rkt

Mashruuca aaday kaydka qiyaastii lix bilood ka hor sababtoo ah xaqiiqda ah in RedHat ay iibsatay, markaa anigu si faahfaahsan uga hadli maayo. Guud ahaan, waxay ka tagtay aragti aad u wanaagsan, laakiin marka la barbardhigo Docker, iyo xitaa in ka badan Podman, waxay u egtahay mid la isku daray. Waxaa sidoo kale jiray qaybinta CoreOS oo lagu dhisay dusha sare ee rkt (inkasta oo ay markii hore lahaayeen Docker), laakiin taasi waxay sidoo kale dhamaatay ka dib iibkii RedHat.

Ku garaac

More hal mashruuc, qoraaga kaas oo doonayey in uu dhiso oo uu maamulo haamaha. Marka la eego dukumentiyada iyo koodhka, qoraagu ma raacin heerarka, laakiin si fudud ayuu u go'aansaday inuu qoro hirgelintiisa, taas oo, mabda'a, uu sameeyay.

natiijooyinka

Xaaladda Kubernetes waa mid aad u xiiso badan: dhinaca kale, Docker, waxaad soo ururin kartaa koox (qaab raxan ah), taas oo aad xitaa ku socodsiin karto jawiga wax soo saarka ee macaamiisha, tani waxay si gaar ah u tahay kooxaha yaryar (3-5 qof). ), ama culeys yar oo guud, ama rabitaan la'aanta ah in la fahmo qallafsanaanta dejinta Kubernetes, oo ay ku jiraan culeysyo badan.

Podman ma bixiso iswaafajin buuxda, laakiin waxay leedahay hal faa'iido oo muhiim ah - waafaqsanaanta Kubernetes, oo ay ku jiraan qalab dheeraad ah (dhismaha iyo kuwa kale). Sidaa darteed, waxaan u wajahi doonaa xulashada qalabka shaqada sida soo socota: kooxo yaryar, ama miisaaniyad xaddidan - Docker (oo leh qaab raxan ah oo suurtagal ah), horumarinta naftayda shakhsi ahaaneed ee degaanka - saaxiibada Podman, iyo qof kasta oo kale. - Kubernetes.

Ma hubo in xaaladda Docker aysan isbedeli doonin mustaqbalka, ka dib oo dhan, waxay yihiin horjoogayaal, sidoo kale si tartiib tartiib ah ayey u jaangooyeen tallaabo tallaabo, laakiin Podman, oo leh dhammaan cilladaheeda (waxay ka shaqeysaa oo keliya Linux, ma jiro koox, shir). iyo ficilada kale waa go'aano dhinac saddexaad ah) mustaqbalku wuu cad yahay, markaa waxaan ku martiqaadayaa qof walba inuu ka hadlo natiijooyinkan faallooyinka.

PS Ogosto 3 waxaan bilaabeynaa "Koorsada fiidiyowga ee Dockerhalkaas oo aad wax badan ka baran karto shaqadiisa. Waxaan falanqeyn doonaa dhammaan qalabkeeda: laga bilaabo qoraallada aasaasiga ah ilaa xuduudaha shabakada, nuucyada la shaqeynta nidaamyada hawlgalka ee kala duwan iyo luqadaha barnaamijka. Waxaad baran doontaa farsamada oo aad fahmi doontaa halka iyo sida ugu wanaagsan ee loo isticmaalo Docker. Waxaan sidoo kale wadaagi doonaa kiisaska dhaqanka ugu fiican.

Qiimaha hore u dalbashada ka hor inta aan la sii deyn: 5000 rubles. Barnaamijka "Docker Video Course" waa la heli karaa bogga koorsada.

Source: www.habr.com

Add a comment