This commit is contained in:
2026-03-27 16:56:12 +00:00
parent 2667208da4
commit 6bf27d241f
13 changed files with 2 additions and 930 deletions

View File

@@ -1,16 +0,0 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: fileserver
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
namespace: fileserver
server: https://kubernetes.default.svc
project: default
source:
path: fileserver
repoURL: http://gitea.gitea.svc.k8s.undercloud.local:3000/Undercloud/k8s-apps.git
targetRevision: HEAD

View File

@@ -1,16 +0,0 @@
# Fileserver
## samba + filebrowser + csi-smb-driver
csi-smb
makes it possible to use SMB shares as kubernetes volumes (volume claims etc)
### improvements:
samba
ldap integration
metrics
liveness probes
resource limits
filebrowser
automatically change password
ldap inntegration

View File

@@ -1,90 +0,0 @@
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: fileserver-csi-hourly
namespace: velero
spec:
schedule: "0 15-22 * * *"
useOwnerReferencesInBackup: true
template:
includedNamespaces: ["fileserver"]
ttl: 8h
snapshotVolumes: true
defaultVolumesToFsBackup: false
csiSnapshotTimeout: 10m
---
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: fileserver-csi-daily
namespace: velero
spec:
schedule: "0 0 * * *"
useOwnerReferencesInBackup: true
template:
includedNamespaces: ["fileserver"]
ttl: 168h
snapshotVolumes: true
defaultVolumesToFsBackup: false
csiSnapshotTimeout: 10m
---
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: fileserver-csi-weekly
namespace: velero
spec:
schedule: "0 0 * * 1"
useOwnerReferencesInBackup: true
template:
includedNamespaces: ["fileserver"]
ttl: 730h
snapshotVolumes: true
defaultVolumesToFsBackup: false
csiSnapshotTimeout: 10m
---
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: fileserver-daily
namespace: velero
spec:
schedule: "30 2 * * *" # tous les jours 02:30
useOwnerReferencesInBackup: true
template:
includedNamespaces: [fileserver]
storageLocation: default
ttl: 336h # ~14 jours
snapshotVolumes: false
defaultVolumesToFsBackup: true
---
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: fileserver-weekly
namespace: velero
spec:
schedule: "0 3 * * 0" # chaque dimanche 03:00
useOwnerReferencesInBackup: true
template:
includedNamespaces: [fileserver]
storageLocation: default
ttl: 1344h # ~8 semaines
snapshotVolumes: false
defaultVolumesToFsBackup: true
---
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: fileserver-monthly
namespace: velero
spec:
schedule: "0 4 1 * *" # 1er du mois 04:00
useOwnerReferencesInBackup: true
template:
includedNamespaces: [fileserver]
storageLocation: default
ttl: 8760h # ~12 mois
snapshotVolumes: false
defaultVolumesToFsBackup: true

View File

@@ -1,7 +0,0 @@
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: smb.csi.k8s.io
spec:
attachRequired: false
podInfoOnMount: true

View File

@@ -1,108 +0,0 @@
kind: Deployment
apiVersion: apps/v1
metadata:
name: csi-smb-controller
namespace: fileserver
spec:
replicas: 1
selector:
matchLabels:
app: csi-smb-controller
template:
metadata:
labels:
app: csi-smb-controller
spec:
dnsPolicy: Default # available values: Default, ClusterFirstWithHostNet, ClusterFirst
serviceAccountName: csi-smb-controller-sa
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/controlplane"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: csi-provisioner
image: registry.k8s.io/sig-storage/csi-provisioner:v3.2.0
args:
- "-v=2"
- "--csi-address=$(ADDRESS)"
- "--leader-election"
- "--leader-election-namespace=kube-system"
- "--extra-create-metadata=true"
env:
- name: ADDRESS
value: /csi/csi.sock
volumeMounts:
- mountPath: /csi
name: socket-dir
#resources:
# limits:
# cpu: 1
# memory: 300Mi
# requests:
# cpu: 10m
# memory: 20Mi
- name: liveness-probe
image: registry.k8s.io/sig-storage/livenessprobe:v2.7.0
args:
- --csi-address=/csi/csi.sock
- --probe-timeout=3s
- --health-port=29642
- --v=2
volumeMounts:
- name: socket-dir
mountPath: /csi
#resources:
# limits:
# cpu: 1
# memory: 100Mi
# requests:
# cpu: 10m
# memory: 20Mi
- name: smb
image: registry.k8s.io/sig-storage/smbplugin:v1.9.0
imagePullPolicy: IfNotPresent
args:
- "--v=5"
- "--endpoint=$(CSI_ENDPOINT)"
- "--metrics-address=0.0.0.0:29644"
ports:
- containerPort: 29642
name: healthz
protocol: TCP
- containerPort: 29644
name: metrics
protocol: TCP
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: healthz
initialDelaySeconds: 30
timeoutSeconds: 10
periodSeconds: 30
env:
- name: CSI_ENDPOINT
value: unix:///csi/csi.sock
securityContext:
privileged: true
volumeMounts:
- mountPath: /csi
name: socket-dir
#resources:
# limits:
# memory: 200Mi
# requests:
# cpu: 10m
# memory: 20Mi
volumes:
- name: socket-dir
emptyDir: {}

View File

@@ -1,128 +0,0 @@
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: csi-smb-node
namespace: fileserver
spec:
updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
app: csi-smb-node
template:
metadata:
labels:
app: csi-smb-node
spec:
hostNetwork: true
dnsPolicy: Default # available values: Default, ClusterFirstWithHostNet, ClusterFirst
serviceAccountName: csi-smb-node-sa
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-node-critical
tolerations:
- operator: "Exists"
containers:
- name: liveness-probe
volumeMounts:
- mountPath: /csi
name: socket-dir
image: registry.k8s.io/sig-storage/livenessprobe:v2.7.0
args:
- --csi-address=/csi/csi.sock
- --probe-timeout=3s
- --health-port=29643
- --v=2
#resources:
# limits:
# memory: 100Mi
# requests:
# cpu: 10m
# memory: 20Mi
- name: node-driver-registrar
image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1
args:
- --csi-address=$(ADDRESS)
- --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
- --v=2
livenessProbe:
exec:
command:
- /csi-node-driver-registrar
- --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
- --mode=kubelet-registration-probe
initialDelaySeconds: 30
timeoutSeconds: 15
env:
- name: ADDRESS
value: /csi/csi.sock
- name: DRIVER_REG_SOCK_PATH
value: /var/lib/kubelet/plugins/smb.csi.k8s.io/csi.sock
volumeMounts:
- name: socket-dir
mountPath: /csi
- name: registration-dir
mountPath: /registration
#resources:
#limits:
# memory: 100Mi
#requests:
# cpu: 10m
# memory: 20Mi
- name: smb
image: registry.k8s.io/sig-storage/smbplugin:v1.9.0
imagePullPolicy: IfNotPresent
args:
- "--v=5"
- "--endpoint=$(CSI_ENDPOINT)"
- "--nodeid=$(KUBE_NODE_NAME)"
- "--metrics-address=0.0.0.0:29645"
ports:
- containerPort: 29643
name: healthz
protocol: TCP
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: healthz
initialDelaySeconds: 30
timeoutSeconds: 10
periodSeconds: 30
env:
- name: CSI_ENDPOINT
value: unix:///csi/csi.sock
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
securityContext:
privileged: true
volumeMounts:
- mountPath: /csi
name: socket-dir
- mountPath: /var/lib/kubelet/
mountPropagation: Bidirectional
name: mountpoint-dir
#resources:
# limits:
# memory: 200Mi
# requests:
# cpu: 10m
# memory: 20Mi
volumes:
- hostPath:
path: /var/lib/kubelet/plugins/smb.csi.k8s.io
type: DirectoryOrCreate
name: socket-dir
- hostPath:
path: /var/lib/kubelet/
type: DirectoryOrCreate
name: mountpoint-dir
- hostPath:
path: /var/lib/kubelet/plugins_registry/
type: DirectoryOrCreate
name: registration-dir

View File

@@ -1,55 +0,0 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-smb-controller-sa
namespace: fileserver
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-smb-node-sa
namespace: fileserver
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: smb-external-provisioner-role
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["csinodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: smb-csi-provisioner-binding
subjects:
- kind: ServiceAccount
name: csi-smb-controller-sa
namespace: fileserver
roleRef:
kind: ClusterRole
name: smb-external-provisioner-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,79 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: filebrowser-db
namespace: fileserver
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 4Gi
storageClassName: cephfs-hyper
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: filebrowser
namespace: fileserver
labels:
app: filebrowser
spec:
replicas: 1
selector:
matchLabels:
app: filebrowser
template:
metadata:
labels:
app: filebrowser
spec:
initContainers:
- name: createfile
image: debian
command: ["bash", "-c", "touch /database/database.db && ls -la /database"]
volumeMounts:
- mountPath: "/database/"
name: filebrowser-db
containers:
- name: filebrowser
image: filebrowser/filebrowser
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/srv"
name: filebrowser
- mountPath: "/database.db"
name: filebrowser-db
subPath: database.db
volumes:
- name: filebrowser
persistentVolumeClaim:
claimName: samba
- name: filebrowser-db
persistentVolumeClaim:
claimName: filebrowser-db
---
apiVersion: v1
kind: Service
metadata:
name: filebrowser
namespace: fileserver
labels:
app: filebrowser
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv6
- IPv4
ipFamilyPolicy: PreferDualStack
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: filebrowser
sessionAffinity: None
type: ClusterIP

View File

@@ -1,28 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fileserver
namespace: fileserver
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/proxy-body-size: "16g"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
tls:
- hosts:
- fileserver.apps.undercloud.dev
secretName: fileserver-tls
rules:
- host: fileserver.apps.undercloud.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: filebrowser
port:
number: 80

View File

@@ -1,6 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: fileserver
labels:
prometheus: prometheus

View File

@@ -1,367 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: samba
namespace: fileserver
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 500Gi
storageClassName: cephfs-hyper
---
apiVersion: v1
kind: ConfigMap
metadata:
name: samba-ldap-config
namespace: fileserver
data:
smb.conf: |
[global]
workgroup = UNDERCLOUD
netbios name = SAMBA
server string = Undercloud Samba LDAP Server
security = user
encrypt passwords = yes
passdb backend = ldapsam:ldap://ldap.openldap.svc
ldap admin dn = cn=admin,dc=undercloud,dc=local
ldap suffix = dc=undercloud,dc=local
ldap user suffix = ou=users
ldap group suffix = ou=groups
ldap passwd sync = yes
ldap ssl = off
obey pam restrictions = no
unix password sync = no
passwd program = /bin/false
passwd chat = *Enter\snew\spassword:* %n\n *Retype\snew\spassword:* %n\n .
map to guest = Never
guest account = nobody
log file = /var/log/samba/log.%m
max log size = 1000
logging = file
log level = 2
server min protocol = SMB2
client min protocol = SMB2
disable netbios = no
name resolve order = host bcast
[data]
path = /mnt/data
browseable = yes
read only = no
valid users = shodan glados sebastian samba
create mask = 0664
directory mask = 0775
[music]
path = /mnt/music
browseable = yes
read only = no
valid users = shodan glados sebastian samba
create mask = 0664
directory mask = 0775
[movies]
path = /mnt/movies
browseable = yes
read only = no
valid users = shodan glados sebastian samba
create mask = 0664
directory mask = 0775
[tvshows]
path = /mnt/tvshows
browseable = yes
read only = no
valid users = shodan glados sebastian samba
create mask = 0664
directory mask = 0775
libnss-ldap.conf: |
base dc=undercloud,dc=local
uri ldap://ldap.openldap.svc
ldap_version 3
binddn cn=admin,dc=undercloud,dc=local
bindpw __LDAP_BINDPW__
ssl off
pam_password clear
smbldap.conf: |
SID="S-1-5-21-123456789-123456789-123456789"
sambaDomain="samba"
slaveLDAP="ldap://ldap.openldap.svc"
masterLDAP="ldap://ldap.openldap.svc"
ldapTLS="0"
verify="none"
suffix="dc=undercloud,dc=local"
usersdn="ou=users,${suffix}"
groupsdn="ou=groups,${suffix}"
computersdn="ou=computers,${suffix}"
idmapdn="ou=idmap,${suffix}"
binddn="cn=admin,dc=undercloud,dc=local"
uidStart="10000"
uidEnd="99999"
gidStart="10000"
gidEnd="99999"
userLoginShell="/bin/false"
userHome="/nonexistent"
userSmbHome="\\\\SAMBA\\data\\%U"
userProfile="\\\\SAMBA\\profiles\\%U"
userHomeDrive="H:"
userScript=""
mailDomain="undercloud.local"
smbldap_bind.conf: |
slaveDN="cn=admin,dc=undercloud,dc=local"
slavePw="__LDAP_BINDPW__"
masterDN="cn=admin,dc=undercloud,dc=local"
masterPw="__LDAP_BINDPW__"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: samba
namespace: fileserver
labels:
app: samba
spec:
replicas: 1
selector:
matchLabels:
app: samba
template:
metadata:
labels:
app: samba
spec:
dnsConfig:
options:
- name: ndots
value: "1"
enableServiceLinks: false
initContainers:
- name: createfolders
image: debian:12-slim
command:
- bash
- -ec
- |
mkdir -p /data/music /data/movies /data/tvshows /data/data
chmod -R 0777 /data
ls -la /data
volumeMounts:
- mountPath: /data
name: data
- name: render-config
image: debian:12-slim
env:
- name: LDAP_BINDPW
valueFrom:
secretKeyRef:
name: samba-ldap-secrets
key: LDAP_BINDPW
command:
- bash
- -ec
- |
mkdir -p /rendered
sed "s|__LDAP_BINDPW__|${LDAP_BINDPW}|g" /config/libnss-ldap.conf > /rendered/libnss-ldap.conf
sed "s|__LDAP_BINDPW__|${LDAP_BINDPW}|g" /config/smbldap.conf > /rendered/smbldap.conf
sed "s|__LDAP_BINDPW__|${LDAP_BINDPW}|g" /config/smbldap_bind.conf > /rendered/smbldap_bind.conf
cp /config/smb.conf /rendered/smb.conf
ls -la /rendered
volumeMounts:
- name: samba-config
mountPath: /config
- name: rendered-config
mountPath: /rendered
- name: network-diagnostics
image: andrespp/samba-ldap:latest
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -ec
- |
echo "=== network diagnostics start ==="
echo
echo "--- /etc/resolv.conf ---"
cat /etc/resolv.conf || true
echo
echo "--- hostname ---"
hostname || true
echo
echo "--- env grep for kubernetes/service hints ---"
env | sort | grep -Ei 'kubernetes|service|dns|cluster|ldap' || true
echo
for bin in ping ping6 getent nslookup host dig nc; do
if command -v "$bin" >/dev/null 2>&1; then
echo "FOUND: $bin -> $(command -v "$bin")"
else
echo "MISSING: $bin"
fi
done
echo
echo "--- name resolution tests ---"
if command -v getent >/dev/null 2>&1; then
echo "getent hosts ldap.openldap.svc"
getent hosts ldap.openldap.svc || true
echo "getent hosts ldap.openldap.svc.cluster.local"
getent hosts ldap.openldap.svc.cluster.local || true
echo "getent hosts ldap.undercloud.local"
getent hosts ldap.undercloud.local || true
fi
if command -v nslookup >/dev/null 2>&1; then
echo "nslookup ldap.openldap.svc"
nslookup ldap.openldap.svc || true
echo "nslookup ldap.openldap.svc.cluster.local"
nslookup ldap.openldap.svc.cluster.local || true
echo "nslookup ldap.undercloud.local"
nslookup ldap.undercloud.local || true
fi
if command -v host >/dev/null 2>&1; then
echo "host ldap.openldap.svc"
host ldap.openldap.svc || true
echo "host ldap.openldap.svc.cluster.local"
host ldap.openldap.svc.cluster.local || true
echo "host ldap.undercloud.local"
host ldap.undercloud.local || true
fi
if command -v dig >/dev/null 2>&1; then
echo "dig ldap.openldap.svc"
dig ldap.openldap.svc || true
echo "dig ldap.openldap.svc.cluster.local"
dig ldap.openldap.svc.cluster.local || true
echo "dig ldap.undercloud.local"
dig ldap.undercloud.local || true
fi
echo
echo "--- connectivity tests ---"
if command -v ping >/dev/null 2>&1; then
echo "ping -4 10.0.91.41"
ping -4 -c 2 -W 2 10.0.91.41 || true
echo "ping -6 2001:470:7116:f:1::41"
ping -6 -c 2 -W 2 2001:470:7116:f:1::41 || true
echo "ping ldap.openldap.svc"
ping -c 2 -W 2 ldap.openldap.svc || true
echo "ping ldap.undercloud.local"
ping -c 2 -W 2 ldap.undercloud.local || true
fi
echo
if command -v nc >/dev/null 2>&1; then
echo "nc -zvw3 10.0.91.41 389"
nc -zvw3 10.0.91.41 389 || true
echo "nc -zvw3 10.0.91.41 636"
nc -zvw3 10.0.91.41 636 || true
echo "nc -zvw3 ldap.openldap.svc 389"
nc -zvw3 ldap.openldap.svc 389 || true
echo "nc -zvw3 ldap.openldap.svc 636"
nc -zvw3 ldap.openldap.svc 636 || true
echo "nc -zvw3 ldap.undercloud.local 389"
nc -zvw3 ldap.undercloud.local 389 || true
echo "nc -zvw3 ldap.undercloud.local 636"
nc -zvw3 ldap.undercloud.local 636 || true
fi
echo
echo "=== network diagnostics end ==="
containers:
- name: samba
image: andrespp/samba-ldap:latest
imagePullPolicy: IfNotPresent
env:
- name: SAMBA_LDAP_PASSWORD
valueFrom:
secretKeyRef:
name: samba-ldap-secrets
key: LDAP_BINDPW
ports:
- containerPort: 139
protocol: TCP
- containerPort: 445
protocol: TCP
volumeMounts:
- mountPath: /etc/samba/smb.conf
name: rendered-config
subPath: smb.conf
readOnly: true
- mountPath: /etc/libnss-ldap.conf
name: rendered-config
subPath: libnss-ldap.conf
readOnly: true
- mountPath: /etc/smbldap-tools/smbldap.conf
name: rendered-config
subPath: smbldap.conf
readOnly: true
- mountPath: /etc/smbldap-tools/smbldap_bind.conf
name: rendered-config
subPath: smbldap_bind.conf
readOnly: true
- mountPath: /mnt
name: data
readinessProbe:
tcpSocket:
port: 445
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 445
initialDelaySeconds: 30
periodSeconds: 20
volumes:
- name: data
persistentVolumeClaim:
claimName: samba
- name: samba-config
configMap:
name: samba-ldap-config
- name: rendered-config
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: samba
namespace: fileserver
labels:
app: samba
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv6
- IPv4
ipFamilyPolicy: PreferDualStack
ports:
- name: smb1
port: 139
protocol: TCP
targetPort: 139
- name: smb2
port: 445
protocol: TCP
targetPort: 445
selector:
app: samba
sessionAffinity: None
type: ClusterIP

View File

@@ -1,28 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: fileserver-smb-account
namespace: fileserver
type: Opaque
data:
username: YWRtaW4=
password: NElzVGhlTWluZEtpbGxlcg==
domain: bG9jYWxob3N0
---
apiVersion: v1
kind: Secret
metadata:
name: samba-users
namespace: fileserver
type: Opaque
data:
user: YWRtaW47NElzVGhlTWluZEtpbGxlcg==
---
apiVersion: v1
kind: Secret
metadata:
name: samba-ldap-secrets
namespace: fileserver
type: Opaque
data:
LDAP_BINDPW: NElzVGhlTWluZEtpbGxlcg==

View File

@@ -409,8 +409,8 @@ spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv6
- IPv4
ipFamilyPolicy: PreferDualStack
#- IPv4
ipFamilyPolicy: SingleStack
type: ClusterIP
selector:
app: nextcloud