Предварительная версия. Функциональность может измениться, но основные возможности сохранятся. Совместимость с будущими версиями может потребовать ручных действий по миграции.
Как установить ОС в виртуальной машине из ISO-образа?
Рассмотрим пример установки ОС из ISO-образа ОС Windows. Для этого загрузите и опубликуйте его на каком-либо HTTP-сервисе, доступном из кластера.
-
Создайте пустой диск для установки ОС:
1apiVersion: virtualization.deckhouse.io/v1alpha2 2kind: VirtualDisk 3metadata: 4 name: win-disk 5 namespace: default 6spec: 7 persistentVolumeClaim: 8 size: 100Gi 9 storageClassName: local-path
-
Создайте ресурсы с ISO-образами ОС Windows и драйверами virtio:
1apiVersion: virtualization.deckhouse.io/v1alpha2 2kind: ClusterVirtualImage 3metadata: 4 name: win-11-iso 5spec: 6 dataSource: 7 type: HTTP 8 http: 9 url: "http://example.com/win11.iso"
1apiVersion: virtualization.deckhouse.io/v1alpha2 2kind: ClusterVirtualImage 3metadata: 4 name: win-virtio-iso 5spec: 6 dataSource: 7 type: HTTP 8 http: 9 url: "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"
-
Создайте виртуальную машину:
1apiVersion: virtualization.deckhouse.io/v1alpha2 2kind: VirtualMachine 3metadata: 4 name: win-vm 5 namespace: default 6 labels: 7 vm: win 8spec: 9 virtualMachineClassName: generic 10 runPolicy: Manual 11 osType: Windows 12 bootloader: EFI 13 cpu: 14 cores: 6 15 coreFraction: 50% 16 memory: 17 size: 8Gi 18 enableParavirtualization: true 19 blockDeviceRefs: 20 - kind: VirtualDisk 21 name: win-disk 22 - kind: ClusterVirtualImage 23 name: win-11-iso 24 - kind: ClusterVirtualImage 25 name: win-virtio-iso
-
После создания ресурса запустите ВМ:
1d8 v start win-vm
-
К ней необходимо подключиться и с помощью графического установщика выполнить установку ОС и драйверов
virtio
.Команда для подключения:
1d8 v vnc -n default win-vm
-
После окончания установки перезагрузите виртуальную машину.
-
Для продолжения работы с виртуальной машиной также используйте команду:
1d8 v vnc -n default win-vm
Как предоставить файл ответов Windows(Sysprep)?
Чтобы выполнить автоматическую установку Windows, создайте файл ответов (обычно именуются unattend.xml или autounattend.xml). Для примера возьмем файл, позволяющий:
- Добавить русский язык и раскладку;
- Указать расположение virtio драйверов необходимых для установки (поэтому важен порядок дисковых устройств в спецификации ВМ);
- Разметить диски для установки windows на ВМ c EFI;
- Создать в группе администраторов пользователя cloud с паролем cloud;
- Создать непривилегированного пользователя user с паролем user.
autounattend.xml
1<?xml version="1.0" encoding="utf-8"?>
2<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
3 <settings pass="offlineServicing"></settings>
4 <settings pass="windowsPE">
5 <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
6 <SetupUILanguage>
7 <UILanguage>ru-RU</UILanguage>
8 </SetupUILanguage>
9 <InputLocale>0409:00000409;0419:00000419</InputLocale>
10 <SystemLocale>en-US</SystemLocale>
11 <UILanguage>ru-RU</UILanguage>
12 <UserLocale>en-US</UserLocale>
13 </component>
14 <component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
15 <DriverPaths>
16 <PathAndCredentials wcm:keyValue="4b29ba63" wcm:action="add">
17 <Path>E:\amd64\w11</Path>
18 </PathAndCredentials>
19 <PathAndCredentials wcm:keyValue="25fe51ea" wcm:action="add">
20 <Path>E:\NetKVM\w11\amd64</Path>
21 </PathAndCredentials>
22 </DriverPaths>
23 </component>
24 <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
25 <DiskConfiguration>
26 <Disk wcm:action="add">
27 <DiskID>0</DiskID>
28 <WillWipeDisk>true</WillWipeDisk>
29 <CreatePartitions>
30 <!-- Recovery partition -->
31 <CreatePartition wcm:action="add">
32 <Order>1</Order>
33 <Type>Primary</Type>
34 <Size>250</Size>
35 </CreatePartition>
36 <!-- EFI system partition (ESP) -->
37 <CreatePartition wcm:action="add">
38 <Order>2</Order>
39 <Type>EFI</Type>
40 <Size>100</Size>
41 </CreatePartition>
42 <!-- Microsoft reserved partition (MSR) -->
43 <CreatePartition wcm:action="add">
44 <Order>3</Order>
45 <Type>MSR</Type>
46 <Size>128</Size>
47 </CreatePartition>
48 <!-- Windows partition -->
49 <CreatePartition wcm:action="add">
50 <Order>4</Order>
51 <Type>Primary</Type>
52 <Extend>true</Extend>
53 </CreatePartition>
54 </CreatePartitions>
55 <ModifyPartitions>
56 <!-- Recovery partition -->
57 <ModifyPartition wcm:action="add">
58 <Order>1</Order>
59 <PartitionID>1</PartitionID>
60 <Label>Recovery</Label>
61 <Format>NTFS</Format>
62 <TypeID>de94bba4-06d1-4d40-a16a-bfd50179d6ac</TypeID>
63 </ModifyPartition>
64 <!-- EFI system partition (ESP) -->
65 <ModifyPartition wcm:action="add">
66 <Order>2</Order>
67 <PartitionID>2</PartitionID>
68 <Label>System</Label>
69 <Format>FAT32</Format>
70 </ModifyPartition>
71 <!-- MSR partition does not need to be modified -->
72 <!-- Windows partition -->
73 <ModifyPartition wcm:action="add">
74 <Order>3</Order>
75 <PartitionID>4</PartitionID>
76 <Label>Windows</Label>
77 <Letter>C</Letter>
78 <Format>NTFS</Format>
79 </ModifyPartition>
80 </ModifyPartitions>
81 </Disk>
82 <WillShowUI>OnError</WillShowUI>
83 </DiskConfiguration>
84 <ImageInstall>
85 <OSImage>
86 <InstallTo>
87 <DiskID>0</DiskID>
88 <PartitionID>4</PartitionID>
89 </InstallTo>
90 </OSImage>
91 </ImageInstall>
92 <UserData>
93 <ProductKey>
94 <Key>VK7JG-NPHTM-C97JM-9MPGT-3V66T</Key>
95 <WillShowUI>OnError</WillShowUI>
96 </ProductKey>
97 <AcceptEula>true</AcceptEula>
98 </UserData>
99 <UseConfigurationSet>false</UseConfigurationSet>
100 </component>
101 </settings>
102 <settings pass="generalize"></settings>
103 <settings pass="specialize">
104 <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
105 <RunSynchronous>
106 <RunSynchronousCommand wcm:action="add">
107 <Order>1</Order>
108 <Path>powershell.exe -NoProfile -Command "$xml = [xml]::new(); $xml.Load('C:\Windows\Panther\unattend.xml'); $sb = [scriptblock]::Create( $xml.unattend.Extensions.ExtractScript ); Invoke-Command -ScriptBlock $sb -ArgumentList $xml;"</Path>
109 </RunSynchronousCommand>
110 <RunSynchronousCommand wcm:action="add">
111 <Order>2</Order>
112 <Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Setup\Scripts\Specialize.ps1' -Raw | Invoke-Expression;"</Path>
113 </RunSynchronousCommand>
114 <RunSynchronousCommand wcm:action="add">
115 <Order>3</Order>
116 <Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
117 </RunSynchronousCommand>
118 <RunSynchronousCommand wcm:action="add">
119 <Order>4</Order>
120 <Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Setup\Scripts\DefaultUser.ps1' -Raw | Invoke-Expression;"</Path>
121 </RunSynchronousCommand>
122 <RunSynchronousCommand wcm:action="add">
123 <Order>5</Order>
124 <Path>reg.exe unload "HKU\DefaultUser"</Path>
125 </RunSynchronousCommand>
126 </RunSynchronous>
127 </component>
128 </settings>
129 <settings pass="auditSystem"></settings>
130 <settings pass="auditUser"></settings>
131 <settings pass="oobeSystem">
132 <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
133 <InputLocale>0409:00000409;0419:00000419</InputLocale>
134 <SystemLocale>en-US</SystemLocale>
135 <UILanguage>ru-RU</UILanguage>
136 <UserLocale>en-US</UserLocale>
137 </component>
138 <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
139 <UserAccounts>
140 <LocalAccounts>
141 <LocalAccount wcm:action="add">
142 <Name>cloud</Name>
143 <DisplayName>cloud</DisplayName>
144 <Group>Administrators</Group>
145 <Password>
146 <Value>cloud</Value>
147 <PlainText>true</PlainText>
148 </Password>
149 </LocalAccount>
150 <LocalAccount wcm:action="add">
151 <Name>User</Name>
152 <DisplayName>user</DisplayName>
153 <Group>Users</Group>
154 <Password>
155 <Value>user</Value>
156 <PlainText>true</PlainText>
157 </Password>
158 </LocalAccount>
159 </LocalAccounts>
160 </UserAccounts>
161 <AutoLogon>
162 <Username>cloud</Username>
163 <Enabled>true</Enabled>
164 <LogonCount>1</LogonCount>
165 <Password>
166 <Value>cloud</Value>
167 <PlainText>true</PlainText>
168 </Password>
169 </AutoLogon>
170 <OOBE>
171 <ProtectYourPC>3</ProtectYourPC>
172 <HideEULAPage>true</HideEULAPage>
173 <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
174 <HideOnlineAccountScreens>false</HideOnlineAccountScreens>
175 </OOBE>
176 <FirstLogonCommands>
177 <SynchronousCommand wcm:action="add">
178 <Order>1</Order>
179 <CommandLine>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Setup\Scripts\FirstLogon.ps1' -Raw | Invoke-Expression;"</CommandLine>
180 </SynchronousCommand>
181 </FirstLogonCommands>
182 </component>
183 </settings>
184</unattend>
Создайте секрет из этого xml файла:
1d8 k create secret generic sysprep-config --type="provisioning.virtualization.deckhouse.io/sysprep" --from-file=./autounattend.xml
Затем можно создать виртуальную машину, которая в процессе установки будет использовать файл ответов.
Чтобы предоставить виртуальной машине Windows файл ответов, необходимо указать provisioning с типом SysprepRef. Вы также можете указать здесь другие файлы в формате base64, необходимые для успешного выполнения скриптов внутри файла ответов.
1apiVersion: virtualization.deckhouse.io/v1alpha2
2kind: VirtualMachine
3metadata:
4 name: win-vm
5 namespace: default
6 labels:
7 vm: win
8spec:
9 virtualMachineClassName: generic
10 provisioning:
11 type: SysprepRef
12 sysprepRef:
13 kind: Secret
14 name: sysprep-config
15 runPolicy: AlwaysOn
16 osType: Windows
17 bootloader: EFI
18 cpu:
19 cores: 6
20 coreFraction: 50%
21 memory:
22 size: 8Gi
23 enableParavirtualization: true
24 blockDeviceRefs:
25 - kind: VirtualDisk
26 name: win-disk
27 - kind: ClusterVirtualImage
28 name: win-11-iso
29 - kind: ClusterVirtualImage
30 name: win-virtio-iso
Как использовать Ansible для конфигурирования виртуальных машин?
Ansible — это инструмент автоматизации, который позволяет выполнять задачи на удаленных серверах с использованием протокола SSH. В данном примере мы рассмотрим, как использовать Ansible для управления виртуальными машинами расположенных в проекте demo-app.
В рамках примера предполагается, что:
- У вас есть виртуальная машина с именем frontend в проекте demo-app.
- На виртуальной машине создан пользователь cloud для доступа по SSH.
- Приватный SSH-ключ пользователя хранится в файле ./tmp/demo на сервере Ansible.
Пример inventory-файла:
1---
2all:
3 vars:
4 ansible_ssh_common_args: '-o ProxyCommand="d8 v port-forward --stdio=true %h %p"'
5 # Пользователь по умолчанию, для доступа по SSH.
6 ansible_user: cloud
7 # Путь к приватному ключу.
8 ansible_ssh_private_key_file: ./tmp/demo
9 hosts:
10 # Название узла в формате <название ВМ>.<название проекта>.
11 frontend.demo-app:
Чтобы проверить значение аптайма виртуальной машины, используйте следующую команду:
1ansible -m shell -a "uptime" -i inventory.yaml all
2
3# frontend.demo-app | CHANGED | rc=0 >>
4# 12:01:20 up 2 days, 4:59, 0 users, load average: 0.00, 0.00, 0.00
Если вы не хотите использовать файл inventory, можно передать все параметры прямо в командной строке:
1ansible -m shell -a "uptime" \
2 -i "frontend.demo-app," \
3 -e "ansible_ssh_common_args='-o ProxyCommand=\"d8 v port-forward --stdio=true %h %p\"'" \
4 -e "ansible_user=cloud" \
5 -e "ansible_ssh_private_key_file=./tmp/demo" \
6 all
Как перенаправить трафик на виртуальную машину?
Виртуальная машина функционирует в кластере Kubernetes, поэтому направление сетевого трафика осуществляется аналогично направлению трафика на поды.
-
Создайте сервис с требуемыми настройками.
В качестве примера приведена виртуальная машина с HTTP-сервисом, опубликованным на порте 80, и следующим набором меток:
1apiVersion: virtualization.deckhouse.io/v1alpha2 2kind: VirtualMachine 3metadata: 4 name: web 5 labels: 6 vm: web 7spec: ...
-
Чтобы направить сетевой трафик на 80-й порт виртуальной машины, создайте сервис:
1apiVersion: v1 2kind: Service 3metadata: 4 name: svc-1 5spec: 6 ports: 7 - name: http 8 port: 8080 9 protocol: TCP 10 targetPort: 80 11 selector: 12 app: old
Можно изменять метки виртуальной машины без необходимости перезапуска, что позволяет настраивать перенаправление сетевого трафика между различными сервисами в реальном времени.
Предположим, что был создан новый сервис и требуется перенаправить трафик на виртуальную машину от этого сервиса:
1apiVersion: v1 2kind: Service 3metadata: 4 name: svc-2 5spec: 6 ports: 7 - name: http 8 port: 8080 9 protocol: TCP 10 targetPort: 80 11 selector: 12 app: new
При изменении метки на виртуальной машине, трафик с сервиса
svc-2
будет перенаправлен на виртуальную машину:1metadata: 2 labels: 3 app: old
Как увеличить размер DVCR?
Чтобы увеличить размер диска для DVCR, необходимо установить больший размер в конфигурации модуля virtualization
, чем текущий размер.
-
Проверьте текущий размер DVCR:
1d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}'
Пример вывода:
1 {"size":"58G","storageClass":"linstor-thick-data-r1"}
-
Задайте размер:
1d8 k patch mc virtualization \ 2 --type merge -p '{"spec": {"settings": {"dvcr": {"storage": {"persistentVolumeClaim": {"size":"59G"}}}}}}'
Пример вывода:
1 moduleconfig.deckhouse.io/virtualization patched
-
Проверьте изменение размера:
1d8 k get mc virtualization -o jsonpath='{.spec.settings.dvcr.storage.persistentVolumeClaim}'
Пример вывода:
1{"size":"59G","storageClass":"linstor-thick-data-r1"}
-
Проверьте текущее состояние DVCR:
1d8 k get pvc dvcr -n d8-virtualization
Пример вывода:
1NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE 2dvcr Bound pvc-6a6cedb8-1292-4440-b789-5cc9d15bbc6b 57617188Ki RWO linstor-thick-data-r1 7d