A Kubernetes upgrade is rarely just a matter of changing a version number.

For a production .NET application, the cluster version sits underneath the application runtime, networking, storage, ingress, observability stack, admission controllers, deployment tooling, and platform integrations. A change that looks safe at the cluster level can still expose an incompatibility somewhere in that chain.

Kubernetes 1.34 is particularly relevant for upgrade planning because its current support timeline is approaching a transition point. The official Kubernetes release information lists 1.34.9 as the latest patch release and shows maintenance mode beginning on August 27, 2026, with end of life scheduled for October 27, 2026.

That does not mean every application running Kubernetes 1.34 must immediately upgrade. It does mean platform teams should have a repeatable way to determine whether their .NET workloads are ready for the next supported Kubernetes version.

This article presents a practical upgrade-readiness methodology focused on production .NET applications.

Why Kubernetes Upgrade Testing Matters

A typical .NET application deployed to Kubernetes has more dependencies than its container image suggests.

A simplified architecture might look like this:

                    Kubernetes Cluster
                           |
             +-------------+-------------+
             |                           |
        Control Plane                 Worker Nodes
             |                           |
             |                    +------+------+
             |                    |             |
             |                 .NET API      Worker
             |                    |             |
             +-------------+------+-------------+
                           |
                    Ingress / Service
                           |
                    Database / Cache

The application itself may not need to change at all during a Kubernetes upgrade.

The surrounding platform can still affect:

The purpose of upgrade testing is therefore to verify the complete application path, not just whether a Pod reaches Running.

Define an Upgrade Readiness Baseline

Before changing anything, record the current environment.

Start with:

kubectl version
kubectl get nodes -o wide
kubectl get pods -A
kubectl get deployments -A
kubectl get statefulsets -A

Also capture important workload configuration:

kubectl get deployment my-api -o yaml

Do not treat the resulting YAML as something to blindly restore later. It is primarily a baseline for understanding what is deployed.

Record:

AreaBaseline
Kubernetes versionCurrent cluster version
.NET runtimeApplication runtime
Container imageCurrent application image
Node OSCurrent node image
CPU requests/limitsCurrent configuration
Memory requests/limitsCurrent configuration
Replica countCurrent deployment
HPACurrent scaling configuration
IngressCurrent controller/configuration
StoragePVC/storage configuration
ObservabilityMetrics/logging/tracing
Admission policiesCurrent policies

This makes comparison much easier after the upgrade.

Check Kubernetes Version Skew

One of the first things to understand is that Kubernetes components do not all have unlimited version compatibility.

The official version-skew policy defines supported relationships between components such as kube-apiserver, kubelet, kube-proxy, controllers, and kubectl. For example, kubelet must not be newer than kube-apiserver, while supported older versions are allowed within documented limits. kubectl is supported within one minor version of the API server.

This matters during rolling upgrades because a cluster is temporarily running mixed component versions.

The upgrade should therefore follow the supported component order rather than upgrading arbitrary components independently.

The Kubernetes project also recommends moving from the latest patch version of the current minor release to the latest patch version of the target minor release when preparing an upgrade.

Test the .NET Application Before the Upgrade

The application should have a known-good baseline before the cluster changes.

For an ASP.NET Core application, verify the health endpoints.

For example:

builder.Services.AddHealthChecks()
    .AddCheck("application", () => HealthCheckResult.Healthy());

var app = builder.Build();

app.MapHealthChecks("/health/live");
app.MapHealthChecks("/health/ready");

A production application should distinguish between liveness and readiness when appropriate.

A liveness probe answers:

Is this process alive?

A readiness probe answers:

Can this instance currently receive traffic?

Those questions become especially important during rolling upgrades.

Review Kubernetes Probes

A typical Deployment might define:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-api
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: orders-api
          image: orders-api:1.0
          ports:
            - containerPort: 8080

          startupProbe:
            httpGet:
              path: /health/live
              port: 8080
            failureThreshold: 30
            periodSeconds: 5

          readinessProbe:
            httpGet:
              path: /health/ready
              port: 8080
            periodSeconds: 10

          livenessProbe:
            httpGet:
              path: /health/live
              port: 8080
            periodSeconds: 20

The exact values should be based on application startup and recovery behavior.

Do not copy probe timings from another service simply because they appear to work there.

Test Graceful Shutdown

A Kubernetes upgrade can cause Pods to be terminated and recreated.

The .NET application should handle termination cleanly.

ASP.NET Core applications participate in the host's graceful shutdown process, but your application should still be tested under actual termination conditions.

For example, if the service consumes background work, verify that shutdown does not result in:

A simple application test can terminate a Pod deliberately:

kubectl delete pod <pod-name>

Then observe:

kubectl get pods -w

The goal is not merely to confirm that Kubernetes creates a replacement.

You want to verify that the application exits and recovers correctly.

Validate Resource Requests and Limits

Kubernetes scheduling and resource management are closely connected to application stability.

A .NET deployment should define appropriate resource requests and, where appropriate, limits:

resources:
  requests:
    cpu: "250m"
    memory: "256Mi"
  limits:
    cpu: "1"
    memory: "1Gi"

These numbers are examples, not recommended defaults.

During upgrade testing, compare actual utilization against configured resources.

Useful commands include:

kubectl top pods
kubectl top nodes

Look for:

A Kubernetes upgrade should not be considered successful if the cluster is technically healthy but the application has degraded resource behavior.

Test Autoscaling

If the .NET application uses an HPA, test scaling before and after the upgrade.

Inspect the configuration:

kubectl get hpa orders-api
kubectl describe hpa orders-api

A typical HPA might look like:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: orders-api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: orders-api
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Run a controlled load test and verify:

Traffic increases
      |
      v
CPU increases
      |
      v
HPA detects utilization
      |
      v
Replica count increases
      |
      v
Traffic is distributed

The important measurement is not simply whether replicas increase.

Check whether scaling happens quickly enough for the application's traffic profile and whether newly created Pods become ready successfully.

Validate Service and Ingress Networking

A .NET API can be healthy while external traffic is broken.

Test the entire path:

Client
  |
  v
Load Balancer
  |
  v
Ingress
  |
  v
Service
  |
  v
Pod
  |
  v
ASP.NET Core

Validate:

kubectl get ingress
kubectl get svc
kubectl get endpoints

Then perform real HTTP requests.

For example:

curl -i https://api.example.com/health/ready

Test both normal traffic and failure scenarios.

Terminate one Pod while sending requests and verify that traffic continues through the remaining replicas.

Test Database Connectivity

Many .NET applications depend on PostgreSQL, SQL Server, Redis, or another external service.

Kubernetes upgrades should not be tested with only an application health endpoint.

A health check that says "process is alive" does not prove that database operations are working.

For a controlled integration test:

builder.Services.AddHealthChecks()
    .AddDbContextCheck<AppDbContext>();

Be careful with dependency-heavy readiness checks. If the database is temporarily unavailable, you want Kubernetes to stop sending traffic to an unhealthy instance, but you also do not want an unhealthy dependency to create an uncontrolled cascading restart loop.

The appropriate behavior depends on the application architecture.

Test Deployment Behavior

Perform a normal rolling deployment before and after the cluster upgrade.

Inspect the Deployment:

kubectl rollout status deployment/orders-api

Then verify:

kubectl get pods
kubectl get rs
kubectl describe deployment orders-api

A successful rollout should preserve the application's availability expectations.

Test:

Rollback should be tested deliberately, not assumed.

kubectl rollout undo deployment/orders-api

Test Disruption Scenarios

Upgrade readiness is more meaningful when the application is tested under controlled failure.

Useful scenarios include:

ScenarioWhat to Verify
Delete one PodTraffic continues
Restart a nodeWorkloads reschedule
Increase trafficHPA responds
Database temporarily unavailableCorrect application behavior
Ingress restartTraffic recovers
Rolling deploymentAvailability maintained
Pod startup delayProbes behave correctly
Application crashReplacement Pod becomes ready

Do not run destructive tests against production unless they are part of an approved resilience program.

Use a staging or dedicated upgrade environment wherever possible.

Compare Application Metrics

Before and after the upgrade, compare application-level telemetry.

Useful metrics include:

For an ASP.NET Core API, OpenTelemetry or another observability system can provide the application-side view while Kubernetes metrics provide the platform-side view.

The objective is to correlate changes.

For example:

Kubernetes Upgrade
       |
       v
Pod startup time increases
       |
       v
Readiness delayed
       |
       v
Available replicas decrease
       |
       v
Request latency increases

That tells a much more useful story than simply reporting that "the upgrade caused higher latency."

Build a Production Readiness Matrix

Before approving the upgrade, create a simple readiness matrix.

TestExpected ResultActual ResultStatus
Application startupSuccessfulRecord resultPass/Fail
Readiness probeHealthyRecord resultPass/Fail
Liveness probeHealthyRecord resultPass/Fail
Rolling deploymentNo unacceptable outageRecord resultPass/Fail
RollbackSuccessfulRecord resultPass/Fail
HPAScales correctlyRecord resultPass/Fail
Service networkingHealthyRecord resultPass/Fail
IngressHealthyRecord resultPass/Fail
Database accessHealthyRecord resultPass/Fail
Pod disruptionRecoversRecord resultPass/Fail
Resource usageWithin limitsRecord resultPass/Fail
Application latencyWithin baselineRecord resultPass/Fail

This creates an auditable decision instead of relying on a manual "looks good" assessment.

Common Upgrade Mistakes

Testing Only kubectl get pods

A Running Pod does not prove that the application is serving correct traffic.

Skipping Version-Skew Checks

Mixed-version components during upgrades must remain within Kubernetes' supported skew rules.

Testing Without Production-Like Load

A cluster can appear healthy at idle while showing latency or autoscaling problems under realistic traffic.

Ignoring Admission Controllers

Admission policies, webhooks, and security controls can affect workload creation during an upgrade.

Test actual deployment operations rather than only existing Pods.

Forgetting Rollback

A successful forward upgrade is only half the operational story.

Verify that the team can recover if a problem appears after the upgrade.

Changing Application Code at the Same Time

If possible, do not combine a Kubernetes upgrade with unrelated application, runtime, database, or infrastructure changes.

Fewer variables make failures easier to diagnose.

Troubleshooting Failed Upgrade Tests

When something fails, first determine which layer changed.

Use this model:

Application
    |
ASP.NET Core
    |
Container
    |
Pod
    |
Service
    |
Node
    |
Kubernetes Control Plane

For application failures, inspect:

kubectl logs deployment/orders-api

For Pod-level issues:

kubectl describe pod <pod-name>

For scheduling problems:

kubectl describe node <node-name>

For Deployment behavior:

kubectl describe deployment orders-api

For cluster-wide events:

kubectl get events --sort-by=.lastTimestamp

Do not immediately roll back because a single test failed. First determine whether the failure is deterministic, environment-specific, or unrelated to the upgrade.

Kubernetes 1.34 Upgrade Timing

Kubernetes' official release schedule currently lists 1.34.9 as the latest patch release and October 27, 2026 as its end-of-life date. The branch enters maintenance mode on August 27, 2026.

That creates a useful planning window for teams still running 1.34.

The correct response is not to rush an untested upgrade simply because a date is approaching. Instead:

  1. Inventory affected clusters.

  2. Identify workloads still running 1.34.

  3. Establish a baseline.

  4. Test the target Kubernetes version.

  5. Run application and infrastructure validation.

  6. Perform a controlled rollout.

  7. Monitor the upgraded environment.

  8. Keep a tested rollback path.

The exact target version should be selected according to the organization's support policy and the Kubernetes versions supported by its managed Kubernetes provider or platform.

Frequently Asked Questions

Does a Kubernetes upgrade require changes to a .NET application?

Not necessarily. Many applications can run without code changes, but application behavior should still be validated because the surrounding platform can affect networking, scheduling, probes, resources, and deployment behavior.

Is a Pod being Running enough to declare the upgrade successful?

No. Running only describes one part of Pod state. Application readiness, traffic handling, dependencies, scaling, latency, and recovery should also be tested.

Should the .NET runtime be upgraded at the same time?

Preferably not unless there is a specific reason to combine the changes. Separating infrastructure and application-runtime upgrades makes troubleshooting easier.

How much load should be used during testing?

Use a workload representative of the application's expected production behavior. A single universal load level would not be appropriate for every service.

Should upgrade testing happen in production?

Use a dedicated or staging environment that closely resembles production whenever possible. Production testing should follow an approved operational and resilience-testing process.

Best Practices Checklist

  1. Record the current Kubernetes and application baseline.

  2. Verify Kubernetes version-skew requirements.

  3. Use the latest supported patch releases appropriate to the upgrade path.

  4. Test .NET startup and shutdown behavior.

  5. Validate readiness and liveness probes.

  6. Test Service and Ingress traffic.

  7. Test database and external-service connectivity.

  8. Exercise HPA behavior under representative load.

  9. Test rolling deployments and rollback.

  10. Run controlled disruption scenarios.

  11. Compare application latency and error metrics.

  12. Document every failed test and its remediation.

  13. Keep application and infrastructure changes separated when practical.

  14. Maintain a tested rollback procedure.

Conclusion

Kubernetes upgrade readiness is ultimately an application-platform compatibility problem, not simply a cluster-version problem.

For .NET applications, the most valuable testing covers the complete path from container startup to readiness, service discovery, ingress, database connectivity, autoscaling, deployment, observability, and recovery.

Kubernetes 1.34's approaching maintenance and end-of-life milestones make upgrade planning particularly relevant right now. The official Kubernetes documentation should remain the source of truth for supported versions, patch releases, and version-skew rules.

A good upgrade is not one where the control plane reports healthy. It is one where the application continues to meet its operational requirements before, during, and after the platform change.

The safest approach is therefore straightforward: establish a baseline, test the real workload, measure the important behaviors, document the results, and only then approve the production rollout.