Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

88 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

k8sOperator

A modern Kubernetes Operator framework for .NET that makes it easy to build custom controllers and operators.

License Release

k8sOperator logo

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

About

Kubernetes operator framework for .NET - Build custom controllers with CRDs, informers, reconcilers, and leader election. Supports trimmed single-file deployment and self-updating CLI.

Topics

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages