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
|
# MinIO now managed by Terraform (terraform/minio.tf) via official minio/minio
|
||||||
kind: Application
|
# chart — removed from ArgoCD to avoid dual-controller conflict on storage NS.
|
||||||
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
|
|
||||||
---
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
apiVersion: argoproj.io/v1alpha1
|
||||||
kind: Application
|
kind: Application
|
||||||
metadata:
|
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" {
|
resource "helm_release" "argocd" {
|
||||||
name = "argocd"
|
name = "argocd"
|
||||||
repository = local.helm_repos["argo"]
|
repository = local.helm_repos["argo"]
|
||||||
@@ -27,13 +43,6 @@ resource "helm_release" "argocd" {
|
|||||||
rbac = {
|
rbac = {
|
||||||
"policy.default" = "role:readonly"
|
"policy.default" = "role:readonly"
|
||||||
}
|
}
|
||||||
repositories = {
|
|
||||||
"minio-operator" = {
|
|
||||||
url = "https://operator.min.io"
|
|
||||||
name = "minio-operator"
|
|
||||||
type = "helm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
server = {
|
server = {
|
||||||
extraArgs = [
|
extraArgs = [
|
||||||
@@ -44,6 +53,14 @@ resource "helm_release" "argocd" {
|
|||||||
hosts = [
|
hosts = [
|
||||||
"argocd.${var.cluster_domain}"
|
"argocd.${var.cluster_domain}"
|
||||||
]
|
]
|
||||||
|
annotations = {
|
||||||
|
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTPS"
|
||||||
|
}
|
||||||
|
ingressClassName = "nginx"
|
||||||
|
}
|
||||||
|
service = {
|
||||||
|
type = "ClusterIP"
|
||||||
|
port = 80
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
repoServer = {
|
repoServer = {
|
||||||
@@ -80,7 +97,8 @@ resource "helm_release" "argocd" {
|
|||||||
]
|
]
|
||||||
|
|
||||||
depends_on = [
|
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
|
# Note: lifecycle.ignore_changes removed to allow CA cert update
|
||||||
@@ -97,8 +115,7 @@ resource "kubernetes_manifest" "argocd_project" {
|
|||||||
}
|
}
|
||||||
spec = {
|
spec = {
|
||||||
sourceRepos = [
|
sourceRepos = [
|
||||||
"https://forgejo.riotpiao.homelab.com/riotpiao.com/*",
|
"https://forgejo.riotpiao.homelab.com/riotpiao.com/*"
|
||||||
"https://operator.min.io"
|
|
||||||
]
|
]
|
||||||
destinations = [
|
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