Автоустановка на основе MAC

Коротко:

Я ищу способ PXE-загрузки Ubuntu 20.04 и использую новую автоматическую установку для полностью автоматической установка. Но я бы хотел, чтобы user-data YAML был изменен на стороне сервера на основе MAC клиента

Что я обнаружил

  • У меня есть вариант загрузки ядра nocloud-net; s = http: // ... но я не вижу способа отправить настраиваемую строку как часть URL-адреса (или полностью изменить URL-адрес на основе локального MAC-адреса)
  • Я вижу ранние команды , в которых говорится, что autoinstall будет обновлен после того, как они будут запущены, но я не придумал какой-либо допустимый способ использовать его для внедрения измененных данных в новую автоустановку; например. do wget http: // myurl / $ MAC затем grep этот файл и измените уже запущенную автоинсталляцию
  • Использование late-command - это крайний вариант, где я действительно мог бы сделать wget http: // myurl / $ MAC && .. && ... , например. установить статический IP / GW / маску сети, но это кажется более подверженным ошибкам
  • Изменить: кажется, у меня может быть другой способ, но также требуется ручная обработка за пределами моего ожидаемого веб-управления, а именно для обслуживания разных pxelinux.cfg для каждого клиента и измените URL-адрес там, но он обслуживается через TFTP, поэтому никаких сценариев на стороне сервера (если нет обходного пути?) Редактировать # 2: это может сработать, укажите серверы TFTP и HTTP в одну и ту же папку (-и) и сообщите PHP для создания настраиваемого файлы в /pxelinux.cfg/AA-BB-CC-DD-EE-01 ... -02 ... -03 .. и т. д. для каждого MAC в моей базе данных и проверять / регенерировать файлы всякий раз, когда запись в БД сохранен. По крайней мере, сохраняет представление о единой точке управления. Но я оставлю вопрос, если кто-то знает лучшее решение (см. Варианты выше)

Конечная цель

Я хотел бы иметь «главный» PXE-сервер, который является домом для HTTPS-сервера, и веб-управление, где я может иметь таблицу всех устройств (например, в MySQL) и все настройки, относящиеся к каждому устройству. Затем, когда мы развертываем новых клиентов (в основном, это просто несколько тупых киосков и прочее), я выбираю их MAC-адреса, включаю PXE-загрузку, помечаю их и отправляю в удаленное место. Этот MAC-адрес и местоположение будут введены в MySQL через веб-управление вместе с такими вещами, как статический IP, GW, DNS, домашняя страница браузера, поворот экрана и т. Д. Как только они прибудут и кто-то их подключит, они загрузятся с автоматической установкой PXE, проходя через это, в процессе они извлекали конфигурации с веб-сервера (например, user-data фактически обрабатывались PHP и при необходимости вводили необходимую конфигурацию), и это было бы - ну ... просто работай. Это может быть применимо и к живым образам, только по-другому.

Я в основном застрял с автоматической установкой и загрузкой nocloud-net , это поначалу кажется отличным, когда я мог бы обслуживать настраиваемый автоматический файл каждому клиенту, за исключением того факта, что я не смогу отличить одного клиента от другого. Получение http: // myserver / user-data? AA-BB-CC-DD-EE-FF , похоже, не входит в спецификации, просто выбор его по IP не сработает, как если бы быть случайным DHCP, к сожалению, исправить это с помощью резервирования DHCP - это кошмар, поскольку мы говорим о более чем 100 местоположениях, каждое со своим собственным локальным DHCP и т. д.

У меня заканчиваются идеи, так что, надеюсь, кто-нибудь сможет вмешаться. Любой идея, чтобы заставить меня работать (очевидно из late-commands ) была бы замечательной! Это не обязательно должен быть MAC, может быть UIID или другой идентификатор оборудования (серийный и т. Д.), Но он должен быть уникальным и легко извлекаемым. И MAC обычно - это наклейка на внешней стороне коробки.

О, и если вам интересно, почему я так против поздних команд ... ну ... дело в том, что я не против это, просто этот динамически изменяемый файл автоматической установки был бы намного более гибким.Я мог установить имя хоста, IP, имя пользователя, пароль, размер диска и все это с самого начала. Это чище, чем загрузка с некоторыми настройками по умолчанию, затем попробуйте пройти через все места с помощью сценариев bash, пытаясь исправить это (особенно диски / разделы). В конце концов, именно поэтому у нас в первую очередь есть сценарии автоустановки , чтобы не делать все заново после первой загрузки.

1
задан 8 November 2020 в 20:05

3 ответа

Так что, похоже, я наконец решил это. Это одновременно просто и изобилует ошибками и препятствиями. Ответ - да - используйте ранние команды. Но правда в деталях, так что подробный ответ.

Прежде всего, подготовьте остальную часть вашей среды, вы можете увидеть мой другой пост о подробных шагах, которые я сделал, чтобы выполнить загрузку BIOS / UEFI PXE 20.04 и 20.10 : https://askubuntu.com/a/1292097/1080682

Теперь, когда ваша среда работает правильно (удачи), давайте выполним индивидуальную автоматическую установку на основе изменений конфигурации, выполняемых через промежуточную установку HTTP.

Итак, если вы следуете руководству, которое я разместил по ссылке, я сохранил свои пользовательские данные Ubuntu здесь:

/var/www/html/ubuntu-server-20.04.1/user-data

Измените файл примерно так (обратите внимание, что я сократил его для удобства чтения):

#cloud-config

autoinstall:
  version: 1
  refresh-installer:
    update: yes
  apt:
    <apt stuff>
  identity:
    hostname: pxe-client
    password: $6$zN/uHJD1rEXD/ETf$q8CoBt3xXmBT37RslyWcpLT1za4RJR3QEtosggRKN5aZAAf6/mYbFEQO66AIPm965glBXB1DGd0Sf.oKi.Rfx/
    realname: pxe
    username: pxe
  keyboard: {layout: hr, toggle: toggle, variant: ""}
  early-commands:
    - curl -G -o /autoinstall.yaml http://10.10.2.1/user-data -d "mac=$(ip a | grep ether | cut -d ' ' -f6)"
  locale: en_US
  network:
    network:
      version: 2
      ethernets:
        eth0:
          dhcp4: yes
          dhcp6: no

Теперь этот пользователь- данные могут быть очень простыми, все, что нам действительно нужно, - это включить для них сеть и однострочный curl в ранних командах . IP 10.10.2.1 - это локальный IP-адрес моего HTTP-сервера (также моего PXE-сервера, поскольку я обслуживаю другие файлы конфигурации, образы ISO и все такое через него, но это не имеет значения).

Используйте все, что угодно. вы хотите изменить и использовать этот файл в соответствии с запросом. Как это делается выше с помощью curl, вы фактически запросите у сервера что-то вроде этого:

GET /user-data?mac=fa:fa:fa:00:0e:07

Часть fa: fa: fa: 00: 0e: 07 - это то, что сервер отправляет после запроса своих собственных интерфейсов. Если у вас несколько интерфейсов, вам, возможно, потребуется настроить скрипт или убедиться, что на ранних этапах установки задействован только один интерфейс.

Я планирую использовать его через PHP + MySQL, а после загрузки в PHP с помощью $ _ GET ["mac"] выполните что-то вроде SELECT * FROM autoinstall-configs WHERE mac = '$ _GET ["mac"]'; и из данных в таблице базы данных создайте новый autoinstall.yaml и верните его в соответствие.

В любом случае, в вашем ответе НЕОБХОДИМО ИМЕЕТ строку autoinstall: !!

Вот минимальный пример того, что HTTP / PHP ответит, я изменил только имя хоста и имя пользователя и изменил его так, чтобы он проходил проверку синтаксиса на неполноценность, ох, и исключил раннюю команду, чтобы не застревать в цикле:

  version: 1
  refresh-installer:
    update: yes
  apt:
    <apt stuff>
  identity:
    hostname: php-client
    password: $6$zN/uHJD1rEXD/ETf$q8CoBt3xXmBT37RslyWcpLT1za4RJR3QEtosggRKN5aZAAf6/mYbFEQO66AIPm965glBXB1DGd0Sf.oKi.Rfx/
    realname: php
    username: php
  keyboard: {layout: hr, toggle: toggle, variant: ""}
  locale: en_US
  network:
    network:
      version: 2
      ethernets:
        eth0:
          dhcp4: yes
          dhcp6: no
  ssh:
    allow-pw: true
    install-server: true
  late-commands:
    - poweroff

Чтобы прояснить, вот разница двух файлов:

diff /var/www/html/ubuntu-server-20.04.1/user-data /var/www/html/user-data

1,3d0
< #cloud-config
<
< autoinstall:
16c13
<     hostname: pxe-client
---
>     hostname: php-client
18,19c15,16
<     realname: pxe
<     username: pxe
---
>     realname: php
>     username: php
21,22d17
<   early-commands:
<     - curl -G -o /autoinstall.yaml http://10.10.2.1/user-data -d "mac=$(ip a | grep ether | cut -d ' ' -f6)"

Так что это почти то же самое, только нет. Эти изменения (удаление autoinstall: и early-commands: ) необходимо для перехода к остальной части установки. Вы можете самостоятельно протестировать другие настройки.

После этого установка будет продолжена с любой новой информацией, полученной в ответ на запрос / user-data? Mac = .

Теперь это открывает дверь к дальнейшим возможностям создания собственного веб-управления для ваших виртуальных машин, серверных ферм или чего-то еще. Вам больше не нужен вручную созданный файл пользовательских данных для каждого сервера или группы серверов. Вы можете отправить каждому их уникальную конфигурацию, включая точный статический IP-адрес, размеры разделов, другое имя хоста, пароль и т. Д.

Канонический, если вы выберете идею из этого, укажите мне в титрах по крайней мере :)

Дело закрыто, ура!

1
ответ дан 3 January 2021 в 22:49

В зависимости от того, что вы используете для PXE, вы можете использовать переменные в аргументах загрузки. Например, использование GRUB (обычно используемого для машин UEFI) предоставит $ {net_default_mac} в качестве переменной для MAC-адреса.

В общем, я думаю, что ранние команды - это лучший вариант. Я не уверен, что не удалось, когда вы это попробовали. Я бы подумал, что вы могли бы просто получить свой динамически сгенерированный файл пользовательских данных и перезаписать файл /autoinstall.yaml .

0
ответ дан 3 January 2021 в 22:49

Я реализовал нечто подобное, но использовал Ansible/Ansible Tower в качестве источника правды. По сути, мой скрипт iPXE настроен на доступ к простому фляжному приложению, хранящемуся в OpenShift (kubernetes), с MAC-адресом машины, запрашивающей конфигурацию автоустановки. Затем Ansible запускается и создает файл конфигурации автоустановки для конкретной машины (с использованием шаблона Jinja2) и обслуживает его. Никаких ранних сценариев.

Я делаю что-то подобное с preseed для выпусков Ubuntu старше 20.04.

import json
import requests
import subprocess
from flask import Flask, abort, request, redirect, send_from_directory

@autoinstaller.route('/ubuntu', defaults={'path': ''})
@autoinstaller.route('/ubuntu/<path:mac_address>')
@autoinstaller.route('/ubuntu/<path:mac_address>/meta-data')
@autoinstaller.route('/ubuntu/<path:mac_address>/user-data')
def get_autoinstall_config(mac_address):
    candidate_hostname = _isknownhost(mac_address)
    if candidate_hostname == None:
        abort(404)
    else:
        subprocess.run(["ansible-playbook", "playbooks/ubuntu/generate_autoinstall.yml", "--limit", f"{candidate_hostname}", "-e", f"candidate_mac={mac_address} candidate_hostname={candidate_hostname} authorized=True ansible_connection=local"])
        return send_from_directory(f'/tmp/{mac_address}', 'user-data')

_isknownhost — это функция, которая вызывает ansible-inventory для поиска системы с совпадающим MAC-адресом.

def _isknownhost(mac_address):
    query = subprocess.Popen(["ansible-inventory", "--list"], stdout=subprocess.PIPE)
    hosts = json.loads(query.communicate()[0])['_meta']['hostvars']
    for system in hosts.keys():
        for hostvar in hosts[system].values():
            if hostvar == mac_address:
                return system
    return None

0
ответ дан 19 January 2021 в 16:43

Другие вопросы по тегам:

Похожие вопросы: