Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Jobs, CronJobs and Workers: Running an EF Core Migration Bundle as a Job
Run EF Core migrations once, in a versioned Job at the start of the deploy, not in every replica's init container; in our test the EF Core 9+ migration lock did not stop concurrent init containers from racing. With real output we package the bundle in a chiseled image, tune backoffLimit and TTL, hit Job immutability, write a pipeline script that catches Complete/Failed, and set up a CronJob with timeZone.
Environments with Kustomize: Bases, Overlays, Image Tags and configMapGenerator
With Kustomize shared manifests live in a base, each environment writes only its differences in an overlay, and configMapGenerator's hash suffix triggers a rollout when config changes. With real output we share an HPA/PDB through a component, compare JSON Patch with strategic merge patch, run kustomize edit set image in CI, and watch commonLabels change a selector and take the service down through a half-finished apply.
Kubernetes Security: ServiceAccounts, RBAC, Pod Security Standards, securityContext and NetworkPolicy
Give every app its own ServiceAccount, don't mount the token unless needed, protect the namespace with restricted Pod Security Standards, and after a default deny NetworkPolicy open only the paths you need. With real kind output we test RBAC with kubectl auth can-i, catch the aspnet:10.0 image running as root, see what readOnlyRootFilesystem does to .NET Data Protection, try user namespaces and hit a default deny that forgot DNS.
Debugging in Kubernetes: CrashLoopBackOff, ImagePullBackOff, Pending and kubectl debug
Pod failures always follow the same order: read the symptom with get, the events with describe, the app's voice with logs --previous, and if needed bring an ephemeral container into a shell-less pod with kubectl debug. With real output we cover Pending, ImagePullBackOff, CrashLoopBackOff, OOMKilled and a port mismatch, a .NET process hanging as PID 1, and dotnet-dump killing a pod that runs near its limit.
End to End: Taking a .NET + Angular App to Managed Kubernetes (AKS, EKS, GKE) and a Production Checklist
On managed Kubernetes the control plane stays with the provider; if you use node identity for image pulls and workload identity for cloud access, not a single cloud secret is left in the pipeline or the cluster. We cover AKS, EKS and GKE differences, an OIDC deploy-to-AKS workflow validated with actionlint, deprecated API clients that pluto can't see, and a production checklist as code that runs on kind.
Reading Old Kubernetes Manifests: dockershim, PodSecurityPolicy and Removed APIs (1.16–1.25)
Converting 2018–2021-era manifests takes more than changing apiVersion: apps/v1 requires a selector, kubectl convert writes the old defaults (infinite progressDeadlineSeconds, maxUnavailable: 1) into the manifest, and Ingress backends changed shape. With real output we see that the dockershim removal didn't affect Docker images, replace PodSecurityPolicy with Pod Security Admission and scan with pluto.
What's New in Kubernetes 1.33–1.37: Native Sidecars, In-Place Resize, preStop Sleep, Gateway API and Life After ingress-nginx
The changes in Kubernetes 1.33–1.37 that matter most to app developers are native sidecars (1.33), preStop sleep (1.34), in-place resize (1.35), user namespaces (1.36) and HPA tolerance (1.37). With real output we see a sidecar ignoring SIGTERM stretch a Job to 39 seconds, the externalIPs and Endpoints deprecations, KYAML, the ingress-nginx retirement and Gateway API v1.7.