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..75cbe29 --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +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: + 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..fd3a0b5 --- /dev/null +++ b/kubernetes/apps/storage/proxmox-csi/app/secret.sops.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Secret +metadata: + name: proxmox-csi-config +stringData: + config.yaml: ENC[AES256_GCM,data:PA0fLwDJAxsCKSe5szky6wTK001YcXHMGfDJNG1H8kSycTLybPDVRfbmDI9D0JYPMcBaOb63QWCflF+wlvQZ2dTO9ZT1qsrLKmHpPA4SULM+3dHrKxAakzfzQv0BDIypvneAcn5VZs/vG1UCEfqz6UnnwMU1F59Nsbc5SSuh10zBBea812rV9D5+q76EviwYUTrNUjYve5Wx4zSLEpPMXq2CBAcKhq/w31pAsysKvMIVb2HPPmKudkO+GdN+mA==,iv:TRznl4Fg2C75hhNcoiKoOzO4G7f5sElXlQ9ri2xZk2A=,tag:zELD8rJi4KXQxyIcNtjAWA==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IG1sa2VtNzY4eDI1NTE5IEU0cWdlQ1Q5 + VVoyeUNpdjR3NjRpVzdTZlNoQkdjT3VYOEovZ045cDZmK2pNVUVSMm9sa2tMT1d3 + a05OOHc3ZTJ2SFIzcHgzbDhvdEVxNTJ2U2ZXN0tvOFYrZlM2OXlpbTNEODh0aWd5 + ZUZhSkttWktMcEE1WSt0WHR4bGoza1d1QVBTRC9OSkRWK0pZN2dQK3NIRUNHSlFM + MVpWemJBaFpnejZnTTBhSmxsRU9iN2dvQ29iaXBjYmMyT0xrS2hnYjYrUno2S2JH + Z3pOUm8vK0lTSVRPYVMvSnRaenZOTHFGNTZsY0VrSWVMVG9mUjRaU0hJNDlsSCtF + WWdpYnFyRTl4RmUyU1JOeWVsWWRpLzFLSEJVdTlTZDJ2UFdpYnh2eENrOTJFVjFS + c1Y0UWMxS3Y1OTJhRkNwL1NlUzZQdmk2VXRqbFpqVnFpT09XemN6ZC9hRlRKVjR3 + THpHRUprTGhGMnpiTWtNY0xBVCtHMkY1NUdDTDRhVnpXd3FSRlhNMjZ3OUlabmJt + N1hKRHlvbGhxSmFNQjQ4UmY0akdFNEl1NytWNzhIMWw4V2pCM3ZDZldBWTdMMmRz + MUtQQTM3Sld3TGRod0VPU29GVkhIdzZWejRvTnhvOUdyQk14YWZ4WGMyV1pPaGhT + c3NMaFhGaFlOQVc1VzBDRnk1YUZ3ejNjek9SdnBiY1ZkRkNISHdXVXJTcEhRQkVn + ZTNnNzFQVnRFd05ZaGdacUlWbDVzN2lFaHZiMFB5c3lGSDhBUWQyaTAvd3F0bWtj + eEJMaHpsdDNJVG12TzdDM1hWNDhsNm1yL0hLZ3VaTmdKanlyWGd4aHl0ZlcyclRO + RWdjV0p0S2VUV2s2c3RCd09xWWVGcjBYbkVWbG5qY0dhUUxmOWxIRTRLZTZ2NDQy + MEJCL1FTUXpLZVBSbmhBSzJ4ZUY3bStjOWpEbENib2h1aTFxMHFWdlQ5eEJ5NjZi + OENuRkZ4Q3ptWHI0RVc4Ryt2T3ZDQlQ5K3o0RURhME4wNDRQenJzcnJqNDNTdjA5 + ZW5IQnJ1ekZINitsQStZRm4vdVhqckFqWVFNZFpKRWx1WG5yZnFydE5UTEJxc0lL + UVhQZlBRekhlWW95eElvWkVyS1lyVUJYRXhGeWp5eXZNUkNKQUNld3VTSmpJM0Z0 + QWZQd0p1UlFPbjQzazVmNzV2YWdaWkpJK2pEUzNWUzZJdlpKUnZyQXhYbFFMdnJG + M2lNTWp0a1V6ODZteXBzcGdWMlFBNE5DdTJuRGpwOExQLzFZVTNzb3NKOTVjbFBF + bTVLc0NIMzVFZUtPVzIvRHNNcFNiTTl0TXI3WXk4MG9LMkVHSTkvTHRjV254WW5M + ZHVoV0xsbEcwaElpaytMMmR3RWQrNnMxZUdCa24rUndDQkJDeDkzc3ZWRmF5czZw + WWtZMTlpZGpNSm9lc21ocE4vcHpxaW1TWjlrUmFncWtIVWo2Mzc2QS9MV0JYTGhU + K05wTW9ydmJUYUludmVlSHpOY2NFVXFKbVQ4dC9tM3g4d0t1ZWw4Z2Q5OTdFcnFi + T2ZVS2ZNWTNHWmFNcko1ZnhkdE40bitESFMreGpKRTZlSGRLVnk3WEFnNk9MTTNi + NkVpK21HNENLSDdvSHV2SDhYeGVGTythYmMxUUoxbzFxOE56SHY5dlNUcjNMRDJv + YUtybVk2MHRJY2tvQXJoT1IxSFhNTXpoZWQyQzNGby9IZnVNT2dVSXVvWmt2Z3pJ + b0RFZzZ1QW0vYUM3d3lNOXhkdjhQL010QjRxRkJTMEdhS2NJMkFRRGROdEhDN1N2 + eE44NUMwZk9GbkNQT09xWCtuN1VIVDJZSGVWUUdYUDNVUmUrUWNqeTBBWjRSTEx3 + TEFnWnMzVkQ2ZUxlYjRWWjE1dHdRM3RBakprYzQ1Q0tVNVVoNkMya00yL29MSjBy + aEt4eDV2dC9lR1Y4a2FRM3YyOFZNai9wRHJONmY4OWViSHVPZFJnZTZydVhWUQpD + cE5uMHJVT2YrcjFqakVqTytNSE5oRHBWRFhwTHNrZUVGQlpJMVl6S3VvCi0tLSBE + ZEVGcHphK3djWTBybU90NUVQQi9hU2hSTWNSbVMrSm5WYXpnYXV6ZnprChbbmrjR + B+lczEcigg+5l38Pyv8lY1Ez/XygX/eE8V801fukdahZn7kXRXSv23Lvdi5EUq/6 + pmGSN0RLoC36CCM= + -----END AGE ENCRYPTED FILE----- + recipient: age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6 + encrypted_regex: ^(data|stringData)$ + lastmodified: "2026-09-17T15:29:19Z" + mac: ENC[AES256_GCM,data:OJohLIGwg5ULgiqtnk9KBIB1WhcVd9MslmaRtA2ZM5YrftbZ9g/FbzAgm4UzR+aga6DCtfQTIFpK0M/kxYh5vPAIBZ5T58bDbheV35jRQvIDVz/LAajewWcxOF1zqID07eix41PPP+QKk6rQ3zP1JUBwC6nNdEmEG2YBxA2z14M=,iv:gn2+TzRVeTYBLUSSFzuTDS2LE0wDWdA8spoVRM0lbfM=,tag:4rAQljRM3aDWpsE9GXyqyg==,type:str] + mac_only_encrypted: true + version: 3.13.3 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..31640a8 --- /dev/null +++ b/talos/all/32-node-labels.yaml @@ -0,0 +1,14 @@ +# Метки топологии для Proxmox CSI Plugin. +# Talos 1.14: node labels задаются ТОЛЬКО типизированным документом KubeNodeConfig — +# legacy-поле machine.nodeLabels в v1alpha1-конфиге deprecated, и обе формы +# одновременно применяться не могут (нода отвечает «.machine.nodeLabels is +# already set in v1alpha1 config»). +# region обязан совпадать с именем Proxmox-кластера (у нас на pve создан +# кластер `home-ops`), zone — с именем узла Proxmox (хост называется `pve`). +# Документ лежит в all/, то есть применяется и к будущим worker-нодам; патч, +# снимающий control-plane taint, остаётся в talos/control-plane/. +apiVersion: v1alpha1 +kind: KubeNodeConfig +labels: + topology.kubernetes.io/region: home-ops + topology.kubernetes.io/zone: pve