diff --git a/api/core/v1alpha2/cluster_virtual_image.go b/api/core/v1alpha2/cluster_virtual_image.go index 2f7496d2a9..dda945c29e 100644 --- a/api/core/v1alpha2/cluster_virtual_image.go +++ b/api/core/v1alpha2/cluster_virtual_image.go @@ -32,6 +32,7 @@ const ( // // With this resource in the cluster, a container image is created and stored in a dedicated Deckhouse Virtualization Container Registry (DVCR). // +// **Note:** The `metadata.name` field must comply with [Kubernetes object naming conventions](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/) and must not exceed 48 characters. // +kubebuilder:object:root=true // +kubebuilder:metadata:labels={heritage=deckhouse,module=virtualization,backup.deckhouse.io/cluster-config=true} // +kubebuilder:resource:categories={virtualization-cluster},scope=Cluster,shortName={cvi},singular=clustervirtualimage diff --git a/api/core/v1alpha2/virtual_disk.go b/api/core/v1alpha2/virtual_disk.go index 307908220e..0bf8eb8b0f 100644 --- a/api/core/v1alpha2/virtual_disk.go +++ b/api/core/v1alpha2/virtual_disk.go @@ -29,7 +29,9 @@ const ( // The VirtualDisk resource describes the desired virtual machine disk configuration. A VirtualDisk can be mounted statically in the virtual machine by specifying it in the `.spec.blockDeviceRefs` disk list, or mounted on-the-fly using the VirtualMachineBlockDeviceAttachments resource. // -// Once a VirtualDisk is created, only the disk size field `.spec.persistentVolumeClaim.size` can be changed. All other fields are immutable. +// Once a VirtualDisk is created, the following fields in `.spec.persistentVolumeClaim` can be changed: `size` and `storageClassName`. All other fields are immutable. +// +// **Note:** The `metadata.name` field must comply with [Kubernetes object naming conventions](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/) and must not exceed 60 characters. // +kubebuilder:object:root=true // +kubebuilder:metadata:labels={heritage=deckhouse,module=virtualization} // +kubebuilder:resource:categories={virtualization},scope=Namespaced,shortName={vd},singular=virtualdisk diff --git a/api/core/v1alpha2/virtual_image.go b/api/core/v1alpha2/virtual_image.go index 2bbf256d70..ecb335d406 100644 --- a/api/core/v1alpha2/virtual_image.go +++ b/api/core/v1alpha2/virtual_image.go @@ -31,6 +31,8 @@ const ( // > This resource cannot be modified once it has been created. // // With this resource in the cluster, a container image is created and stored in a dedicated Deckhouse Virtualization Container Registry (DVCR) or PVC, with the data filled in from the source. +// +// **Note:** The `metadata.name` field must comply with [Kubernetes object naming conventions](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/) and must not exceed 49 characters. // +genclient // +kubebuilder:object:root=true // +kubebuilder:metadata:labels={heritage=deckhouse,module=virtualization} diff --git a/crds/doc-ru-virtualdisks.yaml b/crds/doc-ru-virtualdisks.yaml index 5680ca78a3..af3143b254 100644 --- a/crds/doc-ru-virtualdisks.yaml +++ b/crds/doc-ru-virtualdisks.yaml @@ -6,7 +6,7 @@ spec: description: | Ресурс VirtualDisk описывает желаемую конфигурацию диска виртуальной машины. VirtualDisk можно смонтировать в виртуальной машине статически, указав его в списке дисков `.spec.blockDeviceRefs`, или «на лету» – с помощью ресурса VirtualMachineBlockDeviceAttachments. - После создания VirtualDisk можно изменить только размер диска с помощью поля `.spec.persistentVolumeClaim.size`. Все остальные поля изменить нельзя. + После создания VirtualDisk в `.spec.persistentVolumeClaim` можно изменить поля `size` и `storageClassName`. Все остальные поля неизменяемы. **Важно:** Поле `metadata.name` должно соответствовать [правилам именования объектов Kubernetes](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/) и не должно превышать 60 символов. properties: diff --git a/crds/virtualdisks.yaml b/crds/virtualdisks.yaml index c0d6a84b76..6f720ded92 100644 --- a/crds/virtualdisks.yaml +++ b/crds/virtualdisks.yaml @@ -57,7 +57,7 @@ spec: description: |- The VirtualDisk resource describes the desired virtual machine disk configuration. A VirtualDisk can be mounted statically in the virtual machine by specifying it in the `.spec.blockDeviceRefs` disk list, or mounted on-the-fly using the VirtualMachineBlockDeviceAttachments resource. - Once a VirtualDisk is created, only the disk size field `.spec.persistentVolumeClaim.size` can be changed. All other fields are immutable. + Once a VirtualDisk is created, the following fields in `.spec.persistentVolumeClaim` can be changed: `size` and `storageClassName`. All other fields are immutable. **Note:** The `metadata.name` field must comply with [Kubernetes object naming conventions](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/) and must not exceed 60 characters. properties: diff --git a/crds/virtualmachineipaddresses.yaml b/crds/virtualmachineipaddresses.yaml index 6443d8bfc4..7a7f802a60 100644 --- a/crds/virtualmachineipaddresses.yaml +++ b/crds/virtualmachineipaddresses.yaml @@ -121,7 +121,7 @@ spec: * `Pending`: The resource is being created. * `Bound`: The VirtualMachineIPAddress has been bound to the VirtualMachineIPAddressLease resource. - * `Attached`: The VirtualMachineIPAddress resource has been bound to the VirtualMachine resource. + * `Attached`: The VirtualMachineIPAddress is attached to the VirtualMachine resource. observedGeneration: type: integer description: | diff --git a/docs/ADMIN_GUIDE.md b/docs/ADMIN_GUIDE.md index d885cd0610..37a8a18e47 100644 --- a/docs/ADMIN_GUIDE.md +++ b/docs/ADMIN_GUIDE.md @@ -194,26 +194,65 @@ Where: Not available in CE edition. {{< /alert >}} -{{< alert level="warning" >}} -To set up auditing, the following modules must be enabled: +To enable security event auditing: -- `log-shipper`, -- `runtime-audit-engine`. -{{< /alert >}} +1. Enable `log-shipper` and `runtime-audit-engine` modules. +1. Enable Kubernetes API audit by setting `.spec.settings.apiserver.auditPolicyEnabled: true` in the `control-plane-manager` module. +1. Set `.spec.settings.audit.enabled: true` in the `virtualization` module: -To enable security event auditing, set the module’s `.spec.settings.audit.enabled` parameter to `true`: + ```yaml + spec: + settings: + audit: + enabled: true + ``` + +For a complete list of configuration options, see [Configuration](./configuration.html). + +Events are collected by the `virtualization-audit-*` pod in the `d8-virtualization` namespace. To forward events to the cluster logging system (e.g., Loki), create a ClusterLoggingConfig: ```yaml +apiVersion: deckhouse.io/v1alpha1 +kind: ClusterLoggingConfig +metadata: + name: virtualization-audit-logs spec: - enabled: true - settings: - audit: - enabled: true + destinationRefs: + - d8-loki + kubernetesPods: + namespaceSelector: + matchNames: + - d8-virtualization + labelSelector: + matchLabels: + app: virtualization-audit + type: KubernetesPods ``` -{{< alert level="info" >}} -For a complete list of configuration options, see [Configuration](./configuration.html). -{{< /alert >}} +To view events in Grafana, use a Loki query: + +```logql +{namespace="d8-virtualization", pod=~"virtualization-audit-.*"} +``` + +Available fields in the logs: +- `type`: Event type (Access to VM, VM Management, etc.). +- `name`: Human-readable description. +- `request_subject`: Username or ServiceAccount. +- `datetime`: Event timestamp. +- `virtualmachine_name`: Affected VM. +- `source_ip`: Request source IP (for forbidden operations). + +### Security events + +The audit system logs the following events: + +- Access to VM: Connection via console, VNC, or port forward. Includes VM name, OS, versions, storage, and node address. +- VM Management: Create, update, patch, or delete operations on [VirtualMachine](/modules/virtualization/cr.html#virtualmachine) resources. +- VM Control Operations: Start, stop, restart, migrate, or evict via [VirtualMachineOperation](/modules/virtualization/cr.html#virtualmachineoperation) resource. +- Integrity Check: SHA256 verification of VM configuration. Logs when checksum changes. +- Module Control: Create, update, or delete operations on ModuleConfig. +- Forbidden Operations: Operations blocked by the platform. Includes user, operation, resource, source IP, and denial reason. ## Images diff --git a/docs/ADMIN_GUIDE.ru.md b/docs/ADMIN_GUIDE.ru.md index 2dcf015f91..c30d69bf6c 100644 --- a/docs/ADMIN_GUIDE.ru.md +++ b/docs/ADMIN_GUIDE.ru.md @@ -194,26 +194,65 @@ spec: Недоступно в CE-редакции. {{< /alert >}} -{{< alert level="warning" >}} -Для активации аудита требуется, чтобы были включены следующие модули: +Для активации аудита событий безопасности: -- `log-shipper`, -- `runtime-audit-engine`. -{{< /alert >}} +1. Включить модули `log-shipper` и `runtime-audit-engine`. +1. Включить аудит Kubernetes API, установив `.spec.settings.apiserver.auditPolicyEnabled: true` в модуле `control-plane-manager`. +1. Установить `.spec.settings.audit.enabled: true` в модуле `virtualization`: + + ```yaml + spec: + settings: + audit: + enabled: true + ``` + +Полный перечень параметров конфигурации приведён в разделе [Настройки](./configuration.html). -Чтобы включить аудит событий безопасности, установите параметр `.spec.settings.audit.enabled` настроек модуля в `true`: +События собираются подом `virtualization-audit-*` в пространстве имён `d8-virtualization`. Чтобы перенаправить события в систему логирования кластера (например, Loki), создайте ClusterLoggingConfig: ```yaml +apiVersion: deckhouse.io/v1alpha1 +kind: ClusterLoggingConfig +metadata: + name: virtualization-audit-logs spec: - enabled: true - settings: - audit: - enabled: true + destinationRefs: + - d8-loki + kubernetesPods: + namespaceSelector: + matchNames: + - d8-virtualization + labelSelector: + matchLabels: + app: virtualization-audit + type: KubernetesPods ``` -{{< alert level="info" >}} -Полный перечень параметров конфигурации приведен в разделе [Настройки](./configuration.html). -{{< /alert >}} +Для просмотра событий в Grafana используйте запрос к Loki: + +```logql +{namespace="d8-virtualization", pod=~"virtualization-audit-.*"} +``` + +Доступные поля в логах: +- `type` — тип события (Access to VM, VM Management и т.д.); +- `name` — описание события; +- `request_subject` — username или ServiceAccount; +- `datetime` — время события; +- `virtualmachine_name` — имя ВМ; +- `source_ip` — IP-адрес источника (для запрещённых операций). + +### События безопасности + +Система аудита фиксирует следующие события: + +- Доступ к ВМ — подключение через console, VNC или port forward. Включает имя ВМ, ОС, версии, хранилище и адрес узла. +- Управление ВМ — создание, обновление, изменение или удаление ресурсов [VirtualMachine](/modules/virtualization/cr.html#virtualmachine). +- Управление ВМ через операции — Start, Stop, Restart, Migrate или Evict через ресурс [VirtualMachineOperation](/modules/virtualization/cr.html#virtualmachineoperation). +- Проверка целостности — проверка SHA256 конфигурации ВМ. Логируется при изменении контрольной суммы. +- Управление модулем — создание, обновление или удаление ModuleConfig. +- Запрещённые операции — операции, заблокированные платформой. Включает пользователя, операцию, ресурс, IP-адрес и причину отказа. ## Образы diff --git a/docs/FAQ.md b/docs/FAQ.md index 6310c6147d..a55ab15fdf 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -3,94 +3,93 @@ title: "FAQ" weight: 70 --- -## How to install an operating system in a virtual machine from an iso-image? +## Working with virtual machines -Let's consider installing an operating system in a virtual machine from an iso-image, -using Windows OS installation as an example. +### Installing and configuring the operating system -To install the OS we will need an iso-image of Windows OS. -We need to download it and publish it on some http-service available from the cluster. +#### How to install an operating system in a virtual machine from an ISO image? -1. Create an empty disk for OS installation: +Below is a typical Windows guest OS installation scenario from an ISO image. Before you begin, host the ISO on an HTTP endpoint reachable from the cluster. - ```bash - d8 k apply -f -<autounattend.xml +
Example of the contents of the autounattend.xml file… ```xml @@ -308,53 +305,255 @@ For example, let's take a file that allows you to:
-Create a secret from this xml file: +1. Save the answer file as `autounattend.xml` (use the example above or adjust it to your needs). -```bash -d8 k create secret generic sysprep-config --type="provisioning.virtualization.deckhouse.io/sysprep" --from-file=./autounattend.xml -``` +1. Create a secret with the type `provisioning.virtualization.deckhouse.io/sysprep`: + + ```bash + d8 k create secret generic sysprep-config --type="provisioning.virtualization.deckhouse.io/sysprep" --from-file=./autounattend.xml + ``` -Then you can create a virtual machine that will use an answer file during installation. -To provide the Windows virtual machine with the answer file, -you need to specify provisioning with the type SysprepRef. -You can also specify here other files in base64 format, that you need to successfully execute scripts inside the answer file. +1. Create a virtual machine that will use the answer file during installation. Specify `provisioning` with type `SysprepRef` in the specification. If necessary, add other Base64-encoded files to the specification required for the answer file scripts to run successfully. -```yaml -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: win-vm - namespace: default - labels: - vm: win -spec: - virtualMachineClassName: generic - provisioning: - type: SysprepRef - sysprepRef: - kind: Secret - name: sysprep-config - runPolicy: AlwaysOn - osType: Windows - bootloader: EFI - cpu: - cores: 6 - coreFraction: 50% - memory: - size: 8Gi - enableParavirtualization: true - blockDeviceRefs: - - kind: VirtualDisk - name: win-disk - - kind: ClusterVirtualImage - name: win-11-iso - - kind: ClusterVirtualImage - name: win-virtio-iso -``` + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: VirtualMachine + metadata: + name: win-vm + namespace: default + labels: + vm: win + spec: + virtualMachineClassName: generic + provisioning: + type: SysprepRef + sysprepRef: + kind: Secret + name: sysprep-config + runPolicy: AlwaysOn + osType: Windows + bootloader: EFI + cpu: + cores: 6 + coreFraction: 50% + memory: + size: 8Gi + enableParavirtualization: true + blockDeviceRefs: + - kind: VirtualDisk + name: win-disk + - kind: ClusterVirtualImage + name: win-11-iso + - kind: ClusterVirtualImage + name: win-virtio-iso + ``` -## How to use cloud-init to configure virtual machines? +#### How to create a golden image for Linux? -Cloud-Init is a tool for automatically configuring virtual machines on first boot. The configuration is written in YAML format and must start with the `#cloud-config` header. +A golden image is a pre-configured virtual machine image that can be used to quickly create new VMs with pre-installed software and settings. + +1. Create a virtual machine, install the required software on it, and perform all necessary configurations. + +1. Install and configure qemu-guest-agent (recommended): + + - For RHEL/CentOS: + + ```bash + yum install -y qemu-guest-agent + ``` + + - For Debian/Ubuntu: + + ```bash + apt-get update + apt-get install -y qemu-guest-agent + ``` + +1. Enable and start the service: + + ```bash + systemctl enable qemu-guest-agent + systemctl start qemu-guest-agent + ``` + +1. Set the VM run policy to [runPolicy: AlwaysOnUnlessStoppedManually](/modules/virtualization/cr.html#virtualmachine-v1alpha2-spec-runpolicy) — this is required so you can shut down the VM. + +1. Prepare the image. Clean unused filesystem blocks: + + ```bash + fstrim -v / + fstrim -v /boot + ``` + +1. Clean network settings: + + - For RHEL: + + ```bash + nmcli con delete $(nmcli -t -f NAME,DEVICE con show | grep -v ^lo: | cut -d: -f1) + rm -f /etc/sysconfig/network-scripts/ifcfg-eth* + ``` + + - For Debian/Ubuntu: + + ```bash + rm -f /etc/network/interfaces.d/* + ``` + +1. Clean system identifiers: + + ```bash + echo -n > /etc/machine-id + rm -f /var/lib/dbus/machine-id + ln -s /etc/machine-id /var/lib/dbus/machine-id + ``` + +1. Remove SSH host keys: + + ```bash + rm -f /etc/ssh/ssh_host_* + ``` + +1. Clean systemd journal: + + ```bash + journalctl --vacuum-size=100M --vacuum-time=7d + ``` + +1. Clean package manager cache: + + - For RHEL: + + ```bash + yum clean all + ``` + + - For Debian/Ubuntu: + + ```bash + apt-get clean + ``` + +1. Clean temporary files: + + ```bash + rm -rf /tmp/* + rm -rf /var/tmp/* + ``` + +1. Clean logs: + + ```bash + find /var/log -name "*.log" -type f -exec truncate -s 0 {} \; + ``` + +1. Clean command history: + + ```bash + history -c + ``` + + For RHEL: reset and restore SELinux contexts (choose one of the following): + + - Option 1: Check and restore contexts immediately: + + ```bash + restorecon -R / + ``` + + - Option 2: Schedule relabel on next boot: + + ```bash + touch /.autorelabel + ``` + +1. Verify that `/etc/fstab` references UUID or `LABEL` rather than names like `/dev/sdX`: + + ```bash + blkid + cat /etc/fstab + ``` + +1. Reset cloud-init state (logs and seed): + + ```bash + cloud-init clean --logs --seed + ``` + +1. Perform final synchronization and buffer cleanup: + + ```bash + sync + echo 3 > /proc/sys/vm/drop_caches + ``` + +1. Shut down the virtual machine: + + ```bash + poweroff + ``` + +1. Create a [VirtualImage](/modules/virtualization/cr.html#virtualimage) resource that references the prepared VM’s [VirtualDisk](/modules/virtualization/cr.html#virtualdisk): + + ```bash + d8 k apply -f -< + namespace: + spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualDisk + name: + EOF + ``` + + Or create a [ClusterVirtualImage](/modules/virtualization/cr.html#clustervirtualimage) resource so the image is available cluster-wide for all projects: + + ```bash + d8 k apply -f -< + spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualDisk + name: + namespace: + EOF + ``` + +1. Create a new [VirtualDisk](/modules/virtualization/cr.html#virtualdisk) from the resulting image: + + ```bash + d8 k apply -f -< + namespace: + spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualImage + name: + EOF + ``` + +After completing these steps, you will have a golden image that can be used to quickly create new virtual machines with pre-installed software and configurations. + +## Configuring virtual machines + +### How to use cloud-init to configure virtual machines? + +[Cloud-init](https://cloudinit.readthedocs.io/) is used for initial guest OS configuration on first boot. The configuration is written in YAML and starts with the `#cloud-config` directive. {{< alert level="warning" >}} When using cloud images (for example, official distribution images), you must provide a cloud-init configuration. Without it, some distributions do not configure network connectivity, and the virtual machine becomes unreachable on the network, even if the main network (Main) is attached. @@ -362,9 +561,9 @@ When using cloud images (for example, official distribution images), you must pr In addition, cloud images do not allow login by default — you must either add SSH keys for the default user or create a new user with SSH access. Otherwise, you will not be able to access the virtual machine. {{< /alert >}} -### Updating and installing packages +#### Updating and installing packages -Example configuration for updating the system and installing packages: +Example `cloud-config` for updating the system and installing packages from a list: ```yaml #cloud-config @@ -382,9 +581,9 @@ runcmd: - systemctl enable --now nginx.service ``` -### Creating a user +#### Creating a user -Example configuration for creating a user with a password and SSH key: +Example `cloud-config` for creating a local user with a password and SSH key: ```yaml #cloud-config @@ -401,11 +600,15 @@ users: ssh_pwauth: true ``` -To generate a password hash, use the `mkpasswd --method=SHA-512 --rounds=4096` command. +To generate a password hash for the `passwd` field, run: + +```shell +mkpasswd --method=SHA-512 --rounds=4096 +``` -### Creating a file with required permissions +#### Creating a file with required permissions -Example configuration for creating a file with specified access permissions: +Example `cloud-config` for creating a file with specified access permissions: ```yaml #cloud-config @@ -419,9 +622,9 @@ write_files: permissions: '0755' # Access permissions (octal format) ``` -### Configuring disk and filesystem +#### Configuring disk and filesystem -Example configuration for disk partitioning, filesystem creation, and mounting: +Example `cloud-config` for disk partitioning, filesystem creation, and mounting: ```yaml #cloud-config @@ -445,19 +648,19 @@ mounts: - ["/dev/sdb1", "/mnt/data", "ext4", "defaults", "0", "2"] ``` -### Configuring network interfaces for additional networks - -For more information on connecting additional networks to a virtual machine, see the [Additional network interfaces](./user_guide.html#additional-network-interfaces) section. +#### Configuring network interfaces for additional networks {{< alert level="warning" >}} The settings described in this section apply only to additional networks. The main network (Main) is configured automatically via cloud-init and does not require manual configuration. {{< /alert >}} -If additional networks are connected to a virtual machine, they must be configured manually via cloud-init. Use `write_files` to create configuration files and `runcmd` to apply the settings. +If additional networks are connected to a virtual machine, configure them manually via cloud-init: create configuration files in `write_files` and apply the settings in `runcmd`. -#### For systemd-networkd +For more information on connecting additional networks to a virtual machine, see [Additional network interfaces](/products/virtualization-platform/documentation/user/resource-management/virtual-machines.html#additional-network-interfaces). -Use the following example on distributions that use `systemd-networkd` (for example, Debian, CoreOS): +##### For systemd-networkd + +Example `cloud-config` for distributions that use `systemd-networkd` (Debian, CoreOS, and others): ```yaml #cloud-config @@ -476,9 +679,9 @@ runcmd: - systemctl restart systemd-networkd ``` -#### For Netplan (Ubuntu) +##### For Netplan (Ubuntu) -Use the following example on Ubuntu and other distributions that use `Netplan`: +Example `cloud-config` for Ubuntu and other systems that use `Netplan`: ```yaml #cloud-config @@ -501,9 +704,9 @@ runcmd: - netplan apply ``` -#### For ifcfg (RHEL/CentOS) +##### For ifcfg (RHEL/CentOS) -Use the following example on RHEL, CentOS and other distributions that use the `ifcfg` scheme with `NetworkManager`: +Example `cloud-config` for RHEL-compatible distributions that use the `ifcfg` scheme and `NetworkManager`: ```yaml #cloud-config @@ -523,9 +726,9 @@ runcmd: - nmcli connection up eth1 ``` -#### For Alpine Linux +##### For Alpine Linux -Use the following example on Alpine Linux and other distributions that use the traditional `/etc/network/interfaces` format: +Example `cloud-config` for distributions that use the traditional `/etc/network/interfaces` format (Alpine and similar): ```yaml #cloud-config @@ -543,396 +746,199 @@ runcmd: - /etc/init.d/networking restart ``` -## How to use Ansible to provision virtual machines? +### How to use Ansible to provision virtual machines? -[Ansible](https://docs.ansible.com/ansible/latest/index.html) is an automation tool that helps you to run tasks on remote servers via SSH. In this example, we will show you how to use Ansible to manage virtual machines in a demo-app project. +[Ansible](https://docs.ansible.com/ansible/latest/index.html) is an automation tool for running tasks on remote servers over SSH. This example shows how to use Ansible with virtual machines in the `demo-app` project. -The following assumptions will be used: +The example assumes that: -- There is a frontend virtual machine in a demo-app project. -- A cloud user is set up on the virtual machine for SSH access. -- The SSH private key for the cloud user is stored in the /home/user/.ssh/id_rsa file on the Ansible server. +- `demo-app` namespace contains a VM named `frontend`. +- VM has a `cloud` user with SSH access. +- Private SSH key on the machine where Ansible runs is stored in `/home/user/.ssh/id_rsa`. -Ansible inventory file example: +1. Create an `inventory.yaml` file: -```yaml ---- -all: - vars: - ansible_ssh_common_args: '-o ProxyCommand="d8 v port-forward --stdio=true %h %h %p"' - # Default user for SSH access. - ansible_user: cloud - # Path to private key. - ansible_ssh_private_key_file: /home/user/.ssh/id_rsa - hosts: - # Host name in the format .. - frontend.demo-app: -``` + ```yaml + --- + all: + vars: + ansible_ssh_common_args: '-o ProxyCommand="d8 v port-forward --stdio=true %h %p"' + # Default user for SSH access. + ansible_user: cloud + # Path to private key. + ansible_ssh_private_key_file: /home/user/.ssh/id_rsa + hosts: + # Host name in the format .. + frontend.demo-app: -To check the virtual machine's uptime value, use the following command: + ``` -```bash -ansible -m shell -a "uptime" -i inventory.yaml all -# frontend.demo-app | CHANGED | rc=0 >> -# 12:01:20 up 2 days, 4:59, 0 users, load average: 0.00, 0.00, 0.00 -``` +1. Check the virtual machine `uptime`: -If you prefer not to use the inventory file, you can specify and pass all the parameters directly in the command line: + ```bash + ansible -m shell -a "uptime" -i inventory.yaml all + + # frontend.demo-app | CHANGED | rc=0 >> + # 12:01:20 up 2 days, 4:59, 0 users, load average: 0.00, 0.00, 0.00 + ``` + +If you do not want to use an inventory file, pass all parameters on the command line: ```bash ansible -m shell -a "uptime" \ -i "frontend.demo-app," \ - -e "ansible_ssh_common_args='-o ProxyCommand=\"d8 v port-forward --stdio=true %h %p %p\"'" \ + -e "ansible_ssh_common_args='-o ProxyCommand=\"d8 v port-forward --stdio=true %h %p\"'" \ -e "ansible_user=cloud" \ -e "ansible_ssh_private_key_file=/home/user/.ssh/id_rsa" \ all ``` -## How to automatically generate inventory for Ansible? +### How to automatically generate inventory for Ansible? {{< alert level="warning" >}} -The `d8 v ansible-inventory` command requires `d8` version v0.27.0 or higher. -{{< /alert >}} +The `d8 v ansible-inventory` command requires `d8` v0.27.0 or higher. -{{< alert level="warning" >}} -The command works only for virtual machines with the main cluster network (Main) connected. +The command works only for virtual machines that have the main cluster network (Main) connected. {{< /alert >}} Instead of manually creating an inventory file, you can use the `d8 v ansible-inventory` command, which automatically generates an Ansible inventory from virtual machines in the specified namespace. The command is compatible with the [ansible inventory script](https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#inventory-scripts) interface. The command includes only virtual machines with assigned IP addresses in the `Running` state. Host names are formatted as `.` (for example, `frontend.demo-app`). -If necessary, configure host variables through annotations (for example, SSH user): +1. Optionally set host variables via annotations (for example, the SSH user): -```bash -d8 k -n demo-app annotate vm frontend provisioning.virtualization.deckhouse.io/ansible_user="cloud" -``` + ```bash + d8 k -n demo-app annotate vm frontend provisioning.virtualization.deckhouse.io/ansible_user="cloud" + ``` -Use the command directly: +1. Run Ansible with a dynamically generated inventory: -```bash -ANSIBLE_INVENTORY_ENABLED=yaml ansible -m shell -a "uptime" all -i <(d8 v ansible-inventory -n demo-app -o yaml) -``` + ```bash + ANSIBLE_INVENTORY_ENABLED=yaml ansible -m shell -a "uptime" all -i <(d8 v ansible-inventory -n demo-app -o yaml) + ``` {{< alert level="info" >}} The `<(...)` construct is necessary because Ansible expects a file or script as the source of the host list. Simply specifying the command in quotes will not work — Ansible will try to execute the string as a script. The `<(...)` construct passes the command output as a file that Ansible can read. {{< /alert >}} -Or save the inventory to a file: - -```bash -d8 v ansible-inventory --list -o yaml -n demo-app > inventory.yaml -ansible -m shell -a "uptime" -i inventory.yaml all -``` - -## How to redirect traffic to a virtual machine? - -The virtual machine operates within a Kubernetes cluster, so directing network traffic to it is similar to routing traffic to pods. To route network traffic to a virtual machine, Kubernetes uses a standard mechanism — the Service resource, which selects target objects using labels selectors. - -1. Create a Service with the required settings. - - For example, consider a virtual machine with the label `vm: frontend-0`, an HTTP service exposed on ports 80 and 443, and SSH access on port 22: - - ```yaml - apiVersion: virtualization.deckhouse.io/v1alpha2 - kind: VirtualMachine - metadata: - name: frontend-0 - namespace: dev - labels: - vm: frontend-0 - spec: ... - ``` - -1. To route network traffic to the virtual machine's ports, create the following Service: - - This Service listens on ports 80 and 443 and forwards traffic to the target virtual machine’s ports 80 and 443. SSH access from outside the cluster is provided on port 2211. - - ```yaml - apiVersion: v1 - kind: Service - metadata: - name: frontend-0-svc - namespace: dev - spec: - type: LoadBalancer - ports: - - name: ssh - port: 2211 - protocol: TCP - targetPort: 22 - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https - port: 443 - protocol: TCP - targetPort: 443 - selector: - vm: frontend-0 - ``` - -## How to increase the DVCR size? - -To increase the disk size for DVCR, you must set a larger size in the `virtualization` module configuration than the current size. - -1. Check the current DVCR size: - - ```shell - d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' - ``` - - Example output: - - ```console - {"size":"58G","storageClass":"linstor-thick-data-r1"} - ``` - -1. Set the size: - - ```shell - d8 k patch mc virtualization \ - --type merge -p '{"spec": { "settings": { "dvcr": { "storage": { "persistentVolumeClaim": {"size": "59G"}}}}}}' - ``` - - Example output: - - ```console - moduleconfig.deckhouse.io/virtualization patched - ``` - -1. Check the resizing: - - ```shell - d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' - ``` - - Example output: - - ```console - {"size":"59G","storageClass":"linstor-thick-data-r1"} - ``` - -1. Check the current status of the DVCR: - - ```shell - d8 k get pvc dvcr -n d8-virtualization - ``` - - Example output: - - ```console - NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE - dvcr Bound pvc-6a6cedb8-1292-4440-b789-5cc9d15bbc6b 57617188Ki RWO linstor-thick-data-r1 7d - ``` - -## How to create a golden image for Linux? - -A golden image is a pre-configured virtual machine image that can be used to quickly create new VMs with pre-installed software and settings. - -1. Create a virtual machine, install the required software on it, and perform all necessary configurations. - -1. Install and configure qemu-guest-agent (recommended): - - - For RHEL/CentOS: - - ```bash - yum install -y qemu-guest-agent - ``` - - - For Debian/Ubuntu: - - ```bash - apt-get update - apt-get install -y qemu-guest-agent - ``` - -1. Enable and start the service: - - ```bash - systemctl enable qemu-guest-agent - systemctl start qemu-guest-agent - ``` - -1. Set the VM run policy to [`runPolicy: AlwaysOnUnlessStoppedManually`](/modules/virtualization/stable/cr.html#virtualmachine-v1alpha2-spec-runpolicy). This is required to be able to shut down the VM. - -1. Prepare the image. Clean unused filesystem blocks: +1. Or save the inventory to a file and run the check: ```bash - fstrim -v / - fstrim -v /boot + d8 v ansible-inventory --list -o yaml -n demo-app > inventory.yaml + ansible -m shell -a "uptime" -i inventory.yaml all ``` -1. Clean network settings: - - - For RHEL: +### How to redirect traffic to a virtual machine? - ```bash - nmcli con delete $(nmcli -t -f NAME,DEVICE con show | grep -v ^lo: | cut -d: -f1) - rm -f /etc/sysconfig/network-scripts/ifcfg-eth* - ``` +The virtual machine runs in a Kubernetes cluster, so directing network traffic to it works like routing traffic to pods. To route traffic to a virtual machine, use the standard Kubernetes mechanism — the Service resource, which selects targets using a label selector. - - For Debian/Ubuntu: +1. Create a service with the required settings. - ```bash - rm -f /etc/network/interfaces.d/* - ``` - -1. Clean system identifiers: + For example, consider a virtual machine with the label `vm: frontend-0`, an HTTP service exposed on ports 80 and 443, and SSH access on port 22: - ```bash - echo -n > /etc/machine-id - rm -f /var/lib/dbus/machine-id - ln -s /etc/machine-id /var/lib/dbus/machine-id + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: VirtualMachine + metadata: + name: frontend-0 + namespace: dev + labels: + vm: frontend-0 + spec: ... ``` -1. Remove SSH host keys: +1. To route network traffic to the virtual machine's ports, create the following Service: - ```bash - rm -f /etc/ssh/ssh_host_* - ``` +1. To route network traffic to the virtual machine's ports, create the following service: -1. Clean systemd journal: +This service listens on ports 80 and 443 and forwards traffic to the target virtual machine’s ports 80 and 443. SSH access from outside the cluster is provided on port 2211. - ```bash - journalctl --vacuum-size=100M --vacuum-time=7d + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: frontend-0-svc + namespace: dev + spec: + type: LoadBalancer + ports: + - name: ssh + port: 2211 + protocol: TCP + targetPort: 22 + - name: http + port: 80 + protocol: TCP + targetPort: 80 + - name: https + port: 443 + protocol: TCP + targetPort: 443 + selector: + vm: frontend-0 ``` -1. Clean package manager cache: - - - For RHEL: +## Platform management - ```bash - yum clean all - ``` +### How to increase the DVCR size? - - For Debian/Ubuntu: - - ```bash - apt-get clean - ``` - -1. Clean temporary files: +The DVCR volume size is set in the `virtualization` module ModuleConfig (`spec.settings.dvcr.storage.persistentVolumeClaim.size`). The new value must be greater than the current one. - ```bash - rm -rf /tmp/* - rm -rf /var/tmp/* - ``` - -1. Clean logs: +1. Check the current DVCR size: - ```bash - find /var/log -name "*.log" -type f -exec truncate -s 0 {} \; + ```shell + d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' ``` -1. Clean command history: + Example output: - ```bash - history -c + ```console + {"size":"58G","storageClass":"linstor-thick-data-r1"} ``` - For RHEL: reset and restore SELinux contexts (choose one of the following): - - - Option 1: Check and restore contexts immediately: - - ```bash - restorecon -R / - ``` - - - Option 2: Schedule relabel on next boot: +1. Increase `size` using `patch` (set the value you need): - ```bash - touch /.autorelabel - ``` - -1. Verify that `/etc/fstab` uses UUID or LABEL instead of device names (e.g., `/dev/sdX`). To check, run: - - ```bash - blkid - cat /etc/fstab + ```shell + d8 k patch mc virtualization \ + --type merge -p '{"spec": {"settings": {"dvcr": {"storage": {"persistentVolumeClaim": {"size":"59G"}}}}}}' ``` -1. Clean cloud-init state, logs, and seed (recommended method): + Example output: - ```bash - cloud-init clean --logs --seed + ```console + moduleconfig.deckhouse.io/virtualization patched ``` -1. Perform final synchronization and buffer cleanup: +1. Verify that ModuleConfig shows the new size: - ```bash - sync - echo 3 > /proc/sys/vm/drop_caches + ```shell + d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' ``` -1. Shut down the virtual machine: + Example output: - ```bash - poweroff + ```console + {"size":"59G","storageClass":"linstor-thick-data-r1"} ``` -1. Create a `VirtualImage` resource from the prepared VM disk: +1. Check the current DVCR status: - ```bash - d8 k apply -f -< - namespace: - spec: - dataSource: - type: ObjectRef - objectRef: - kind: VirtualDisk - name: - EOF + ```shell + d8 k get pvc dvcr -n d8-virtualization ``` - Alternatively, create a `ClusterVirtualImage` to make the image available at the cluster level for all projects: - - ```bash - d8 k apply -f -< - spec: - dataSource: - type: ObjectRef - objectRef: - kind: VirtualDisk - name: - namespace: - EOF - ``` - -1. Create a VM disk from the created image: + Example output: - ```bash - d8 k apply -f -< - namespace: - spec: - dataSource: - type: ObjectRef - objectRef: - kind: VirtualImage - name: - EOF + ```console + NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE + dvcr Bound pvc-6a6cedb8-1292-4440-b789-5cc9d15bbc6b 57617188Ki RWO linstor-thick-data-r1 7d ``` -After completing these steps, you will have a golden image that can be used to quickly create new virtual machines with pre-installed software and configurations. - -## How to restore the cluster if images from registry.deckhouse.io cannot be pulled after a license change? +### How to restore the cluster if images from registry.deckhouse.io cannot be pulled after a license change? -After a license change on a cluster with `containerd v1` and removal of the outdated license, images from `registry.deckhouse.io` may stop being pulled. In that case, nodes still have the outdated config file `/etc/containerd/conf.d/dvcr.toml`, which is not removed automatically. Because of it, the `registry` module does not start, and without it DVCR does not work. +After a license change on a cluster with `containerd v1` and removal of the outdated license, images from `registry.deckhouse.io` may stop being pulled. Nodes then retain the outdated configuration file `/etc/containerd/conf.d/dvcr.toml`, which is not removed automatically. Because of it, the `registry` module does not start, and without it DVCR does not work. -To fix this, apply a NodeGroupConfiguration (NGC) manifest: it will remove the file on the nodes. After the `registry` module starts, remove the manifest, since this is a one-time fix. +Applying a NodeGroupConfiguration (NGC) manifest removes the file on the nodes. After the `registry` module starts, delete the manifest, since this is a one-time fix. 1. Save the manifest to a file (for example, `containerd-dvcr-remove-old-config.yaml`): @@ -960,7 +966,7 @@ To fix this, apply a NodeGroupConfiguration (NGC) manifest: it will remove the f rm -f /etc/containerd/conf.d/dvcr.toml ``` -1. Apply the manifest: +1. Apply the saved manifest: ```bash d8 k apply -f containerd-dvcr-remove-old-config.yaml @@ -972,7 +978,7 @@ To fix this, apply a NodeGroupConfiguration (NGC) manifest: it will remove the f d8 k -n d8-system -o yaml get secret registry-state | yq -C -P '.data | del .state | map_values(@base64d) | .conditions = (.conditions | from_yaml)' ``` - Example output when the `registry` module is running: + Example output when the `registry` module has started successfully: ```yaml conditions: @@ -984,7 +990,7 @@ To fix this, apply a NodeGroupConfiguration (NGC) manifest: it will remove the f type: Ready ``` -1. Delete the NGC manifest: +1. Delete the one-time NodeGroupConfiguration manifest: ```bash d8 k delete -f containerd-dvcr-remove-old-config.yaml diff --git a/docs/FAQ.ru.md b/docs/FAQ.ru.md index bb78f8aa06..dc5f4c3036 100644 --- a/docs/FAQ.ru.md +++ b/docs/FAQ.ru.md @@ -3,118 +3,118 @@ title: "FAQ" weight: 70 --- -## Как установить ОС в виртуальной машине из ISO-образа? - -Рассмотрим пример установки ОС из ISO-образа ОС Windows. -Для этого загрузите и опубликуйте его на каком-либо HTTP-сервисе, доступном из кластера. - -1. Создайте пустой диск для установки ОС: - - ```yaml - apiVersion: virtualization.deckhouse.io/v1alpha2 - kind: VirtualDisk - metadata: - name: win-disk - namespace: default - spec: - persistentVolumeClaim: - size: 100Gi - storageClassName: local-path - ``` +## Работа с виртуальными машинами -1. Создайте ресурсы с ISO-образами ОС Windows и драйверами virtio: - - ```yaml - apiVersion: virtualization.deckhouse.io/v1alpha2 - kind: ClusterVirtualImage - metadata: - name: win-11-iso - spec: - dataSource: - type: HTTP - http: - url: "http://example.com/win11.iso" - ``` +### Установка и настройка ОС - ```yaml - apiVersion: virtualization.deckhouse.io/v1alpha2 - kind: ClusterVirtualImage - metadata: - name: win-virtio-iso - spec: - dataSource: - type: HTTP - http: - url: "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" - ``` +#### Как установить ОС в виртуальной машине из ISO-образа? + +Ниже приведён типовой сценарий установки гостевой ОС Windows из ISO-образа. Перед началом разместите ISO-образ на HTTP-ресурсе, доступном из кластера. + +1. Создайте пустой [VirtualDisk](/modules/virtualization/cr.html#virtualdisk) для установки ОС: + + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: VirtualDisk + metadata: + name: win-disk + namespace: default + spec: + persistentVolumeClaim: + size: 100Gi + storageClassName: local-path + ``` + +1. Создайте ресурсы [ClusterVirtualImage](/modules/virtualization/cr.html#clustervirtualimage) для ISO-образа ОС Windows и дистрибутива драйверов `VirtIO`: + + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: ClusterVirtualImage + metadata: + name: win-11-iso + spec: + dataSource: + type: HTTP + http: + url: "http://example.com/win11.iso" + ``` + + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: ClusterVirtualImage + metadata: + name: win-virtio-iso + spec: + dataSource: + type: HTTP + http: + url: "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" + ``` 1. Создайте виртуальную машину: - ```yaml - apiVersion: virtualization.deckhouse.io/v1alpha2 - kind: VirtualMachine - metadata: - name: win-vm - namespace: default - labels: - vm: win - spec: - virtualMachineClassName: generic - runPolicy: Manual - osType: Windows - bootloader: EFI - cpu: - cores: 6 - coreFraction: 50% - memory: - size: 8Gi - enableParavirtualization: true - blockDeviceRefs: - - kind: VirtualDisk - name: win-disk - - kind: ClusterVirtualImage - name: win-11-iso - - kind: ClusterVirtualImage - name: win-virtio-iso - ``` + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: VirtualMachine + metadata: + name: win-vm + namespace: default + labels: + vm: win + spec: + virtualMachineClassName: generic + runPolicy: Manual + osType: Windows + bootloader: EFI + cpu: + cores: 6 + coreFraction: 50% + memory: + size: 8Gi + enableParavirtualization: true + blockDeviceRefs: + - kind: VirtualDisk + name: win-disk + - kind: ClusterVirtualImage + name: win-11-iso + - kind: ClusterVirtualImage + name: win-virtio-iso + ``` -1. После создания ресурса запустите ВМ: +1. Запустите виртуальную машину: ```bash d8 v start win-vm ``` -1. К ней необходимо подключиться и с помощью графического установщика -выполнить установку ОС и драйверов `virtio`. +1. Подключитесь к консоли ВМ и завершите установку ОС и драйверов `VirtIO` при помощи графического установщика. - Команда для подключения: + Подключение по VNC: ```bash d8 v vnc -n default win-vm ``` -1. После окончания установки перезагрузите виртуальную машину. +1. После завершения установки перезагрузите виртуальную машину. -1. Для продолжения работы с виртуальной машиной также используйте команду: +1. Для дальнейшей работы снова подключитесь по VNC: ```bash d8 v vnc -n default win-vm ``` -## Как предоставить файл ответов Windows(Sysprep)? +#### Как предоставить файл ответов Windows (Sysprep)? -Чтобы выполнить автоматическую установку Windows, -создайте файл ответов (обычно именуются unattend.xml или autounattend.xml). -Для примера возьмем файл, позволяющий: +Автоматическая установка Windows выполняется с файлом ответов (`unattend.xml` или `autounattend.xml`). -- Добавить русский язык и раскладку; -- Указать расположение virtio драйверов необходимых для установки - (поэтому важен порядок дисковых устройств в спецификации ВМ); -- Разметить диски для установки windows на ВМ c EFI; -- Создать в группе администраторов пользователя *cloud* с паролем *cloud*; -- Создать непривилегированного пользователя *user* с паролем *user*. +В примере ниже файл ответов: -
autounattend.xml +- задаёт русский язык интерфейса и раскладку; +- подключает драйверы `VirtIO` для этапа установки (порядок устройств в `blockDeviceRefs` у ресурса [VirtualMachine](/modules/virtualization/cr.html#virtualmachine) должен совпадать с путями в файле); +- создаёт разметку диска для установки с EFI; +- создаёт пользователя `cloud` (администратор, пароль `cloud`) и пользователя `user` (пароль `user`). + +
Пример содержимого файла autounattend.xml… ```xml @@ -305,63 +305,265 @@ weight: 70
-Создайте секрет из этого xml файла: +1. Сохраните файл ответов в `autounattend.xml` (воспользуйтесь примером из блока выше или измените его под свои требования). -```bash -d8 k create secret generic sysprep-config --type="provisioning.virtualization.deckhouse.io/sysprep" --from-file=./autounattend.xml -``` +1. Создайте секрет с типом `provisioning.virtualization.deckhouse.io/sysprep`: -Затем можно создать виртуальную машину, которая в процессе установки будет использовать файл ответов. + ```bash + d8 k create secret generic sysprep-config --type="provisioning.virtualization.deckhouse.io/sysprep" --from-file=./autounattend.xml + ``` -Чтобы предоставить виртуальной машине Windows файл ответов, необходимо указать provisioning с типом SysprepRef. -Вы также можете указать здесь другие файлы в формате base64, необходимые для успешного выполнения скриптов внутри файла ответов. +1. Создайте виртуальную машину, которая в процессе установки будет использовать файл ответов. Укажите в спецификации `provisioning` с типом `SysprepRef`. При необходимости добавьте в спецификацию другие файлы в формате Base64, необходимые для успешного выполнения скриптов внутри файла ответов: -```yaml -apiVersion: virtualization.deckhouse.io/v1alpha2 -kind: VirtualMachine -metadata: - name: win-vm - namespace: default - labels: - vm: win -spec: - virtualMachineClassName: generic - provisioning: - type: SysprepRef - sysprepRef: - kind: Secret - name: sysprep-config - runPolicy: AlwaysOn - osType: Windows - bootloader: EFI - cpu: - cores: 6 - coreFraction: 50% - memory: - size: 8Gi - enableParavirtualization: true - blockDeviceRefs: - - kind: VirtualDisk - name: win-disk - - kind: ClusterVirtualImage - name: win-11-iso - - kind: ClusterVirtualImage - name: win-virtio-iso -``` + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: VirtualMachine + metadata: + name: win-vm + namespace: default + labels: + vm: win + spec: + virtualMachineClassName: generic + provisioning: + type: SysprepRef + sysprepRef: + kind: Secret + name: sysprep-config + runPolicy: AlwaysOn + osType: Windows + bootloader: EFI + cpu: + cores: 6 + coreFraction: 50% + memory: + size: 8Gi + enableParavirtualization: true + blockDeviceRefs: + - kind: VirtualDisk + name: win-disk + - kind: ClusterVirtualImage + name: win-11-iso + - kind: ClusterVirtualImage + name: win-virtio-iso + ``` + +#### Как создать golden image для Linux? + +Golden image — это предварительно настроенный образ виртуальной машины, который можно использовать для быстрого создания новых ВМ с уже установленным программным обеспечением и настройками. + +1. Создайте виртуальную машину, установите на неё необходимое программное обеспечение и выполните все требуемые настройки. + +1. Установите и настройте `qemu-guest-agent` (рекомендуется): -## Как использовать cloud-init для конфигурирования виртуальных машин? + - Для RHEL/CentOS: -Cloud-Init — это инструмент для автоматической настройки виртуальных машин при первом запуске. Конфигурация записывается в формате YAML и должна начинаться с заголовка `#cloud-config`. + ```bash + yum install -y qemu-guest-agent + ``` + + - Для Debian/Ubuntu: + + ```bash + apt-get update + apt-get install -y qemu-guest-agent + ``` + +1. Включите и запустите сервис: + + ```bash + systemctl enable qemu-guest-agent + systemctl start qemu-guest-agent + ``` + +1. Установите политику запуска ВМ [runPolicy: AlwaysOnUnlessStoppedManually](/modules/virtualization/cr.html#virtualmachine-v1alpha2-spec-runpolicy) — это потребуется, чтобы ВМ можно было выключить. + +1. Подготовьте образ. Очистите неиспользуемые блоки файловой системы: + + ```bash + fstrim -v / + fstrim -v /boot + ``` + +1. Очистите сетевые настройки: + + - Для RHEL: + + ```bash + nmcli con delete $(nmcli -t -f NAME,DEVICE con show | grep -v ^lo: | cut -d: -f1) + rm -f /etc/sysconfig/network-scripts/ifcfg-eth* + ``` + + - Для Debian/Ubuntu: + + ```bash + rm -f /etc/network/interfaces.d/* + ``` + +1. Очистите системные идентификаторы: + + ```bash + echo -n > /etc/machine-id + rm -f /var/lib/dbus/machine-id + ln -s /etc/machine-id /var/lib/dbus/machine-id + ``` + +1. Удалите SSH host keys: + + ```bash + rm -f /etc/ssh/ssh_host_* + ``` + +1. Очистите systemd journal: + + ```bash + journalctl --vacuum-size=100M --vacuum-time=7d + ``` + +1. Очистите кеш пакетных менеджеров: + + - Для RHEL: + + ```bash + yum clean all + ``` + + - Для Debian/Ubuntu: + + ```bash + apt-get clean + ``` + +1. Очистите временные файлы: + + ```bash + rm -rf /tmp/* + rm -rf /var/tmp/* + ``` + +1. Очистите логи: + + ```bash + find /var/log -name "*.log" -type f -exec truncate -s 0 {} \; + ``` + +1. Очистите историю команд: + + ```bash + history -c + ``` + + Для RHEL: выполните сброс и восстановление контекстов SELinux (выберите один из вариантов): + + - Вариант 1: Проверка и восстановление контекстов немедленно: + + ```bash + restorecon -R / + ``` + + - Вариант 2: Запланировать `relabel` при следующей загрузке: + + ```bash + touch /.autorelabel + ``` + +1. Проверьте, что в `/etc/fstab` указаны UUID или `LABEL`, а не имена вида `/dev/sdX`: + + ```bash + blkid + cat /etc/fstab + ``` + +1. Сбросьте состояние cloud-init (логи и seed): + + ```bash + cloud-init clean --logs --seed + ``` + +1. Выполните финальную синхронизацию и очистку буферов: + + ```bash + sync + echo 3 > /proc/sys/vm/drop_caches + ``` + +1. Выключите виртуальную машину: + + ```bash + poweroff + ``` + +1. Создайте ресурс [VirtualImage](/modules/virtualization/cr.html#virtualimage), указав исходный ресурс [VirtualDisk](/modules/virtualization/cr.html#virtualdisk) подготовленной ВМ: + + ```bash + d8 k apply -f -< + namespace: + spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualDisk + name: + EOF + ``` + + Либо создайте ресурс [ClusterVirtualImage](/modules/virtualization/cr.html#clustervirtualimage), чтобы образ был доступен на уровне кластера для всех проектов: + + ```bash + d8 k apply -f -< + spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualDisk + name: + namespace: + EOF + ``` + +1. Создайте новый ресурс [VirtualDisk](/modules/virtualization/cr.html#virtualdisk) из полученного образа: + + ```bash + d8 k apply -f -< + namespace: + spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualImage + name: + EOF + ``` + +После выполнения всех шагов у вас будет Golden image, который можно использовать для быстрого создания новых виртуальных машин с предустановленным программным обеспечением и настройками. + +## Конфигурирование виртуальных машин + +### Как использовать cloud-init для конфигурирования виртуальных машин? + +[Cloud-init](https://cloudinit.readthedocs.io/) применяется для первичной настройки гостевой ОС при первом запуске. Конфигурация задаётся в YAML и начинается с директивы `#cloud-config`. {{< alert level="warning" >}} -При использовании cloud-образов (например, официальных образов дистрибутивов) необходимо обязательно предоставить конфигурацию cloud-init. Без неё на некоторых дистрибутивах не настраивается сетевое подключение, и виртуальная машина становится недоступной в сети, даже если подключена основная сеть (Main). +Для образов, рассчитанных на cloud-init (в том числе официальных cloud-образов дистрибутивов), конфигурацию cloud-init нужно передать явно: иначе на части дистрибутивов не поднимается сеть, и ВМ оказывается недоступна по сети даже при подключении основной сети (Main). Кроме того, в cloud-образах по умолчанию отключена возможность входа в систему — необходимо добавить SSH-ключи для пользователя по умолчанию либо создать нового пользователя с SSH-доступом, иначе доступ к виртуальной машине будет невозможен. {{< /alert >}} -### Обновление и установка пакетов +#### Обновление и установка пакетов -Пример конфигурации для обновления системы и установки пакетов: +Пример `cloud-config` для обновления системы и установки пакетов из списка: ```yaml #cloud-config @@ -379,9 +581,9 @@ runcmd: - systemctl enable --now nginx.service ``` -### Создание пользователя +#### Создание пользователя -Пример конфигурации для создания пользователя с паролем и SSH-ключом: +Пример `cloud-config` для создания локального пользователя с паролем и SSH-ключом: ```yaml #cloud-config @@ -389,7 +591,7 @@ runcmd: users: - name: cloud # Имя пользователя passwd: "$6$rounds=4096$saltsalt$..." # Хеш пароля (SHA-512) - lock_passwd: false # Не блокировать учетную запись + lock_passwd: false # Не блокировать учётную запись sudo: ALL=(ALL) NOPASSWD:ALL # Права sudo без запроса пароля shell: /bin/bash # Оболочка по умолчанию ssh-authorized-keys: # SSH-ключи для доступа @@ -398,11 +600,15 @@ users: ssh_pwauth: true ``` -Для генерации хеша пароля используйте команду `mkpasswd --method=SHA-512 --rounds=4096`. +Чтобы получить хеш пароля для поля `passwd`, выполните команду: + +```shell +mkpasswd --method=SHA-512 --rounds=4096 +``` -### Создание файла с нужными правами +#### Создание файла с нужными правами -Пример конфигурации для создания файла с заданными правами доступа: +Пример `cloud-config` для создания файла с заданными правами доступа: ```yaml #cloud-config @@ -416,9 +622,9 @@ write_files: permissions: '0755' # Права доступа (восьмеричный формат) ``` -### Настройка диска и файловой системы +#### Настройка диска и файловой системы -Пример конфигурации для разметки диска, создания файловой системы и монтирования: +Пример `cloud-config` для разметки диска, создания файловой системы и монтирования: ```yaml #cloud-config @@ -442,19 +648,19 @@ mounts: - ["/dev/sdb1", "/mnt/data", "ext4", "defaults", "0", "2"] ``` -### Настройка сетевых интерфейсов для дополнительных сетей - -Подробнее о подключении дополнительных сетей к виртуальной машине см. в разделе [Дополнительные сетевые интерфейсы](./user_guide.html#дополнительные-сетевые-интерфейсы). +#### Настройка сетевых интерфейсов для дополнительных сетей {{< alert level="warning" >}} Настройки, описанные в этом разделе, применяются только для дополнительных сетей. Основная сеть (Main) настраивается автоматически через cloud-init и не требует ручной конфигурации. {{< /alert >}} -Если к виртуальной машине подключены дополнительные сети, их необходимо настроить вручную через cloud-init: используйте `write_files` для создания конфигурационных файлов и `runcmd` для применения настроек. +Если к виртуальной машине подключены дополнительные сети, их необходимо настроить вручную через cloud-init: конфигурационные файлы создаются в `write_files`, применение настроек — в `runcmd`. -#### Для systemd-networkd +Подробнее о подключении дополнительных сетей к виртуальной машине см. в разделе [Дополнительные сетевые интерфейсы](/products/virtualization-platform/documentation/user/resource-management/virtual-machines.html#дополнительные-сетевые-интерфейсы). -Пример для дистрибутивов, использующих `systemd-networkd` (например, Debian, CoreOS): +##### Для systemd-networkd + +Пример `cloud-config` для дистрибутивов, использующих `systemd-networkd` (Debian, CoreOS и др.): ```yaml #cloud-config @@ -473,9 +679,9 @@ runcmd: - systemctl restart systemd-networkd ``` -#### Для Netplan (Ubuntu) +##### Для Netplan (Ubuntu) -Пример для Ubuntu и других дистрибутивов, использующих `Netplan`: +Пример `cloud-config` для Ubuntu и других систем, использующих `Netplan`: ```yaml #cloud-config @@ -498,9 +704,9 @@ runcmd: - netplan apply ``` -#### Для ifcfg (RHEL/CentOS) +##### Для ifcfg (RHEL/CentOS) -Пример для RHEL, CentOS и других дистрибутивов, использующих схему `ifcfg` с `NetworkManager`: +Пример `cloud-config` для RHEL-совместимых дистрибутивов, использующих схему `ifcfg` и `NetworkManager`: ```yaml #cloud-config @@ -520,9 +726,9 @@ runcmd: - nmcli connection up eth1 ``` -#### Для Alpine Linux +##### Для Alpine Linux -Пример для Alpine Linux и других дистрибутивов, использующих традиционный формат `/etc/network/interfaces`: +Пример `cloud-config` для дистрибутивов, использующих традиционный формат `/etc/network/interfaces` (Alpine и аналоги): ```yaml #cloud-config @@ -540,43 +746,43 @@ runcmd: - /etc/init.d/networking restart ``` -## Как использовать Ansible для конфигурирования виртуальных машин? +### Как использовать Ansible для конфигурирования виртуальных машин? -[Ansible](https://docs.ansible.com/ansible/latest/index.html) — это инструмент автоматизации, который позволяет выполнять задачи на удаленных серверах с использованием протокола SSH. В данном примере мы рассмотрим, как использовать Ansible для управления виртуальными машинами расположенных в проекте demo-app. +[Ansible](https://docs.ansible.com/ansible/latest/index.html) — это инструмент автоматизации, который позволяет выполнять задачи на удаленных серверах с использованием протокола SSH. В данном примере мы рассмотрим, как использовать Ansible для управления виртуальными машинами расположенными в проекте `demo-app`. В рамках примера предполагается, что: -- У вас есть виртуальная машина с именем frontend в проекте demo-app. -- На виртуальной машине создан пользователь cloud для доступа по SSH. -- Приватный SSH-ключ пользователя хранится в файле /home/user/.ssh/id_rsa на сервере Ansible. +- в неймспейсе `demo-app` есть ВМ `frontend`; +- в ВМ есть пользователь `cloud` с доступом по SSH; +- на машине, где запускается Ansible, приватный SSH-ключ хранится в файле `/home/user/.ssh/id_rsa`. -Пример inventory-файла: +1. Создайте файл `inventory.yaml`: -```yaml ---- -all: - vars: - ansible_ssh_common_args: '-o ProxyCommand="d8 v port-forward --stdio=true %h %p"' - # Пользователь по умолчанию, для доступа по SSH. - ansible_user: cloud - # Путь к приватному ключу. - ansible_ssh_private_key_file: /home/user/.ssh/id_rsa - hosts: - # Название узла в формате <название ВМ>.<название проекта>. - frontend.demo-app: + ```yaml + --- + all: + vars: + ansible_ssh_common_args: '-o ProxyCommand="d8 v port-forward --stdio=true %h %p"' + # Пользователь по умолчанию, для доступа по SSH. + ansible_user: cloud + # Путь к приватному ключу. + ansible_ssh_private_key_file: /home/user/.ssh/id_rsa + hosts: + # Название узла в формате <название ВМ>.<название проекта>. + frontend.demo-app: -``` + ``` -Чтобы проверить значение аптайма виртуальной машины, используйте следующую команду: +1. Проверьте значение `uptime` виртуальной машины: -```bash -ansible -m shell -a "uptime" -i inventory.yaml all + ```bash + ansible -m shell -a "uptime" -i inventory.yaml all -# frontend.demo-app | CHANGED | rc=0 >> -# 12:01:20 up 2 days, 4:59, 0 users, load average: 0.00, 0.00, 0.00 -``` + # frontend.demo-app | CHANGED | rc=0 >> + # 12:01:20 up 2 days, 4:59, 0 users, load average: 0.00, 0.00, 0.00 + ``` -Если вы не хотите использовать файл inventory, можно передать все параметры прямо в командной строке: +Если вы не хотите использовать файл inventory, передайте все параметры прямо в командной строке: ```bash ansible -m shell -a "uptime" \ @@ -587,13 +793,11 @@ ansible -m shell -a "uptime" \ all ``` -## Как автоматически сгенерировать inventory для Ansible? +### Как автоматически сгенерировать inventory для Ansible? {{< alert level="warning" >}} Для использования команды `d8 v ansible-inventory` требуется версия `d8` v0.27.0 или выше. -{{< /alert >}} -{{< alert level="warning" >}} Команда работает только для виртуальных машин, у которых подключена основная сеть кластера (Main). {{< /alert >}} @@ -601,337 +805,138 @@ ansible -m shell -a "uptime" \ Команда включает в инвентарь только виртуальные машины с назначенными IP-адресами в состоянии `Running`. Имена хостов формируются в формате `.` (например, `frontend.demo-app`). -При необходимости настройте переменные хоста через аннотации (например, пользователя для SSH): +1. При необходимости задайте переменные хоста через аннотации (например, пользователя для SSH): -```bash -d8 k -n demo-app annotate vm frontend provisioning.virtualization.deckhouse.io/ansible_user="cloud" -``` + ```bash + d8 k -n demo-app annotate vm frontend provisioning.virtualization.deckhouse.io/ansible_user="cloud" + ``` -Используйте команду напрямую: +1. Запустите Ansible с динамически сформированным инвентарём: -```bash -ANSIBLE_INVENTORY_ENABLED=yaml ansible -m shell -a "uptime" all -i <(d8 v ansible-inventory -n demo-app -o yaml) -``` + ```bash + ANSIBLE_INVENTORY_ENABLED=yaml ansible -m shell -a "uptime" all -i <(d8 v ansible-inventory -n demo-app -o yaml) + ``` {{< alert level="info" >}} Конструкция `<(...)` необходима, потому что Ansible ожидает файл или скрипт в качестве источника списка хостов. Простое указание команды в кавычках не сработает — Ansible попытается выполнить строку как скрипт. Конструкция `<(...)` передаёт вывод команды как файл, который Ansible может прочитать. {{< /alert >}} -Или сохраните инвентарь в файл: - -```bash -d8 v ansible-inventory --list -o yaml -n demo-app > inventory.yaml -ansible -m shell -a "uptime" -i inventory.yaml all -``` - -## Как перенаправить трафик на виртуальную машину? - -Виртуальная машина функционирует в кластере Kubernetes, поэтому направление сетевого трафика к ней осуществляется аналогично направлению трафика к подам. Для маршрутизации сетевого трафика на виртуальную машину применяется стандартный механизм Kubernetes — ресурс Service, который выбирает целевые объекты по меткам (label selector). - -1. Создайте сервис с требуемыми настройками. - - В качестве примера приведена виртуальная машина с меткой `vm: frontend-0`, HTTP-сервисом, опубликованным на портах 80 и 443, и открытым SSH на порту 22: - - ```yaml - apiVersion: virtualization.deckhouse.io/v1alpha2 - kind: VirtualMachine - metadata: - name: frontend-0 - namespace: dev - labels: - vm: frontend-0 - spec: ... - ``` - -1. Чтобы направить сетевой трафик на порты виртуальной машины, создайте Service: - - Следующий Service обеспечивает доступ к виртуальной машине: он слушает порты 80 и 443 и перенаправляет трафик на соответствующие порты целевой виртуальной машины. SSH-доступ извне предоставляется по порту 2211: - - ```yaml - apiVersion: v1 - kind: Service - metadata: - name: frontend-0-svc - namespace: dev - spec: - type: LoadBalancer - ports: - - name: ssh - port: 2211 - protocol: TCP - targetPort: 22 - - name: http - port: 80 - protocol: TCP - targetPort: 80 - - name: https - port: 443 - protocol: TCP - targetPort: 443 - selector: - vm: frontend-0 - ``` - -## Как увеличить размер DVCR? - -Чтобы увеличить размер диска для DVCR, необходимо установить больший размер в конфигурации модуля `virtualization`, чем текущий размер. - -1. Проверьте текущий размер DVCR: - - ```shell - d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' - ``` - - Пример вывода: - - ```txt - {"size":"58G","storageClass":"linstor-thick-data-r1"} - ``` - -1. Задайте размер: - - ```shell - d8 k patch mc virtualization \ - --type merge -p '{"spec": {"settings": {"dvcr": {"storage": {"persistentVolumeClaim": {"size":"59G"}}}}}}' - ``` - - Пример вывода: - - ```txt - moduleconfig.deckhouse.io/virtualization patched - ``` - -1. Проверьте изменение размера: - - ```shell - d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' - ``` - - Пример вывода: - - ```txt - {"size":"59G","storageClass":"linstor-thick-data-r1"} - ``` - -1. Проверьте текущее состояние DVCR: - - ```shell - d8 k get pvc dvcr -n d8-virtualization - ``` - - Пример вывода: - - ```txt - NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE - dvcr Bound pvc-6a6cedb8-1292-4440-b789-5cc9d15bbc6b 57617188Ki RWO linstor-thick-data-r1 7d - ``` - -## Как создать golden image для Linux? - -Golden image — это предварительно настроенный образ виртуальной машины, который можно использовать для быстрого создания новых ВМ с уже установленным программным обеспечением и настройками. - -1. Создайте виртуальную машину, установите на неё необходимое программное обеспечение и выполните все требуемые настройки. - -1. Установите и настройте qemu-guest-agent (рекомендуется): - - - Для RHEL/CentOS: - - ```bash - yum install -y qemu-guest-agent - ``` - - - Для Debian/Ubuntu: - - ```bash - apt-get update - apt-get install -y qemu-guest-agent - ``` - -1. Включите и запустите сервис: - - ```bash - systemctl enable qemu-guest-agent - systemctl start qemu-guest-agent - ``` - -1. Установите политику запуска ВМ [runPolicy: AlwaysOnUnlessStoppedManually](/modules/virtualization/stable/cr.html#virtualmachine-v1alpha2-spec-runpolicy) — это потребуется, чтобы ВМ можно было выключить. - -1. Подготовьте образ. Очистите неиспользуемые блоки файловой системы: +1. Либо сохраните инвентарь в файл и выполните проверку: ```bash - fstrim -v / - fstrim -v /boot + d8 v ansible-inventory --list -o yaml -n demo-app > inventory.yaml + ansible -m shell -a "uptime" -i inventory.yaml all ``` -1. Очистите сетевые настройки: - - - Для RHEL: - - ```bash - nmcli con delete $(nmcli -t -f NAME,DEVICE con show | grep -v ^lo: | cut -d: -f1) - rm -f /etc/sysconfig/network-scripts/ifcfg-eth* - ``` +### Как перенаправить трафик на виртуальную машину? - - Для Debian/Ubuntu: +Виртуальная машина функционирует в кластере Kubernetes, поэтому сетевой трафик направляется к ней по аналогии с направлением трафика к подам. Для маршрутизации сетевого трафика на виртуальную машину применяется стандартный механизм Kubernetes — ресурс Service, который выбирает целевые объекты по лейблам (label selector). - ```bash - rm -f /etc/network/interfaces.d/* - ``` +1. Создайте сервис с требуемыми настройками. -1. Очистите системные идентификаторы: + В качестве примера приведена виртуальная машина с меткой `vm: frontend-0`, HTTP-сервисом, опубликованным на портах 80 и 443, и открытым SSH на порту 22: - ```bash - echo -n > /etc/machine-id - rm -f /var/lib/dbus/machine-id - ln -s /etc/machine-id /var/lib/dbus/machine-id + ```yaml + apiVersion: virtualization.deckhouse.io/v1alpha2 + kind: VirtualMachine + metadata: + name: frontend-0 + namespace: dev + labels: + vm: frontend-0 + spec: ... ``` -1. Удалите SSH host keys: +1. Чтобы направить сетевой трафик на порты виртуальной машины, создайте сервис: - ```bash - rm -f /etc/ssh/ssh_host_* - ``` - -1. Очистите systemd journal: + Следующий сервис обеспечивает доступ к виртуальной машине: он слушает порты 80 и 443 и перенаправляет трафик на соответствующие порты целевой виртуальной машины. SSH-доступ извне предоставляется по порту 2211: - ```bash - journalctl --vacuum-size=100M --vacuum-time=7d + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: frontend-0-svc + namespace: dev + spec: + type: LoadBalancer + ports: + - name: ssh + port: 2211 + protocol: TCP + targetPort: 22 + - name: http + port: 80 + protocol: TCP + targetPort: 80 + - name: https + port: 443 + protocol: TCP + targetPort: 443 + selector: + vm: frontend-0 ``` -1. Очистите кэш пакетных менеджеров: - - - Для RHEL: - - ```bash - yum clean all - ``` +## Управление платформой - - Для Debian/Ubuntu: +### Как увеличить размер DVCR? - ```bash - apt-get clean - ``` +Размер тома DVCR задаётся в ModuleConfig модуля `virtualization` (`spec.settings.dvcr.storage.persistentVolumeClaim.size`). Новое значение должно быть больше текущего. -1. Очистите временные файлы: +1. Проверьте текущий размер DVCR: - ```bash - rm -rf /tmp/* - rm -rf /var/tmp/* + ```shell + d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' ``` -1. Очистите логи: + Пример вывода: - ```bash - find /var/log -name "*.log" -type f -exec truncate -s 0 {} \; + ```console + {"size":"58G","storageClass":"linstor-thick-data-r1"} ``` -1. Очистите историю команд: +1. Увеличьте `size` через `patch` (подставьте нужное значение): - ```bash - history -c + ```shell + d8 k patch mc virtualization \ + --type merge -p '{"spec": {"settings": {"dvcr": {"storage": {"persistentVolumeClaim": {"size":"59G"}}}}}}' ``` - Для RHEL: выполните сброс и восстановление контекстов SELinux (выберите один из вариантов): - - - Вариант 1: Проверка и восстановление контекстов сразу: - - ```bash - restorecon -R / - ``` - - - Вариант 2: Запланировать relabel при следующей загрузке: - - ```bash - touch /.autorelabel - ``` - -1. Убедитесь, что в `/etc/fstab` используются UUID или LABEL вместо имён устройств (например, `/dev/sdX`). Для проверки выполните: - - ```bash - blkid - cat /etc/fstab - ``` - -1. Очистите состояние cloud-init, логи и seed (рекомендуемый способ): + Пример вывода: - ```bash - cloud-init clean --logs --seed + ```console + moduleconfig.deckhouse.io/virtualization patched ``` -1. Выполните финальную синхронизацию и очистку буферов: +1. Убедитесь, что в ModuleConfig отображается новый размер: - ```bash - sync - echo 3 > /proc/sys/vm/drop_caches + ```shell + d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}' ``` -1. Выключите виртуальную машину: + Пример вывода: - ```bash - poweroff + ```console + {"size":"59G","storageClass":"linstor-thick-data-r1"} ``` -1. Создайте ресурс `VirtualImage` из диска подготовленной ВМ: +1. Проверьте текущее состояние DVCR: - ```bash - d8 k apply -f -< - namespace: - spec: - dataSource: - type: ObjectRef - objectRef: - kind: VirtualDisk - name: - EOF + ```shell + d8 k get pvc dvcr -n d8-virtualization ``` - Альтернативно, создайте `ClusterVirtualImage`, чтобы образ был доступен на уровне кластера для всех проектов: - - ```bash - d8 k apply -f -< - spec: - dataSource: - type: ObjectRef - objectRef: - kind: VirtualDisk - name: - namespace: - EOF - ``` - -1. Создайте диск ВМ из созданного образа: + Пример вывода: - ```bash - d8 k apply -f -< - namespace: - spec: - dataSource: - type: ObjectRef - objectRef: - kind: VirtualImage - name: - EOF + ```console + NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE + dvcr Bound pvc-6a6cedb8-1292-4440-b789-5cc9d15bbc6b 57617188Ki RWO linstor-thick-data-r1 7d ``` -После выполнения этих шагов у вас будет golden image, который можно использовать для быстрого создания новых виртуальных машин с предустановленным программным обеспечением и настройками. - -## Как восстановить кластер, если после смены лицензии образы из registry.deckhouse.io не загружаются? +### Как восстановить кластер, если после смены лицензии образы из registry.deckhouse.io не загружаются? После смены лицензии на кластере с `containerd v1` и удаления устаревшей лицензии образы из `registry.deckhouse.io` могут перестать загружаться. При этом на узлах остаётся устаревший файл конфигурации `/etc/containerd/conf.d/dvcr.toml`, который не удаляется автоматически. Из-за него не запускается модуль `registry`, без которого не работает DVCR. -Чтобы это исправить, примените манифест NodeGroupConfiguration (NGC): он удалит файл на узлах. После запуска модуля `registry` манифест нужно удалить, так как это разовое исправление. +Манифест NodeGroupConfiguration (NGC) после применения удалит файл на узлах. После запуска модуля `registry` манифест нужно удалить, так как это разовое исправление. 1. Сохраните манифест в файл (например, `containerd-dvcr-remove-old-config.yaml`): @@ -959,7 +964,7 @@ Golden image — это предварительно настроенный об rm -f /etc/containerd/conf.d/dvcr.toml ``` -1. Примените манифест: +1. Примените сохранённый манифест: ```bash d8 k apply -f containerd-dvcr-remove-old-config.yaml @@ -983,7 +988,7 @@ Golden image — это предварительно настроенный об type: Ready ``` -1. Удалите манифест NGC: +1. Удалите разовый манифест NodeGroupConfiguration: ```bash d8 k delete -f containerd-dvcr-remove-old-config.yaml diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 34992c317c..98159fa83b 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -35,6 +35,12 @@ Ensuring the stable operation of live migration mechanisms requires using the sa Differences between kernel versions can lead to incompatible interfaces, system calls, and resource handling, which can disrupt the virtual machine migration process. {{< /alert >}} +It is recommended to use Linux kernels with up-to-date security updates provided by the maintainers of your chosen distribution. Such updates are not a prerequisite for virtualization to function, but they reduce security risks for the cluster as a whole. + +{{< alert level="info" >}} +On Astra Linux nodes, **Astra Linux platform version 1.8.3 or higher** is required for virtualization to work correctly (earlier versions contain a bug that interferes with virtualization). +{{< /alert >}} + ## Supported guest operating systems The virtualization platform supports operating systems running on `x86` and `x86_64` architectures as guest operating systems. For correct operation in paravirtualization mode, `VirtIO` drivers must be installed to ensure efficient interaction between the virtual machine and the hypervisor. diff --git a/docs/INSTALL.ru.md b/docs/INSTALL.ru.md index 8f1ef929bd..c1717b9258 100644 --- a/docs/INSTALL.ru.md +++ b/docs/INSTALL.ru.md @@ -35,6 +35,12 @@ weight: 15 Это связано с тем, что различия в версиях ядра могут привести к несовместимости интерфейсов, системных вызовов и особенностей работы с ресурсами, что может нарушить процесс миграции виртуальных машин. {{< /alert >}} +Рекомендуется использовать ядра Linux с актуальными обновлениями безопасности, предоставляемыми разработчиками выбранного дистрибутива. Такие обновления не являются обязательным условием работы виртуализации с точки зрения функциональности, но снижают риски для защищённости кластера в целом. + +{{< alert level="info" >}} +Для узлов на базе Astra Linux для корректной работы виртуализации требуется версия платформы Astra Linux **не ниже 1.8.3** (в более ранних версиях есть ошибка, мешающая работе виртуализации). +{{< /alert >}} + ## Поддерживаемые гостевые ОС Модуль виртуализации поддерживает операционные системы, работающие на архитектурах `x86` и `x86-64`, в качестве гостевых ОС. Для корректной работы в режиме паравиртуализации необходимо установить драйверы `VirtIO`, обеспечивающие эффективное взаимодействие между виртуальной машиной и гипервизором. diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 17edb3043c..c943cd8aa5 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -694,7 +694,7 @@ spec: EOF ``` -After creation, the `VirtualDisk` resource can be in the following states (phases): +After creation, the `VirtualDisk` resource can be in the following phase: - `Pending`: Waiting for all dependent resources required for disk creation to be ready. - `Provisioning`: Disk creation process is in progress. @@ -710,6 +710,10 @@ After creation, the `VirtualDisk` resource can be in the following states (phase As long as the disk has not reached the `Ready` phase, you can modify any fields in the `.spec` block. When changes are made, the disk creation process is restarted. +{{< alert level="info" >}} +After the disk reaches the `Ready` phase, you can still change `.spec.persistentVolumeClaim.size` and `.spec.persistentVolumeClaim.storageClassName`. All other `.spec` fields are immutable. +{{< /alert >}} + If the `.spec.persistentVolumeClaim.storageClassName` parameter is not specified, the default `StorageClass` at the cluster level will be used, or for images if specified in [module settings](./admin_guide.html#storage-class-settings-for-disks). Diagnosing problems with a resource is done by analyzing the information in the `.status.conditions` block @@ -2128,7 +2132,12 @@ How to work with bootable block devices in the web interface: - Go to the "Virtualization" → "Virtual Machines" section. - Select the required VM from the list and click on its name. - On the "Configuration" tab, scroll down to the "Disks and Images" section. -- You can add, extract, delete, resize, and reorder bootable block devices in the "Boot Disks" section. +- In the "Boot Disks" section you can: + - Add: Attach a new disk or image to the VM. + - Extract: Detach the device from the VM (the image or disk remains in the project and can be attached again to this or another VM). + - Delete: Remove the image or disk resource from the cluster (after deletion it cannot be reused). + - Resize: Change the size of the disk. + - Reorder: Change the boot order of devices. #### Additional Block Devices @@ -2219,7 +2228,11 @@ How to work with additional block devices in the web interface: - Go to the "Virtualization" → "Virtual Machines" section. - Select the required VM from the list and click on its name. - On the "Configuration" tab, scroll down to the "Disks and Images" section. -- You can add, extract, delete, and resize additional block devices in the "Additional Disks" section. +- In the "Additional Disks" section you can: + - Add: Attach a new disk or image to the VM. + - Extract: Detach the device from the VM (the image or disk remains in the project and can be attached again to this or another VM). + - Delete: Remove the image or disk resource from the cluster (after deletion it cannot be reused). + - Resize: Change the size of the disk. #### Disk naming in guest OS @@ -2297,6 +2310,10 @@ Use stable identifiers instead of `ethX`: In configuration files and scripts, use stable interface names (`enpXsY`) or MAC address binding instead of `ethX` names. +{{< alert level="info" >}} +Predictable interface order works only on guest OS with systemd (e.g. Ubuntu, Debian). On Alpine and other distros without systemd the order may not match. +{{< /alert >}} + ### Organizing interaction with virtual machines Virtual machines can be accessed directly via their fixed IP addresses. However, this approach has limitations: direct use of IP addresses requires manual management, complicates scaling, and makes the infrastructure less flexible. An alternative is services—a mechanism that abstracts access to VMs by providing logical entry points instead of binding to physical addresses. @@ -2850,7 +2867,13 @@ NAME VIRTUALMACHINEIPADDRESS STATUS A ip-10-66-10-14 {"name":"linux-vm-7prpx","namespace":"default"} Bound 12h ``` -`VirtualMachineIPAddress` (`vmip`) resource: A project/namespace resource that is responsible for reserving leased IP addresses and binding them to virtual machines. IP addresses can be allocated automatically or by explicit request. +[`VirtualMachineIPAddress`](/modules/virtualization/cr.html#virtualmachineipaddress) (`vmip`) resource: A project/namespace resource that is responsible for reserving leased IP addresses and binding them to virtual machines. IP addresses can be allocated automatically or by explicit request. + +After creation, the [`VirtualMachineIPAddress`](/modules/virtualization/cr.html#virtualmachineipaddress) resource can have the following `Phase` values: + +- `Pending`: Resource is being created. +- `Bound`: [VirtualMachineIPAddress](/modules/virtualization/cr.html#virtualmachineipaddress) is bound to the [VirtualMachineIPAddressLease](/modules/virtualization/cr.html#virtualmachineipaddresslease) resource. +- `Attached`: [VirtualMachineIPAddress](/modules/virtualization/cr.html#virtualmachineipaddress) is attached to the [VirtualMachine](/modules/virtualization/cr.html#virtualmachine) resource. By default, an ip address is automatically assigned to a virtual machine from the subnets defined in the module and is assigned to it until it is deleted. You can check the assigned ip address using the command: @@ -3734,6 +3757,7 @@ The [USBDevice](/modules/virtualization/cr.html#usbdevice) resource provides sta - **Attached**: Indicates whether the device is attached to a virtual machine. - `AttachedToVirtualMachine`: Device is attached to a VM. - `Available`: Device is available for attachment. + - `NoFreeUSBIPPort`: Device is requested by a VM but cannot be attached because there are no free USBIP ports on the target node. In this case, `Attached=False`. ### Attaching USB Device to VM @@ -3759,7 +3783,7 @@ The USB device is automatically forwarded to the node where the virtual machine {{< /alert >}} {{< alert level="warning" >}} -If a virtual machine with an attached USB device is migrated to another node, the USB device is automatically detached for the entire duration of the migration. After a successful migration, the device is forwarded to the new node again and reattached to the VM. If the migration fails, the device is reattached on the original node. +During VM migration, the USB device briefly disconnects and reconnects on the new node when the VM switches to it. If migration fails, the device will remain on the original node. {{< /alert >}} ### Viewing USB Device Details diff --git a/docs/USER_GUIDE.ru.md b/docs/USER_GUIDE.ru.md index 013238a760..c22c8ebeb6 100644 --- a/docs/USER_GUIDE.ru.md +++ b/docs/USER_GUIDE.ru.md @@ -702,21 +702,25 @@ spec: EOF ``` -После создания ресурс `VirtualDisk` может находиться в следующих состояниях (фазах): - -- `Pending` - ожидание готовности всех зависимых ресурсов, требующихся для создания диска. -- `Provisioning` - идет процесс создания диска. -- `Resizing` - идет процесс изменения размера диска. -- `WaitForFirstConsumer` - диск ожидает создания виртуальной машины, которая будет его использовать. -- `WaitForUserUpload` - диск ожидает от пользователя загрузки образа (type: Upload). -- `Ready` - диск создан и готов для использования. -- `Migrating` - живая миграция диска. -- `Exporting` - идет процесс экспорта диска. -- `Failed` - произошла ошибка в процессе создания. -- `PVCLost` - системная ошибка, PVC с данными утерян. -- `Terminating` - идет процесс удаления диска. Диск может «зависнуть» в данном состоянии, если он еще подключен к виртуальной машине. - -До тех пор, пока диск не перешёл в фазу `Ready`, можно изменять любые поля блока `.spec`. При изменении процесс создания диска будет запущен заново. +После создания ресурс [VirtualDisk](/modules/virtualization/cr.html#virtualdisk) может находиться в следующих состояниях (`Phase`): + +- `Pending` – ожидание готовности всех зависимых ресурсов, требующихся для создания диска. +- `Provisioning` — идет процесс создания диска. +- `Resizing` — идет процесс изменения размера диска. +- `WaitForFirstConsumer` — диск ожидает создания виртуальной машины, которая будет его использовать. +- `WaitForUserUpload` — диск ожидает от пользователя загрузки образа (type: Upload). +- `Ready` — диск создан и готов для использования. +- `Migrating` — живая миграция диска. +- `Exporting` — идет процесс экспорта диска. +- `Failed` — произошла ошибка в процессе создания. +- `PVCLost` — системная ошибка, PVC с данными утерян. +- `Terminating` — идет процесс удаления диска. Диск может «зависнуть» в данном состоянии, если он еще подключен к виртуальной машине. + +До тех пор, пока диск не перешёл в состояние `Ready`, можно изменять любые поля блока `.spec`. При изменении процесс создания диска будет запущен заново. + +{{< alert level="info" >}} +После перехода диска в состояние `Ready` по-прежнему можно менять `.spec.persistentVolumeClaim.size` и `.spec.persistentVolumeClaim.storageClassName`. Остальные поля `.spec` будут неизменяемы. +{{< /alert >}} Диагностика проблем с ресурсом осуществляется путем анализа информации в блоке `.status.conditions`. @@ -2150,7 +2154,12 @@ spec: - Перейдите в раздел «Виртуализация» → «Виртуальные машины». - Из списка выберите необходимую ВМ и нажмите на её имя. - На вкладке «Конфигурация» прокрутите страницу до раздела «Диски и образы». -- Вы можете добавлять, извлекать, удалять, изменять размер, менять порядок загрузочных блочных устройств в секции «Загрузочные диски». +- В секции «Загрузочные диски» доступны следующие действия: + - Добавить — подключить к ВМ новый диск или образ; + - Извлечь — отключить устройство от ВМ (образ или диск остаётся в проекте, его можно снова подключить к этой или другой ВМ); + - Удалить — удалить сам ресурс образа или диска из кластера (после удаления его нельзя использовать повторно); + - Изменить размер — изменить размер диска; + - Изменить порядок — изменить порядок загрузки с устройств. #### Дополнительные блочные устройства @@ -2241,7 +2250,11 @@ EOF - Перейдите в раздел «Виртуализация» → «Виртуальные машины». - Из списка выберите необходимую ВМ и нажмите на её имя. - На вкладке «Конфигурация» прокрутите страницу до раздела «Диски и образы». -- Вы можете добавлять, извлекать, удалять, изменять размер дополнительных блочных устройств в секции «Дополнительные диски». +- В секции «Дополнительные диски» доступны следующие действия: + - Добавить — подключить к ВМ новый диск или образ; + - Извлечь — отключить устройство от ВМ (образ или диск остаётся в проекте, его можно снова подключить к этой или другой ВМ); + - Удалить — удалить сам ресурс образа или диска из кластера (после удаления его нельзя использовать повторно); + - Изменить размер — изменить размер диска. #### Именование дисков в гостевой ОС @@ -2319,6 +2332,10 @@ MAC-адреса остаются неизменными, но имена инт В конфигурационных файлах и скриптах используйте стабильные имена интерфейсов (`enpXsY`) или привязку по MAC-адресу вместо имён `ethX`. +{{< alert level="info" >}} +Предсказуемый порядок интерфейсов соблюдается только в гостевых ОС с systemd (например, Ubuntu, Debian). В Alpine и других дистрибутивах без systemd порядок может не совпадать. +{{< /alert >}} + ### Организация взаимодействия с ВМ К виртуальным машинам можно обращаться напрямую по их фиксированным IP-адресам. Однако такой подход имеет ограничения: прямое использование IP-адресов требует ручного управления, усложняет масштабирование и делает инфраструктуру менее гибкой. Альтернативой служат сервисы — механизм, который абстрагирует доступ к ВМ, предоставляя логические точки входа вместо привязки к физическим адресам. @@ -2884,7 +2901,13 @@ NAME VIRTUALMACHINEIPADDRESS STATUS AG ip-10-66-10-14 {"name":"linux-vm-7prpx","namespace":"default"} Bound 12h ``` -Ресурс `VirtualMachineIPAddress` (`vmip`): проектный/неймспейсный ресурс, который отвечает за резервирование арендованных IP-адресов и их привязку к виртуальным машинам. IP-адреса могут выделяться автоматически или по явному запросу. +Ресурс [VirtualMachineIPAddres](/modules/virtualization/cr.html#virtualmachineipaddress) (`vmip`): проектный/неймспейсный ресурс, который отвечает за резервирование арендованных IP-адресов и их привязку к виртуальным машинам. IP-адреса могут выделяться автоматически или по явному запросу. + +После создания ресурс `VirtualMachineIPAddress` может находиться в следующих состояниях: + +- `Pending` — выполняется создание ресурса; +- `Bound` — ресурс [VirtualMachineIPAddress](/modules/virtualization/cr.html#virtualmachineipaddress) привязан к ресурсу [VirtualMachineIPAddressLease](/modules/virtualization/cr.html#virtualmachineipaddresslease); +- `Attached` — ресурс [VirtualMachineIPAddress](/modules/virtualization/cr.html#virtualmachineipaddress) подключен к ресурсу [VirtualMachine](/modules/virtualization/cr.html#virtualmachineipaddress). По умолчанию IP-адрес виртуальной машине назначается автоматически из подсетей, определенных в модуле и закрепляется за ней до её удаления. Проверить назначенный IP-адрес можно с помощью команды: @@ -3770,6 +3793,7 @@ logitech-webcam node-2 Logitech Webcam C920 ABC123456 False - **Attached**: Указывает, подключено ли устройство к виртуальной машине. - `AttachedToVirtualMachine` — устройство подключено к ВМ; - `Available` — устройство доступно для подключения; + - `NoFreeUSBIPPort` — устройство запрошено ВМ, но не может быть подключено, так как на целевом узле нет свободных USBIP-портов. В этом случае `Attached=False`. ### Подключение USB-устройства к ВМ @@ -3795,7 +3819,7 @@ USB-устройство автоматически пробрасывается {{< /alert >}} {{< alert level="warning" >}} -Если виртуальная машина с подключённым USB-устройством мигрирует на другой узел, USB-устройство автоматически отсоединяется на всё время миграции. После успешного завершения миграции устройство снова пробрасывается на новый узел и подключается к ВМ. Если миграция не удалась, устройство подключается обратно на старый узел. +Во время миграции ВМ USB-устройство ненадолго отключится и подключится на новом узле в момент переключения ВМ. При сбое миграции устройство останется на старом узле. {{< /alert >}} ### Просмотр информации об USB-устройстве