Every journey needs a start, every program a main

Apache License Licensed under the Apache License, Version 2.0 (the “License”);you may not use this file except in compliance with the License.You may obtain a copy of the License at
  1. http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an “AS IS” BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.

Our package starts out with some basic imports. Particularly:

  • The core controller-runtime library
  • The default controller-runtime logging, Zap (more on that a bit later)
  1. package main
  2. import (
  3. "flag"
  4. "os"
  5. "k8s.io/apimachinery/pkg/runtime"
  6. _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
  7. ctrl "sigs.k8s.io/controller-runtime"
  8. "sigs.k8s.io/controller-runtime/pkg/log/zap"
  9. // +kubebuilder:scaffold:imports
  10. )

Every set of controllers needs aScheme,which provides mappings between Kinds and their corresponding Go types. We’lltalk a bit more about Kinds when we write our API definition, so just keep thisin mind for later.

  1. var (
  2. scheme = runtime.NewScheme()
  3. setupLog = ctrl.Log.WithName("setup")
  4. )
  5. func init() {
  6. // +kubebuilder:scaffold:scheme
  7. }

At this point, our main function is fairly simple:

  • We set up some basic flags for metrics.

  • We instantiate a manager, which keeps track of running all ofour controllers, as well as setting up shared caches and clients to the APIserver (notice we tell the manager about our Scheme).

  • We run our manager, which in turn runs all of our controllers and webhooks.The manager is set up to run until it receives a graceful shutdown signal.This way, when we’re running on Kubernetes, we behave nicely with gracefulpod termination.

While we don’t have anything to run just yet, remember where that+kubebuilder:scaffold:builder comment is — things’ll get interesting theresoon.

  1. func main() {
  2. var metricsAddr string
  3. flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
  4. flag.Parse()
  5. ctrl.SetLogger(zap.Logger(true))
  6. mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{Scheme: scheme, MetricsBindAddress: metricsAddr})
  7. if err != nil {
  8. setupLog.Error(err, "unable to start manager")
  9. os.Exit(1)
  10. }
  11. // +kubebuilder:scaffold:builder
  12. setupLog.Info("starting manager")
  13. if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
  14. setupLog.Error(err, "problem running manager")
  15. os.Exit(1)
  16. }
  17. }

With that out of the way, we can get on to scaffolding our API!