k8sOperator 1.0.0-alpha0026
dotnet add package k8sOperator --version 1.0.0-alpha0026
NuGet\Install-Package k8sOperator -Version 1.0.0-alpha0026
<PackageReference Include="k8sOperator" Version="1.0.0-alpha0026" />
<PackageVersion Include="k8sOperator" Version="1.0.0-alpha0026" />
<PackageReference Include="k8sOperator" />
paket add k8sOperator --version 1.0.0-alpha0026
#r "nuget: k8sOperator, 1.0.0-alpha0026"
#:package k8sOperator@1.0.0-alpha0026
#addin nuget:?package=k8sOperator&version=1.0.0-alpha0026&prerelease
#tool nuget:?package=k8sOperator&version=1.0.0-alpha0026&prerelease
k8sOperator
A modern Kubernetes Operator framework for .NET that makes it easy to build custom controllers and operators.
Features
- 🎯 Simple API - Fluent builder pattern for Kubernetes resources
- 🔄 Reconciliation - Built-in controller pattern with informers and caching
- 📦 Custom Resources - Full CRD support with type-safe definitions
- 🗳️ Leader Election - High availability out of the box
- 🚀 AOT Ready - Optimized for trimmed, single-file deployments
- 🛠️ CLI Included - Built-in commands for install, create, and version
- 📊 Source Generators - Automatic builder extensions for your resources
Installation
dotnet add package k8sOperator
Quick Start
1. Define Your Custom Resource
[KubernetesEntity(Group = KubeGroup, ApiVersion = KubeApiVersion, Kind = KubeKind, PluralName = KubePluralName)]
public class V1MyApp : IKubernetesObject<V1ObjectMeta>, ISpec<V1MyAppSpec>, IStatus<V1MyAppStatus>
{
public const string KubeApiVersion = "v1";
public const string KubeKind = "MyApp";
public const string KubeGroup = "modern-engineering.io";
public const string KubePluralName = "myapps";
public string ApiVersion { get; set; } = $"{KubeGroup}/{KubeApiVersion}";
public string Kind { get; set; } = KubeKind;
public V1ObjectMeta Metadata { get; set; } = new V1ObjectMeta();
public V1MyAppSpec Spec { get; set; } = new V1MyAppSpec();
public V1MyAppStatus Status { get; set; } = new V1MyAppStatus();
}
public class V1MyAppSpec
{
public int Replicas { get; set; }
public string? Image { get; set; }
}
public class V1MyAppStatus
{
public string? Phase { get; set; }
public int ReadyReplicas { get; set; }
}
2. Create a Reconciler
public class MyAppReconciler
{
public async Task<IReconcileResult> ReconcileAsync(ReconcileContext context)
{
var app = context.GetResource<V1MyApp>();
var informer = context.GetInformer<V1MyApp>();
// Your reconciliation logic here
// You can access other resources from the cache
var allApps = informer.List().Count();
return ReconcileResult.Success<V1MyApp>(x =>
{
x.WithLabel("managed-by", "simple-operator");
x.WithLabel("processed", "true");
x.WithStatus(x =>
{
x.Phase = "Reconciling";
x.ReadyReplicas = resource.Spec?.Replicas ?? 0;
});
});
}
}
3. Create a JsonSerializerContext
JsonSerializerContext is needed because it gives the .NET source generator a compile-time map of which types should be serialized and deserialized. That helps the framework avoid reflection-heavy runtime work and makes JSON handling more efficient, especially in trimmed or AOT-friendly applications.
[JsonSerializable(typeof(V1MyApp))]
[JsonSerializable(typeof(V1MyAppSpec))]
[JsonSerializable(typeof(V1MyAppStatus))]
[JsonSourceGenerationOptions(
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
GenerationMode = JsonSourceGenerationMode.Default)]
public partial class AppJsonSerializerContext : JsonSerializerContext
{
}
4. Register and Run
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOperator(x =>
{
x.Name = "simple-operator";
x.Namespace = "default";
x.JsonSerializerContext = AppJsonSerializerContext.Default;
x.Install.Resources.Add(typeof(V1MyApp));
});
var app = builder.Build();
app.AddReconciler<V1MyApp>(V1MyAppReconciler.ReconcileAsync);
await app.RunOperatorAsync();
Building Resources
Use the fluent builder API:
var deployment = ObjectBuilder.Create<V1Deployment>()
.WithName("my-app")
.WithNamespace("default")
.WithLabel("app", "my-app")
.WithSpec(spec => spec
.WithReplicas(3)
.WithTemplate(template => template
.WithSpec(podSpec => podSpec
.WithContainer(c => c
.WithImage("nginx:latest")
.WithPort(80)))))
.Build();
CLI Commands
# Show version
myoperator version
# Install CRDs
myoperator install
# Create resource
myoperator create myapp --name demo
# Show help
myoperator help
Configuration
Configure via appsettings.json or attributes:
{
"Operator": {
"Name": "my-operator",
"Namespace": "default",
}
}
Links
Requirements
- .NET 10.0 or later
- Kubernetes 1.25+
License
MIT License
Built with ❤️ by Patrick Evers
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- KubernetesClient (>= 19.0.2)
- Microsoft.Extensions.Hosting (>= 10.0.10)
- Microsoft.Extensions.Logging (>= 10.0.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-alpha0026 | 71 | 8/1/2026 |
| 1.0.0-alpha0024 | 94 | 7/28/2026 |
| 1.0.0-alpha0023 | 55 | 7/28/2026 |
| 1.0.0-alpha0022 | 48 | 7/25/2026 |
| 1.0.0-alpha0021 | 63 | 7/25/2026 |
| 1.0.0-alpha0020 | 97 | 7/1/2026 |
| 1.0.0-alpha0019 | 108 | 6/25/2026 |
| 1.0.0-alpha0018 | 116 | 6/18/2026 |
| 1.0.0-alpha0017 | 282 | 2/23/2026 |
| 1.0.0-alpha0016 | 74 | 2/23/2026 |
| 1.0.0-alpha0015 | 93 | 2/23/2026 |
| 1.0.0-alpha0014 | 140 | 2/18/2026 |
| 1.0.0-alpha0013 | 82 | 2/18/2026 |
| 1.0.0-alpha0012 | 75 | 2/18/2026 |
| 1.0.0-alpha0011 | 104 | 2/17/2026 |
| 1.0.0-alpha0010 | 76 | 2/17/2026 |
| 1.0.0-alpha0008 | 80 | 2/13/2026 |
| 1.0.0-alpha0007 | 132 | 2/12/2026 |
| 1.0.0-alpha0006 | 89 | 2/12/2026 |
| 1.0.0-alpha0005 | 81 | 2/12/2026 |