Google Antigravity Directory

The #1 directory for Google Antigravity prompts, rules, workflows & MCP servers. Optimized for Gemini 3 agentic development.

Resources

PromptsMCP ServersAntigravity RulesGEMINI.md GuideBest Practices

Company

Submit PromptAntigravityAI.directory

Popular Prompts

Next.js 14 App RouterReact TypeScriptTypeScript AdvancedFastAPI GuideDocker Best Practices

Legal

Privacy PolicyTerms of ServiceContact Us
Featured on FazierVerified on Verified ToolsFeatured on WayfindioAntigravity AI - Featured on Startup FameFeatured on Wired BusinessFeatured on Twelve ToolsListed on Turbo0Featured on findly.toolsFeatured on Aura++That App ShowFeatured on FazierVerified on Verified ToolsFeatured on WayfindioAntigravity AI - Featured on Startup FameFeatured on Wired BusinessFeatured on Twelve ToolsListed on Turbo0Featured on findly.toolsFeatured on Aura++That App Show

© 2026 Antigravity AI Directory. All rights reserved.

The #1 directory for Google Antigravity IDE

This website is not affiliated with, endorsed by, or associated with Google LLC. "Google" and "Gemini" are trademarks of Google LLC.

Antigravity AI Directory
PromptsMCPBest PracticesUse CasesLearn
Home
Prompts
Kubernetes Custom Operators

Kubernetes Custom Operators

Build custom K8s controllers

KubernetesOperatorsGo
by Antigravity Team
⭐0Stars
👁️3Views
.antigravity
# Kubernetes Custom Operators

You are an expert in building Kubernetes operators using the Operator SDK to extend Kubernetes functionality with custom controllers.

## Key Principles
- Operators encode operational knowledge as code
- Use the Kubernetes controller pattern for reconciliation
- Design CRDs with clear status and spec separation
- Implement idempotent reconciliation logic
- Handle edge cases and failure scenarios gracefully

## Operator SDK Setup
```bash
# Install Operator SDK
brew install operator-sdk

# Initialize new operator project
operator-sdk init --domain company.com --repo github.com/company/myapp-operator

# Create API (CRD + Controller)
operator-sdk create api --group apps --version v1alpha1 --kind MyApp --resource --controller
```

## Custom Resource Definition (CRD)
```go
// api/v1alpha1/myapp_types.go
package v1alpha1

import (
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// MyAppSpec defines the desired state of MyApp
type MyAppSpec struct {
    // Size is the number of replicas
    // +kubebuilder:validation:Minimum=1
    // +kubebuilder:validation:Maximum=10
    Size int32 `json:"size"`

    // Image is the container image to use
    // +kubebuilder:validation:Required
    Image string `json:"image"`

    // Version is the application version
    Version string `json:"version,omitempty"`

    // Resources defines resource requirements
    Resources ResourceRequirements `json:"resources,omitempty"`

    // Database configuration
    // +optional
    Database *DatabaseSpec `json:"database,omitempty"`
}

type DatabaseSpec struct {
    // Enabled creates a database for the app
    Enabled bool `json:"enabled,omitempty"`
    
    // Size in Gi
    // +kubebuilder:default=10
    Size int32 `json:"size,omitempty"`
}

// MyAppStatus defines the observed state of MyApp
type MyAppStatus struct {
    // Conditions represent the latest observations
    Conditions []metav1.Condition `json:"conditions,omitempty"`

    // ReadyReplicas is the number of ready pods
    ReadyReplicas int32 `json:"readyReplicas,omitempty"`

    // Phase represents the current lifecycle phase
    // +kubebuilder:validation:Enum=Pending;Running;Failed;Succeeded
    Phase string `json:"phase,omitempty"`

    // ObservedGeneration is the generation observed by controller
    ObservedGeneration int64 `json:"observedGeneration,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Size",type="integer",JSONPath=".spec.size"
//+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

// MyApp is the Schema for the myapps API
type MyApp struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   MyAppSpec   `json:"spec,omitempty"`
    Status MyAppStatus `json:"status,omitempty"`
}
```

## Controller Implementation
```go
// controllers/myapp_controller.go
package controllers

import (
    "context"
    "time"

    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/errors"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/apimachinery/pkg/types"
    ctrl "sigs.k8s.io/controller-runtime"
    "sigs.k8s.io/controller-runtime/pkg/client"
    "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
    "sigs.k8s.io/controller-runtime/pkg/log"

    appsv1alpha1 "github.com/company/myapp-operator/api/v1alpha1"
)

const myAppFinalizer = "apps.company.com/finalizer"

type MyAppReconciler struct {
    client.Client
    Scheme *runtime.Scheme
}

//+kubebuilder:rbac:groups=apps.company.com,resources=myapps,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=apps.company.com,resources=myapps/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=apps.company.com,resources=myapps/finalizers,verbs=update
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete

func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    logger := log.FromContext(ctx)

    // Fetch the MyApp instance
    myApp := &appsv1alpha1.MyApp{}
    if err := r.Get(ctx, req.NamespacedName, myApp); err != nil {
        if errors.IsNotFound(err) {
            logger.Info("MyApp resource not found, ignoring")
            return ctrl.Result{}, nil
        }
        return ctrl.Result{}, err
    }

    // Handle finalizer for cleanup
    if myApp.ObjectMeta.DeletionTimestamp.IsZero() {
        if !controllerutil.ContainsFinalizer(myApp, myAppFinalizer) {
            controllerutil.AddFinalizer(myApp, myAppFinalizer)
            if err := r.Update(ctx, myApp); err != nil {
                return ctrl.Result{}, err
            }
        }
    } else {
        // Object is being deleted
        if controllerutil.ContainsFinalizer(myApp, myAppFinalizer) {
            if err := r.cleanupResources(ctx, myApp); err != nil {
                return ctrl.Result{}, err
            }
            controllerutil.RemoveFinalizer(myApp, myAppFinalizer)
            if err := r.Update(ctx, myApp); err != nil {
                return ctrl.Result{}, err
            }
        }
        return ctrl.Result{}, nil
    }

    // Reconcile Deployment
    if err := r.reconcileDeployment(ctx, myApp); err != nil {
        return ctrl.Result{}, err
    }

    // Reconcile Service
    if err := r.reconcileService(ctx, myApp); err != nil {
        return ctrl.Result{}, err
    }

    // Update status
    if err := r.updateStatus(ctx, myApp); err != nil {
        return ctrl.Result{}, err
    }

    return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}

func (r *MyAppReconciler) reconcileDeployment(ctx context.Context, myApp *appsv1alpha1.MyApp) error {
    deploy := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name:      myApp.Name,
            Namespace: myApp.Namespace,
        },
    }

    _, err := controllerutil.CreateOrUpdate(ctx, r.Client, deploy, func() error {
        // Set owner reference
        if err := controllerutil.SetControllerReference(myApp, deploy, r.Scheme); err != nil {
            return err
        }

        // Define desired state
        labels := map[string]string{"app": myApp.Name}
        deploy.Spec = appsv1.DeploymentSpec{
            Replicas: &myApp.Spec.Size,
            Selector: &metav1.LabelSelector{MatchLabels: labels},
            Template: corev1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{Labels: labels},
                Spec: corev1.PodSpec{
                    Containers: []corev1.Container{{
                        Name:  "app",
                        Image: myApp.Spec.Image,
                        Ports: []corev1.ContainerPort{{
                            ContainerPort: 8080,
                        }},
                    }},
                },
            },
        }
        return nil
    })

    return err
}

func (r *MyAppReconciler) updateStatus(ctx context.Context, myApp *appsv1alpha1.MyApp) error {
    deploy := &appsv1.Deployment{}
    if err := r.Get(ctx, types.NamespacedName{Name: myApp.Name, Namespace: myApp.Namespace}, deploy); err != nil {
        return err
    }

    myApp.Status.ReadyReplicas = deploy.Status.ReadyReplicas
    myApp.Status.ObservedGeneration = myApp.Generation

    if deploy.Status.ReadyReplicas == *deploy.Spec.Replicas {
        myApp.Status.Phase = "Running"
    } else {
        myApp.Status.Phase = "Pending"
    }

    return r.Status().Update(ctx, myApp)
}

func (r *MyAppReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&appsv1alpha1.MyApp{}).
        Owns(&appsv1.Deployment{}).
        Owns(&corev1.Service{}).
        Complete(r)
}
```

## Testing Operators
```go
// controllers/suite_test.go
var _ = Describe("MyApp Controller", func() {
    Context("When creating MyApp", func() {
        It("Should create Deployment", func() {
            myApp := &appsv1alpha1.MyApp{
                ObjectMeta: metav1.ObjectMeta{
                    Name:      "test-app",
                    Namespace: "default",
                },
                Spec: appsv1alpha1.MyAppSpec{
                    Size:  3,
                    Image: "nginx:latest",
                },
            }
            Expect(k8sClient.Create(ctx, myApp)).Should(Succeed())

            Eventually(func() bool {
                deploy := &appsv1.Deployment{}
                err := k8sClient.Get(ctx, types.NamespacedName{
                    Name:      "test-app",
                    Namespace: "default",
                }, deploy)
                return err == nil
            }, timeout, interval).Should(BeTrue())
        })
    })
})
```

## Best Practices
- Use owner references for garbage collection
- Implement finalizers for cleanup logic
- Make reconciliation idempotent
- Use status subresource for state updates
- Add proper RBAC with minimal permissions
- Implement health checks and metrics

When to Use This Prompt

This Kubernetes prompt is ideal for developers working on:

  • Kubernetes applications requiring modern best practices and optimal performance
  • Projects that need production-ready Kubernetes code with proper error handling
  • Teams looking to standardize their kubernetes development workflow
  • Developers wanting to learn industry-standard Kubernetes patterns and techniques

By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their kubernetes implementations.

How to Use

  1. Copy the prompt - Click the copy button above to copy the entire prompt to your clipboard
  2. Paste into your AI assistant - Use with Claude, ChatGPT, Cursor, or any AI coding tool
  3. Customize as needed - Adjust the prompt based on your specific requirements
  4. Review the output - Always review generated code for security and correctness
💡 Pro Tip: For best results, provide context about your project structure and any specific constraints or preferences you have.

Best Practices

  • ✓ Always review generated code for security vulnerabilities before deploying
  • ✓ Test the Kubernetes code in a development environment first
  • ✓ Customize the prompt output to match your project's coding standards
  • ✓ Keep your AI assistant's context window in mind for complex requirements
  • ✓ Version control your prompts alongside your code for reproducibility

Frequently Asked Questions

Can I use this Kubernetes prompt commercially?

Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.

Which AI assistants work best with this prompt?

This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.

How do I customize this prompt for my specific needs?

You can modify the prompt by adding specific requirements, constraints, or preferences. For Kubernetes projects, consider mentioning your framework version, coding style, and any specific libraries you're using.

Related Prompts

💬 Comments

Loading comments...