commit aaa94ecd58c35f001fd389be4038bf8b544d0032 Author: bnolge Date: Tue Mar 17 10:47:36 2026 +0300 Initial commit: LXC ZFS deployment with static MAC and VLAN diff --git a/group_vars/all.yml b/group_vars/all.yml new file mode 100644 index 0000000..05b1422 --- /dev/null +++ b/group_vars/all.yml @@ -0,0 +1,78 @@ +--- +- name: Финальное развертывание Unprivileged LXC (ZFS + VLAN) + hosts: localhost + connection: local + become: yes + gather_facts: no + vars: + # Базовый конфиг (ID маппинг согласно вашему /etc/subuid) + base_lxc_conf: | + lxc.include = /usr/share/lxc/config/common.conf + lxc.include = /usr/share/lxc/config/debian.common.conf + lxc.arch = x86_64 + # Маппинг для безопасного root (хост: 1,000,000 -> контейнер: 0) + lxc.idmap = u 0 1000000 65536 + lxc.idmap = g 0 1000000 65536 + # Сетевой интерфейс + lxc.net.0.type = veth + lxc.net.0.link = br0 + lxc.net.0.flags = up + lxc.net.0.name = eth0 + + tasks: + - name: 1. Мгновенный клон из обновленного шаблона + shell: "zfs clone pool/lxc/template-debian12@snap0 pool/lxc/{{ item }}" + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 2. Настройка Legacy Mountpoint (важно для ZFS + LXC) + shell: "zfs set mountpoint=legacy pool/lxc/{{ item }}" + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 3. Подготовка директорий контейнеров + file: + path: "/var/lib/lxc/{{ item }}" + state: directory + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 4. Права на внешние данные почты (UID 1000000) + file: + path: /pool/bit-mail-data + owner: "1000000" + group: "1000000" + state: directory + recurse: yes + + - name: 5. Запись конфига ПРИНТЕР (VLAN 30) + copy: + dest: /var/lib/lxc/bit-srv-prn/config + content: | + {{ base_lxc_conf }} + lxc.uts.name = bit-srv-prn + lxc.rootfs.path = zfs:pool/lxc/bit-srv-prn + lxc.net.0.veth.vlan.id = 30 + + - name: 6. Запись конфига ПОЧТА (VLAN 60 + Mount) + copy: + dest: /var/lib/lxc/mail-bit-it-ru/config + content: | + {{ base_lxc_conf }} + lxc.uts.name = mail-bit-it-ru + lxc.rootfs.path = zfs:pool/lxc/mail-bit-it-ru + lxc.net.0.veth.vlan.id = 60 + lxc.mount.entry = /pool/bit-mail-data var/mail none bind,create=dir 0 0 + + - name: 7. Запуск контейнеров + shell: "lxc-start -n {{ item }} -d" + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 8. Проверка статуса (ждем загрузку) + pause: + seconds: 5 + + - name: 9. Итоговая таблица + shell: "lxc-ls -f" + register: lxc_final + + - name: Результат + debug: + msg: "{{ lxc_final.stdout_lines }}" diff --git a/group_vars/all.yml-old b/group_vars/all.yml-old new file mode 100644 index 0000000..cd967b8 --- /dev/null +++ b/group_vars/all.yml-old @@ -0,0 +1,69 @@ +--- +- name: Развертывание Unprivileged LXC (Финал) + hosts: localhost + connection: local + become: yes + gather_facts: no + vars: + # Конфиг уже включает ID Mapping + base_conf: | + lxc.include = /usr/share/lxc/config/common.conf + lxc.include = /usr/share/lxc/config/debian.common.conf + lxc.arch = x86_64 + lxc.idmap = u 0 100000 65536 + lxc.idmap = g 0 100000 65536 + lxc.net.0.type = veth + lxc.net.0.link = br0 + lxc.net.0.flags = up + lxc.net.0.name = eth0 + + tasks: + - name: 1. Очистка старых контейнеров + shell: | + lxc-stop -n {{ item }} -k || true + lxc-destroy -n {{ item }} || true + zfs destroy -r pool/lxc/{{ item }} || true + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + failed_when: false + + - name: 2. Мгновенный клон ZFS (уже с правами 100000) + shell: "zfs clone pool/lxc/template-debian12@snap0 pool/lxc/{{ item }}" + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 3. Установка legacy mountpoint + shell: "zfs set mountpoint=legacy pool/lxc/{{ item }}" + loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 4. Подготовка папок LXC + file: + path: "/var/lib/lxc/{{ item }}" + state: directory + + +loop: [ 'bit-srv-prn', 'mail-bit-it-ru' ] + + - name: 5. Права на внешние данные (для почты) + file: + path: /pool/bit-mail-data + owner: "100000" + group: "100000" + recurse: yes + + - name: 6. Запись конфигов + copy: + dest: "/var/lib/lxc/{{ item.name }}/config" + content: | + {{ base_conf }} + lxc.net.0.veth.vlan.id = {{ item.vlan }} + lxc.rootfs.path = zfs:pool/lxc/{{ item.name }} + lxc.uts.name = {{ item.name }} + {% if item.mount is defined %}{{ item.mount }}{% endif %} + loop: + - { name: 'bit-srv-prn', vlan: '30' } + - { name: 'mail-bit-it-ru', vlan: '60', mount: 'lxc.mount.entry = /pool/bit-mail-data var/mail none bind,create=dir 0 0' } + + - name: 7. Запуск + shell: "lxc-start -n {{ item.name }} -d" + loop: + - { name: 'bit-srv-prn' } + - { name: 'mail-bit-it-ru' } diff --git a/group_vars/create-container-vlan-30.yml b/group_vars/create-container-vlan-30.yml new file mode 100644 index 0000000..0264b13 --- /dev/null +++ b/group_vars/create-container-vlan-30.yml @@ -0,0 +1,76 @@ +--- +- name: Деплой LXC с контролем уникальности MAC + hosts: localhost + become: yes + gather_facts: no + vars: + target_name: "default-container" + template_snap: "pool/lxc/template-debian12@snap0" + target_ds: "pool/lxc/{{ target_name }}" + base_lxc_path: "/var/lib/lxc/{{ target_name }}" + vlan_id: 30 + + tasks: + - name: 1. Валидация входных данных + fail: + msg: "Укажите имя: -e 'target_name=имя'" + when: target_name == "default-container" + + - name: 2. Генерация детерминированного MAC-адреса + # Берем первые 6 символов sha256 от имени и разбиваем по 2 символа + set_fact: + generated_mac: "00:16:3e:{{ (target_name | checksum) | truncate(6, False, '') | batch(2) | map('join') | join(':') }}" + + - name: 3. Сбор существующих MAC-адресов в системе + # Ищем строки lxc.net.0.hwaddr во всех конфигах /var/lib/lxc/*/config + shell: "grep -h 'lxc.net.0.hwaddr' /var/lib/lxc/*/config | awk '{print $3}' || true" + register: existing_macs + changed_when: false + + - name: 4. Проверка на дубликат (если это новый контейнер) + fail: + msg: "Конфликт! MAC {{ generated_mac }} уже занят другим контейнером." + # Проверяем, есть ли сгенерированный мак в списке, + # НО игнорируем проверку, если мы просто пересобираем текущий контейнер + when: + - generated_mac in existing_macs.stdout_lines + - not (ansible_check_mode or (base_lxc_path + '/config') is file) + + - name: 5. Создание ZFS клона + community.general.zfs: + name: "{{ target_ds }}" + origin: "{{ template_snap }}" + state: present + extra_zfs_properties: + mountpoint: legacy + + - name: 6. Подготовка директории + file: + path: "{{ base_lxc_path }}" + state: directory + + - name: 7. Запись конфига с фиксированным MAC + copy: + dest: "{{ base_lxc_path }}/config" + content: | + lxc.include = /usr/share/lxc/config/common.conf + lxc.arch = x86_64 + lxc.idmap = u 0 1000000 65536 + lxc.idmap = g 0 1000000 65536 + lxc.net.0.type = veth + lxc.net.0.link = br0 + lxc.net.0.flags = up + lxc.net.0.name = eth0 + lxc.net.0.veth.vlan.id = {{ vlan_id }} + lxc.net.0.hwaddr = {{ generated_mac }} + lxc.uts.name = {{ target_name }} + lxc.rootfs.path = zfs:{{ target_ds }} + + - name: 8. Запуск контейнера + community.general.lxc_container: + name: "{{ target_name }}" + state: started + + - name: Итог + debug: + msg: "Контейнер {{ target_name }} запущен с MAC: {{ generated_mac }} в VLAN {{ vlan_id }}"