- docs/ai/: stable, repo-verified context - README, architecture, tech-stack, edge-cases, plan (confirmed active work only), migration-tofu (the blue-green OpenTofu migration runbook and per-service findings), legacy-warning, links. - AGENTS.md: slimmed to a working contract that points at docs/ai instead of restating it; CLAUDE.md is an adapter that @-includes it. - README.md, ansible/README.md, ansible/roles/README.md, roles/lxc_docker_host/README.md: bring wording in line with the current control plane (Makefile entry point, registry, tofu, memoir-bot gone). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uoq5AVK8mkBgg83Mq6o5V
84 lines
4.4 KiB
Markdown
84 lines
4.4 KiB
Markdown
# lxc_docker_host
|
|
|
|
Приводит непривилегированный Proxmox LXC в состояние «здесь можно запускать
|
|
Docker»: пакеты, проверка `/dev/fuse`, `storage-driver: fuse-overlayfs`,
|
|
запуск демона и базовый UFW.
|
|
|
|
Роль вынесена из повторяющихся блоков `playbooks/pve-*.yml`
|
|
(gitea, vaultwarden, mihomo, adguard, docker-test, grimmory, hermes-ai) —
|
|
суммарно около 350 строк копипасты.
|
|
|
|
## Что делает
|
|
|
|
1. Ставит `ca-certificates`, `curl`, `docker.io`, `fuse-overlayfs`
|
|
(+ `lxc_docker_host_extra_packages`, `ufw` при управлении фаерволом).
|
|
2. `stat` + `assert` на `/dev/fuse`: без символьного устройства
|
|
fuse-overlayfs не работает, и Docker молча деградирует до `vfs`.
|
|
Сообщение об ошибке подсказывает, какие строки добавить в
|
|
`/etc/pve/lxc/<vmid>.conf` на узле PVE.
|
|
3. Пишет `/etc/docker/daemon.json` со `storage-driver: fuse-overlayfs`.
|
|
4. `systemd: docker` — `enabled: true`, `restarted` при смене daemon.json,
|
|
иначе `started`.
|
|
5. UFW: SSH из `homelab_lan_cidr` и `openvpn_network_cidr`, node-exporter
|
|
9100/tcp с хоста мониторинга (192.168.1.30), произвольные порты сервиса
|
|
из `lxc_docker_host_ufw_service_rules`, затем `policy deny incoming`.
|
|
Разрешающие правила ставятся ДО включения политики — иначе прогон
|
|
обрывает собственную SSH-сессию.
|
|
6. Проверяет `docker info --format '{{.Driver}}'` и падает при расхождении.
|
|
|
|
## Переменные
|
|
|
|
Полный список с комментариями — в `defaults/main.yml`. Ключевые:
|
|
|
|
| Переменная | По умолчанию | Назначение |
|
|
|---|---|---|
|
|
| `lxc_docker_host_extra_packages` | `[]` | доп. пакеты сервиса |
|
|
| `lxc_docker_host_require_fuse` | `true` | проверять `/dev/fuse` |
|
|
| `lxc_docker_host_storage_driver` | `fuse-overlayfs` | драйвер хранилища |
|
|
| `lxc_docker_host_manage_ufw` | `true` | трогать ли UFW вообще |
|
|
| `lxc_docker_host_ssh_sources` | LAN + OpenVPN | откуда разрешён SSH |
|
|
| `lxc_docker_host_allow_node_exporter` | `true` | 9100 с хоста мониторинга |
|
|
| `lxc_docker_host_ufw_service_rules` | `[]` | порты сервиса |
|
|
| `lxc_docker_host_ufw_enable` | `true` | включать `deny incoming` |
|
|
| `lxc_docker_host_verify_storage_driver` | `true` | финальная проверка |
|
|
|
|
## Пример: как выглядела бы подготовка хоста Grimmory
|
|
|
|
```yaml
|
|
- name: Prepare the Grimmory Docker host
|
|
hosts: grimmory
|
|
gather_facts: true
|
|
vars:
|
|
ansible_become: false
|
|
roles:
|
|
- role: lxc_docker_host
|
|
lxc_docker_host_extra_packages:
|
|
- mariadb-client
|
|
- openssl
|
|
lxc_docker_host_install_node_exporter: true
|
|
lxc_docker_host_ufw_service_rules:
|
|
- port: "{{ homelab_services.grimmory.ports[0].port }}"
|
|
proto: tcp
|
|
comment: Grimmory HTTP
|
|
sources:
|
|
- "{{ homelab_lan_cidr }}"
|
|
- "{{ openvpn_network_cidr }}"
|
|
```
|
|
|
|
Эти 12 строк заменяют 86 строк из `playbooks/pve-grimmory.yml`.
|
|
|
|
## Чего роль НЕ делает
|
|
|
|
* Не создаёт LXC и не правит `/etc/pve/lxc/<vmid>.conf` — это роль `pve_lxc`
|
|
и соответствующий `pve-*.yml`. Роль только проверяет результат.
|
|
* Не публикует порты Docker в обход UFW. Помните: `-p` в Docker обходит UFW,
|
|
поэтому для публикуемых портов нужны правила в цепочке `DOCKER-USER`
|
|
(см. `grimmory-docker-firewall` в `playbooks/pve-grimmory.yml`).
|
|
* Не ставит node-exporter по умолчанию — этим занимается `monitoring_exporter`.
|
|
|
|
## Handlers
|
|
|
|
Их нет намеренно. Docker перезапускается прямо в задаче через
|
|
`state: restarted if changed else started`: handler отработал бы в конце
|
|
play, уже после того как compose-стек стартовал на старом драйвере хранилища.
|