Если вы видите что-то необычное, просто сообщите мне. Skip to main content

Пример ansible для установки и настройки docker swarm

Описание

Что необходимо на входе

4 хоста с предустановленной debian ОС на борту. В моем случае это 4 виртуальные машины созданные методом копирования пустой установленной системы Debian ОС.

Что получим на выходе

Кластер docker-swarm с 4мя нодами: 1 менеджер и 3 воркера Кластер glusterfs на всех 4х нодах. Файл размещенные по пути /mnt будут синхронизироваться на всех хостах. Это позволит запускать контейнеры на любой ноде зная, что данные будет доступны для любого контейнера на любой ноде.

Необходимые ansible параметры для настройки хостов

Подготавливаем inventory.ini

[manager]
manager    ansible_host=192.168.1.46 ansible_user=USERNAME
[nodes]
node1 ansible_host=192.168.1.61 ansible_user=USERNAME
node2 ansible_host=192.168.1.67 ansible_user=USERNAME
node3 ansible_host=192.168.1.96 ansible_user=USERNAME

В файле мы разделили ховксты на 2 группы:

  • manager - хосты для управлервния кластеровм
  • nodes - хосты для работы кластера

Необходимо указать

  • имена хостов: manager,node1,node2,node3 указаны для примера, эти имена будут использоваться для того, чтобы задать имена хостам.
  • ansible_host - ip адрес хоста
  • ansible_user - пользователь под которым будет происходить настройка серверва.

в случае использования Debian часто приходится отдельно добавлять пользователя USERNAME в группу sudo. Для этого нужнно установить sudo, и добавить пользователя в группу sudo командой под супер пользователем.

su //  ввести root пароль
/usr/sbin/useradd -aG sudo USERNAME

Playbook для настройки сервера

Данный playbook выполняется для всех хостов в файле inventory.ini

#play-hostconfig.yaml
- name: Prepear hosts
  hosts: all
  become: true
  tasks:
    - name: Изменение имени хоста
      ansible.builtin.hostname:
        name: "{{ inventory_hostname }}"

    # Шаг может быть пропущен если вы используете внешний dns  
    - name: Создаем dns записи для нашего кластера
      lineinfile:
        dest: /etc/hosts
        regexp: '.*{{ item }}$'
        line: '{{ hostvars[item].ansible_default_ipv4.address }} {{item}}'
        state: present
      with_items: '{{ groups["all"] }}'

    - name: Установка пакетов для поддержки HTTPS в apt
      apt:
        name:
          - apt-transport-https
          - ca-certificates
          - curl
          - gnupg2
          - software-properties-common
        state: present

Устновка glusterfs

Приведенный пример ниже, устанавливает на 34 хоста glusterfs - создает папку и сервис который синхронизирует её между серверами, а так же устанавливает docker.

Ч

#play-glusterfs.yaml
---
- name: Устоанавливаем необходимые ко мпомненять

  • hosts: host_list на hosts: 192.168.1.3,192.168.1.51,192.168.1.28
  • swarm_manager - хосты манагер, обычно один
  • swarm_nodes - остальные хоосты ноды.
---
- name: Apply GlusterFS configuration
  hosts: host_listall
  become: true
  tasks:
    - name: AddОбновляем GlusterFS repository
      apt_repository:
        repo: "ppa:gluster/glusterfs-10"
        state: present

    - name: Update apt cacheкэш
      apt:
        update_cache: true

    - name: InstallУстанавливаем GlusterFS serverсервер
      apt:
        name: glusterfs-server
        state: present

    - name: StartЗапускаем glusterd serviceсервис
      systemd:
        name: glusterd
        state: started
        enabled: true


    - name: Gluster peer probe pi4lab01
      command: gluster peer probe pi4lab01
      ignore_errors: true

    - name: Gluster peer probe pi4lab02
      command: gluster peer probe pi4lab02
      ignore_errors: true

    - name: CreateСоздаем /gluster/volumes directoryпапку
      file:
        path: /gluster/volumes
        state: directory
        mode: '0755'
        owner: root
        group: root

- name: Применяем GlusterFS конфигурацию для manager 
  hosts: manager
  become: true
  tasks:

    - name: Проверяем доступность нод
      command: "gluster peer probe {{ item }}"
      ignore_errors: true
      with_items: '{{ groups["nodes"] }}'

    # Требует доступности хостов друг другу во всех направлениях
    - name: Create gluster volume staging-gfs
      command: >
        gluster volume create staging-gfs replica 34
        elzim:manager:/gluster/volumes
        pi4lab01:node1:/gluster/volumes
        pi4lab02:node2:/gluster/volumes
        node3:/gluster/volumes
        force
      register: volume_create_result
      changed_when: "'Volume successfully created' in volume_create_result.stdout"
      ignore_errors: true

    - name: StartСоздаем gluster volumeраздел staging-gfs для glusterfs
      command: gluster volume start staging-gfs
      when:ignore_errors: volume_create_resulttrue


is- changedname: Создаем автомонтирование раздела staging-gfs на всех хостах
  hosts: all
  serial: 1
  become: true
  tasks:

    - name: Обновляем fstab
      lineinfile:
        dest: /etc/fstab
        regexp: '.*staging-gfs.*'
          #line: localhost:/staging-gfs /mnt glusterfs defaults,_netdev,backupvolfile-server=localhost,x-systemd.requires=network-online.target 0 0
        line: localhost:/staging-gfs /mnt glusterfs defaults,_netdev,noauto,x-systemd.automount 0 0
        state: absent


    - name: Создаем задачу при запуске системы "@reboot mount.glusterfs localhost:/staging-gfs /mnt"
      ansible.builtin.cron:
        name: "mount for reboot"
        special_time: reboot
        job: "sleep 20 && /usr/sbin/mount.glusterfs localhost:/staging-gfs /mnt > /root/mount.log 2>&1"
        state: present

    - name: Перезагружаем сервер после завершения конфигурации
      ansible.builtin.reboot:

Заведение серверов в dockekr swarm.

#play-docker.yaml
---
- name: Установка docker
  hosts: host_listall
  become: true
  tasks:
    - name: Установка пакетов для поддержки HTTPS в apt
      apt:
        name:
          - apt-transport-https
          - ca-certificates
          - curl
          - gnupg2
          - software-properties-common
        state: present
    - name: Добавление GPG-ключа Docker
      apt_key:
        url: https://download.docker.com/linux/debian/gpg
        state: present

    - name: Добавление репозитория Docker
      apt_repository:
        repo: deb https://download.docker.com/linux/debian buster stable
        state: present

    - name: Установка Docker Engine
      apt:
        name: docker-ce
        state: present

    - name: Добавление текущего пользователя в группу docker
      user:
        name: user
        append: yes
        groups: docker

    - name: Меняем владельца на docker для /mnt папки
      file:
        path: /mnt
        owner: root
        group: docker
        recurse: yes

- name: Создание и настройка Swarm кластера
  hosts: swarm_managermanagers
  gather_facts: false
  tasks:
    - name: Инициализация Swarm кластера
      command: docker swarm init
      ignore_errors: true
      register: swarm_init_output
      changed_when: false
    - debug:
        var: swarm_init_output.stdout
    - set_fact:
        join_command: "{{ swarm_init_output.stdout_lines[-2] }}"

- name: Присоединение узлов к кластеру
  hosts: swarm_nodesnodes
  gather_facts: false

  tasks:
    - name: Присоединение к кластеру
      command: "{{ hostvars['swarm_manager'manager'].join_command }}"
      changed_when: false
      ignore_errors: true
      register: swarm_join_output
    - debug:
        var: swarm_join_output.stdout

#  В зависимости от того добавляем или удаляем метки, нужно будет изменить `changed_when` параметр заменить на true/false.
- name: Настройка меток для узлов кластера
  hosts: swarm_managermanager
  gather_facts: false

  tasks:
    - name: Добавление меток для узлов кластера
      command: docker node update --label-add {{ item.label }} {{ item.node }}
      with_items: "{{ node_labels }}"
      changed_when: false

    - name: Удаление меток для узлов кластера
      command: docker node update --label-rm {{ item.label }} {{ item.node }}
      with_items: "{{ node_labels }}"
      changed_when: false

  vars:
    node_labels:
      - { label: "env=prod", node: "node1" }
      - { label: "env=staging", node: "node2" }
      - { label: "env=dev", node: "node3" }

Команужнода будетля заприменить значения хконфигурации с помощью ansible

ansible-playbook -i inventory.ini play-hostconf.yaml -kK
ansible-playbook -i inventory.ini play-glusterfs.yaml -kK
ansible-playbook -i inventory.ini play-docker.yaml -kK

Ключи -kK говорят о тов в разделах hosts: swarm_manager и hosts: swarm_nodes соответственном, чтоб я не использую id_rsa ключ. Вместо этого ввожу пароль для пользователя и для root доступа в ручную в момент запуска команды указатьansible-playbook. IP-адреЕса или вашимена хосты имеют установленные включи, вашей среде. Такжето можно наопустроить метки узлов, добавив или удалив соответствующие элементы в списке node_labels.-kK.