Docker Swarm ორკესტრაციისთვის

ისწავლეთ როგორ გამოიყენოთ Docker-ის შიდა კლასტერირებისა და ორკესტრაციის შესაძლებლობები Docker Swarm-ით

Docker Swarm

Docker Swarm-ი არის Docker-ის შიდა კლასტერირებისა და ორკესტრაციის გადაწყვეტა, რომელიც Docker-ის ჰოსტების ჯგუფს ერთ ვირტუალურ ჰოსტად აქცევს, რაც უზრუნველყოფს მაღალ ხელმისაწვდომობასა და დატვირთვის დაბალანსებას კონტეინერიზებული აპლიკაციებისთვის. გარე ორკესტრატორებისგან განსხვავებით, Swarm-ი ჩაშენებულია Docker-ის ძრავაში, რაც გვთავაზობს კონტეინერების ორკესტრაციის უფრო მარტივ მიდგომას მინიმალური დაყენების დანახარჯებით, Docker CLI-ის ნაცნობი გამოცდილების შენარჩუნებით.

Swarm-ის არქიტექტურა

მართვის პანელი (Control Plane)

  • მენეჯერი კვანძები (Manager nodes): ინარჩუნებენ კლასტერის მდგომარეობას, ახდენენ სერვისების ორკესტრაციას და ამუშავებენ API მოთხოვნებს; რეკომენდებულია 3, 5, ან 7 მენეჯერი მაღალი ხელმისაწვდომობისთვის
  • განაწილებული მდგომარეობის საცავი (Raft consensus): ჩაშენებული მონაცემთა ბაზა, რომელიც ინარჩუნებს კლასტერის თანმიმდევრულ მდგომარეობას მენეჯერ კვანძებს შორის; მოითხოვს მენეჯერების უმრავლესობის (N/2+1) ხელმისაწვდომობას
  • API ენდფოინთები: აჩენს Docker API-ს კლასტერის მართვისთვის; ავტომატურად ნაწილდება დატვირთვა მენეჯერ კვანძებს შორის
  • ორკესტრაციის გადაწყვეტილებების მიღება: გეგმავს ამოცანებს, ასწორებს სასურველ მდგომარეობას, ამუშავებს კვანძების შეცდომებს და ასრულებს მოძრავ განახლებებს (rolling updates)
  • მაღალი ხელმისაწვდომობის კონფიგურაცია: მდგომარეობის რეპლიკაცია მრავალ მენეჯერ კვანძს შორის ლიდერის არჩევით შეცდომებისადმი მდგრადობისთვის

მონაცემთა პანელი (Data Plane)

  • მუშა კვანძები (Worker nodes): ასრულებენ კონტეინერიზებულ დატვირთვებს მენეჯერების მიერ მინიჭებისამებრ; შეუძლიათ ათასობით კვანძამდე მასშტაბირება
  • დავალების შესრულება: აწარმოებენ კონტეინერის ინსტანციებს ორკესტრაციის ფენის მითითებით ჯანმრთელობის მონიტორინგით
  • კონტეინერის გარემო (Container runtime): სტანდარტული Docker-ის ძრავა, რომელიც მუშაობს თითოეულ კვანძზე კონტეინერის თანმიმდევრული შესრულებისთვის
  • ქსელის ოვერლეი (Network overlay): მრავალ-ჰოსტიანი ქსელი ავტომატური სერვისების აღმოჩენითა და დატვირთვის დაბალანსებით
  • დატვირთვის განაწილება: ანაწილებს სერვისებს კვანძებს შორის განთავსების შეზღუდვების, რესურსების ხელმისაწვდომობისა და მაღალი ხელმისაწვდომობის მოთხოვნების საფუძველზე

Swarm კლასტერის დაყენება

# ახალი swarm-ის ინიციალიზაცია (მენეჯერ კვანძზე)
docker swarm init --advertise-addr <MANAGER-IP>
# --advertise-addr მიუთითებს მისამართს, რომელსაც სხვა კვანძები გამოიყენებენ ამ მენეჯერთან დასაკავშირებლად
# თუ გამოტოვებულია, Docker-ი შეეცდება IP-ის ავტომატურად აღმოჩენას, რაც შეიძლება არასწორი იყოს მრავალ-ინტერფეისიან სერვერებზე

# გამოტანილი შედეგი მოგცემთ ტოკენს მუშა კვანძების დასამატებლად
# მაგალითი:
# docker swarm join --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c <MANAGER-IP>:2377
# ეს ტოკენი ახდენს ახალი კვანძების ავთენტიფიკაციას swarm-ში, რაც უზრუნველყოფს კლასტერის უსაფრთხო გაფართოებას

# კვანძის დამატება როგორც მუშა
docker swarm join --token <TOKEN> <MANAGER-IP>:2377
# მუშა კვანძები იღებენ და ასრულებენ დავალებებს, მაგრამ არ შეუძლიათ კლასტერის მდგომარეობის მართვა
# პორტი 2377 არის swarm-ის მართვის სტანდარტული პორტი

# კვანძის დამატება როგორც მენეჯერი
docker swarm join-token manager
# ეს ბრძანება აგენერირებს სხვა ტოკენს სპეციალურად მენეჯერი კვანძებისთვის
# შემდეგ გამოიყენეთ მოწოდებული ტოკენი მენეჯერად დასამატებლად
docker swarm join --token <MANAGER-TOKEN> <MANAGER-IP>:2377
# მენეჯერი კვანძები მონაწილეობენ Raft კონსენსუსში და შეუძლიათ კლასტერის მართვა

# კვანძების სია swarm-ში
docker node ls
# აჩვენებს ყველა კვანძს მათი როლებით, ხელმისაწვდომობის სტატუსით და მენეჯერის სტატუსით
# MANAGER STATUS სვეტი აჩვენებს "Leader"-ს მთავარი მენეჯერი კვანძისთვის

სერვისები და დავალებები

სერვისების შექმნა და მართვა

# რეპლიცირებული სერვისის შექმნა
docker service create --name webserver \
  --replicas 3 \
                        # კონტეინერის 3 ინსტანციის გაშვება
  --publish 80:80 \
                      # პორტ 80-ის გამოქვეყნება ყველა swarm კვანძზე
  --update-delay 10s \
                  # თითოეული კონტეინერის განახლებას შორის 10 წამის დაყოვნება
  --update-parallelism 1 \
              # ერთ ჯერზე ერთი კონტეინერის განახლება
  --restart-condition on-failure \
      # ავტომატურად გადატვირთეთ კონტეინერები, რომლებიც არა-ნულოვანი კოდით გამოდიან
  nginx:latest                          # გამოსაყენებელი კონტეინერის იმიჯი

# სერვისების სია
docker service ls
# აჩვენებს ყველა სერვისს მათი ID-ით, სახელით, რეჟიმით (replicated/global), რეპლიკებით, იმიჯით და პორტებით

# სერვისის შემოწმება
docker service inspect webserver
# აბრუნებს სერვისის კონფიგურაციის დეტალურ JSON-ს, მათ შორის:
# - კონტეინერის კონფიგურაცია
# - რესურსების შეზღუდვები
# - ქსელები
# - განახლებისა და დაბრუნების (rollback) კონფიგურაცია
# - განთავსების შეზღუდვები

# სერვისის დავალებების (კონტეინერების) ნახვა
docker service ps webserver
# აჩვენებს სერვისის ყველა დავალებას (კონტეინერს) მათი:
# - ID-ით, სახელით, იმიჯით
# - კვანძზე მინიჭებით
# - სასურველი და მიმდინარე მდგომარეობით
# - შეცდომის შეტყობინებებით (თუ არსებობს)
# - როდის შეიქმნა და განახლდა დავალება

# სერვისის მასშტაბირება
docker service scale webserver=5
# ზრდის ან ამცირებს რეპლიკების რაოდენობას
# Swarm-ი შექმნის ან წაშლის კონტეინერებს სასურველი რაოდენობის შესაბამისად
# გამოიყენეთ მძიმით გამოყოფილი სია მრავალი სერვისის მასშტაბირებისთვის: webserver=5,api=3

# სერვისის განახლება
docker service update --image nginx:1.21 \
  --limit-cpu 0.5 \
                        # CPU ლიმიტების დამატება
  --limit-memory 512M \
                      # მეხსიერების ლიმიტების დამატება
  --rollback-parallelism 2 \
                # დაბრუნების ქცევის კონფიგურაცია
  webserver

# სერვისის წაშლა
docker service rm webserver
# შლის სერვისს და აჩერებს ყველა დაკავშირებულ კონტეინერს

Swarm ქსელი

ოვერლეი ქსელები (Overlay Networks)

# ოვერლეი ქსელის შექმნა
docker network create --driver overlay \
                      # მრავალ-ჰოსტიანი ქსელის დრაივერი
  --attachable \
                           # დამოუკიდებელ კონტეინერებს დაკავშირების საშუალება
  --subnet 10.0.9.0/24 \
                       # მორგებული ქვექსელის განსაზღვრა (არასავალდებულო)
  --gateway 10.0.9.1 \
                       # მორგებული გეითვეის განსაზღვრა (არასავალდებულო)
  --opt encrypted \
                          # ტრაფიკის დაშიფვრის ჩართვა (არასავალდებულო)
  backend-network                            # ქსელის სახელი

# სერვისის შექმნა ქსელთან ერთად
docker service create --name api \
  --network backend-network \
                 # ოვერლეი ქსელთან მიერთება
  --replicas 3 \
                              # 3 ინსტანციის გაშვება
  --endpoint-mode dnsrr \
                     # DNS round-robin რეჟიმი (VIP-ის ალტერნატივა)
  myapi:latest

ოვერლეი ქსელები უზრუნველყოფენ:

  • ჰოსტებს შორის კომუნიკაციას კონტეინერებს შორის
  • იზოლირებულ ქსელის სეგმენტებს მრავალ-დონიანი აპლიკაციებისთვის
  • შიდა DNS რეზოლუციას სერვისების აღმოსაჩენად
  • არასავალდებულო დაშიფვრას მგრძნობიარე ტრაფიკისთვის

შემომავალი ქსელი (Ingress Network)

  • ჩაშენებული დატვირთვის დაბალანსება: გამჭვირვალე დატვირთვის დაბალანსება გამოქვეყნებული პორტებისთვის Linux IPVS-ის გამოყენებით
  • მარშრუტიზაციის ბადე (Routing mesh) სერვისის პორტებისთვის: სერვისების გამოჩენა ყველა კვანძზე, მიუხედავად იმისა, მუშაობს თუ არა ამ კვანძზე ამ სერვისის ინსტანცია
  • მოთხოვნების განაწილება კვანძებს შორის: შემომავალი მოთხოვნების გადამისამართება ნებისმიერი კვანძიდან აქტიურ კონტეინერზე, თუნდაც ის სხვა კვანძზე მუშაობდეს
  • სერვისების ავტომატური აღმოჩენა: სერვისებს შეუძლიათ კომუნიკაცია სახელის მიხედვით ხელით დაკავშირების ან IP კონფიგურაციის გარეშე
  • კონტეინერებს შორის კომუნიკაცია: კონტეინერებს შეუძლიათ უსაფრთხოდ კომუნიკაცია ჰოსტებს შორის იმავე ოვერლეი ქსელში

შემომავალი ქსელი იყენებს მდგომარეობის არმქონე (stateless) დატვირთვის დაბალანსების მექანიზმს:

[გარე კლიენტი] → [ნებისმიერი Swarm კვანძის პორტი 80] → [მარშრუტიზაციის ბადე] → [სერვისის გამშვები კონტეინერი]

მარშრუტიზაციაზე მეტი კონტროლისთვის:

# სერვისის შექმნა კონკრეტული გამოქვეყნების რეჟიმით
docker service create --name web \
  --publish mode=host,target=80,published=8080 \
  nginx
# 'host' რეჟიმი გვერდს უვლის მარშრუტიზაციის ბადეს, მაგრამ მოითხოვს პორტების ხელით მინიჭებას თითოეულ კვანძზე

სერვისების აღმოჩენა

Docker Swarm-ი უზრუნველყოფს ჩაშენებულ სერვისების აღმოჩენას, რაც კონტეინერებს საშუალებას აძლევს იპოვონ და დაუკავშირდნენ ერთმანეთს სერვისის სახელების გამოყენებით:

# სერვისების აღმოჩენის მაგალითი
docker service create --name db \
  --network backend-network \
                # ოვერლეი ქსელში გაწევრიანება
  --mount type=volume,source=db-data,target=/var/lib/postgresql/data \
               # მუდმივი საცავი
  --env POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
               # საიდუმლოებების გამოყენება უსაფრთხოებისთვის
  --replicas 1 \
                             # მონაცემთა ბაზა ჩვეულებრივ ერთ ინსტანციას აწარმოებს
  postgres:13                               # მონაცემთა ბაზის იმიჯი

docker service create --name api \
  --network backend-network \
                # იგივე ქსელი, რაც db სერვისს
  --env DB_HOST=db \
                        # მონაცემთა ბაზაზე მითითება სერვისის სახელით
  --env DB_PORT=5432 \
                      # სტანდარტული PostgreSQL პორტი
  --replicas 3 \
                            # მრავალი API ინსტანციის გაშვება
  --update-order start-first \
              # განახლებისას ახალი დავალებების დაწყება ძველების შეჩერებამდე
  myapi:latest                              # API იმიჯი

სერვისების აღმოჩენა მუშაობს:

  1. შიდა DNS სერვერის საშუალებით: Swarm-ის ყველა კონტეინერს შეუძლია ჩაშენებულ DNS სერვერთან დაკავშირება
  2. სერვისის VIP-ების (ვირტუალური IP-ები) საშუალებით: თითოეული სერვისი იღებს ვირტუალურ IP-ს ოვერლეი ქსელში
  3. DNS round-robin-ის საშუალებით: კონტეინერებს შეუძლიათ სერვისის სახელების გადაჭრა ყველა დავალების IP-ზე DNS-ის გამოყენებით

კავშირის მაგალითი კონტეინერის შიგნიდან:

# მონაცემთა ბაზასთან დაკავშირება api კონტეინერის შიგნიდან
docker exec -it $(docker ps -q -f name=api) bash
ping db       # გადაიჭრება სერვისის VIP-ად
psql -h db -U postgres -d myapp  # მონაცემთა ბაზასთან დაკავშირება სერვისის სახელით

მრავალი რეპლიკის მქონე სერვისებისთვის, კავშირები ავტომატურად ნაწილდება:

# ფრონტენდ სერვისის შექმნა, რომელიც უკავშირდება API-ს
docker service create --name frontend \
  --network backend-network \
  --env API_URL=http://api:8000/ \
  # API სერვისის სახელი ავტომატურად გადაიჭრება და დატვირთვა დაბალანსდება
  --publish 80:80 \
  frontend:latest

Swarm-ის გაშვება სტეკებით (Stacks)

Docker Compose Swarm-ისთვის

# docker-compose.yml Swarm-ის გაშვებისთვის
version: '3.8'  # Compose ფაილის ფორმატის ვერსია swarm-ის მხარდაჭერით

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"  # გამოქვეყნებული პორტი (ხელმისაწვდომია გარედან)
    deploy:
      mode: replicated       # 'replicated' (მასშტაბირებული) ან 'global' (ერთი თითო კვანძზე)
      replicas: 3            # კონტეინერის ინსტანციების რაოდენობა
      update_config:
        parallelism: 1       # ერთ ჯერზე ერთი კონტეინერის განახლება
        delay: 10s           # განახლებებს შორის 10 წამის დაყოვნება
        order: start-first   # ახალი დავალებების დაწყება ძველების შეჩერებამდე
        failure_action: rollback  # ავტომატური დაბრუნება შეცდომისას
      restart_policy:
        condition: on-failure    # გადატვირთვა, თუ კონტეინერი არა-ნულოვანი კოდით გამოვა
        max_attempts: 3          # გადატვირთვის მაქსიმალური მცდელობა
        window: 120s             # დროის ფანჯარა გადატვირთვის მცდელობების შესაფასებლად
      placement:
        constraints:
          - node.role == worker  # მხოლოდ მუშა კვანძებზე გაშვება
        preferences:
          - spread: node.labels.datacenter  # მონაცემთა ცენტრებში განაწილება
      resources:
        limits:
          cpus: '0.5'       # CPU-ს მაქსიმალური გამოყენება
          memory: 512M      # მეხსიერების მაქსიმალური გამოყენება
        reservations:
          cpus: '0.1'       # გარანტირებული CPU-ს გამოყოფა
          memory: 128M      # გარანტირებული მეხსიერების გამოყოფა
  
  api:
    image: myapi:latest
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.labels.zone == frontend  # მხოლოდ ამ ლეიბლის მქონე კვანძებზე გაშვება
        max_replicas_per_node: 1          # ინსტანციების შეზღუდვა თითო კვანძზე HA-სთვის
      update_config:
        parallelism: 2                    # ერთდროულად ორი კონტეინერის განახლება
      rollback_config:
        parallelism: 3                    # საჭიროების შემთხვევაში უფრო სწრაფი დაბრუნება
    environment:
      - DB_HOST=db                     # სერვისის აღმოჩენა სახელით
      - API_KEY_FILE=/run/secrets/api_key  # საიდუმლოზე მითითება
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s                # საწყისი საშეღავათო პერიოდი
    networks:
      - backend                        # backend ქსელთან დაკავშირება
    secrets:
      - api_key                        # ქვემოთ განსაზღვრულ საიდუმლოზე მითითება
  
  db:
    image: postgres:13
    volumes:
      - db-data:/var/lib/postgresql/data  # მუდმივი საცავი
    deploy:
      placement:
        constraints:
          - node.labels.zone == database  # მხოლოდ მონაცემთა ბაზის კვანძებზე გაშვება
      replicas: 1                         # ერთი მონაცემთა ბაზის ინსტანცია
      restart_policy:
        condition: any                    # ყოველთვის გადატვირთვა
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    networks:
      - backend
    secrets:
      - db_password

networks:
  backend:
    driver: overlay               # მრავალ-ჰოსტიანი ქსელი
    attachable: true              # დამოუკიდებელ კონტეინერებს დაკავშირების საშუალება
    driver_opts:
      encrypted: "true"           # ამ ქსელზე ტრაფიკის დაშიფვრა

volumes:
  db-data:
    driver: local                 # ლოკალური საცავის გამოყენება (ნაგულისხმევი)
    # პროდაქშენისთვის, განიხილეთ დისკის დრაივერის გამოყენება, რომელსაც რეპლიკაციის მხარდაჭერა აქვს

secrets:
  api_key:
    file: ./secrets/api_key.txt   # ლოკალური ფაილიდან ჩატვირთვა გაშვებისას
  db_password:
    file: ./secrets/db_password.txt

მაღალი ხელმისაწვდომობა და შეცდომებისადმი მდგრადობა

მენეჯერის მაღალი ხელმისაწვდომობა

  • მრავალი მენეჯერი კვანძის გაშვება (რეკომენდებულია 3, 5, ან 7):
    • 3 მენეჯერი უძლებს 1 შეცდომას
    • 5 მენეჯერი უძლებს 2 შეცდომას
    • 7 მენეჯერი უძლებს 3 შეცდომას
    • 7-ზე მეტი ამცირებს წარმადობას შეცდომებისადმი მდგრადობის გაუმჯობესების გარეშე
  • კვორუმის შენარჩუნება კონსენსუსისთვის:
    • მოითხოვს მენეჯერების უმრავლესობის (N/2+1) ოპერატიულობას
    • კვორუმის დაკარგვა ხელს უშლის კლასტერის მდგომარეობის ცვლილებებს
    • კრიტიკული ოპერაციები მოითხოვს კონსენსუსს:
      • სერვისის შექმნა/განახლება
      • კვანძების დამატება/წაშლა
      • საიდუმლოებების მართვა
  • მენეჯერების განაწილება შეცდომის დომენებში:
    • განათავსეთ სხვადასხვა ფიზიკურ ჰოსტებზე
    • გაანაწილეთ ხელმისაწვდომობის ზონებში
    • გამოიყენეთ სხვადასხვა ქსელის სეგმენტები
    • გაითვალისწინეთ ენერგიისა და გაგრილების სიჭარბე
  • ლიდერის ავტომატური არჩევა:
    • Raft პროტოკოლი ირჩევს ლიდერ მენეჯერს
    • ამუშავებს შეცდომის გადაცემას ხელით ჩარევის გარეშე
    • ჩვეულებრივ სრულდება წამებში
    • მხოლოდ ერთი ლიდერი აქტიურად იღებს ორკესტრაციის გადაწყვეტილებებს
  • მდგომარეობის რეპლიკაცია მენეჯერებს შორის:
    • Raft კონსენსუსი უზრუნველყოფს თანმიმდევრულ მდგომარეობას
    • თითოეული მენეჯერი ინახავს კლასტერის მდგომარეობის სრულ ასლს
    • ცვლილებები ვრცელდება ყველა მენეჯერზე
    • მუდმივი მდგომარეობა ინახება /var/lib/docker/swarm/-ში

მუშა კვანძის შეცდომებისადმი მდგრადობა

  • დავალებების ავტომატური გადაგეგმვა:
    • დაზიანებული კვანძებიდან დავალებები (კონტეინერები) ავტომატურად გადაიგეგმება
    • ახალი დავალებები ინარჩუნებენ სერვისის კონფიგურაციებსა და შეზღუდვებს
    • სისტემა ცდილობს დატვირთვის თანაბრად განაწილებას
    • ითვალისწინებს განთავსების შეზღუდვებს გადაგეგმვისას
  • ჯანმრთელობის შემოწმებები:
    • კონტეინერის ჯანმრთელობის შემოწმებები აკონტროლებენ აპლიკაციის ჯანმრთელობას
    • კვანძის ჯანმრთელობის მონიტორინგი აღმოაჩენს ინფრასტრუქტურის შეცდომებს
    • არაჯანსაღი კონტეინერების პროაქტიული ჩანაცვლება
    • მორგებადი ჯანმრთელობის შემოწმების პარამეტრები:
      healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost/health"]
        interval: 30s
        timeout: 10s
        retries: 3
      
  • სერვისის ხელახლა შექმნა:
    • დაზიანებული სერვისები ავტომატურად ხელახლა იქმნება
    • ინარჩუნებს სასურველი რეპლიკების რაოდენობას
    • ინარჩუნებს სერვისის კონფიგურაციას
    • ცდილობს გადატვირთვას ექსპონენციალური უკან დახევით
  • მოძრავი განახლებები (Rolling updates):
    • განაახლეთ სერვისები შეფერხების გარეშე
    • აკონტროლეთ პარალელიზმი და დაყოვნება განახლებებს შორის
    • აკონტროლეთ ჯანმრთელობა განახლებების დროს
    • ავტომატური დაბრუნება შეცდომისას (როდესაც კონფიგურირებულია)
  • გადატვირთვის პოლიტიკები:
    • always: ყოველთვის გადატვირთეთ კონტეინერები
    • on-failure: გადატვირთეთ მხოლოდ არა-ნულოვანი გასვლის კოდებზე
    • unless-stopped: გადატვირთეთ, თუ აშკარად არ არის შეჩერებული
    • none: არასოდეს ავტომატურად არ გადატვირთოთ
    • კონფიგურირებადი მაქსიმალური მცდელობები და გადატვირთვის ფანჯარა

Swarm-ის საიდუმლოებების მართვა

# საიდუმლოს შექმნა
echo "mypassword" | docker secret create db_password -
# საიდუმლოებები ინახება დაშიფრული სახით Raft ლოგში
# ისინი არასოდეს იწერება დისკზე დაშიფვრის გარეშე
# `-` ბოლოს მიუთითებს stdin-დან შეყვანას

# სერვისის შექმნა საიდუმლოთი
docker service create --name db \
  --secret db_password \
                           # შექმნილ საიდუმლოზე მითითება
  --env POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
                           # აპლიკაციისთვის მითითება, სად იპოვოს იგი
  --secret source=ssl_cert,target=server.crt \
                           # საიდუმლოსთვის მორგებული სამიზნე გზა
  --secret source=ssl_key,target=server.key,mode=0400 \
                           # მორგებული ფაილის უფლებები
  postgres:13

# კონტეინერის შიგნით, საიდუმლოებები ჩანს როგორც ფაილები /run/secrets/-ში
# მაგალითი:
# /run/secrets/db_password
# /run/secrets/server.crt
# /run/secrets/server.key

# საიდუმლოებების სია
docker secret ls
# აჩვენებს ყველა საიდუმლოს შექმნის დროითა და ID-ით

# საიდუმლოს შემოწმება (აჩვენებს მხოლოდ მეტამონაცემებს, არა რეალურ შინაარსს)
docker secret inspect db_password

# საიდუმლოს წაშლა
docker secret rm db_password
# შენიშვნა: არ შეიძლება გაშვებული სერვისების მიერ გამოყენებული საიდუმლოებების წაშლა
# ჯერ უნდა განაახლოთ ან წაშალოთ სერვისები

# საიდუმლოს შექმნა ფაილიდან
docker secret create ssl_cert ./server.crt

Swarm-ის კონფიგურაციები (Configs)

რესურსების შეზღუდვები

# სერვისის შექმნა რესურსების შეზღუდვებით
docker service create --name resource-limited \
  --limit-cpu 0.5 \
                    # CPU-ს მაქსიმალური გამოყენება (ერთი ბირთვის 50%)
  --limit-memory 512M \
                    # მეხსიერების მაქსიმალური გამოყენება (512MB)
  --reserve-cpu 0.2 \
                    # გარანტირებული CPU (ერთი ბირთვის 20%)
  --reserve-memory 256M \
                    # გარანტირებული მეხსიერება (256MB)
  --reserve-memory-swap 512M \
                   # მეხსიერების+swap-ის მთლიანი რეზერვაცია
  --generic-resource "gpu=1" \
                   # 1 GPU-ს მოთხოვნა (მოითხოვს კვანძის ლეიბლებს)
  --ulimit nofile=65536:65536 \
                  # ფაილის დესკრიპტორების ლიმიტების დაყენება
  --ulimit nproc=4096:4096 \
                   # პროცესების ლიმიტები
  nginx:latest

# რესურსების შეზღუდვები უზრუნველყოფენ:
# 1. რესურსების სამართლიან განაწილებას სერვისებს შორის
# 2. დაცვას ხმაურიანი მეზობლებისგან
# 3. პროგნოზირებად წარმადობას
# 4. კონტეინერების ეფექტურ შეფუთვას

# გრაფიკის შემდგენელი იყენებს რეზერვაციებს განთავსების გადაწყვეტილებების მისაღებად
# ლიმიტები აწესებენ რესურსების მაქსიმალურ გამოყენებას
# კვანძს უნდა ჰქონდეს რეზერვაციის შესაბამისი ხელმისაწვდომი რესურსები

მოძრავი განახლებები და დაბრუნებები

მოძრავი განახლებები

# განახლება მოძრავი განახლების სტრატეგიით
docker service update \
  --image nginx:1.21 \
                      # გასაშვები ახალი იმიჯი
  --update-parallelism 2 \
                  # ერთდროულად 2 დავალების განახლება
  --update-delay 20s \
                      # თითოეული ჯგუფის განახლებას შორის 20 წამის დაყოვნება
  --update-order start-first \
                  # ახალი დავალებების დაწყება ძველების შეჩერებამდე
  --update-failure-action pause \
                  # განახლებების შეჩერება, თუ დავალება ვერ შესრულდა
  --update-monitor 30s \
                    # ახალი დავალებების მონიტორინგი 30 წამის განმავლობაში გაგრძელებამდე
  --update-max-failure-ratio 0.2 \
                  # დავალებების 20%-ის შეცდომის დაშვება შეჩერებამდე
  --health-cmd "curl -f http://localhost/ || exit 1" \
                  # ჯანმრთელობის შემოწმების ბრძანება
  --health-interval 5s \
                    # ჯანმრთელობის შემოწმება ყოველ 5 წამში განახლებისას
  --health-retries 3 \
                      # ჯანმრთელობის შემოწმების მცდელობების რაოდენობა
  webserver

# მოძრავი განახლების პროცესი:
# 1. 2 ახალი კონტეინერის დაწყება განახლებული იმიჯით
# 2. დაელოდეთ, სანამ ისინი ჯანმრთელები გახდებიან (30 წამის მონიტორინგის პერიოდი)
# 3. თუ ჯანმრთელები არიან, შეაჩერეთ 2 ძველი კონტეინერი
# 4. დაელოდეთ 20 წამს (update-delay)
# 5. გაიმეორეთ, სანამ ყველა კონტეინერი არ განახლდება

დაბრუნებები (Rollbacks)

# წინა ვერსიაზე დაბრუნება
docker service update --rollback webserver
# ეს აბრუნებს კონფიგურაციას ბოლო განახლებამდე

# დაბრუნების ქცევის კონფიგურაცია
docker service update \
  --rollback-parallelism 3 \
                # ერთდროულად 3 დავალების დაბრუნება
  --rollback-delay 10s \
                    # ჯგუფებს შორის 10 წამის დაყოვნება
  --rollback-failure-action continue \
                  # დაბრუნების გაგრძელება, თუნდაც დავალებები ვერ შესრულდეს
  --rollback-order stop-first \
                  # ძველი დავალებების შეჩერება ახლების დაწყებამდე
  --rollback-monitor 10s \
                    # ახალი დავალებების მონიტორინგი 10 წამის განმავლობაში გაგრძელებამდე
  webserver

# განახლების/დაბრუნების სტატუსის შემოწმება
docker service inspect --pretty webserver
# აჩვენებს მიმდინარე განახლების სტატუსს, პროგრესს და კონფიგურაციას

# განახლების ისტორიის ნახვა
docker service ps --no-trunc webserver
# აჩვენებს დავალებების ყველა წინა ვერსიას მათი იმიჯებით

მოძრავი განახლებები და დაბრუნებები საშუალებას გაძლევთ:

  1. გაუშვათ ახალი ვერსიები შეფერხების გარეშე
  2. შეამოწმოთ განახლებები კანარის გაშვებით (ნაწილობრივი განახლებები)
  3. სწრაფად დააბრუნოთ პრობლემური ცვლილებები
  4. შეინარჩუნოთ კონტროლი განახლების პროცესსა და დროზე
  5. დანერგოთ ლურჯი-მწვანე გაშვების შაბლონები

კვანძების მართვა

# კვანძების სია
docker node ls
# გამოტანილი შედეგი აჩვენებს:
# - NODE ID: თითოეული კვანძის უნიკალური იდენტიფიკატორი
# - HOSTNAME: კვანძის ჰოსტის სახელი
# - STATUS: Ready, Down, ან Disconnected
# - AVAILABILITY: Active, Pause, ან Drain
# - MANAGER STATUS: Leader, Reachable, ან Unreachable (მენეჯერი კვანძებისთვის)
# - ENGINE VERSION: Docker-ის ძრავის ვერსია

# კვანძის შემოწმება
docker node inspect node-1
# აბრუნებს დეტალურ ინფორმაციას კვანძის შესახებ:
# - ლეიბლები და კვანძის ატრიბუტები
# - რესურსების ხელმისაწვდომობა
# - პლატფორმა და არქიტექტურა
# - ქსელის მისამართები
# - შეერთების ტოკენები და სერთიფიკატები
# - სტატუსი და ჯანმრთელობა

# შემოწმების შედეგის ფორმატირება კონკრეტული ინფორმაციისთვის
docker node inspect -f '{{.Status.Addr}}' node-1
# აბრუნებს მხოლოდ კვანძის IP მისამართს

# კვანძის ხელმისაწვდომობის დაყენება
docker node update --availability drain node-1  # მომზადება ტექნიკური სამუშაოებისთვის
# Drain: აჩერებს ახალი დავალებების დაგეგმვას და შლის არსებულ დავალებებს კვანძიდან
# არსებული დავალებები შეუფერხებლად გადაიგეგმება სხვა კვანძებზე
# იდეალურია ტექნიკური სამუშაოებისა და განახლებებისთვის

docker node update --availability active node-1 # სერვისში დაბრუნება
# Active: კვანძი იღებს ახალ დავალებებს და ინარჩუნებს არსებულებს
# Pause: კვანძი ინარჩუნებს არსებულ დავალებებს, მაგრამ არ მიიღებს ახლებს

# კვანძებზე ლეიბლების დამატება
docker node update --label-add zone=frontend node-1
docker node update --label-add datacenter=east --label-add cpu=high-performance node-1
# ლეიბლები საშუალებას იძლევა რთული დაგეგმვის სტრატეგიების:
# - გეოგრაფიული განაწილება
# - აპარატურის დიფერენციაცია
# - გარემოს გამოყოფა (prod/staging)
# - სპეციალიზებული დატვირთვის მიზნობრიობა

# კვანძების ფილტრაცია ლეიბლებით
docker node ls --filter node.label=zone=frontend

# მუშა კვანძის მენეჯერად დაწინაურება
docker node promote node-2
# მუშა კვანძს გარდაქმნის მენეჯერის როლში
# უერთდება Raft კონსენსუსის ჯგუფს
# იღებს კლასტერის მდგომარეობის ასლს
# ახლა შეუძლია მართვის ბრძანებების მიღება

# მენეჯერის მუშა კვანძად დაქვეითება
docker node demote node-2
# შლის კვანძს მართვის პანელიდან
# თუ ეს დაარღვევს კვორუმს, ოპერაცია ვერ შესრულდება
# საუკეთესო პრაქტიკა: დააქვეითეთ მენეჯერი კვანძების წაშლამდე

# კვანძის წაშლა swarm-იდან
# ჯერ, წასაშლელ კვანძზე:
docker swarm leave
# შემდეგ მენეჯერ კვანძზე:
docker node rm node-3

Swarm-ის მონიტორინგი

Swarm vs. Kubernetes

Swarm-ის უპირატესობები

  • უფრო მარტივი შესწავლის მრუდი: უფრო ადვილი შესასწავლი და გასაშვები მინიმალური ახალი კონცეფციებით
  • შიდა Docker-ის ინტეგრაცია: ჩაშენებულია Docker-ის ძრავაში დამატებითი კომპონენტების გარეშე
  • მსუბუქი იმპლემენტაცია: ნაკლები რესურსების დანახარჯი და უფრო მარტივი არქიტექტურა
  • თანმიმდევრული Docker CLI გამოცდილება: იყენებს ნაცნობ Docker-ის ბრძანებებსა და სინტაქსს
  • უფრო სწრაფი გაშვება მცირე კლასტერებისთვის: უფრო სწრაფი დაყენების დრო მცირე და საშუალო ზომის გაშვებებისთვის
  • ნაკლები ოპერაციული სირთულე: ნაკლები მოძრავი ნაწილები და კონფიგურაციის ოპციები
  • შეუფერხებელი Docker Compose ინტეგრაცია: Compose ფაილების პირდაპირი გაშვება stack deploy-ით
  • ინტეგრირებული საიდუმლოებების მართვა: მგრძნობიარე მონაცემების ჩაშენებული დამუშავება

Kubernetes-ის უპირატესობები

  • უფრო ვრცელი ეკოსისტემა: უფრო დიდი საზოგადოება მეტი ინსტრუმენტებით, გაფართოებებითა და ინტეგრაციებით
  • გაფართოებული დაგეგმვის შესაძლებლობები: უფრო რთული პოდების განთავსებისა და აფინურობის წესები
  • უფრო ფართო ინდუსტრიული მიღება: უფრო ფართო გამოყენება პროდაქშენ გარემოში სხვადასხვა ინდუსტრიაში
  • უფრო გაფართოებადი არქიტექტურა: მორგებული რესურსების განმარტებები და ოპერატორები ფუნქციონალის გასაფართოებლად
  • უფრო დიდი მასშტაბირება დიდი გაშვებებისთვის: უკეთესი წარმადობა ძალიან დიდ მასშტაბზე (1000+ კვანძი)
  • უფრო დეტალური კონტროლი: ქსელის, უსაფრთხოებისა და რესურსების დეტალური კონფიგურაცია
  • დეკლარაციული კონფიგურაცია: უფრო ძლიერი აქცენტი GitOps-სა და ინფრასტრუქტურა-როგორც-კოდის შაბლონებზე
  • მტკიცე თვით-აღდგენა: უფრო მოწინავე ჯანმრთელობის შემოწმება და ავტომატური აღდგენის მექანიზმები
  • სტანდარტიზებული მიდგომა: ხდება ინდუსტრიის სტანდარტი კონტეინერების ორკესტრაციისთვის

სარეზერვო ასლის შექმნა და აღდგენა

# swarm-ის მდგომარეობის სარეზერვო ასლის შექმნა (მენეჯერ კვანძზე)
# ჯერ, შექმენით სრული სარეზერვო ასლი
tar -czvf swarm-backup.tar.gz /var/lib/docker/swarm
# ეს მოიცავს:
# - Raft ლოგებსა და კონსენსუსის მონაცემებს
# - TLS სერთიფიკატებსა და გასაღებებს
# - საიდუმლო მონაცემებს (დაშიფრული)
# - კვანძის ინფორმაციასა და შეერთების ტოკენებს

# უფრო სრულყოფილი სარეზერვო ასლისთვის, ჩართეთ:
docker service ls > services.txt
docker service inspect $(docker service ls -q) > service-details.json
docker secret ls > secrets.txt
docker config ls > configs.txt
docker network ls --filter driver=overlay > networks.txt

# swarm-ის აღდგენა
# 1. შეაჩერეთ Docker-ი მენეჯერზე
systemctl stop docker

# 2. აღადგინეთ სარეზერვო ასლი
tar -xzvf swarm-backup.tar.gz -C /
# სარეზერვო ასლი უნდა აღდგეს იმავე გზის სტრუქტურაზე

# 3. გაუშვით Docker-ი
systemctl start docker
# Docker-ი ინიციალიზაციას მოახდენს აღდგენილი swarm-ის მდგომარეობის გამოყენებით
# კვანძი განაახლებს თავის როლს (ლიდერი ან მიმდევარი)

# 4. შეამოწმეთ აღდგენა
docker node ls
docker service ls

# ალტერნატიული სარეზერვო ასლის მიდგომა მენეჯერის UCP-ის გამოყენებით
# შეინახეთ UCP სარეზერვო ფაილი, რომელიც მოიცავს swarm-ის კონფიგურაციას
docker container run --log-driver none --rm -i --name ucp \
  -v /var/run/docker.sock:/var/run/docker.sock \
  docker/ucp:latest backup --id $(docker container ls -q --filter name=ucp-controller) \
  --passphrase "secret" > ucp-backup.tar.gz

სრული კატასტროფის აღდგენის გეგმისთვის:

  1. swarm-ის მდგომარეობის რეგულარული ავტომატური სარეზერვო ასლები
  2. ყველა მორგებული კონფიგურაციის დოკუმენტაცია
  3. სკრიპტები სერვისების ხელახლა შესაქმნელად, თუ სარეზერვო ასლი მიუწვდომელია
  4. აღდგენის პროცედურების ტესტირება საცდელ გარემოში
  5. მდგომარეობის მქონე სერვისებისა და მათი მონაცემების გათვალისწინება

საუკეთესო პრაქტიკები

პრობლემების მოგვარება

ხშირი პრობლემები

  • მენეჯერი კვანძის ხელმისაწვდომობა
    • სიმპტომები: სერვისების შექმნის/განახლების შეუძლებლობა, კვორუმის დაკარგვა
    • მიზეზები: ქსელის პრობლემები, აპარატურის შეცდომა, არასწორი მასშტაბირება
    • გადაწყვეტა: აღადგინეთ მენეჯერი კვანძები, უზრუნველყავით სათანადო განაწილება
    # შეამოწმეთ მენეჯერის სტატუსი
    docker node ls
    # მოძებნეთ "Leader", "Reachable", ან "Unreachable" MANAGER STATUS სვეტში
    
  • ქსელური კავშირის პრობლემები
    • სიმპტომები: სერვისები ვერ უკავშირდებიან, DNS რეზოლუციის შეცდომები
    • მიზეზები: ფაირვოლის წესები, ოვერლეი ქსელის პრობლემები, DNS კონფიგურაცია
    • გადაწყვეტა: შეამოწმეთ ფაირვოლი, შეამოწმეთ ქსელის კონფიგურაცია
    # შეამოწმეთ ოვერლეი ქსელის კონფიგურაცია
    docker network inspect service_network
    
    # შეამოწმეთ, არის თუ არა საჭირო პორტები ღია კვანძებს შორის
    # TCP პორტი 2377 - კლასტერის მართვა
    # TCP/UDP პორტი 7946 - კვანძებს შორის კომუნიკაცია
    # UDP პორტი 4789 - ოვერლეი ქსელის ტრაფიკი
    nc -zv manager-node 2377
    
  • დავალების განთავსების შეზღუდვები
    • სიმპტომები: დავალებები მომლოდინეა, მაგრამ არ იწყება, "შესაფერისი კვანძი არ არის" შეცდომები
    • მიზეზები: შეუძლებელი შეზღუდვები, რესურსების მიუწვდომლობა
    • გადაწყვეტა: შეცვალეთ შეზღუდვები, დაამატეთ რესურსები
    # იხილეთ წარუმატებელი დავალების დეტალები
    docker service ps --no-trunc service_name
    
    # შეამოწმეთ განთავსების შეზღუდვები
    docker service inspect --format '{{.Spec.TaskTemplate.Placement}}' service_name
    
    # შეზღუდვების შესაბამისი კვანძების სია
    docker node ls --filter node.label=region=east
    
  • რესურსების შეზღუდვები
    • სიმპტომები: სერვისები ვერ იწყება, OOM კლავს
    • მიზეზები: არასაკმარისი მეხსიერება/CPU, არასწორი რესურსების სპეციფიკაციები
    • გადაწყვეტა: შეცვალეთ რესურსების ლიმიტები, გაზარდეთ ინფრასტრუქტურა
    # შეამოწმეთ კვანძის რესურსები
    docker node inspect node_name --format '{{.Description.Resources}}'
    
    # იხილეთ სერვისის რესურსების მოთხოვნები
    docker service inspect --format '{{.Spec.TaskTemplate.Resources}}' service_name
    
    # აკონტროლეთ რესურსების გამოყენება
    docker stats $(docker ps --format "{{.Names}}" --filter label=com.docker.swarm.service.name=service_name)
    
  • იმიჯის ხელმისაწვდომობა
    • სიმპტომები: "image not found" შეცდომები, სერვისები "preparing" მდგომარეობაშია გაჭედილი
    • მიზეზები: კერძო რეესტრის ავთენტიფიკაციის პრობლემები, იმიჯი არ არსებობს, ქსელის პრობლემები
    • გადაწყვეტა: შეამოწმეთ რეესტრზე წვდომა, შეამოწმეთ იმიჯის გზა
    # შეამოწმეთ იმიჯის გადმოწერა ხელით
    docker pull image_name:tag
    
    # დააკონფიგურირეთ რეესტრის ავთენტიფიკაცია
    docker login registry.example.com
    
    # შექმენით რეესტრის რწმუნებათა სიგელები როგორც საიდუმლო
    echo "$DOCKER_AUTH_CONFIG" | docker secret create registry-auth -
    
    # გამოიყენეთ რწმუნებათა სიგელები სერვისთან
    docker service create --name myservice \
      --secret registry-auth \
      --env DOCKER_AUTH_CONFIG_FILE=/run/secrets/registry-auth \
      registry.example.com/myimage:latest
    
  • სერვისის განახლების/მასშტაბირების პრობლემები
    • სიმპტომები: განახლებები ჩერდება, არათანმიმდევრული რეპლიკების რაოდენობა
    • მიზეზები: ჯანმრთელობის შემოწმების შეცდომები, რესურსების შეზღუდვები
    • გადაწყვეტა: შეამოწმეთ ჯანმრთელობის შემოწმებები, შეცვალეთ განახლების კონფიგურაცია
    # აკონტროლეთ განახლების პროგრესი
    docker service inspect --format '{{.UpdateStatus}}' service_name
    
    # გადატვირთეთ სერვისის განახლება, თუ გაჭედილია
    docker service update --force service_name
    

დიაგნოსტიკური ბრძანებები

# შეამოწმეთ swarm-ის სტატუსი
docker info | grep Swarm
# შეამოწმეთ, არის თუ არა კვანძი swarm რეჟიმში და მისი როლი (manager/worker)

# იხილეთ დავალების ლოგები
docker service logs service_name
# დაამატეთ --details მეტამონაცემების სანახავად, მათ შორის რომელი კვანძი აწარმოებს თითოეულ დავალებას
docker service logs --details service_name

# შეამოწმეთ წარუმატებელი დავალებები
docker service ps --filter "desired-state=running" --filter "actual-state=failed" service_name
# აჩვენებს დავალებებს, რომლებიც უნდა მუშაობდნენ, მაგრამ ვერ შესრულდა, შეცდომის შეტყობინებებით

# იხილეთ დავალების ისტორია
docker service ps --no-trunc service_name
# აჩვენებს ყველა დავალებას, მათ შორის წინა წარუმატებელ მცდელობებს

# შეამოწმეთ ქსელური კავშირი
docker run --rm --network service_network alpine ping service_name
# ამოწმებს DNS რეზოლუციასა და კავშირს ოვერლეი ქსელში

# შეამოწმეთ სერვისის კონფიგურაცია
docker service inspect --pretty service_name
# ადამიანისთვის წაკითხვადი სერვისის კონფიგურაცია

# შეამოწმეთ ქსელის კონფიგურაცია
docker network inspect service_network
# აჩვენებს ქსელის დეტალებს, დაკავშირებულ კონტეინერებსა და ქვექსელის ინფორმაციას

# შეამოწმეთ კვანძის სტატუსი და ჯანმრთელობა
docker node inspect --pretty node_name
# ადამიანისთვის წაკითხვადი კვანძის ინფორმაცია, ჯანმრთელობის სტატუსის ჩათვლით

# იხილეთ სერვისის შეზღუდვები
docker service inspect --format '{{.Spec.TaskTemplate.Placement.Constraints}}' service_name
# აჩვენებს განთავსების შეზღუდვებს, რომლებმაც შეიძლება ხელი შეუშალონ დაგეგმვას

# სერვისების აღმოჩენის გამართვა
docker run --rm --network service_network nicolaka/netshoot \
  dig service_name
# ქსელის გაფართოებული გამართვა სპეციალიზებული ინსტრუმენტების გამოყენებით
::