diff --git a/kubernetes/apps/storage/kustomization.yaml b/kubernetes/apps/storage/kustomization.yaml new file mode 100644 index 0000000..bcaadc5 --- /dev/null +++ b/kubernetes/apps/storage/kustomization.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: storage + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./proxmox-csi/ks.yaml diff --git a/kubernetes/apps/storage/namespace.yaml b/kubernetes/apps/storage/namespace.yaml new file mode 100644 index 0000000..f1bcfa1 --- /dev/null +++ b/kubernetes/apps/storage/namespace.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: storage + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled + # proxmox-csi-plugin ставит привилегированный node-DaemonSet (работа с + # /dev и монтированием дисков), поэтому PSA для этого ns ослаблен. + pod-security.kubernetes.io/enforce: privileged diff --git a/kubernetes/apps/storage/proxmox-csi/app/helmrelease.yaml b/kubernetes/apps/storage/proxmox-csi/app/helmrelease.yaml new file mode 100644 index 0000000..4b69996 --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/app/helmrelease.yaml @@ -0,0 +1,62 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: proxmox-csi-plugin +spec: + chartRef: + kind: OCIRepository + name: proxmox-csi-plugin + interval: 1h + maxHistory: 3 + install: + crds: CreateReplace + remediation: + retries: 3 + upgrade: + crds: CreateReplace + cleanupOnFail: true + remediation: + retries: 3 + values: + # Подключение к Proxmox (url/токен/region) и StorageClass'ы: сам конфиг лежит + # в Secret'е proxmox-csi-config (файл secret.sops.yaml рядом, шифруется sops). + existingConfigSecret: proxmox-csi-config + existingConfigSecretKey: config.yaml + storageClass: + # local-zfs = пул rpool (зеркало 2x NVMe) — дефолтный класс: сюда идут + # Vault, базы и всё, что требует избыточности на уровне дисков. + - name: proxmox-local-zfs + storage: local-zfs + fstype: ext4 + ssd: true + reclaimPolicy: Delete + annotations: + storageclass.kubernetes.io/is-default-class: "true" + # ssd = большой пул (2 TB, одиночный NVMe) — под bulk-данные. + - name: proxmox-ssd + storage: ssd + fstype: ext4 + ssd: true + reclaimPolicy: Delete + controller: + # Все три ноды — control-plane, поэтому контроллер цепляем туда же + # (и терпим taint control-plane). + nodeSelector: + node-role.kubernetes.io/control-plane: "" + tolerations: + - key: node-role.kubernetes.io/control-plane + effect: NoSchedule + node: + tolerations: + - key: node-role.kubernetes.io/control-plane + effect: NoSchedule + - key: karpenter.sh/disrupted + operator: Exists + effect: NoSchedule + - key: node.kubernetes.io/unschedulable + operator: Exists + effect: NoSchedule + - key: node.kubernetes.io/disk-pressure + operator: Exists + effect: NoSchedule diff --git a/kubernetes/apps/storage/proxmox-csi/app/kustomization.yaml b/kubernetes/apps/storage/proxmox-csi/app/kustomization.yaml new file mode 100644 index 0000000..f79ce82 --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/app/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./ocirepository.yaml + - ./helmrelease.yaml + - ./secret.sops.yaml diff --git a/kubernetes/apps/storage/proxmox-csi/app/ocirepository.yaml b/kubernetes/apps/storage/proxmox-csi/app/ocirepository.yaml new file mode 100644 index 0000000..4930701 --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/app/ocirepository.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: proxmox-csi-plugin +spec: + interval: 12h + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + # Версия ЧАРТА, а не приложения: у релиза v0.20.0 (appVersion v0.20.0) + # чарт идёт с version 0.5.10 (см. charts/proxmox-csi-plugin/Chart.yaml). + tag: 0.5.10 + url: oci://ghcr.io/sergelogvinov/charts/proxmox-csi-plugin diff --git a/kubernetes/apps/storage/proxmox-csi/app/secret.sops.yaml b/kubernetes/apps/storage/proxmox-csi/app/secret.sops.yaml new file mode 100644 index 0000000..72e888e --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/app/secret.sops.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: proxmox-csi-config +stringData: + config.yaml: |- + clusters: + - url: https://pve.grachevko.ru:8006/api2/json + # PVE отдаёт самоподписанный сертификат — проверку отключаем. + insecure: true + token_id: kubernetes-csi@pve!csi + # TODO: вписать секрет токена из `pveum user token add kubernetes-csi@pve csi` + # и зашифровать файл: sops -e -i kubernetes/apps/storage/proxmox-csi/app/secret.sops.yaml + token_secret: REPLACE_WITH_PVE_TOKEN_SECRET + # region = имя существующего Proxmox-кластера на pve (переименование не + # делаем: PVE не поддерживает смену имени кластера). zone = имя узла PVE + # и приходит из метки topology.kubernetes.io/zone (сейчас `pve`). + region: home-ops diff --git a/kubernetes/apps/storage/proxmox-csi/ks.yaml b/kubernetes/apps/storage/proxmox-csi/ks.yaml new file mode 100644 index 0000000..e416da1 --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/ks.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: proxmox-csi +spec: + interval: 1h + path: ./kubernetes/apps/storage/proxmox-csi/app + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: storage + wait: true + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + name: proxmox-csi-plugin + namespace: storage diff --git a/talos/all/32-node-labels.yaml b/talos/all/32-node-labels.yaml new file mode 100644 index 0000000..fa3886e --- /dev/null +++ b/talos/all/32-node-labels.yaml @@ -0,0 +1,7 @@ +# Метки топологии для Proxmox CSI Plugin. +# region обязан совпадать с именем Proxmox-кластера (у нас на pve уже создан +# кластер `home-ops`), zone — с именем узла Proxmox (хост называется `pve`). +machine: + nodeLabels: + topology.kubernetes.io/region: home-ops + topology.kubernetes.io/zone: pve