diff --git a/.codeassistant/mcp.json b/.codeassistant/mcp.json new file mode 100644 index 0000000..7bf1ce1 --- /dev/null +++ b/.codeassistant/mcp.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "sourcecraft": { + "type": "streamable-http", + "url": "https://api.sourcecraft.tech/mcp", + "disabled": false, + "headers": {}, + "disabledTools": [], + "timeout": 60, + "alwaysAllow": [] + } + } +} \ No newline at end of file diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..f84fcc0 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,6 @@ +[defaults] +inventory = ./inventory.ini +remote_user = iurii +private_key_file = ~/.ssh/id_rsa +host_key_checking = false +interpreter_python = auto_silent \ No newline at end of file diff --git a/ansible/inventory.ini b/ansible/inventory.ini new file mode 100644 index 0000000..5c5b08f --- /dev/null +++ b/ansible/inventory.ini @@ -0,0 +1,2 @@ +[docker] +lab1 ansible_host=192.168.20.11 \ No newline at end of file diff --git a/ansible/playbook.yml b/ansible/playbook.yml new file mode 100644 index 0000000..68eba8b --- /dev/null +++ b/ansible/playbook.yml @@ -0,0 +1,45 @@ +--- +- name: Install Docker on Rocky Linux 9 + hosts: docker + become: true + + vars: + docker_packages: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + + tasks: + - name: Install dnf plugins + ansible.builtin.dnf: + name: dnf-plugins-core + state: present + + - name: Add Docker CE repository + ansible.builtin.get_url: + url: https://download.docker.com/linux/rhel/docker-ce.repo + dest: /etc/yum.repos.d/docker-ce.repo + mode: "0644" + + - name: Install Docker packages + ansible.builtin.dnf: + name: "{{ docker_packages }}" + state: present + update_cache: true + + - name: Enable and start Docker + ansible.builtin.systemd: + name: docker + enabled: true + state: started + + - name: Verify Docker service + ansible.builtin.command: systemctl is-active docker + register: docker_status + changed_when: false + + - name: Show Docker status + ansible.builtin.debug: + var: docker_status.stdout \ No newline at end of file diff --git a/cluster/cloud-config/rocky.yml b/cluster/cloud-config/rocky.yml new file mode 100644 index 0000000..7309db3 --- /dev/null +++ b/cluster/cloud-config/rocky.yml @@ -0,0 +1,21 @@ +#cloud-config +timezone: Europe/Moscow + +users: + - name: iurii + groups: [wheel] + shell: /bin/bash + lock_passwd: false + passwd: "$6$Zc8nwvtw0Kns5.sD$FpQ4aBSeGogefqjM4we4U5QQd4YBtC98tuG3rR4j9ZmbtC1kyFf2sY/IodYW3wG.U81aEntlZrtOTOqw3ZcOc0" + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + ssh_authorized_keys: + - ${ssh_key} + +package_update: true + +packages: + - qemu-guest-agent + +runcmd: + - systemctl enable --now qemu-guest-agent + - hostnamectl set-hostname ${hostname} \ No newline at end of file diff --git a/cluster/locals.tf b/cluster/locals.tf index 1606811..ad0b759 100644 --- a/cluster/locals.tf +++ b/cluster/locals.tf @@ -99,7 +99,8 @@ locals { nodes = { k8s-master-1 = { - cloudinit = "master.yml" + cloudinit = "rocky.yml" + image_file = "import/rocky9.qcow2" index = 1 cpu = var.worker_cpu memory = 4092 @@ -115,45 +116,45 @@ locals { gateway = "192.168.20.1" } ] - }, - k8s-worker-1 = { - cloudinit = "worker.yml" - index = 2 - cpu = var.worker_cpu - memory = 8192 - disk = var.worker_disk - datastore = var.worker_datastore + } + # k8s-worker-1 = { + # cloudinit = "worker.yml" + # index = 2 + # cpu = var.worker_cpu + # memory = 8192 + # disk = var.worker_disk + # datastore = var.worker_datastore - network_devices = [ - { - bridge = var.node_bridge - vlan_id = 20 - ip = "192.168.20.22" - cidr = 24 - gateway = "192.168.20.1" - } - ] - }, - k8s-worker-2 = { - cloudinit = "worker.yml" - index = 3 - cpu = var.worker_cpu - memory = 8192 - disk = var.worker_disk - datastore = var.worker_datastore + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.22" + # cidr = 24 + # gateway = "192.168.20.1" + # } + # ] + # }, + # k8s-worker-2 = { + # cloudinit = "worker.yml" + # index = 3 + # cpu = var.worker_cpu + # memory = 8192 + # disk = var.worker_disk + # datastore = var.worker_datastore - network_devices = [ - { - bridge = var.node_bridge - vlan_id = 20 - ip = "192.168.20.23" - cidr = 24 - gateway = "192.168.20.1" - }, - { - bridge = "vmbr0" - } - ] - } + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.23" + # cidr = 24 + # gateway = "192.168.20.1" + # }, + # { + # bridge = "vmbr0" + # } + # ] + # } } } \ No newline at end of file diff --git a/example_locals.tf b/example_locals.tf new file mode 100644 index 0000000..b50fa16 --- /dev/null +++ b/example_locals.tf @@ -0,0 +1,124 @@ +locals { + nodes = { + k8s-worker-1 = { + index = 1 + cpu = 2 + memory = 2048 + + disks = [ + { + datastore = "ssd2" + interface = "scsi0" + size = 20 + import_from = "local:import/ubuntu-24.qcow2" + } + ] + + network_devices = [ + { + bridge = "vmbr0" + vlan_id = 20 + ip = "192.168.20.10" + cidr = 24 + gateway = "192.168.20.1" + } + ] + }, + k8s-worker-2 = { + index = 2 + cpu = 2 + memory = 2048 + + disks = [ + { + datastore = "ssd2" + interface = "scsi0" + size = 20 + import_from = "local:import/ubuntu-24.qcow2" + } + ] + + network_devices = [ + { + bridge = "vmbr0" + vlan_id = 20 + ip = "192.168.20.11" + cidr = 24 + gateway = "192.168.20.1" + } + ] + }, + k8s-worker-3 = { + index = 3 + cpu = 2 + memory = 2048 + + disks = [ + { + datastore = "ssd2" + interface = "scsi0" + size = 20 + import_from = "local:import/ubuntu-24.qcow2" + } + ] + + network_devices = [ + { + bridge = "vmbr0" + vlan_id = 20 + ip = "192.168.20.12" + cidr = 24 + gateway = "192.168.20.1" + } + ] + }, + k8s-worker-4 = { + index = 4 + cpu = 2 + memory = 2048 + + disks = [ + { + datastore = "ssd2" + interface = "scsi0" + size = 20 + import_from = "local:import/ubuntu-24.qcow2" + } + ] + + network_devices = [ + { + bridge = "vmbr0" + vlan_id = 20 + ip = "192.168.20.13" + cidr = 24 + gateway = "192.168.20.1" + } + ] + }, + k8s-worker-5 = { + index = 5 + cpu = 2 + memory = 2048 + + disks = [ + { + datastore = "ssd2" + interface = "scsi0" + size = 20 + import_from = "local:import/ubuntu-24.qcow2" + } + ] + + network_devices = [ + { + bridge = "vmbr0" + vlan_id = 20 + ip = "192.168.20.14" + cidr = 24 + gateway = "192.168.20.1" + } + ] + } + } +} diff --git a/generate.py b/generate.py new file mode 100644 index 0000000..86836aa --- /dev/null +++ b/generate.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +BASE_IP = "192.168.20" +START = 10 +COUNT = 5 + +CPU = 2 +MEMORY = 2048 +GATEWAY = "192.168.20.1" + +def generate(): + print("locals {") + print(" nodes = {") + + for i in range(COUNT): + idx = i + 1 + last_octet = START + i + + if last_octet > 254: + raise ValueError("IP overflow") + + ip = f"{BASE_IP}.{last_octet}" + comma = "," if i < COUNT - 1 else "" + + print(f""" k8s-worker-{idx} = {{ + index = {idx} + cpu = {CPU} + memory = {MEMORY} + + disks = [ + {{ + datastore = "ssd2" + interface = "scsi0" + size = 20 + import_from = "local:import/ubuntu-24.qcow2" + }} + ] + + network_devices = [ + {{ + bridge = "vmbr0" + vlan_id = 20 + ip = "{ip}" + cidr = 24 + gateway = "{GATEWAY}" + }} + ] + }}{comma}""") + + print(" }") + print("}") + +if __name__ == "__main__": + generate() \ No newline at end of file diff --git a/infra/cloud-config/vm.yml b/infra/cloud-config/master.yml similarity index 93% rename from infra/cloud-config/vm.yml rename to infra/cloud-config/master.yml index d2d933a..d77615e 100644 --- a/infra/cloud-config/vm.yml +++ b/infra/cloud-config/master.yml @@ -1,5 +1,5 @@ #cloud-config -# vpn +# Создать passwd hash: openssl passwd -6 timezone: Europe/Moscow diff --git a/infra/cloud-config/rocky.yml b/infra/cloud-config/rocky.yml new file mode 100644 index 0000000..7309db3 --- /dev/null +++ b/infra/cloud-config/rocky.yml @@ -0,0 +1,21 @@ +#cloud-config +timezone: Europe/Moscow + +users: + - name: iurii + groups: [wheel] + shell: /bin/bash + lock_passwd: false + passwd: "$6$Zc8nwvtw0Kns5.sD$FpQ4aBSeGogefqjM4we4U5QQd4YBtC98tuG3rR4j9ZmbtC1kyFf2sY/IodYW3wG.U81aEntlZrtOTOqw3ZcOc0" + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + ssh_authorized_keys: + - ${ssh_key} + +package_update: true + +packages: + - qemu-guest-agent + +runcmd: + - systemctl enable --now qemu-guest-agent + - hostnamectl set-hostname ${hostname} \ No newline at end of file diff --git a/lab/cloud-config/vm.yml b/infra/cloud-config/worker.yml similarity index 93% rename from lab/cloud-config/vm.yml rename to infra/cloud-config/worker.yml index d2d933a..d77615e 100644 --- a/lab/cloud-config/vm.yml +++ b/infra/cloud-config/worker.yml @@ -1,5 +1,5 @@ #cloud-config -# vpn +# Создать passwd hash: openssl passwd -6 timezone: Europe/Moscow diff --git a/infra/locals.tf b/infra/locals.tf index cc609e7..ad0b759 100644 --- a/infra/locals.tf +++ b/infra/locals.tf @@ -1,43 +1,160 @@ # nodes — описание виртуальных машин # +# Общая идея: +# - каждая VM может иметь несколько сетевых интерфейсов (network_devices) +# - каждый интерфейс полностью описывает свою сеть (bridge, VLAN, IP, gateway) +# - порядок элементов в network_devices важен: +# [0] → eth0 (основной интерфейс, обычно с default gateway) +# [1] → eth1 +# [2] → eth2 +# +# network_devices: +# - список сетевых интерфейсов VM +# +# поля: +# +# bridge: +# - имя Proxmox bridge (например vmbr0, vmbr1) +# - ОБЯЗАТЕЛЬНО +# # vlan_id: -# - опциональный параметр -# - если НЕ указан → VM будет в обычной сети (untagged, vmbr0) -# - если указан → VM попадет в соответствующий VLAN (например 20 → 192.168.20.0/24) +# - опционально +# - если НЕ указан → интерфейс untagged +# - если указан → интерфейс будет в VLAN (например 20 → зависит от настройки Proxmox bridge) +# +# ip: +# - IPv4 адрес без CIDR (например "192.168.20.11") +# - если не указан → будет использован DHCP (если доступен в сети) +# +# cidr: +# - маска сети (например 24) +# - используется вместе с ip → итог: ip/cidr +# +# gateway: +# - опционально +# - указывать ТОЛЬКО для одного интерфейса (обычно первого) +# - задаёт default route внутри VM +# +# ВАЖНО: +# - gateway должен быть только у одного интерфейса +# - порядок network_devices критичен (eth0, eth1 и т.д.) +# - неправильный порядок → потеря доступа к VM +# +# # cloudinit: # - опциональный параметр -# - указывает имя cloud-init файла для конкретной VM -# - файл должен находиться в root: cloud-config/<имя>.yml -# - если НЕ указан → используется "default.yml" -# - если файл НЕ найден в root → используется fallback из модуля (modules/node/cloud-config/default.yml) +# - имя cloud-init файла +# - ищется в: +# cloud-config/<имя>.yml (root) +# - если не найден → fallback: +# modules/node/cloud-config/default.yml # # пример: -# - cloudinit = "worker.yml" → будет использован cloud-config/worker.yml -# - cloudinit не задан → будет использован default.yml +# - cloudinit = "worker.yml" → cloud-config/worker.yml +# - не указан → default.yml +# +# +# пример одной сети (single NIC): +# +# network_devices = [ +# { +# bridge = "vmbr0" +# vlan_id = 20 +# ip = "192.168.20.11" +# cidr = 24 +# gateway = "192.168.20.1" +# } +# ] +# +# +# пример двух сетей: +# +# network_devices = [ +# { +# bridge = "vmbr0" +# vlan_id = 20 +# ip = "192.168.20.23" +# cidr = 24 +# gateway = "192.168.20.1" +# }, +# { +# bridge = "vmbr1" +# ip = "192.168.22.26" +# cidr = 24 +# } +# ] +# +# +# РЕКОМЕНДАЦИИ: +# - первый интерфейс (eth0) → management сеть +# - второй интерфейс → storage / overlay / secondary +# - не задавать gateway на вторичных интерфейсах +# +# +# ПОВЕДЕНИЕ: +# - ip_config генерируется автоматически из network_devices +# - соответствие: порядок массива = порядок интерфейсов +# locals { nodes = { - # sing-box-tun= { - # cloudinit = "vm.yml" - # index = 2 - # cpu = 1 - # memory = 2048 - # disk = 7 - # datastore = "local-lvm" - # ip_offset = 0 - # ip = "192.168.22.50" - # } - - lesson= { - cloudinit = "vm.yml" - index = 2 - cpu = 2 - memory = 2048 - disk = 7 - datastore = "local-lvm" - ip_offset = 0 - ip = "192.168.22.52" - } + k8s-master-1 = { + cloudinit = "rocky.yml" + image_file = "import/rocky9.qcow2" + index = 1 + cpu = var.worker_cpu + memory = 4092 + disk = var.worker_disk + datastore = var.worker_datastore + network_devices = [ + { + bridge = var.node_bridge + vlan_id = 20 + ip = "192.168.20.11" + cidr = 24 + gateway = "192.168.20.1" + } + ] + } + # k8s-worker-1 = { + # cloudinit = "worker.yml" + # index = 2 + # cpu = var.worker_cpu + # memory = 8192 + # disk = var.worker_disk + # datastore = var.worker_datastore + + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.22" + # cidr = 24 + # gateway = "192.168.20.1" + # } + # ] + # }, + # k8s-worker-2 = { + # cloudinit = "worker.yml" + # index = 3 + # cpu = var.worker_cpu + # memory = 8192 + # disk = var.worker_disk + # datastore = var.worker_datastore + + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.23" + # cidr = 24 + # gateway = "192.168.20.1" + # }, + # { + # bridge = "vmbr0" + # } + # ] + # } } -} +} \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf index beb3713..f57953d 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -8,7 +8,6 @@ module "cluster" { nodes = local.nodes ssh_key = trimspace(data.local_file.ssh_key.content) - cluster_ip_start = var.cluster_ip_start worker_vmid_start = var.worker_vmid_start cloudinit_datastore = var.cloudinit_datastore @@ -19,9 +18,5 @@ module "cluster" { image_file = var.image_file disk_interface = var.disk_interface - network_base = var.network_base - network_cidr = var.network_cidr - cluster_gateway = var.cluster_gateway - data_datastore = var.data_datastore } diff --git a/infra/variables.tf b/infra/variables.tf index 7929429..2ded399 100644 --- a/infra/variables.tf +++ b/infra/variables.tf @@ -41,23 +41,6 @@ variable "worker_disk" { default = 20 } -variable "network_base" { - default = "192.168.22" -} - -variable "network_cidr" { - default = "24" -} - -variable "cluster_gateway" { - default = "192.168.22.1" -} - -variable "cluster_ip_start" { - default = 10 -} - - variable "worker_ip_offset" { default = 5 } @@ -66,6 +49,7 @@ variable "node_bridge" { default = "vmbr0" } + variable "worker_datastore" { type = string default = "local-lvm" diff --git a/lab/cloud-config/master.yml b/lab/cloud-config/master.yml new file mode 100644 index 0000000..d77615e --- /dev/null +++ b/lab/cloud-config/master.yml @@ -0,0 +1,34 @@ +#cloud-config +# Создать passwd hash: openssl passwd -6 + +timezone: Europe/Moscow + +users: + - name: iurii + groups: [sudo] + shell: /bin/bash + lock_passwd: false + passwd: "$6$Zc8nwvtw0Kns5.sD$FpQ4aBSeGogefqjM4we4U5QQd4YBtC98tuG3rR4j9ZmbtC1kyFf2sY/IodYW3wG.U81aEntlZrtOTOqw3ZcOc0" + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + ssh_authorized_keys: + - ${ssh_key} + +package_update: true + +packages: + - qemu-guest-agent + +runcmd: + - systemctl enable --now qemu-guest-agent + - hostnamectl set-hostname ${hostname} + - systemctl disable --now packagekit + - systemctl disable --now ModemManager + - systemctl disable --now multipathd + +write_files: + - path: /etc/motd + content: | + Managed by OpenTofu + + +final_message: "cloud-init finished" \ No newline at end of file diff --git a/lab/cloud-config/rocky.yml b/lab/cloud-config/rocky.yml new file mode 100644 index 0000000..7309db3 --- /dev/null +++ b/lab/cloud-config/rocky.yml @@ -0,0 +1,21 @@ +#cloud-config +timezone: Europe/Moscow + +users: + - name: iurii + groups: [wheel] + shell: /bin/bash + lock_passwd: false + passwd: "$6$Zc8nwvtw0Kns5.sD$FpQ4aBSeGogefqjM4we4U5QQd4YBtC98tuG3rR4j9ZmbtC1kyFf2sY/IodYW3wG.U81aEntlZrtOTOqw3ZcOc0" + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + ssh_authorized_keys: + - ${ssh_key} + +package_update: true + +packages: + - qemu-guest-agent + +runcmd: + - systemctl enable --now qemu-guest-agent + - hostnamectl set-hostname ${hostname} \ No newline at end of file diff --git a/lab/cloud-config/worker.yml b/lab/cloud-config/worker.yml new file mode 100644 index 0000000..d77615e --- /dev/null +++ b/lab/cloud-config/worker.yml @@ -0,0 +1,34 @@ +#cloud-config +# Создать passwd hash: openssl passwd -6 + +timezone: Europe/Moscow + +users: + - name: iurii + groups: [sudo] + shell: /bin/bash + lock_passwd: false + passwd: "$6$Zc8nwvtw0Kns5.sD$FpQ4aBSeGogefqjM4we4U5QQd4YBtC98tuG3rR4j9ZmbtC1kyFf2sY/IodYW3wG.U81aEntlZrtOTOqw3ZcOc0" + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + ssh_authorized_keys: + - ${ssh_key} + +package_update: true + +packages: + - qemu-guest-agent + +runcmd: + - systemctl enable --now qemu-guest-agent + - hostnamectl set-hostname ${hostname} + - systemctl disable --now packagekit + - systemctl disable --now ModemManager + - systemctl disable --now multipathd + +write_files: + - path: /etc/motd + content: | + Managed by OpenTofu + + +final_message: "cloud-init finished" \ No newline at end of file diff --git a/lab/locals.tf b/lab/locals.tf index cec4421..3dcaad8 100644 --- a/lab/locals.tf +++ b/lab/locals.tf @@ -1,31 +1,179 @@ # nodes — описание виртуальных машин # +# Общая идея: +# - каждая VM может иметь несколько сетевых интерфейсов (network_devices) +# - каждый интерфейс полностью описывает свою сеть (bridge, VLAN, IP, gateway) +# - порядок элементов в network_devices важен: +# [0] → eth0 (основной интерфейс, обычно с default gateway) +# [1] → eth1 +# [2] → eth2 +# +# network_devices: +# - список сетевых интерфейсов VM +# +# поля: +# +# bridge: +# - имя Proxmox bridge (например vmbr0, vmbr1) +# - ОБЯЗАТЕЛЬНО +# # vlan_id: -# - опциональный параметр -# - если НЕ указан → VM будет в обычной сети (untagged, vmbr0) -# - если указан → VM попадет в соответствующий VLAN (например 20 → 192.168.20.0/24) +# - опционально +# - если НЕ указан → интерфейс untagged +# - если указан → интерфейс будет в VLAN (например 20 → зависит от настройки Proxmox bridge) +# +# ip: +# - IPv4 адрес без CIDR (например "192.168.20.11") +# - если не указан → будет использован DHCP (если доступен в сети) +# +# cidr: +# - маска сети (например 24) +# - используется вместе с ip → итог: ip/cidr +# +# gateway: +# - опционально +# - указывать ТОЛЬКО для одного интерфейса (обычно первого) +# - задаёт default route внутри VM +# +# ВАЖНО: +# - gateway должен быть только у одного интерфейса +# - порядок network_devices критичен (eth0, eth1 и т.д.) +# - неправильный порядок → потеря доступа к VM +# +# # cloudinit: # - опциональный параметр -# - указывает имя cloud-init файла для конкретной VM -# - файл должен находиться в root: cloud-config/<имя>.yml -# - если НЕ указан → используется "default.yml" -# - если файл НЕ найден в root → используется fallback из модуля (modules/node/cloud-config/default.yml) +# - имя cloud-init файла +# - ищется в: +# cloud-config/<имя>.yml (root) +# - если не найден → fallback: +# modules/node/cloud-config/default.yml # # пример: -# - cloudinit = "worker.yml" → будет использован cloud-config/worker.yml -# - cloudinit не задан → будет использован default.yml +# - cloudinit = "worker.yml" → cloud-config/worker.yml +# - не указан → default.yml +# +# +# пример одной сети (single NIC): +# +# network_devices = [ +# { +# bridge = "vmbr0" +# vlan_id = 20 +# ip = "192.168.20.11" +# cidr = 24 +# gateway = "192.168.20.1" +# } +# ] +# +# +# пример двух сетей: +# +# network_devices = [ +# { +# bridge = "vmbr0" +# vlan_id = 20 +# ip = "192.168.20.23" +# cidr = 24 +# gateway = "192.168.20.1" +# }, +# { +# bridge = "vmbr1" +# ip = "192.168.22.26" +# cidr = 24 +# } +# ] +# +# +# РЕКОМЕНДАЦИИ: +# - первый интерфейс (eth0) → management сеть +# - второй интерфейс → storage / overlay / secondary +# - не задавать gateway на вторичных интерфейсах +# +# +# ПОВЕДЕНИЕ: +# - ip_config генерируется автоматически из network_devices +# - соответствие: порядок массива = порядок интерфейсов +# locals { nodes = { - vm1 = { - cloudinit = "vm.yml" + lab-1 = { + cloudinit = "rocky.yml" + image_file = "import/rocky9.qcow2" index = 1 - cpu = 1 - memory = 1024 + cpu = var.worker_cpu + memory = 4092 disk = var.worker_disk datastore = var.worker_datastore - ip_offset = 0 - vlan_id = 20 - } - } -} + + network_devices = [ + { + bridge = var.node_bridge + vlan_id = 20 + ip = "192.168.20.11" + cidr = 24 + gateway = "192.168.20.1" + } + ] + } + # lab-2 = { + # cloudinit = "rocky.yml" + # image_file = "import/rocky9.qcow2" + # index = 2 + # cpu = var.worker_cpu + # memory = 2048 + # disk = var.worker_disk + # datastore = var.worker_datastore + + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.12" + # cidr = 24 + # gateway = "192.168.20.1" + # } + # ] + # } + # k8s-worker-1 = { + # cloudinit = "worker.yml" + # index = 2 + # cpu = var.worker_cpu + # memory = 8192 + # disk = var.worker_disk + # datastore = var.worker_datastore + + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.22" + # cidr = 24 + # gateway = "192.168.20.1" + # } + # ] + # }, + # k8s-worker-2 = { + # cloudinit = "worker.yml" + # index = 3 + # cpu = var.worker_cpu + # memory = 8192 + # disk = var.worker_disk + # datastore = var.worker_datastore + + # network_devices = [ + # { + # bridge = var.node_bridge + # vlan_id = 20 + # ip = "192.168.20.23" + # cidr = 24 + # gateway = "192.168.20.1" + # }, + # { + # bridge = "vmbr0" + # } + # ] + # } + } +} \ No newline at end of file diff --git a/lab/main.tf b/lab/main.tf index beb3713..f57953d 100644 --- a/lab/main.tf +++ b/lab/main.tf @@ -8,7 +8,6 @@ module "cluster" { nodes = local.nodes ssh_key = trimspace(data.local_file.ssh_key.content) - cluster_ip_start = var.cluster_ip_start worker_vmid_start = var.worker_vmid_start cloudinit_datastore = var.cloudinit_datastore @@ -19,9 +18,5 @@ module "cluster" { image_file = var.image_file disk_interface = var.disk_interface - network_base = var.network_base - network_cidr = var.network_cidr - cluster_gateway = var.cluster_gateway - data_datastore = var.data_datastore } diff --git a/lab/variables.tf b/lab/variables.tf index 7929429..2ded399 100644 --- a/lab/variables.tf +++ b/lab/variables.tf @@ -41,23 +41,6 @@ variable "worker_disk" { default = 20 } -variable "network_base" { - default = "192.168.22" -} - -variable "network_cidr" { - default = "24" -} - -variable "cluster_gateway" { - default = "192.168.22.1" -} - -variable "cluster_ip_start" { - default = 10 -} - - variable "worker_ip_offset" { default = 5 } @@ -66,6 +49,7 @@ variable "node_bridge" { default = "vmbr0" } + variable "worker_datastore" { type = string default = "local-lvm" diff --git a/modules/node/main.tf b/modules/node/main.tf index 319b0bb..f836341 100644 --- a/modules/node/main.tf +++ b/modules/node/main.tf @@ -32,6 +32,7 @@ resource "proxmox_virtual_environment_file" "cloudinit" { resource "proxmox_virtual_environment_vm" "nodes" { for_each = local.nodes + tags = ["tofu"] name = local.hostname_map[each.key] node_name = var.proxmox_node @@ -48,6 +49,8 @@ resource "proxmox_virtual_environment_vm" "nodes" { cpu { cores = each.value.cpu + type = "host" + } memory { @@ -63,12 +66,24 @@ resource "proxmox_virtual_environment_vm" "nodes" { } } - disk { +dynamic "clone" { + for_each = try(each.value.template_id, null) == null ? [] : [each.value.template_id] + + content { + vm_id = clone.value + } +} + +dynamic "disk" { + for_each = try(each.value.template_id, null) == null ? [1] : [] + + content { datastore_id = each.value.datastore import_from = "${var.image_datastore}:${var.image_file}" interface = var.disk_interface size = each.value.disk } +} dynamic "disk" { for_each = try([each.value.data_disk], []) diff --git a/modules/node/variables.tf b/modules/node/variables.tf index c2fc9af..dfe1b79 100644 --- a/modules/node/variables.tf +++ b/modules/node/variables.tf @@ -12,6 +12,7 @@ variable "nodes" { vmid = optional(number) data_disk = optional(number) cloudinit = optional(string) + template_id = optional(number) network_devices = list(object({ bridge = string diff --git a/setup_disk.sh b/setup_disk.sh new file mode 100644 index 0000000..980b053 --- /dev/null +++ b/setup_disk.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail + +DISK="/dev/sdb" +PART="${DISK}1" +MOUNT_POINT="/u01" + +echo "[1] Проверка диска" +lsblk "$DISK" + +echo "[2] Создание GPT и раздела" +sudo parted "$DISK" --script mklabel gpt +sudo parted "$DISK" --script mkpart primary ext4 0% 100% + +echo "[3] Ожидание появления раздела" +sleep 2 + +echo "[4] Форматирование" +sudo mkfs.ext4 -F "$PART" + +echo "[5] Создание точки монтирования" +sudo mkdir -p "$MOUNT_POINT" + +echo "[6] Получение UUID" +UUID=$(blkid -s UUID -o value "$PART") + +if [[ -z "$UUID" ]]; then + echo "ERROR: UUID not found" + exit 1 +fi + +echo "[7] Добавление в fstab" +if ! grep -q "$UUID" /etc/fstab; then + echo "UUID=$UUID $MOUNT_POINT ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab +fi + +echo "[8] Применение" +sudo systemctl daemon-reload +sudo mount -a + +echo "[9] Проверка" +df -h | grep "$MOUNT_POINT" + +echo "[10] Подготовка под OpenSearch" +sudo mkdir -p /u01/opensearch +sudo chown -R 1000:1000 /u01/opensearch + +echo "DONE" \ No newline at end of file