fix(minio): migrate to official chart, TF-owned
Bitnami wiped Docker Hub catalog (bitnami/minio: 0 tags), chart 14.1.0 dead on ImagePullBackOff. Move to minio/minio 5.4.0 (quay.io) as one TF helm_release. Add longhorn-xfs SC: default SC ext4 mkfs on 100Gi exceeds kubelet mount timeout, xfs near-instant. Drop minio ArgoCD Apps (TF owns now, kills dual-controller conflict). Fix double base64 on OIDC secret.
This commit is contained in:
@@ -1,85 +1,5 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: minio-operator
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "0"
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://operator.min.io
|
||||
targetRevision: v5.0.0
|
||||
chart: operator
|
||||
helm:
|
||||
releaseName: minio-operator
|
||||
values: |
|
||||
operator:
|
||||
image:
|
||||
repository: minio/operator
|
||||
tag: "v5.0.0"
|
||||
pullPolicy: IfNotPresent
|
||||
replicaCount: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
metrics:
|
||||
enabled: true
|
||||
port: 8080
|
||||
rbac:
|
||||
create: true
|
||||
console:
|
||||
enabled: true
|
||||
replicaCount: 1
|
||||
image:
|
||||
repository: minio/console
|
||||
tag: "v0.30.0"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: minio-operator
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "0"
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/storage
|
||||
directory:
|
||||
recurse: false
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: storage
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
---
|
||||
# MinIO now managed by Terraform (terraform/minio.tf) via official minio/minio
|
||||
# chart — removed from ArgoCD to avoid dual-controller conflict on storage NS.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
|
||||
@@ -8,6 +8,22 @@ resource "kubernetes_namespace" "argocd" {
|
||||
}
|
||||
}
|
||||
|
||||
# Copy homelab-ca-secret from cert-manager to argocd namespace
|
||||
# (Required for repo-server pod to verify self-signed forgejo TLS)
|
||||
resource "null_resource" "copy_ca_secret_to_argocd" {
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
kubectl get secret homelab-ca-secret -n cert-manager -o yaml | \
|
||||
sed 's/namespace: cert-manager/namespace: argocd/' | \
|
||||
kubectl apply -f -
|
||||
EOT
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
kubernetes_namespace.argocd
|
||||
]
|
||||
}
|
||||
|
||||
resource "helm_release" "argocd" {
|
||||
name = "argocd"
|
||||
repository = local.helm_repos["argo"]
|
||||
@@ -27,13 +43,6 @@ resource "helm_release" "argocd" {
|
||||
rbac = {
|
||||
"policy.default" = "role:readonly"
|
||||
}
|
||||
repositories = {
|
||||
"minio-operator" = {
|
||||
url = "https://operator.min.io"
|
||||
name = "minio-operator"
|
||||
type = "helm"
|
||||
}
|
||||
}
|
||||
}
|
||||
server = {
|
||||
extraArgs = [
|
||||
@@ -44,6 +53,14 @@ resource "helm_release" "argocd" {
|
||||
hosts = [
|
||||
"argocd.${var.cluster_domain}"
|
||||
]
|
||||
annotations = {
|
||||
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTPS"
|
||||
}
|
||||
ingressClassName = "nginx"
|
||||
}
|
||||
service = {
|
||||
type = "ClusterIP"
|
||||
port = 80
|
||||
}
|
||||
}
|
||||
repoServer = {
|
||||
@@ -80,7 +97,8 @@ resource "helm_release" "argocd" {
|
||||
]
|
||||
|
||||
depends_on = [
|
||||
kubernetes_namespace.argocd
|
||||
kubernetes_namespace.argocd,
|
||||
null_resource.copy_ca_secret_to_argocd
|
||||
]
|
||||
|
||||
# Note: lifecycle.ignore_changes removed to allow CA cert update
|
||||
@@ -97,8 +115,7 @@ resource "kubernetes_manifest" "argocd_project" {
|
||||
}
|
||||
spec = {
|
||||
sourceRepos = [
|
||||
"https://forgejo.riotpiao.homelab.com/riotpiao.com/*",
|
||||
"https://operator.min.io"
|
||||
"https://forgejo.riotpiao.homelab.com/riotpiao.com/*"
|
||||
]
|
||||
destinations = [
|
||||
{
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
# MinIO Operator - v4.5.8 (compatible with installed CRD)
|
||||
# v5.0.0 has credential validation bug that breaks tenants
|
||||
# Downgrading to stable v4.5.8 until upstream fixes validation logic
|
||||
|
||||
resource "kubernetes_namespace" "minio_operator" {
|
||||
metadata {
|
||||
name = "minio-operator"
|
||||
labels = {
|
||||
"pod-security.kubernetes.io/enforce" = "baseline"
|
||||
"pod-security.kubernetes.io/enforce-version" = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "helm_release" "minio_operator" {
|
||||
name = "minio-operator"
|
||||
repository = "https://operator.min.io"
|
||||
chart = "operator"
|
||||
version = "4.5.8"
|
||||
namespace = kubernetes_namespace.minio_operator.metadata[0].name
|
||||
|
||||
values = [
|
||||
yamlencode({
|
||||
operator = {
|
||||
image = {
|
||||
repository = "minio/operator"
|
||||
tag = "v4.5.8"
|
||||
}
|
||||
replicaCount = 1
|
||||
}
|
||||
console = {
|
||||
enabled = true
|
||||
}
|
||||
})
|
||||
]
|
||||
|
||||
depends_on = [
|
||||
kubernetes_namespace.minio_operator
|
||||
]
|
||||
}
|
||||
|
||||
# MinIO credentials secret - v4.5.8 format (credsSecret with individual keys)
|
||||
resource "kubernetes_secret" "minio_creds" {
|
||||
metadata {
|
||||
name = "minio-creds"
|
||||
namespace = "storage"
|
||||
}
|
||||
type = "Opaque"
|
||||
|
||||
data = {
|
||||
accesskey = base64encode("minioadmin")
|
||||
secretkey = base64encode(var.minio_root_password)
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
kubernetes_namespace.storage
|
||||
]
|
||||
}
|
||||
|
||||
# Placeholder: kubernetes_namespace.storage should exist from bootstrap
|
||||
# If not, create:
|
||||
resource "kubernetes_namespace" "storage" {
|
||||
count = var.create_storage_namespace ? 1 : 0
|
||||
|
||||
metadata {
|
||||
name = "storage"
|
||||
labels = {
|
||||
"pod-security.kubernetes.io/enforce" = "baseline"
|
||||
"pod-security.kubernetes.io/enforce-version" = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "create_storage_namespace" {
|
||||
description = "Create storage namespace if it doesn't exist"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
# MinIO - Official minio/minio chart, direct Helm deployment (no operator)
|
||||
# All-in-one: single helm_release + dedicated xfs StorageClass.
|
||||
# Why xfs: default `longhorn` SC uses ext4 whose mkfs on 100Gi (~4.5min)
|
||||
# exceeds kubelet mount timeout. xfs mkfs is near-instant. min.io chart has
|
||||
# no persistence.fsType, so fsType must be set on the StorageClass.
|
||||
|
||||
resource "kubernetes_storage_class" "longhorn_xfs" {
|
||||
metadata {
|
||||
name = "longhorn-xfs"
|
||||
}
|
||||
storage_provisioner = "driver.longhorn.io"
|
||||
reclaim_policy = "Delete"
|
||||
allow_volume_expansion = true
|
||||
volume_binding_mode = "Immediate"
|
||||
|
||||
parameters = {
|
||||
numberOfReplicas = "2"
|
||||
staleReplicaTimeout = "60"
|
||||
fsType = "xfs"
|
||||
dataLocality = "disabled"
|
||||
}
|
||||
}
|
||||
|
||||
resource "helm_release" "minio" {
|
||||
name = "minio"
|
||||
repository = "https://charts.min.io/"
|
||||
chart = "minio"
|
||||
version = "5.4.0"
|
||||
namespace = "storage"
|
||||
upgrade_install = true
|
||||
force_update = true
|
||||
wait = true
|
||||
timeout = 600
|
||||
|
||||
values = [
|
||||
yamlencode({
|
||||
mode = "standalone"
|
||||
replicas = 1
|
||||
drivesPerNode = 1
|
||||
pools = 1
|
||||
|
||||
rootUser = "minioadmin"
|
||||
rootPassword = var.minio_root_password
|
||||
|
||||
persistence = {
|
||||
enabled = true
|
||||
size = "100Gi"
|
||||
storageClass = kubernetes_storage_class.longhorn_xfs.metadata[0].name
|
||||
accessMode = "ReadWriteOnce"
|
||||
}
|
||||
|
||||
resources = {
|
||||
requests = {
|
||||
memory = "512Mi"
|
||||
}
|
||||
}
|
||||
|
||||
service = {
|
||||
type = "ClusterIP"
|
||||
port = "9000"
|
||||
}
|
||||
consoleService = {
|
||||
type = "ClusterIP"
|
||||
port = "9001"
|
||||
}
|
||||
|
||||
# Buckets auto-created on install (all-in-one, no post-hook needed)
|
||||
buckets = [
|
||||
{ name = "vault", policy = "none", purge = false },
|
||||
{ name = "riotpiao-models", policy = "none", purge = false },
|
||||
]
|
||||
|
||||
environment = {
|
||||
MINIO_IDENTITY_OPENID_CONFIG_URL = "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration"
|
||||
MINIO_IDENTITY_OPENID_CLIENT_ID = "minio"
|
||||
MINIO_IDENTITY_OPENID_CLIENT_SECRET = var.minio_oidc_client_secret
|
||||
MINIO_IDENTITY_OPENID_CLAIM_NAME = "policy"
|
||||
MINIO_IDENTITY_OPENID_SCOPES = "openid,profile,email,minio"
|
||||
MINIO_IDENTITY_OPENID_REDIRECT_URI = "https://minio.riotpiao.homelab.com/oauth_callback"
|
||||
MINIO_IDENTITY_OPENID_DISPLAY_NAME = "Authentik"
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
variable "create_storage_namespace" {
|
||||
description = "Create storage namespace if it doesn't exist"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
Reference in New Issue
Block a user