Thank you for reading this post, don't forget to subscribe!
Данная роль позволит установить ceph кластер, но предварительно необходимо выполнить следующие действия:
На нодах где будут непосредственно храниться данные (мастера) создать lvm группу и том c одинаковыми именами на всех нодах:
vgcreate ceph /dev/sdb
lvcreate -L 5G -n ceph ceph
mkfs.ext4 -L ceph /dev/mapper/ceph-ceph
и задать хостнеймы
hostnamectl set-hostname ceph1
hostnamectl set-hostname ceph2
hostnamectl set-hostname ceph3
в моём случае это 2 мастера ceph1 ceph2 и клиент ceph3
теперь правим файл /etc/ansible/hosts
cat /etc/ansible/hosts
[ceph:children]
cephmaster
cephclient
[cephmaster]
192.168.1.170
192.168.1.171
[cephclient]
192.168.1.172
mkdir /etc/ansible/roles/ceph/tasks/
mkdir /etc/ansible/roles/ceph/templates/
В приведённом ниже плейбуке (с него будем запускать весь этот ужас) указаны следующие переменные:
hosts: ceph это имя которое у нас указано в hosts
user_pass пароль пользователя (он будет задан для системного пользователя ceph)
userdir директория с которой будет запускаться установка в ней будут храниться конфиги и лог установки, в конце обязательно должен стоять слэш /
vgname_lvname здесь задаём lvm группу и имя тома (в моём случае это ceph/ceph задаём им через слеш '/' но не через слэш ))))) )
также отметим что предварительно данные тачки должны быть прогнаны ролью new-server она описывалась в одной из статей, там задавался пользователь ansible под которым мы и будем работать
proxy - включаем или выключаем использование прокси
http_proxy, https_proxy - адрес нашего прокси сервера
name_pool - имя пула
pg_num, pgp_num - количество пг пгп на один осд
cat /etc/ansible/playbooks/roles_play/ceph.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
--- - hosts: ceph become: true ignore_errors: yes become_method: sudo gather_facts: yes vars: - proxy: true # here use true/false - http_proxy: "http://192.168.1.170:3128" - https_proxy: "http://192.168.1.170:3128" - user_pass: ceph - userdir: /var/ceph-adminDIR/ - vgname_lvname: ceph/ceph - name_pool: rbd - pg_num: 128 - pgp_num: 128 roles: - ceph # tasks: # - include_role: # name: name1 # name: name # #менее 5 OSD - значение pg_num и pgp_num ставим 128; #от 5 до 10 OSD - значение pg_num и pgp_num ставим 512; #от 10 до 50 OSD - значение pg_num и pgp_num ставим 4096; |
[/codesyntax]
репозиторий:
cat /etc/ansible/roles/ceph/templates/ceph.repo
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
[ceph-noarch] name=Ceph noarch packages baseurl=http://download.ceph.com/rpm-mimic/el7/noarch enabled=1 gpgcheck=1 type=rpm-md gpgkey=https://download.ceph.com/keys/release.asc |
[/codesyntax]
Список всей подтягиваемых плейбуков:
cat /etc/ansible/roles/ceph/tasks/main.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
--- - import_tasks: proxy-add.yml tags: proxy-add when: proxy - import_tasks: removecephrepo.yml tags: removecephrepoifexist - import_tasks: installepelrepo.yml tags: epel - import_tasks: installcephrepo.yml tags: cephrepo - import_tasks: add-to-hosts.yml tags: /etc/hosts - import_tasks: addusers.yml tags: adduserceph - import_tasks: copy-ssh-key.yml tags: ssh-key - import_tasks: create-home-dir.yml tags: create-dir - import_tasks: install-packpages.yml tags: install-default-packpage - import_tasks: renamerepo.yml tags: rename-ceph-repo - import_tasks: create-ceph-cluster.yml tags: createcephcluster - import_tasks: add-ceph-conf.yml tags: add-ceph - import_tasks: install-ceph-cluster.yml tags: installcephcluster - import_tasks: mon-initial.yml tags: moninitial - import_tasks: osd-create.yml tags: osdcreate - import_tasks: add-node-to-monitoring.yml tags: addnodetomonitoring - import_tasks: copy-key-conf-file.yml tags: copykeyconffile - import_tasks: mgr-create.yml tags: mgrcreate - import_tasks: ceph-client.yml tags: cephclient - import_tasks: pool-create.yml tags: poolcreate - import_tasks: proxy-delete.yml tags: proxy-delete when: proxy - import_tasks: start_and_install_services.yml tags: start_services |
[/codesyntax]
Плейбук для добавления строки в конфиг с указанием подсети в рамках которой будет работать ceph
cat /etc/ansible/roles/ceph/tasks/add-ceph-conf.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
- name: add network to ceph.conf lineinfile: dest: "{{ userdir }}ceph.conf" line: public_network = {{ hostvars[from_this_ip_will_install_ceph].ansible_default_ipv4.network }}/24 state: present delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true |
[/codesyntax]
Добавление мастер нод к мониторингу (mon)
cat /etc/ansible/roles/ceph/tasks/add-node-to-monitoring.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: add all node to monitoring become: yes become_user: ceph shell: cmd: ceph-deploy mon add "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.cephmaster }}" |
[/codesyntax]
Добавление в файл /etc/hosts на всех нодах хостнеймы и ip чтобы работал резолв, так как при частом прогоне данного плейбука данные постоянно добавлялись, я закостылил и добавить 2 башевские команды(башизм в ансибле это печально), одна сохраняет уникальные строки в отдельный файл /etc/hosts2, вторая заменяет им /etc/hosts
cat /etc/ansible/roles/ceph/tasks/add-to-hosts.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- name: Add all hosts and ip to /etc/hosts lineinfile: dest: /etc/hosts regexp: '{{ hostvars[item].ansible_default_ipv4.address }}.*{{ item }}$' line: "{{ hostvars[item].ansible_default_ipv4.address }} {{ hostvars[item].ansible_hostname }}" state: present become: yes with_items: "{{ groups.ceph }}" - name: save only uniq in /etc/hosts to /etc/hosts2 shell: "/usr/bin/cat /etc/hosts | /usr/bin/awk '!a[$0]++' > /etc/hosts2" - name: save only uniq shell: "mv /etc/hosts2 /etc/hosts" |
[/codesyntax]
Добавляю пользователя, задаю ему пароль, группу и генерирую ssh ключи
cat /etc/ansible/roles/ceph/tasks/addusers.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 |
- name: add users user: name: "{{ item }}" group: wheel shell: /bin/bash append: yes password: "{{ user_pass | password_hash('sha512') }}" generate_ssh_key: yes with_items: - ceph |
[/codesyntax]
В данном плейбуке устанавливается ceph клиент,
chdir задаёт директорию откуда будет запускаться команда
become_user задаёт пользователя от которого будет запускаться команда
delegate_to задаёт адрес откуда будет запущена команда, в нашем случае это переменная from_this_ip_will_install_ceph
with_items задаёт группу cephclient которая указана у нас в файле /etc/ansible/hosts
cat /etc/ansible/roles/ceph/tasks/ceph-client.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
- name: copy config file and keys for cephclient become: yes become_user: ceph shell: cmd: ceph-deploy admin "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.cephclient }}" - name: change rights file: path: /etc/ceph/ceph.client.admin.keyring owner: root group: root mode: '0644' delegate_to: "{{ item }}" with_items: "{{ groups.cephclient }}" |
[/codesyntax]
В данном плейбуке мы копируем ключи и конфиг файлы
cat /etc/ansible/roles/ceph/tasks/copy-key-conf-file.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
- name: copy config file and keys become: yes become_user: ceph shell: cmd: ceph-deploy admin "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.cephmaster }}" - name: change rights file: path: /etc/ceph/ceph.client.admin.keyring owner: root group: root mode: '0644' delegate_to: "{{ item }}" with_items: "{{ groups.cephmaster }}" |
[/codesyntax]
В данном плейбуке я копирую публичные ключи со всех нод к себе на ансибл хост в директорию с шаблонами templates, после чего копирую их к одной тачке с которой производится установка, она у нас задана в переменной from_this_ip_will_install_ceph
Также я добавляю на основную ноду с которой производится установка ключи к known_hosts, так как при первом соединении надо ответить yes и тут происходит затык если этого не сделать вручную, или так как я прописал
переменная from_this_ip_will_install_ceph задаётся фактами из инвентори файла /etc/ansible/hosts из группы cephmaster, первый ip
cat /etc/ansible/roles/ceph/tasks/copy-ssh-key.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
- set_fact: from_this_ip_will_install_ceph: "{{ groups.cephmaster[0] }}" - name: copy id_rsa.pub FROM all hosts to local ansible template fetch: src: /home/ceph/.ssh/id_rsa.pub dest: /etc/ansible/roles/ceph/templates/ - name: Set authorized key took from file for users authorized_key: user: ceph state: present key: "{{ lookup('file', '/etc/ansible/roles/ceph/templates/{{ from_this_ip_will_install_ceph }}/home/ceph/.ssh/id_rsa.pub') }}" - name: Set KNOWN HOSTS shell: cmd: "ssh-keyscan -t rsa {{ hostvars[item].ansible_hostname }} >> /home/ceph/.ssh/known_hosts" with_items: '{{ groups.ceph }}' delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true become: yes become_user: ceph |
[/codesyntax]
Здесь мы создаём кластер команда будет запускать только с одной ноды из переменной from_this_ip_will_install_ceph
cat /etc/ansible/roles/ceph/tasks/create-ceph-cluster.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
--- - name: Create tmp files file: path: "{{ userdir }}{{ item }}" state: touch mode: 0775 with_items: - hostname - bash.sh delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true - name: First step Add all hostname for deploy to file "{{ userdir }}hostname" lineinfile: dest: "{{ userdir }}hostname" line: ceph-deploy new {{ansible_hostname}} state: present delegate_to: "{{ from_this_ip_will_install_ceph }}" - name: Second step Create bash for run ceph-deploy new shell: cmd: cat "{{ userdir }}hostname" | awk '{print $3}' | tr -s '\r\n' ' ' | awk '{print "#!/bin/bash \n", "ceph-deploy new", $0}' >"{{ userdir }}bash.sh" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true - name: Create ceph-cluster become: yes become_user: ceph shell: cmd: /bin/bash "{{ userdir }}bash.sh" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true - name: Remove tmp files file: path: "{{ userdir }}{{ item }}" state: absent with_items: - hostname - bash.sh delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true |
[/codesyntax]
Создаём директорию только на одной тачке, из неё мы будем производить установку кластера:
cat /etc/ansible/roles/ceph/tasks/create-home-dir.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
- name: Create dir "{{ userdir }}" file: path: "{{ userdir }}" state: directory recurse: yes owner: ceph group: wheel delegate_to: "{{ from_this_ip_will_install_ceph }}" |
[/codesyntax]
Здесь мы устанавливаем на все узлы кластера
cat /etc/ansible/roles/ceph/tasks/install-ceph-cluster.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 |
--- - name: Install ceph-cluster become: yes become_user: ceph shell: cmd: ceph-deploy install "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.ceph }}" |
[/codesyntax]
Здесь копируем репозиторий ceph из шаблона
cat /etc/ansible/roles/ceph/tasks/installcephrepo.yml
[codesyntax lang="php"]
1 2 3 4 5 6 |
- name: copy template for ceph template: src: /etc/ansible/roles/ceph/templates/ceph.repo dest: /etc/yum.repos.d/ceph.repo mode: 644 |
[/codesyntax]
Здесь устанавливаем репозиторий epel
cat /etc/ansible/roles/ceph/tasks/installepelrepo.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: Install EPEL repo. yum: name: https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm state: present - name: Import EPEL GPG key. rpm_key: key: /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }} state: present |
[/codesyntax]
Тут ставим дефолтные пакеты:
cat /etc/ansible/roles/ceph/tasks/install-packpages.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 |
- name: install default packages yum: name: "{{item}}" state: present with_items: - yum-utils - python2-pip - yum-plugin-priorities - device-mapper-persistent-data - lvm2 - ceph-deploy |
[/codesyntax]
Здесь ставим mgr на мастер ноды, запускается установка с одной ноды из переменной from_this_ip_will_install_ceph
cat /etc/ansible/roles/ceph/tasks/mgr-create.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: mgr create become: yes become_user: ceph shell: cmd: ceph-deploy mgr create "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.cephmaster }}" |
[/codesyntax]
начальная настройка сервера монитора Ceph и установка мониторов на другие мастер ноды
cat /etc/ansible/roles/ceph/tasks/mon-initial.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
- name: monitor initial become: yes become_user: ceph shell: cmd: ceph-deploy mon create-initial chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true - name: create monitor on other ceph-master become: yes become_user: ceph shell: cmd: ceph-deploy --overwrite-conf mon create "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.cephmaster }}" |
[/codesyntax]
Создание и активация osd
cat /etc/ansible/roles/ceph/tasks/osd-create.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: osd create become: yes become_user: ceph shell: cmd: ceph-deploy osd create --data "{{ vgname_lvname }}" "{{ hostvars[item].ansible_hostname }}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true with_items: "{{ groups.cephmaster }}" |
[/codesyntax]
Удаление репозиториев ceph.repo ceph-deploy.repo
cat /etc/ansible/roles/ceph/tasks/removecephrepo.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: remove ceph.repo file: path: /etc/yum.repos.d/ceph.repo state: absent - name: remove ceph-deploy.repo file: path: /etc/yum.repos.d/ceph-deploy.repo state: absent |
[/codesyntax]
Переименование репозиториев ceph.repo в ceph-deploy.repo
cat /etc/ansible/roles/ceph/tasks/renamerepo.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
- name: check exist repo stat: path=/etc/yum.repos.d/ceph.repo register: ceph_stat - name: rename ceph.repo to ceph-deploy.repo command: mv /etc/yum.repos.d/ceph.repo /etc/yum.repos.d/ceph-deploy.repo when: ceph_stat.stat.exists |
[/codesyntax]
Добавляем proxy
cat /etc/ansible/roles/ceph/tasks/proxy-add.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
- name: PROXY ----- changes for install ceph through proxy "{{ http_proxy }}" lineinfile: dest=/etc/yum.conf state=present regexp="{{ http_proxy }}" insertafter=EOF line="proxy={{ http_proxy }}" ignore_errors: yes - name: PROXY ----- add proxy to /etc/environment blockinfile: dest: /etc/environment block: | export http_proxy="{{ http_proxy }}" export https_proxy="{{ http_proxy }}" state: present |
[/codesyntax]
Удаляем proxy
cat /etc/ansible/roles/ceph/tasks/proxy-delete.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
- name: PROXY ----- changes for install ceph through proxy "{{ http_proxy }}" lineinfile: dest=/etc/yum.conf state=absent regexp="{{ http_proxy }}" insertafter=EOF line="proxy={{ http_proxy }}" ignore_errors: yes - name: PROXY ----- add proxy to /etc/environment blockinfile: dest: /etc/environment block: | export http_proxy="{{ http_proxy }}" export https_proxy="{{ http_proxy }}" state: absent |
[/codesyntax]
создаём pool
cat /etc/ansible/roles/ceph/tasks/pool-create.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
- name: pool create become: yes become_user: ceph shell: cmd: ceph osd pool create "{{ name_pool }}" "{{pg_num}}" "{{pgp_num}}" chdir: "{{ userdir }}" delegate_to: "{{ from_this_ip_will_install_ceph }}" run_once: true |
[/codesyntax]
запускаем сервисы, перезапускаем время(синхронизируем)
cat /etc/ansible/roles/ceph/tasks/start_and_install_services.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
- name: Make sure NTP is started up service: name=ntpd state=started enabled=yes - name: force ntp update shell: "systemctl stop ntpd" - name: update ntp shell: "ntpd -q" - name: start ntp shell: "systemctl start ntpd" - name: Create file rbd.conf file: path: /etc/modules-load.d/rbd.conf state: touch mode: 0644 - name: Add rbd in /etc/modules-load.d/rbd.conf lineinfile: dest: "/etc/modules-load.d/rbd.conf" line: rbd state: present - name: Start and enable ceph target service: name="{{item}}" state=started enabled=yes with_items: - ceph-mds.target - ceph-mgr.target - ceph-mon.target - ceph-osd.target - ceph-radosgw.target - ceph.target - rbdmap.service |
[/codesyntax]
готово можем запускать:
ansible-playbook -u ansible /etc/ansible/playbooks/roles_play/ceph.yml
=================================================
Чтобы проверить работу через прокси squid на порту 3128 запускаем следующий скрипт на наших нодах, чтобы не было доступа во внешку:
[codesyntax lang="bash"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#!/bin/bash ### Скрипт конфигурации IPTables ### # Очищаем предыдущие записи iptables -F # Установка политик по умолчанию iptables -P INPUT DROP iptables -P FORWARD ACCEPT iptables -P OUTPUT DROP # Разрешаем локальный интерфейс iptables -A INPUT -i lo -j ACCEPT # REL, ESTB allow iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT # Разрешаем рабочие порты # 22 порт для всех iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Ansible iptables -A INPUT -p tcp -s 192.168.1.177 --dport 22 -j ACCEPT # Прокси iptables -A OUTPUT -p tcp -d 192.168.1.170 --dport 3128 -j ACCEPT # DNS у нас гугловые iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT #сервера ceph iptables -A INPUT -p tcp -s 192.168.1.133,192.168.1.134,192.168.1.135 -j ACCEPT iptables -A OUTPUT -d 192.168.1.133,192.168.1.134,192.168.1.135 -j ACCEPT # Просмотр iptables -L --line-number echo service iptables save echo service iptables reload echo "Done" |
[/codesyntax]