Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[controller] Add data wipe #122

Merged
merged 122 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
eaa249f
Move LLVS to EE
astef Dec 19, 2024
14e1e82
also move snapshots restore to EE
astef Dec 20, 2024
fe9cc5c
fix linter
astef Dec 20, 2024
ac7d566
Resolve merge conflict
krpsh123 Feb 3, 2025
867f1ad
[github] CI: add editions
krpsh123 Feb 3, 2025
0556941
include llvs always
astef Feb 6, 2025
dd3ae07
added webhook
NikolayDemchuk Feb 6, 2025
d502bfb
fixes
NikolayDemchuk Feb 6, 2025
1401ca3
change
NikolayDemchuk Feb 6, 2025
6f9209f
fixes
NikolayDemchuk Feb 6, 2025
536dac9
fixes
NikolayDemchuk Feb 6, 2025
3624ce5
changed go version
NikolayDemchuk Feb 6, 2025
15735cf
fix
NikolayDemchuk Feb 6, 2025
583354f
try
astef Feb 6, 2025
5b14900
[webhooks] fix werf
krpsh123 Feb 6, 2025
441d42e
bump go version to 1.23.5
krpsh123 Feb 6, 2025
060d427
update go
astef Feb 6, 2025
62fdc34
fix yamls
astef Feb 7, 2025
b26795b
fix caBundle
astef Feb 7, 2025
a008529
better message
astef Feb 7, 2025
8b772d2
optionally disable validating webhook when featureLLVSEnabled
astef Feb 7, 2025
4972310
fix overwriting openapi folder in bundle
astef Feb 7, 2025
6284f38
fix bundle problem; change build trigger
astef Feb 7, 2025
13e4c0e
fix typo
astef Feb 7, 2025
a426efa
fix reversed logic of featureLLVSEnabled
astef Feb 7, 2025
71223ab
Merge pull request #123 from deckhouse/ndemchuk-webhook-add
astef Feb 7, 2025
6847728
upgrade Go in workflows
astef Feb 7, 2025
3bbf5ec
fix linter
astef Feb 7, 2025
21866a6
some changes
AleksZimin Feb 9, 2025
fae4764
another fix
AleksZimin Feb 9, 2025
286a747
another fixes2
AleksZimin Feb 9, 2025
704358d
fixes
AleksZimin Feb 9, 2025
2e5baa2
fixes
AleksZimin Feb 9, 2025
0ee6811
some fixes
AleksZimin Feb 9, 2025
a61b92b
change workflows
AleksZimin Feb 9, 2025
d295a22
some changes in choice edition
AleksZimin Feb 9, 2025
50a305d
change werf
AleksZimin Feb 9, 2025
7a7aef8
fix
AleksZimin Feb 10, 2025
c7f2310
First draft of user documentation
asergunov Feb 3, 2025
d46438a
first commit
AleksZimin Feb 3, 2025
b7092c0
Update USAGE.ru.md
asergunov Feb 4, 2025
158c117
some changes
AleksZimin Feb 5, 2025
59f2795
Ешё вариант
asergunov Feb 6, 2025
5ca3263
thin
asergunov Feb 6, 2025
53ff854
Update USAGE.ru.md
asergunov Feb 6, 2025
4774c7c
some changes
AleksZimin Feb 7, 2025
745b1ed
changes
AleksZimin Feb 10, 2025
40a4f4f
fix
AleksZimin Feb 10, 2025
d6e8a45
fix default MODULE_EDITION
krpsh123 Feb 10, 2025
5327da9
leave conditional build only in feature flags
astef Feb 10, 2025
bec8505
fix
AleksZimin Feb 10, 2025
b61e2e9
Merge pull request #124 from deckhouse/azimin-llvs-ee
astef Feb 11, 2025
82db6ec
volume cleanup implementation
asergunov Feb 12, 2025
ba3db24
Closing files, report closing errors, some logs
asergunov Feb 13, 2025
e26157d
missing break
asergunov Feb 13, 2025
91a53f6
add log info for cleaning
asergunov Feb 13, 2025
bde8007
contiguous is not required
asergunov Feb 13, 2025
72d9894
Remove space
asergunov Feb 13, 2025
1c57c57
Add nil checks
asergunov Feb 13, 2025
43b5552
Lint error capitalization
asergunov Feb 13, 2025
7c05d9f
linter unused args
asergunov Feb 13, 2025
07ff5ff
show bad stat in error
asergunov Feb 14, 2025
c45388a
use fstat call
asergunov Feb 14, 2025
91dd945
Use two syscalls to find out block size and count
asergunov Feb 14, 2025
817b927
Fix block device constants
asergunov Feb 14, 2025
e3073ea
Set O_RDWR flag
asergunov Feb 14, 2025
7b83154
Logging
asergunov Feb 14, 2025
f024da5
Measure copy time
asergunov Feb 14, 2025
ae5fd54
Logging
asergunov Feb 14, 2025
a66694f
fix errno
asergunov Feb 14, 2025
8311f89
Correct device size
asergunov Feb 14, 2025
895b79d
import order
asergunov Feb 14, 2025
cd69819
Return no error if all fine
asergunov Feb 14, 2025
496f01e
let it change thick in crd
asergunov Feb 14, 2025
6e1a3cf
More logs
asergunov Feb 17, 2025
392320b
Open `O_RDWR` for discard
asergunov Feb 17, 2025
40fc76f
Fix errno crash
asergunov Feb 17, 2025
03a01b9
Cleaner error message
asergunov Feb 18, 2025
3b4b163
lint
asergunov Feb 18, 2025
6cb1d17
Fix API by ADR
asergunov Feb 18, 2025
0c11d2c
Enable volumeCleanup remove
asergunov Feb 18, 2025
5b97f18
Merge remote-tracking branch 'origin/astef-llvs-ee' into add-data-wipe
asergunov Feb 18, 2025
3e1d821
make it build
asergunov Feb 18, 2025
2e6ba5a
Merge remote-tracking branch 'origin/main' into add-data-wipe
asergunov Feb 18, 2025
bc4c2dc
Make it build
asergunov Feb 18, 2025
d5f8a12
diff cleanup
asergunov Feb 18, 2025
58c00ac
cleanup
asergunov Feb 18, 2025
0bd9e5a
remove setStatusIfNeeded
asergunov Feb 18, 2025
bfdc91a
remove featureLLVSEnabled
asergunov Feb 18, 2025
ac725e6
rename openapi/values_ee.yaml back
asergunov Feb 18, 2025
c2234d7
thick can be removed
asergunov Feb 19, 2025
f90ab13
Fix contiguous validation in CRD
asergunov Feb 19, 2025
7c3b650
unify logging
asergunov Feb 19, 2025
d2276c3
Fix crash
asergunov Feb 19, 2025
92c4bf5
back to one line
asergunov Feb 19, 2025
e7c5173
Add missing `(
asergunov Feb 19, 2025
5624447
Fix CRD
asergunov Feb 19, 2025
a682294
make volumeCleanup optional
asergunov Feb 19, 2025
3503908
Apply suggestions from code review
asergunov Feb 19, 2025
f6aebf2
Changed llv model
duckhawk Feb 19, 2025
5934b49
Change phase before cleaning
asergunov Feb 20, 2025
1d6e802
Merge remote-tracking branch 'origin/add-data-wipe' into add-data-wipe
asergunov Feb 20, 2025
09866b7
prevent simultaneous cleanups of the same volume
asergunov Feb 20, 2025
e4a16cd
preallocate 4Mib buffer for overwrite cleanup
asergunov Feb 20, 2025
ebbc653
Signed-off-by: v.oleynikov <vasily.oleynikov@flant.com>
duckhawk Feb 20, 2025
4c2c8b9
saving last failed method so we don't retry cleaning up if it's not c…
asergunov Feb 20, 2025
fe7badf
Merge remote-tracking branch 'origin/add-data-wipe' into add-data-wipe
asergunov Feb 20, 2025
ed5673f
don't delete failed or cleaning devices
asergunov Feb 20, 2025
06bb8c8
Remove commented text from USAGE
asergunov Feb 20, 2025
35a86c4
Apply suggestions from code review
asergunov Feb 20, 2025
4c0f4af
Apply suggestions from code review
asergunov Feb 20, 2025
167fb64
Update images/agent/src/internal/utils/volume_cleanup_ee.go
asergunov Feb 20, 2025
15493b4
early return for less indentation
asergunov Feb 20, 2025
3e06611
Update docs/USAGE.ru.md
asergunov Feb 20, 2025
fd04ca2
don't requeue cleaning up errors, don't update phase when not heeded
asergunov Feb 20, 2025
bb4bba7
docs: add Protection against data leakage between volumes section in …
Feb 20, 2025
3ef50b1
some fixes
AleksZimin Feb 21, 2025
5e9f33d
Update docs/USAGE.md
AleksZimin Feb 21, 2025
edca6e2
Remove unused constants
asergunov Feb 24, 2025
0c7b1ee
Fix by review
asergunov Feb 24, 2025
d1924e6
Remove check duplication
asergunov Feb 24, 2025
9437bcd
improve naming andadd comment
astef Feb 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .werf/consts.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# base images
{{- $_ := set $ "BASE_ALT" "registry.deckhouse.io/base_images/alt:p10@sha256:f105773c682498700680d7cd61a702a4315c4235aee3622757591fd510fb8b4a" }}
{{- $_ := set $ "BASE_ALT_P11" "registry.deckhouse.io/base_images/alt:p11@sha256:e47d84424485d3674240cb2f67d3a1801b37d327e6d1eb8cc8d01be8ed3b34f3" }}
{{- $_ := set $ "BASE_GOLANG_1_23" "registry.deckhouse.io/base_images/golang:1.23.5-alpine3.20@sha256:623ef3f63012bbd648021a2f097de3f411889332ba83bd98f0ac8d1288bdaa06" }}
{{- $_ := set $ "BASE_GOLANG_1_23" "registry.deckhouse.io/base_images/golang:1.23.6-alpine3.20@sha256:3058c63e0e2532881949c4186414baa24a0f9a8f9349b1853daa49be816f42e9" }}
{{- $_ := set $ "BASE_SCRATCH" "registry.deckhouse.io/base_images/scratch@sha256:653ae76965c98c8cd1c8c9ff7725316d2983986f896655b30e0f44d2f8b2dd7e" }}
{{- $_ := set $ "BASE_ALPINE" "registry.deckhouse.io/base_images/alpine:3.20.3@sha256:41628df7c9b935d248f64542634e7a843f9bc7f2252d7f878e77f7b79a947466" }}

Expand Down
1 change: 1 addition & 0 deletions api/v1alpha1/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package v1alpha1
const (
PhaseCreated = "Created"
PhasePending = "Pending"
PhaseCleaning = "Cleaning"
PhaseResizing = "Resizing"
PhaseFailed = "Failed"
PhaseNotReady = "NotReady"
Expand Down
3 changes: 2 additions & 1 deletion api/v1alpha1/lvm_logical_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ type LVMLogicalVolumeThinSpec struct {
}

type LVMLogicalVolumeThickSpec struct {
Contiguous *bool `json:"contiguous"`
Contiguous *bool `json:"contiguous,omitempty"`
VolumeCleanup *string `json:"volumeCleanup,omitempty"`
}
type LVMLogicalVolumeStatus struct {
Phase string `json:"phase"`
Expand Down
8 changes: 8 additions & 0 deletions crds/doc-ru-lvmlogicalvolume.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ spec:
contiguous:
description: |
Если true, логический том будет создан с флагом contiguous. Примечание: Этот флаг следует использовать с осторожностью, так как он может привести к невозможности создания LV, не смотря на наличие свободного пространства.
volumeCleanup:
description: |
Метод очистки тома после удаления PV.
Если параметр не задан, после удаления PV данные могут удалиться, либо остаться. Гарантий удаления или неудаления нет.
Допустимые значения:
- `RandomFillSinglePass` - том будет перезаписан случайными данными один раз перед удалением. Использовать эту опцию не рекомендуется для твердотельных накопителей, так как она уменьшает ресурс накопителя.
- `RandomFillThreePass` - том будет перезаписан случайными данными три раза перед удалением. Использовать эту опцию не рекомендуется для твердотельных накопителей, так как она уменьшает ресурс накопителя.
- `Discard` - все блоки тома будут отмечены как свободные с использованием системного вызова `discard` перед удалением. Эта опция имеет смысл только для твердотельных накопителей.
status:
description: |
Описывает состояние ресурса.
Expand Down
29 changes: 19 additions & 10 deletions crds/lvmlogicalvolume.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ spec:
- rule: |
(self.type == "Thin" && has(self.thin) && !has(self.thick)) || self.type != "Thin"
message: "Field 'thin' is required and field 'thick' is forbidden when 'type' is 'Thin'."
- rule: |
(!has(oldSelf.thick) || has(self.thick))
message: "Field 'thick' cannot be removed."
- rule: |
(!has(self.thick) || !has(self.thick.contiguous) || (has(self.thick.contiguous) && self.thick.contiguous == oldSelf.thick.contiguous))
- rule: >
(
(!has(self.thick) || !has(self.thick.contiguous)) &&
(!has(oldSelf.thick) || !has(oldSelf.thick.contiguous))
) || (
has(self.thick) && has(self.thick.contiguous) &&
has(oldSelf.thick) && has(oldSelf.thick.contiguous)
)
message: "Field 'contiguous' is immutable and cannot be added if not specified at creation."
required:
- actualLVNameOnTheNode
Expand Down Expand Up @@ -100,13 +103,9 @@ spec:
thick:
type: object
x-kubernetes-validations:
- rule: self == oldSelf
message: Value is immutable.
- rule: |
(!has(oldSelf.contiguous) || has(self.contiguous))
message: "Field 'contiguous' cannot be removed."
required:
- contiguous
properties:
contiguous:
type: boolean
Expand All @@ -115,6 +114,16 @@ spec:
message: Value is immutable.
description: |
If true, the Logical Volume will be created with the contiguous flag. Use it carefully as LV might not be created even if there is enough space in VG.
volumeCleanup:
type: string
enum: [RandomFillThreePass, RandomFillSinglePass, Discard]
description: |
The method of the volume cleanup before deletion.
If the parameter is not set, after deleting the PV, the data may be deleted or it may remain. There is no guarantee of deletion or non-deletion.
Allowed values:
- `RandomFillSinglePass`: The volume will be overwritten with random data once before deletion. This option is not recommended for solid-state drives, as it reduces the lifespan of the drive.
- `RandomFillThreePass`: The volume will be overwritten with random data three times before deletion. This option is also not recommended for solid-state drives, as it reduces the lifespan of the drive.
- `Discard`: All blocks of the volume will be marked as free using the `discard`` system call before deletion. This option is only applicable to solid-state drives.
source:
type: object
description: |
Expand Down Expand Up @@ -149,7 +158,7 @@ spec:
properties:
phase:
type: string
enum: [Created, Pending, Resizing, Failed]
enum: [Created, Pending, Cleaning, Resizing, Failed]
description: |
The current resource's phase.
reason:
Expand Down
35 changes: 35 additions & 0 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,38 @@ To extract the `BlockDevice` resource from the `LVMVolumeGroup` resource, you ne
> **Caution!** If the deleting `LVM Volume Group` resource contains any `Logical Volume` (even if it is only the `Thin-pool` that is specified in `spec`), a user must delete all those `Logical Volumes` manually. Otherwise, the `LVMVolumeGroup` resource and its `Volume Group` will not be deleted.

> A user can forbid to delete the `LVMVolumeGroup` resource by annotate it with `storage.deckhouse.io/deletion-protection`. If the controller finds the annotation, it will not delete nether the resource or the `Volume Group` till the annotation removal.

## Protection against data leakage between volumes

When deleting files, the operating system does not physically delete the contents, but only marks the corresponding blocks as “free”. If a new volume receives physical blocks previously used by another volume, the previous user's data may remain in them.

This is possible, for example, in the following case:

- user №1 placed files in the volume requested from StorageClass 1 and on node 1 (no matter in “Block” or “Filesystem” mode);
- user №1 deleted the files and the volume;
- the physical blocks it occupied become “free” but not wiped;
- user №2 requested a new volume from StorageClass 1 and on node 1 in “Block” mode;
- there is a risk that some or all of the blocks previously occupied by user №1 will be reallocated to user №2;
- in which case user №2 has the ability to recover user №1's data.

### Thick volumes

The `volumeCleanup` parameter is provided to prevent leaks through thick volumes.
It allows to select the volume cleanup method before deleting the PV.
Allowed values:

* parameter not specified — do not perform any additional actions when deleting a volume. The data may be available to the next user;

* `RandomFillSinglePass` - the volume will be overwritten with random data once before deletion. Use of this option is not recommended for solid-state drives as it reduces the lifespan of the drive.

* `RandomFillThreePass` - the volume will be overwritten with random data three times before deletion. Use of this option is not recommended for solid-state drives as it reduces the lifespan of the drive.

* `Discard` - all blocks of the volume will be marked as free using the `discard` system call before deletion. This option is only applicable to solid-state drives.

Most modern solid-state drives ensure that a `discard` marked block will not return previous data when read. This makes the `Discard' option the most effective way to prevent leakage when using solid-state drives.
However, clearing a cell is a relatively long operation, so it is performed in the background by the device. In addition, many drives cannot clear individual cells, only groups - pages. Because of this, not all drives guarantee immediate unavailability of the freed data. In addition, not all drives that do guarantee this keep the promise.
If the device does not guarantee Deterministic TRIM (DRAT), Deterministic Read Zero after TRIM (RZAT) and is not tested, then it is not recommended.

### Thin volumes

When a thin-pool block is released via `discard` by the guest operating system, this command is forwarded to the device. If a hard disk drive is used or if there is no `discard` support from the solid-state drive, the data may remain on the thin-pool until such a block is used again. However, users are only given access to thin volumes, not the thin-pool itself. They can only retrieve a volume from the pool, and the thin volumes are nulled for the thin-pool block on new use, preventing leakage between clients. This is guaranteed by setting `thin_pool_zero=1` in LVM.
35 changes: 35 additions & 0 deletions docs/USAGE.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,38 @@ kubectl delete lvg %lvg-name%
> **Внимание!** Если удаляемый ресурс `LVMVolumeGroup` содержит `Logical Volume` (даже если это только `Thin-pool`, который указан в `spec`) пользователю необходимо самостоятельно удалить все `Logical Volume`, которые содержит удаляемая `Volume Group`. В противном случае ни ресурс, ни `Volume Group` удалены не будут.

> Пользователь может запретить удаление `LVMVolumeGroup` ресурса, повесив на ресурс специальную аннотацию `storage.deckhouse.io/deletion-protection`. При наличии данной аннотации контроллер не будет удалять ни ресурс, ни соответствующую `Volume Group` до тех пор, пока аннотация не будет снята с ресурса.

## Защита от утечек данных между томами

При удалении файлов операционная система не удаляет содержимое физически, а лишь помечает соответствующие блоки как «свободные». Если новый том получает физические блоки, ранее использовавшиеся другим томом, в них могут остаться данные предыдущего пользователя.

Это возможно, например, в таком случае:

- пользователь №1 разместил файлы в томе, запрошенном из StorageClass 1 и на узле 1 (не важно, в режиме «Block» или «Filesystem»);
- пользователь №1 удалил файлы и том;
- физические блоки, которые он занимал, становятся «свободными», но не затертыми;
- пользователь №2 запросил новый том из StorageClass 1 и на узле 1 в режиме «Block»;
- есть риск, что часть или все блоки, ранее занимаемые пользователем №1, будут снова выделены пользователю №2;
- в этом случае пользователь №2 имеет возможность восстановить данные пользователя №1.

### Thick-тома

Для предотвращения утечек через thick-тома предусмотрен параметр `volumeCleanup`.
Он позволяет выбрать метод очистки тома перед удалением PV.
Возможные значения:

* параметр не задан — не выполнять никаких дополнительных действий при удалении тома. Данные могут оказаться доступными следующему пользователю;

* `RandomFillSinglePass` — том будет перезаписан случайными данными один раз перед удалением. Использовать эту опцию не рекомендуется для твердотельных накопителей, так как она уменьшает ресурс накопителя.

* `RandomFillThreePass` — том будет перезаписан случайными данными три раза перед удалением. Использовать эту опцию не рекомендуется для твердотельных накопителей, так как она уменьшает ресурс накопителя.

* `Discard` — все блоки тома будут отмечены как свободные с использованием системного вызова `discard` перед удалением. Эта опция имеет смысл только для твердотельных накопителей.

Большинство современных твердотельных накопителей гарантирует, что помеченный `discard` блок при чтении не вернет предыдущие данные. Это делает опцию `Discard` самым эффективным способом предотвращения утечек при использовании твердотельных накопителей.
Однако очистка ячейки относительно долгая операция, поэтому выполняется устройством в фоне. К тому-же многие диски не могут очищать индивидуальные ячейки, а только группы - страницы. Из-за этого не все накопители гарантируют немедленную недоступность освобожденных данных. К тому-же не все накопители, гарантирующие это, держат обещание.
Если устройство не гарантирует Deterministic TRIM (DRAT), Deterministic Read Zero after TRIM (RZAT) и не является проверенным, то использовать его не рекомендуется.

### Thin-тома

В момент освобождения блока thin-тома через `discard` гостевой операционной системы, эта команда пересылается на устройство. В случае использования жесткого диска или отсутствии поддержки `discard` со стороны твердотельного накопителя, данные могут остаться на thin-pool до нового использования такого блока. Однако, пользователям предоставляется доступ только к thin-томам, а не к самому thin-пулу. Они могут получить только том из пула, а для thin-томов производится зануление блока thin-pool при новом использовании, что предотвращает утечки между клиентами. Это гарантируется настройкой `thin_pool_zero=1` в LVM.
1 change: 1 addition & 0 deletions images/agent/src/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func main() {
log.Info(fmt.Sprintf("[main] OS/Arch:Go OS/Arch:%s/%s ", goruntime.GOOS, goruntime.GOARCH))

log.Info(fmt.Sprintf("[main] Feature SnapshotsEnabled: %t", feature.SnapshotsEnabled()))
log.Info(fmt.Sprintf("[main] Feature VolumeCleanupEnabled: %t", feature.VolumeCleanupEnabled()))

log.Info("[main] CfgParams has been successfully created")
log.Info(fmt.Sprintf("[main] %s = %s", config.LogLevel, cfgParams.Loglevel))
Expand Down
Loading
Loading