gitops: upgrade Cilium to 1.19.1, add fujarna app, flux web UI, OIDC RBAC, and experiments

- Upgrade Cilium helm release from 1.18.5 to 1.19.1 with gatewayClass creation enabled
- Escalate gitea CI service account to cluster-admin, add OIDC cluster-admin binding
- Deploy fujarna app with full manifest set (deployment, service, PVC, httproutes, external secret)
- Add Flux web UI via flux-operator OCI repository and helm release
- Add experiments kustomization with test resources for gateway API and certificates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-01 22:23:12 +02:00
parent 96ba77a606
commit 5ca27a832b
21 changed files with 413 additions and 3 deletions

View File

@@ -7,6 +7,14 @@ subjects:
name: "gitea_ci@idm.home.hrajfrisbee.cz" # matches preferred_username claim
apiGroup: rbac.authorization.k8s.io
roleRef:
# kind: ClusterRole
# name: edit # scope down as needed
# apiGroup: rbac.authorization.k8s.io
# this is obviously too much permissions
# but we can live with it for homelab
kind: ClusterRole
name: edit # scope down as needed
apiGroup: rbac.authorization.k8s.io
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,15 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: https://idm.home.hrajfrisbee.cz/oauth2/openid/k8s#35842461-a1c4-4ad6-8b29-697c5ddbfe84
- apiGroup: rbac.authorization.k8s.io
kind: User
name: novakj@idm.home.hrajfrisbee.cz

View File

@@ -13,7 +13,7 @@ spec:
kind: HelmRepository
name: cilium
namespace: flux-system
version: 1.18.5
version: 1.19.1
interval: 5m0s
values:
cluster:
@@ -35,6 +35,8 @@ spec:
enabled: true
gatewayAPI:
enabled: true
gatewayClass:
create: "true"
kubeProxyReplacement: true
k8sServiceHost: 192.168.0.31 # or LB IP
k8sServicePort: 6443

View File

@@ -0,0 +1,17 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: operator-test-lab-home-hrajfrisbee-2
namespace: default
annotations:
gateway-cert-operator.io/gateway-name: "cilium-gateway"
gateway-cert-operator.io/gateway-namespace: "kube-system"
spec:
secretName: operator-test-lab-home-hrajfrisbee-2
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-prod
dnsNames:
- "operator-test-2.lab.home.hrajfrisbee.cz"

View File

@@ -0,0 +1,17 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: operator-test-lab-home-hrajfrisbee
namespace: default
annotations:
gateway-cert-operator.io/gateway-name: "cilium-gateway"
gateway-cert-operator.io/gateway-namespace: "kube-system"
spec:
secretName: operator-test-lab-home-hrajfrisbee
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-prod
dnsNames:
- "operator-test.lab.home.hrajfrisbee.cz"

View File

@@ -0,0 +1,30 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: operator-test
namespace: default
labels:
app: operator-test
spec:
replicas: 1
selector:
matchLabels:
app: operator-test
template:
metadata:
labels:
app: operator-test
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
name: http
resources:
requests:
cpu: 10m
memory: 16Mi
limits:
memory: 32Mi

View File

@@ -0,0 +1,25 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: operator-test-redirect
namespace: default
labels:
app: operator-test
spec:
parentRefs:
- name: cilium-gateway
namespace: kube-system
sectionName: http
hostnames:
- operator-test.lab.home.hrajfrisbee.cz
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301

View File

@@ -0,0 +1,24 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: operator-test
namespace: default
labels:
app: operator-test
spec:
parentRefs:
- name: cilium-gateway
namespace: kube-system
sectionName: auto-operator-test-lab-home-hrajfrisbee-operator-test-lab-home-hrajfrisbee-cz
hostnames:
- operator-test.lab.home.hrajfrisbee.cz
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: operator-test
namespace: default
port: 80

View File

@@ -0,0 +1,14 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-kube-system-gateway
namespace: default
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: kube-system
to:
- group: ""
kind: Secret
name: operator-test-lab-home-hrajfrisbee

View File

@@ -0,0 +1,15 @@
---
apiVersion: v1
kind: Service
metadata:
name: operator-test
namespace: default
spec:
type: ClusterIP
selector:
app: operator-test
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http

View File

@@ -130,6 +130,19 @@ spec:
sourceRef:
kind: GitRepository
name: flux-system
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: experiments
namespace: flux-system
spec:
interval: 10m0s
path: ./gitops/home-kubernetes/experiments
prune: true
sourceRef:
kind: GitRepository
name: flux-system
# ---
# apiVersion: kustomize.toolkit.fluxcd.io/v1
# kind: Kustomization

View File

@@ -0,0 +1,16 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: flux-web
namespace: flux-system
spec:
interval: 30m
releaseName: flux-web
chartRef:
kind: OCIRepository
name: flux-operator
values:
fullnameOverride: flux-web
installCRDs: true
web:
serverOnly: true

View File

@@ -0,0 +1,13 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: flux-operator
namespace: flux-system
spec:
interval: 30m
url: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator
layerSelector:
mediaType: "application/vnd.cncf.helm.chart.content.v1.tar+gzip"
operation: copy
ref:
semver: "0.x"

View File

@@ -0,0 +1,60 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: fujarna
namespace: fujarna
labels:
app: fujarna
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: fujarna
template:
metadata:
labels:
app: fujarna
spec:
imagePullSecrets:
- name: gitea-registry
containers:
- name: fujarna
image: gitea.home.hrajfrisbee.cz/kacerr/fujarna:v0.0.2
ports:
- containerPort: 8080
name: http
env:
- name: PORT
value: "8080"
- name: TZ
value: Europe/Prague
volumeMounts:
- name: data
mountPath: /app/data
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
readinessProbe:
httpGet:
path: /api/tournaments
port: 8080
initialDelaySeconds: 2
periodSeconds: 10
timeoutSeconds: 3
livenessProbe:
httpGet:
path: /api/tournaments
port: 8080
initialDelaySeconds: 5
periodSeconds: 30
timeoutSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: tournament-data

View File

@@ -0,0 +1,22 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: gitea-registry
namespace: fujarna
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: gitea-registry
creationPolicy: Owner
template:
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: "{{ .token }}"
data:
- secretKey: token
remoteRef:
key: k8s_home/gitea/container-registry
property: token

View File

@@ -0,0 +1,30 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: fujarna-redirect
namespace: fujarna
labels:
app: fujarna
app.kubernetes.io/name: fujarna-httproute
app.kubernetes.io/instance: fujarna
app.kubernetes.io/version: '6.0'
app.kubernetes.io/component: httproute
app.kubernetes.io/part-of: fujarna
spec:
parentRefs:
- name: cilium-gateway
namespace: kube-system
sectionName: http
hostnames:
- fujarna.lab.home.hrajfrisbee.cz
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301

View File

@@ -0,0 +1,29 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: fujarna
namespace: fujarna
labels:
app: fujarna
app.kubernetes.io/name: fujarna-httproute
app.kubernetes.io/instance: fujarna
app.kubernetes.io/version: '6.0'
app.kubernetes.io/component: httproute
app.kubernetes.io/part-of: fujarna
spec:
parentRefs:
- name: cilium-gateway
namespace: kube-system
sectionName: lab-home-hrajfrisbee-https-wildcard
hostnames:
- fujarna.lab.home.hrajfrisbee.cz
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: fujarna
namespace: fujarna
port: 80

View File

@@ -0,0 +1,30 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fujarna
namespace: fujarna
annotations:
# WebSocket support - increase timeouts for live scoring connections
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
# Uncomment for cert-manager TLS:
# cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx # change to "traefik" for k3s default
rules:
- host: hrajfrisbee.cz # change to your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: fujarna
port:
number: 80
# Uncomment for TLS:
# tls:
# - hosts:
# - hrajfrisbee.cz
# secretName: fujarna-tls

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: fujarna

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tournament-data
namespace: fujarna
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
# storageClassName: local-path # uncomment to override cluster default

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: fujarna
namespace: fujarna
spec:
type: ClusterIP
selector:
app: fujarna
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http