Skip to main content
AI
  • Get started with AI

    • Red Hat AI

      Accelerate the development and deployment of enterprise AI solutions.

    • AI learning hub

      Explore learning materials and tools, organized by task.

    • AI interactive demos

      Click through scenarios with Red Hat AI, including training LLMs and more.

    • AI/ML learning paths

      Expand your Red Hat OpenShift AI knowledge using these learning resources.

    • AI quickstarts

      Focused AI use cases designed for fast deployment on Red Hat AI platforms.

    • No-cost AI training

      Foundational Red Hat AI training.

  • Featured resources

    • Red Hat OpenShift AI
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

Red Hat AI Factory with NVIDIA

Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.

Learn
  • Self-guided

    • Documentation

      Find answers, get step-by-step guidance, and learn how to use Red Hat products.

    • Learning paths

      Explore curated walkthroughs for common development tasks.

    • Guided learning

      Receive custom learning paths powered by our AI assistant.

    • See all learning
  • Hands-on

    • Developer Sandbox

      Spin up Red Hat's products and technologies without setup or configuration.

    • Interactive labs

      Learn by doing in these hands-on, browser-based experiences.

    • Interactive demos

      Click through product features in these guided tours.

  • Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics
  • Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
Build
  • Get started

    • Red Hat build of Podman Desktop

      A downloadable, local development hub to experiment with our products and builds.

    • Developer Sandbox

      Spin up Red Hat's products and technologies without setup or configuration.

  • Download products

    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products
  • Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset
  • References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
Community
  • Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions
  • Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github
  • Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

Join the Red Hat Developer program

Download Red Hat products and project builds, access support documentation, learning content, and more.

ConsoleDocsSupport Search
New For you

Recommended

We'll recommend resources you may like as you browse. Try these suggestions for now.

  • Product downloads
  • Cheat sheets
  • Red Hat Developer learning portal
  • Developer blog
  • E-books
  • Developer Sandbox
Log in

Get more with a Red Hat Developer account

  • Product downloads
  • Console access
  • Event registration
  • Training & trials
Explore more account benefitsLog in or register

A subscription may be required for some services.

Contact us

Getting started with Golang Operators by using Operator SDK

<p>&nbsp;</p> <quillbot-extension-portal></quillbot-extension-portal>

October 4, 2019
Camila Macedo
Related topics:
GoKubernetesOperators
Related products:
Red Hat OpenShift

    The open source Operator Framework is a toolkit to manage Kubernetes-native applications. The framework and its features provide the ability to develop solutions to simplify some complexities, such as the process to install, configure, manage and package applications on Kubernetes and Red Hat OpenShift. It provides the ability to use a client to perform CRUD actions, that is, operations to create, read, update, and delete data on these platforms.

    By using operators, it's possible not only to provide all expected resources but also to manage them dynamically, programmatically, and at execution time. To illustrate this idea, imagine if someone accidentally changed a configuration or removed a resource by mistake; in this case, the operator could fix it without any human intervention. We'll take a look at Operators and the Operator SDK in this article.

    Note: As a prerequisite for this content, it's essential to follow the steps outlined in the Getting Started guide.

    APIs

    When following the Getting Started, one of the first steps is to run the command operator-sdk add api --api-version=cache.example.com/v1alpha1 --kind=Memcached. The purpose of this command is to generate Custom Resource (CR) and Custom Resource Definition (CRD) resources for the Memcached Kind. This command is creating the API with the group cache.example.com, and version v1alpha1  which uniquely identifies the new CRD of the Memcached Kind.

    Consequently, by using the Operator SDK tool, we can create our APIs and objects that will represent our solutions on these platforms. The Getting Started tutorial adds only a single kind of resource; however, it could have as many Kinds as needed (1…N). Basically, the CRDs are a definition of our customized Objects, and the CRs are an instance of it.

    Project

    The Manager is responsible for managing Controllers and, then by the controllers, we can do operations on the cluster side. For a better understanding of how it works, see that in the example, one of the steps was to create a Docker image with the command $operator-sdk build user/image:tag and then replace the value REPLACE_IMAGE in the file operator.yaml file.  This file describes the project instance built by it. Note that, by running the command kubectl create -f deploy/operator.yaml we are creating a pod with this image.

    Demonstrating the idea

    Let's think about the classic scenario where the goal is to have an application and its database running on the platform with Kubernetes. Then, one object could represent the App, and another one could represent the DB. By having one CRD to describe the App and another one for the DB, we will not be hurting concepts such as encapsulation, the single responsibility principle, and cohesion. Damaging these concepts could cause unexpected side effects, such as difficulty in extending, reuse, or maintenance, just to mention a few.

    In conclusion, the App CRD will have as its controller the DB CRD. Imagine, that a Deployment and Service are required for the application run so that the App's Controller will provide these resources in this example. Similarly, the DB's controller will have the business logic implementation of its objects.

    In this way, for each CRD, one controller should be produced according to the design set by the controller-runtime.

    Controller main functions

    Reconcile()

    The reconcile function is responsible for synchronizing the resources and their specifications according to the business logic implemented on them. In this way, it works like a loop, and it does not stop until all conditionals match its implementation. The following is pseudo-code with an example that clarifies it.

    reconcile App {
    
       // Check if a Deployment for the app exists, if not create one
       // If has an error, then go to the beginning of the reconcile
       if err != nil {
           return reconcile.Result{}, err 
       } 
       
       // Check if a Service for the app exists, if not create one 
       // If has an error, then go to the beginning of the reconcile
       if err != nil {
           return reconcile.Result{}, err 
       }  
    
       // Looking for Database CR/CRD 
       // Check the Database Deployments Replicas size
       // If deployment.replicas size != cr.size, then update it
       // Then, go to the beginning of the reconcile
       if err != nil {
           return reconcile.Result{Requeue: true}, nil
       }  
       ...
       
       // If it is at the end of the loop, then:
       // All was done successfully and the reconcile can stop  
       return reconcile.Result{}, nil
    
    }
    

    The following are possible return options to restart the Reconcile:

    • With the error:

    return reconcile.Result{}, err

    • Without an error:

    return reconcile.Result{Requeue: true}, nil

    • Therefore, to stop the Reconcile, use:

    return reconcile.Result{}, nil

    Note: For more details, check the Reconcile and its Result implementations.

    Watch()

    The watches are responsible for ''watching" the objects and triggering the Reconcile. Also, the Operator SDK tool will generate a Watch function for each primary resource (CRD). Here is an example:

    // Watch for changes to primary resource Memcached
    err = c.Watch(&source.Kind{Type: &cachev1alpha1.Memcached{}}, &handler.EnqueueRequestForObject{})
    if err != nil {
        return err
    }
    

    By following the Getting Started, a watch function for each secondary object managed by it will also be implemented, such as below.

    // Watch for changes to secondary resource Pods and requeue the owner Memcached
    
    err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{
        IsController: true,
        OwnerType:    &cachev1alpha1.Memcached{},
    })
    if err != nil {
        return err
    }
    
    err = c.Watch(&source.Kind{Type: &corev1.Service{}}, &handler.EnqueueRequestForOwner{
        IsController: true,
        OwnerType:    &cachev1alpha1.Memcached{},
    })
    if err != nil {
        return err
    }
    

    Also, the following code ensures the quantity of Memcached replicas running on the cluster.

    // Ensure the deployment size is the same as the spec
    size := memcached.Spec.Size
    if *deployment.Spec.Replicas != size {
        deployment.Spec>.Replicas = &size
        err = r.client.Update(context.TODO(), deployment)
        if err != nil {
            reqLogger.Error(err, "Failed to update Deployment.", "Deployment.Namespace", deployment.Namespace, "Deployment.Name", deployment.Name)
             return reconcile.Result{}, err
        }
    }
    

    After that, you can check that the above code worked by doing the following steps.

    1. Scale the Memcached pod up or down.
    2. Check that the replicas will come back for the original size because of the above code.

    Note: The above steps will only work if you were able to follow the guide and all finished successfully.

    Last updated: March 29, 2023

    Recent Posts

    • A day in the life of an NVIDIA H100 on Red Hat OpenShift 5

    • Migrate BuildConfigs to builds for Red Hat OpenShift with one plug-in install

    • Run Red Hat Enterprise Linux CoreOS on NVIDIA BlueField DPUs

    • Agent harness engineering: Separating model capabilities from enforcement

    • What's new for developers in Red Hat Enterprise Linux 10.3 and 9.9

    What’s up next?

     

    Red Hat Developers logo

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    Red Hat Developer

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility
    Ask AI