Operator SDK CLI reference



The operator-sdk build command compiles the code and builds the executables. After build completes, the image is built locally in docker. It must then be pushed to a remote registry.

Table 1. build arguments
Argument Description


The container image to be built, e.g., quay.io/example/operator:v0.0.1.

Table 2. build flags
Flag Description

--enable-tests (bool)

Enable in-cluster testing by adding test binary to the image.

--namespaced-manifest (string)

Path of namespaced resources manifest for tests. Default: deploy/operator.yaml.

--test-location (string)

Location of tests. Default: ./test/e2e

-h, --help

Usage help output.

If --enable-tests is set, the build command also builds the testing binary, adds it to the container image, and generates a deploy/test-pod.yaml file that allows a user to run the tests as a Pod on a cluster.

Example output
$ operator-sdk build quay.io/example/operator:v0.0.1

building example-operator...

building container quay.io/example/operator:v0.0.1...
Sending build context to Docker daemon  163.9MB
Step 1/4 : FROM alpine:3.6
 ---> 77144d8c6bdc
Step 2/4 : ADD tmp/_output/bin/example-operator /usr/local/bin/example-operator
 ---> 2ada0d6ca93c
Step 3/4 : RUN adduser -D example-operator
 ---> Running in 34b4bb507c14
Removing intermediate container 34b4bb507c14
 ---> c671ec1cff03
Step 4/4 : USER example-operator
 ---> Running in bd336926317c
Removing intermediate container bd336926317c
 ---> d6b58a0fcb8c
Successfully built d6b58a0fcb8c
Successfully tagged quay.io/example/operator:v0.0.1


The operator-sdk completion command generates shell completions to make issuing CLI commands quicker and easier.

Table 3. completion subcommands
Subcommand Description


Generate bash completions.


Generate zsh completions.

Table 4. completion flags
Flag Description

-h, --help

Usage help output.

Example output
$ operator-sdk completion bash

# bash completion for operator-sdk                         -*- shell-script -*-
# ex: ts=4 sw=4 et filetype=sh


The operator-sdk print-deps command prints the most recent Golang packages and versions required by Operators. It prints in columnar format by default.

Table 5. print-deps flags
Flag Description


Print packages and versions in Gopkg.toml format.

Example output
$ operator-sdk print-deps --as-file
required = [

  name = "k8s.io/code-generator"
  revision = "6702109cc68eb6fe6350b83e14407c8d7309fd1a"


The operator-sdk generate command invokes a specific generator to generate code as needed.

Table 6. generate subcommands
Subcommand Description


Runs the Kubernetes code-generators for all CRD APIs under pkg/apis/. Currently, k8s only runs deepcopy-gen to generate the required DeepCopy() functions for all custom resource types.

This command must be run every time the API (spec and status) for a custom resource type is updated.

Example output
$ tree pkg/apis/app/v1alpha1/
├── appservice_types.go
├── doc.go
├── register.go

$ operator-sdk generate k8s
Running code-generation for custom resource group versions: [app:v1alpha1]
Generating deepcopy funcs

$ tree pkg/apis/app/v1alpha1/
├── appservice_types.go
├── doc.go
├── register.go
└── zz_generated.deepcopy.go


The operator-sdk new command creates a new Operator application and generates (or scaffolds) a default project directory layout based on the input <project_name>.

Table 7. new arguments
Argument Description


Name of the new project.

Table 8. new flags
Flag Description


Do not initialize the directory as a Git repository.


Type of Operator to initialize: ansible or go (default: go). Also requires the following flags if --type=ansible:

  • --api-version: CRD APIVersion in the format $GROUP_NAME/$VERSION (e.g., app.example.com/v1alpha1)

  • --kind: CRD Kind (e.g., AppService).


Initialize the Operator to be cluster-scoped instead of namespace-scoped.

-h, --help

Usage help output.

Example usage for Go project
$ mkdir $GOPATH/src/github.com/example.com/
$ cd $GOPATH/src/github.com/example.com/
$ operator-sdk new app-operator
Example usage for Ansible project
$ operator-sdk new app-operator \
    --type=ansible \
    --api-version=app.example.com/v1alpha1 \


The operator-sdk add command adds a controller or resource to the project. The command must be run from the Operator project root directory.

Table 9. add subcommands
Subcommand Description


Adds a new API definition for a new custom resource under pkg/apis and generates the customer resource definition (CRD) and custom resource (CR) files under deploy/crds/. If the API already exists at pkg/apis/<group>/<version>, then the command does not overwrite and returns an error.


Adds a new controller under pkg/controller/<kind>/. The controller expects to use the CR type that should already be defined under pkg/apis/<group>/<version> via the operator-sdk add api --kind=<kind> --api-version=<group/version> command. If the controller package for that Kind already exists at pkg/controller/<kind>, then the command does not overwrite and returns an error.


Adds a CRD and the CR files. The <project-name>/deploy path must already exist. The --api-version and --kind flags are required to generate the new Operator application.

  • Generated CRD filename: <project-name>/deploy/crds/<group>_<version>_<kind>_crd.yaml

  • Generated CR filename: <project-name>/deploy/crds/<group>_<version>_<kind>_cr.yaml

Table 10. add flags
Flag Description

--api-version (string)

CRD APIVersion in the format $GROUP_NAME/$VERSION (e.g., app.example.com/v1alpha1).

--kind (string)

CRD Kind (e.g., AppService).

Example add api output
$ operator-sdk add api --api-version app.example.com/v1alpha1 --kind AppService
Create pkg/apis/app/v1alpha1/appservice_types.go
Create pkg/apis/addtoscheme_app_v1alpha1.go
Create pkg/apis/app/v1alpha1/register.go
Create pkg/apis/app/v1alpha1/doc.go
Create deploy/crds/app_v1alpha1_appservice_cr.yaml
Create deploy/crds/app_v1alpha1_appservice_crd.yaml
Running code-generation for custom resource group versions: [app:v1alpha1]
Generating deepcopy funcs

$ tree pkg/apis
├── addtoscheme_app_appservice.go
├── apis.go
└── app
	└── v1alpha1
		├── doc.go
		├── register.go
		├── types.go
Example add controller output
$ operator-sdk add controller --api-version app.example.com/v1alpha1 --kind AppService
Create pkg/controller/appservice/appservice_controller.go
Create pkg/controller/add_appservice.go

$ tree pkg/controller
├── add_appservice.go
├── appservice
│   └── appservice_controller.go
└── controller.go
Example add crd output
$ operator-sdk add crd --api-version app.example.com/v1alpha1 --kind AppService
Generating custom resource definition (CRD) files
Create deploy/crds/app_v1alpha1_appservice_crd.yaml
Create deploy/crds/app_v1alpha1_appservice_cr.yaml


The operator-sdk test command has subcommands that can test the Operator locally or from within a cluster.


The local subcommand runs Go tests built using the Operator SDK’s test framework locally.

Table 11. test local arguments
Arguments Description

<test_location> (string)

Location of e2e test files (e.g., ./test/e2e/).

Table 12. test local flags
Flags Description

--kubeconfig (string)

Location of kubeconfig for a cluster. Default: ~/.kube/config.

--global-manifest (string)

Path to manifest for global resources. Default: deploy/crd.yaml.

--namespaced-manifest (string)

Path to manifest for per-test, namespaced resources. Default: combines deploy/service_account.yaml, deploy/rbac.yaml, and deploy/operator.yaml.

--namespace (string)

If non-empty, a single namespace to run tests in (e.g., operator-test). Default: ""

--go-test-flags (string)

Extra arguments to pass to go test (e.g., -f "-v -parallel=2").


Enable running the Operator locally with go run instead of as an image in the cluster.


Disable test resource creation.

--image (string)

Use a different Operator image from the one specified in the namespaced manifest.

-h, --help

Usage help output.

Example output
$ operator-sdk test local ./test/e2e/

# Output:
ok  	github.com/operator-framework/operator-sdk-samples/memcached-operator/test/e2e	20.410s


The cluster subcommand runs Go tests embedded in an Operator image built using the Operator SDK as a Pod in the cluster.

Table 13. test cluster arguments
Arguments Description

<image_name> (string)

The Operator image that is used to run the tests in a Pod (e.g., quay.io/example/memcached-operator:v0.0.1).

Table 14. test cluster flags
Flags Description

--kubeconfig (string)

Location of kubeconfig for a cluster. Default: ~/.kube/config.

--image-pull-policy (string)

Set test pod image pull policy. Allowed values: Always (default), Never.

--namespace (string)

Namespace to run tests in. Default: default.

--pending-timeout (int)

Timeout in seconds for testing Pod to stay in pending state. Default: 60s.

--service-account (string)

Service account to run tests on. Default: default.


Usage help output.

Example output
$ operator-sdk test cluster quay.io/example/memcached-operator:v0.0.1

# Output:
Test Successfully Completed


The operator-sdk up command has subcommands that can launch the Operator in various ways.


The local subcommand launches the Operator on the local machine by building the Operator binary with the ability to access a Kubernetes cluster using a kubeconfig file.

Table 15. up local arguments
Arguments Description

--kubeconfig (string)

The file path to a Kubernetes configuration file. Defaults: $HOME/.kube/config

--namespace (string)

The namespace where the Operator watches for changes. Default: default


Flags that the local Operator may need. Example: --flag1 value1 --flag2=value2

-h, --help

Usage help output.

Example output
$ operator-sdk up local \
  --kubeconfig "mycluster.kubecfg" \
  --namespace "default" \
  --operator-flags "--flag1 value1 --flag2=value2"

The following example uses the default kubeconfig, the default namespace environment variable, and passes in flags for the Operator. To use the Operator flags, your Operator must know how to handle the option. For example, for an Operator that understands the resync-interval flag:

$ operator-sdk up local --operator-flags "--resync-interval 10"

If you are planning on using a different namespace than the default, use the --namespace flag to change where the Operator is watching for custom resources to be created:

$ operator-sdk up local --namespace "testing"

For this to work, your Operator must handle the WATCH_NAMESPACE environment variable. This can be accomplished using the utility function k8sutil.GetWatchNamespace in your Operator.