Docker sareng sadayana, sadayana, sadayana

TL; DR: Artikel Tinjauan - pituduh pikeun ngabandingkeun lingkungan pikeun ngajalankeun aplikasi dina wadah. Kamungkinan Docker sareng sistem anu sami bakal dipertimbangkeun.

Docker sareng sadayana, sadayana, sadayana

A sajarah saeutik dimana eta sadayana asalna

dongeng

Metodeu anu kasohor munggaran pikeun ngasingkeun aplikasi nyaéta chroot. Sauran sistem tina nami anu sami mastikeun yén diréktori akar dirobih - sahingga mastikeun yén program anu nyauran éta ngan ukur aksés kana file dina diréktori éta. Tapi lamun program dibéré hak husus root internal, éta berpotensi "kabur" chroot tur meunangkeun aksés ka sistem operasi utama. Ogé, salian ngarobah diréktori akar, sumberdaya séjén (RAM, processor), kitu ogé aksés ka jaringan, teu diwatesan.

Cara anu salajengna nyaéta ngaluncurkeun sistem operasi anu lengkep dina wadahna, nganggo mékanisme kernel sistem operasi. Metoda ieu disebut béda dina sistem operasi béda, tapi hakekatna sami - ngajalankeun sababaraha sistem operasi bebas, nu masing-masing dijalankeun dina kernel sarua nu ngajalankeun sistem operasi utama. Ieu kalebet FreeBSD Jails, Zona Solaris, OpenVZ, sareng LXC pikeun Linux. Isolasi disayogikeun henteu ngan ukur pikeun rohangan disk, tapi ogé pikeun sumber anu sanés, khususna, unggal wadahna tiasa gaduh larangan dina waktos prosésor, RAM, rubakpita jaringan. Dibandingkeun sareng chroot, nyéépkeun wadahna langkung sesah, sabab superuser dina wadahna ngan ukur gaduh aksés ka jero wadahna, kumaha ogé, kusabab kabutuhan tetep sistem operasi di jero wadahna up to date sareng panggunaan kernel lami. versi (relevan pikeun Linux Ubuntu, ka extent Lesser FreeBSD), aya hiji non-enol kamungkinan "megatkeun ngaliwatan" sistem isolasi kernel sarta meunang aksés ka sistem operasi utama.

Gantina ngaluncurkeun sistem operasi anu lengkep dina wadahna (kalayan sistem inisialisasi, manajer pakét, jsb.), anjeun tiasa langsung ngaluncurkeun aplikasi, hal utama nyaéta nyayogikeun aplikasi kasempetan sapertos kitu (ku ayana perpustakaan anu diperyogikeun. sareng file sanésna). Gagasan ieu janten dasar pikeun virtualisasi aplikasi wadahna, perwakilan anu paling menonjol sareng terkenal nyaéta Docker. Dibandingkeun jeung sistem saméméhna, mékanisme isolasi leuwih fléksibel, gandeng ku diwangun-di rojongan pikeun jaringan virtual antara peti jeung aplikasi tracking kaayaan dina wadahna, nyababkeun kamampuhan pikeun ngawangun lingkungan koheren tunggal ti sajumlah badag server fisik pikeun ngajalankeun peti - tanpa merlukeun manajemén sumberdaya manual.

Docker

Docker mangrupikeun parangkat lunak wadah aplikasi anu paling kasohor. Ditulis dina basa Go, éta ngagunakeun kamampuan biasa tina kernel Linux - cgroups, namespaces, kamampuhan, jsb, kitu ogé sistem file Aufs jeung nu lianna nu sarupa pikeun ngahemat spasi disk.

Docker sareng sadayana, sadayana, sadayana
Sumber: wikimedia

gawena undagi

Sateuacan vérsi 1.11, Docker damel salaku jasa tunggal anu ngalaksanakeun sadaya operasi sareng wadah: ngaunduh gambar pikeun wadah, ngaluncurkeun wadah, ngolah pamundut API. Dimimitian ku vérsi 1.11, Docker dibagi kana sababaraha bagian anu saling berinteraksi: containerd, pikeun ngolah sadayana siklus kahirupan wadah (alokasi rohangan disk, unduh gambar, damel sareng jaringan, ngaluncurkeun, masang sareng ngawaskeun kaayaan wadah). jeung runC, lingkungan palaksanaan wadahna, dumasar kana pamakéan cgroups sarta fitur sejenna tina kernel Linux Ubuntu. Ladenan docker sorangan tetep, tapi ayeuna ngan ukur dianggo pikeun ngolah pamundut API ditarjamahkeun kana containerd.

Docker sareng sadayana, sadayana, sadayana

Pamasangan sareng konfigurasi

Cara paporit kuring pikeun masang docker nyaéta docker-machine, anu, salian langsung masang sareng ngonpigurasikeun docker dina server jauh (kalebet rupa-rupa awan), ngamungkinkeun anjeun damel sareng sistem file tina server jauh, sareng ogé tiasa ngajalankeun sababaraha paréntah.

Nanging, ti saprak 2018, proyék éta boro-boro dikembangkeun, ku kituna kami bakal masangna dina cara biasa pikeun kalolobaan distribusi Linux - ku nambihan gudang sareng masang bungkusan anu diperyogikeun.

Metoda ieu ogé dianggo pikeun pamasangan otomatis, contona, ngagunakeun Ansible atanapi sistem anu sami, tapi kuring moal nganggap éta dina tulisan ieu.

Instalasi bakal dilaksanakeun dina Centos 7, kuring bakal ngagunakeun mesin virtual salaku server, pikeun masang, ngan ngajalankeun paréntah di handap ieu:

# 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

Saatos instalasi, anjeun kedah ngamimitian jasa, pasang dina autoload:

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

Salaku tambahan, anjeun tiasa nyiptakeun grup docker, anu pangguna tiasa damel sareng docker tanpa sudo, nyetél logging, aktipkeun aksés ka API ti luar, sareng tong hilap ngonpigurasikeun firewall langkung tepat (sagala anu henteu diidinan. dilarang dina conto di luhur sareng di handap - kuring ngaleungitkeun ieu pikeun kesederhanaan sareng kajelasan), tapi kuring moal langkung rinci di dieu.

fitur sejenna

Salian mesin docker di luhur, aya ogé pendaptaran docker, alat pikeun nyimpen gambar pikeun wadahna, kitu ogé docker compose - alat pikeun ngajadikeun otomatis panyebaran aplikasi dina peti, file YAML dianggo pikeun ngawangun sareng ngonpigurasikeun wadah sareng. hal séjén nu patali (Contona, jaringan, sistem file pengkuh pikeun nyimpen data).

Ogé bisa dipaké pikeun ngatur pipelines pikeun CICD. fitur metot séjén gawéna dina modeu klaster, nu disebut mode ngagimbung (saméméh versi 1.12 ieu dipikawanoh salaku docker ngagimbung), nu ngidinan Anjeun pikeun ngumpul infrastruktur tunggal ti sababaraha server pikeun ngajalankeun peti. Aya dukungan pikeun jaringan virtual di luhur sadaya server, aya kasaimbangan beban anu diwangun, ogé dukungan pikeun rahasia pikeun wadah.

File YAML tina docker compose tiasa dianggo pikeun klaster sapertos kitu sareng modifikasi minor, pinuh ngajadikeun otomatis pangropéa klaster leutik sareng sedeng pikeun sababaraha tujuan. Pikeun klaster badag, Kubernetes leuwih hade sabab waragad pangropéa mode swarm bisa ngaleuwihan ongkos Kubernetes. Salian runC, salaku lingkungan palaksanaan pikeun peti, Anjeun tiasa install, contona, Wadahna kata

Gawe sareng Docker

Saatos instalasi sareng konfigurasi, urang bakal nyobian ngawangun klaster dimana urang bakal nyebarkeun GitLab sareng Docker Registry pikeun tim pamekaran. Salaku server, abdi bakal ngagunakeun tilu mesin virtual, nu kuring Sajaba bakal nyebarkeun GlusterFS disebarkeun FS, Kuring bakal make eta salaku gudang jilid docker, Contona, pikeun ngajalankeun versi gagal-aman tina pendaptaran docker. Komponén konci pikeun ngajalankeun: Docker Registry, Postgresql, Redis, GitLab kalayan dukungan pikeun GitLab Runner di luhur Swarm. Postgresql bakal diluncurkeun sareng clustering Stolon, janten anjeun teu kedah nganggo GlusterFS pikeun nyimpen data Postgresql. Sesa data kritis bakal disimpen dina GlusterFS.

Pikeun nyebarkeun GlusterFS dina sadaya server (anjeunna disebut node1, node2, node3), anjeun kedah pasang bungkusan, aktipkeun firewall, jieun diréktori anu diperyogikeun:

# 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

Saatos instalasi, padamelan pikeun ngonpigurasikeun GlusterFS kedah diteruskeun tina hiji titik, contona 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

Teras anjeun kedah pasang volume anu hasilna (paréntah kedah dijalankeun dina sadaya server):

# mount /srv/docker

Mode ngagimbung dikonpigurasikeun dina salah sahiji server, anu bakal janten Pamimpin, sésana kedah ngiringan kluster, janten hasil tina ngajalankeun paréntah dina server anu munggaran kedah disalin sareng dieksekusi dina sésana.

Setélan klaster awal, kuring ngajalankeun paréntah dina 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

Salin hasil paréntah kadua, laksanakeun dina node2 sareng node3:

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

Ieu ngalengkepan konfigurasi awal server, hayu urang ngamimitian ngonpigurasikeun jasa, paréntah anu bakal dieksekusi bakal diluncurkeun tina node1, iwal mun disebutkeun.

Anu mimiti, hayu urang ngadamel jaringan pikeun wadah:

# 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

Teras urang nyirian server, ieu peryogi pikeun ngabeungkeut sababaraha jasa ka server:

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

Salajengna, urang nyieun directories pikeun nyimpen data jsb, gudang KV nu Traefik na Stolon butuh. Sarupa jeung Postgresql, ieu bakal wadahna kabeungkeut server, sangkan ngaéksekusi paréntah ieu dina sakabéh server:

# mkdir -p /srv/etcd

Salajengna, jieun file pikeun ngonpigurasikeun etcd sareng dianggo:

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

Saatos sababaraha waktos, urang pariksa yén kluster etcd naék:

# 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

Kami nyiptakeun diréktori pikeun Postgresql, ngalaksanakeun paréntah dina sadaya server:

# mkdir -p /srv/pgsql

Salajengna, jieun file pikeun ngonpigurasikeun 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

Urang ngahasilkeun Rahasia, nerapkeun file:

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

Sababaraha waktu engké (tingali kaluaran paréntah jasa docker lsyén sadaya jasa parantos naék) ngamimitian klaster 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

Mariksa kesiapan klaster 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

Urang ngonpigurasikeun traefik pikeun muka aksés ka peti ti luar:

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

Kami ngaluncurkeun Redis Cluster, pikeun ngalakukeun ieu kami nyiptakeun diréktori panyimpen dina sadaya titik:

# 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

Tambahkeun pendaptaran Docker:

06registry.yml

version: '3.7'

services:
  registry:
    image: registry:2.6
    networks:
      - traefik
    volumes:
      - registry_data:/var/lib/registry
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
      labels:
        - traefik.enable=true
        - traefik.http.routers.registry.rule=Host(`registry.example.com`)
        - traefik.http.services.registry.loadbalancer.server.port=5000
        - traefik.docker.network=traefik

volumes:
  registry_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/docker/registry"

networks:
  traefik:
    external: true

# mkdir /srv/docker/registry
# docker stack deploy --compose-file 06registry.yml registry

Sareng tungtungna - 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

Kaayaan ahir kluster sareng jasa:

# 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

Naon deui anu tiasa dironjatkeun? Pastikeun pikeun ngonpigurasikeun Traefik pikeun damel sareng wadah https, tambahkeun enkripsi tls pikeun Postgresql sareng Redis. Tapi sacara umum, éta parantos tiasa dipasihkeun ka pamekar salaku PoC. Hayu urang ayeuna ningali alternatif pikeun Docker.

podman

Mesin sejen anu cukup terkenal pikeun ngajalankeun wadah anu dikelompokeun ku pods (pods, grup wadahna disebarkeun babarengan). Beda sareng Docker, éta henteu meryogikeun jasa pikeun ngajalankeun wadah, sadaya padamelan dilakukeun ngalangkungan perpustakaan libpod. Ogé ditulis dina Go, peryogi runtime patuh OCI pikeun ngajalankeun wadah sapertos runC.

Docker sareng sadayana, sadayana, sadayana

Gawe sareng Podman sacara umum nyarupaan Docker, dugi ka anjeun tiasa ngalakukeun sapertos kieu (diklaim ku seueur anu parantos nyobian éta, kalebet panulis tulisan ieu):

$ alias docker=podman

tur anjeun bisa neruskeun gawé. Sacara umum, kaayaan sareng Podman pikaresepeun pisan, sabab upami versi awal Kubernetes damel sareng Docker, teras saprak kira-kira 2015, saatos standarisasi dunya wadahna (OCI - Open Container Initiative) sareng ngabagi Docker kana containerd sareng runC, alternatif pikeun Docker dikembangkeun pikeun ngajalankeun di Kubernetes: CRI-O. Podman dina hal ieu mangrupa alternatif pikeun Docker, diwangun dina prinsip Kubernetes, kaasup wadahna grup, tapi tujuan utama proyék éta pikeun ngajalankeun wadahna Docker-gaya tanpa jasa tambahan. Pikeun alesan atra, teu aya mode ngagimbung, saprak pamekar jelas nyebutkeun yén lamun perlu klaster, nyandak Kubernetes.

setting

Pikeun masang dina Centos 7, ngan aktipkeun gudang Extras, teras pasang sadayana nganggo paréntah:

# yum -y install podman

fitur sejenna

Podman tiasa ngahasilkeun unit pikeun systemd, sahingga ngarengsekeun masalah ngamimitian wadah saatos reboot server. Salaku tambahan, systemd dinyatakeun jalanna leres sakumaha pid 1 dina wadahna. Pikeun ngawangun wadahna, aya alat buildah anu misah, aya ogé alat pihak katilu - analog tina docker-compose, anu ogé ngahasilkeun file konfigurasi anu cocog sareng Kubernetes, ku kituna transisi tina Podman ka Kubernetes saderhana pisan.

Gawe sareng Podman

Kusabab euweuh mode ngagimbung (eta sakuduna dituju ngalih ka Kubernetes lamun klaster diperlukeun), urang bakal ngumpul dina wadah misah.

Pasang podman-compose:

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

Hasilna file config pikeun podman rada béda, sakumaha contona urang kudu mindahkeun bagian volume misah langsung ka bagian jasa.

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

Hasil pagawéan:

# 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

Hayu urang tingali naon anu bakal ngahasilkeun pikeun systemd sareng kubernetes, pikeun ieu urang kedah milarian nami atanapi id pod:

# podman pod ls
POD ID         NAME   STATUS    CREATED          # OF CONTAINERS   INFRA ID
71fc2b2a5c63   root   Running   11 minutes ago   3                 db40ab8bf84b

Kubernet:

# 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

Hanjakalna, sajaba ti ngajalankeun peti, unit dihasilkeun pikeun systemd teu nanaon sejenna (contona, meresihan wadah heubeul nalika layanan ieu restarted), jadi Anjeun kudu nambahkeun hal saperti sorangan.

Sacara prinsip, Podman cukup pikeun nyobaan naon wadahna, mindahkeun konfigurasi lami pikeun docker-compose, teras angkat ka Kubernetes, upami diperyogikeun, dina klaster, atanapi kéngingkeun alternatif anu langkung gampang dianggo pikeun Docker.

rkt

proyek indit ka arsip kira-kira genep bulan kapengker alatan kanyataan yén RedHat meuli eta, jadi kuring moal Huni on eta di leuwih jéntré. Sacara umum, éta ninggalkeun kesan anu saé pisan, tapi dibandingkeun sareng Docker, komo deui ka Podman, sigana sapertos gabungan. Aya ogé sebaran CoreOS diwangun dina luhureun rkt (sanajan maranéhna asalna Docker), tapi éta ogé réngsé sanggeus meuli RedHat.

Kilat

deui hiji proyék, panulis nu ngan hayang ngawangun tur ngajalankeun peti. Ditilik ku dokuméntasi jeung kode, panulis teu nuturkeun standar, tapi ngan mutuskeun nulis palaksanaan sorangan, nu, prinsipna mah, manéhna.

papanggihan

Kaayaan sareng Kubernetes pisan pikaresepeun: di hiji sisi, sareng Docker, anjeun tiasa ngumpul klaster (dina mode ngagimbung), dimana anjeun tiasa ngajalankeun lingkungan produksi pikeun klien, khususna pikeun tim leutik (3-5 jalma). ), atawa kalayan beban sakabéh leutik , atawa kurangna kahayang pikeun ngarti intricacies nyetel Kubernetes, kaasup pikeun beban tinggi.

Podman teu nyadiakeun kasaluyuan pinuh, tapi boga hiji kaunggulan penting - kasaluyuan jeung Kubernetes, kaasup parabot tambahan (buildah jeung sajabana). Ku alatan éta, kuring bakal kaanggo pilihan alat pikeun digawé saperti kieu: pikeun tim leutik, atawa kalayan anggaran kawates - Docker (kalawan mode ngagimbung mungkin), pikeun ngembangkeun sorangan dina localhost pribadi - comrades Podman, jeung dulur sejenna. - Kubernetes.

Kaula teu yakin yén kaayaan kalawan Docker moal robah dina mangsa nu bakal datang, barina ogé, aranjeunna panaratas, sarta ogé lalaunan ngabakukeun step by step, tapi Podman, kalawan sagala shortcomings na (mung dianggo dina Linux Ubuntu, euweuh clustering). , Majelis sareng tindakan sanésna mangrupikeun kaputusan pihak katilu) masa depan langkung jelas, janten kuring ngajak sadayana pikeun ngabahas pamanggihan ieu dina koméntar.

PS Dina 3 Agustus urang ngaluncurkeun "Kursus video Docker", dimana anjeun tiasa diajar langkung seueur ngeunaan karyana. Kami bakal nganalisis sadaya alatna: tina abstraksi dasar kana parameter jaringan, nuansa gawé bareng sababaraha sistem operasi sareng basa pamrograman. Anjeun bakal jadi wawuh jeung téhnologi jeung ngarti dimana jeung kumaha pangalusna ngagunakeun Docker. Urang ogé bakal babagi kasus prakték pangalusna.

Biaya pre-order saméméh release: 5000 rubles. Program "Kursus Video Docker" tiasa dipendakan dina kaca kursus.

sumber: www.habr.com

Tambahkeun komentar