# Quick start

This Quick Start guide will cover:

- [Creating a project](#create-a-project)
- [Creating an API](#create-an-api)
- [Running locally](#test-it-out)
- [Running in-cluster](#run-it-on-the-cluster)

## Prerequisites

- [go](https://go.dev/dl/) version v1.24.6+
- [docker](https://docs.docker.com/install/) version 17.03+.
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) version v1.11.3+.
- Access to a Kubernetes v1.11.3+ cluster.

<aside class="note" role="note">
<p class="note-title">Versions Compatibility and Supportability</p>

Please, ensure that you see the [guidance](./versions_compatibility_supportability.md).

</aside>

## Installation

Install [kubebuilder](https://sigs.k8s.io/kubebuilder):

```bash
# download kubebuilder and install locally.
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"
chmod +x kubebuilder && sudo mv kubebuilder /usr/local/bin/
```

<aside class="note" role="note">
<p class="note-title">Using the Master Branch</p>

You can work with the master branch by cloning the repository and running `make install` to generate the binary.
Please follow the steps in the section **How to Build Kubebuilder Locally** from the [Contributing Guide](https://github.com/kubernetes-sigs/kubebuilder/blob/master/CONTRIBUTING.md#how-to-build-kubebuilder-locally).

</aside>

<aside class="note" role="note">
<p class="note-title">Enabling shell autocompletion</p>

Kubebuilder provides autocompletion support via the command `kubebuilder completion <bash|fish|powershell|zsh>`, which can save you a lot of typing. For further information see the [completion](./reference/completion.md) document.

</aside>

## Create a project

Create a directory, and then run the init command inside of it to initialize a new project. Follows an example.

```bash
mkdir -p ~/projects/guestbook
cd ~/projects/guestbook
kubebuilder init --domain my.domain --repo my.domain/guestbook
```

<aside class="note" role="note">
<p class="note-title">Developing in $GOPATH</p>

If you initialize your project within [`GOPATH`][GOPATH-golang-docs], the implicitly called `go mod init` will interpolate the module path for you.
Otherwise `--repo=<module path>` must be set.

Read the [Go modules blogpost][go-modules-blogpost] if unfamiliar with the module system.

</aside>

## Create an API

Run the following command to create a new API (group/version) as `webapp/v1` and the new Kind(CRD) `Guestbook` on it:

```bash
kubebuilder create api --group webapp --version v1 --kind Guestbook
```

<aside class="note" role="note">
<p class="note-title">Press Options</p>

If you press `y` for Create Resource [y/n] and for Create Controller [y/n] then this creates the files `api/v1/guestbook_types.go` where you define the API
and the `internal/controller/guestbook_controller.go` where you implement the reconciliation business logic for this Kind(CRD).

</aside>

**OPTIONAL:** Edit the API definition and the reconciliation business
logic. For more info see [Designing an API](/cronjob-tutorial/api-design.md) and [What's in
a Controller](cronjob-tutorial/controller-overview.md).

If you are editing the API definitions, generate the manifests such as Custom Resources (CRs) or Custom Resource Definitions (CRDs) using

```bash
make manifests
```

<details><summary>Click here to see an example. <tt>(api/v1/guestbook_types.go)</tt></summary>
<p>

```go
// GuestbookSpec defines the desired state of Guestbook
type GuestbookSpec struct {
	// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// Quantity of instances
	// +kubebuilder:validation:Minimum=1
	// +kubebuilder:validation:Maximum=10
	Size int32 `json:"size"`

	// Name of the ConfigMap for GuestbookSpec's configuration
	// +kubebuilder:validation:MaxLength=15
	// +kubebuilder:validation:MinLength=1
	ConfigMapName string `json:"configMapName"`

	// +kubebuilder:validation:Enum=Phone;Address;Name
	Type string `json:"type,omitempty"`
}

// GuestbookStatus defines the observed state of Guestbook
type GuestbookStatus struct {
	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// PodName of the active Guestbook node.
	Active string `json:"active"`

	// PodNames of the standby Guestbook nodes.
	Standby []string `json:"standby"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster

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

	Spec   GuestbookSpec   `json:"spec,omitempty"`
	Status GuestbookStatus `json:"status,omitempty"`
}
```

</p>
</details>


<aside class="note" role="note">
<p class="note-title"> `+kubebuilder` markers </p>

`+kubebuilder` are [markers][markers] processed by [controller-gen][controller-gen]
to generate CRDs and RBAC. Kubebuilder also provides [scaffolding markers][scaffolding-markers]
to inject code into existing files and simplify common tasks. See `cmd/main.go` for examples.

</aside>

## Test it out

You'll need a Kubernetes cluster to run against. You can use
[KinD][kind] to get a local cluster for testing, or
run against a remote cluster.

<aside class="note" role="note">
<p class="note-title">Context Used</p>

Your controller will automatically use the current context in your
kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).

</aside>

Install the CRDs into the cluster:

```bash
make install
```

For quick feedback and code-level debugging, run your controller (this runs in the foreground, so switch to a new
terminal if you want to leave it running):

```bash
make run
```

## Install instances of custom resources

If you pressed `y` for Create Resource [y/n] then you created a CR for your CRD in your
`config/samples/` directory.

Edit `config/samples/webapp_v1_guestbook.yaml` to contain a valid `spec`. For example:

```yaml
# ...
spec:
  foo: bar
```

Hint: "foo" is a string field defined in `api/v1/guestbook_types.go`:

```go
// foo is an example field of Guestbook. Edit guestbook_types.go to remove/update
// +optional
Foo *string `json:"foo,omitempty"`
```

```bash
kubectl apply -k config/samples/
```

You can have a look at your applied resource now:

```bash
kubectl get guestbooks.webapp.my.domain guestbook-sample -o yaml
```

## Run it on the cluster

When your controller is ready to be packaged and tested in other clusters.

Build and push your image to the location specified by `IMG`:

```bash
make docker-build docker-push IMG=<some-registry>/<project-name>:tag
```

Deploy the controller to the cluster with image specified by `IMG`:

```bash
make deploy IMG=<some-registry>/<project-name>:tag
```

<aside class="note" role="note">
<p class="note-title">Registry Permission</p>

You should publish this image to the personal registry you specified. You also need access to pull the image from the working environment.
Make sure you have the proper permission to the registry if the above commands do not work.

Consider incorporating [Kind][kind] into your workflow for a faster, more efficient local development and CI experience.
Note that, if you are using a [Kind][kind] cluster, there is no need to push your image to a remote container registry.
You can directly load your local image into your specified [Kind][kind] cluster:

```bash
kind load docker-image <your-image-name>:tag --name <your-kind-cluster-name>
```

It is highly recommended to use [Kind][kind] for development purposes and CI.
To know more, see: [Using Kind For Development Purposes and CI](./reference/kind.md)

<p class="note-title">RBAC errors</p>

If you encounter RBAC errors, you may need to grant yourself cluster-admin
privileges or be logged in as admin. See [Prerequisites for using Kubernetes RBAC on GKE cluster v1.11.x and older][pre-rbc-gke] which may be your case.

</aside>

## Uninstall CRDs

To delete your CRDs from the cluster:

```bash
make uninstall
```

## Undeploy controller

Undeploy the controller to the cluster:

```bash
make undeploy
```
## Using plugins

Kubebuilder design is based on [Plugins][plugins] and you can use
[available plugins][available-plugins] to add optional features to your project.

<aside class="note" role="note">
<p class="note-title">References and Examples</p>

Use the [Deploy Image Plugin (deploy-image/v1-alpha)][deploy-image-v1-alpha] as a reference when creating your project. It follows Kubernetes conventions and recommended good practices. For example:

```bash
kubebuilder create api --group webapp --version v1alpha1 --kind Busybox --image=busybox:1.36.1 --plugins="deploy-image/v1-alpha"
```

</aside>

<aside class="note" role="note">
<p class="note-title"> Keeping your project up to date with ecosystem changes </p>

Use [AutoUpdate Plugin][autoupdate-v1-alpha] to keep your project
aligned with the latest ecosystem changes. When a new release is available,
it automatically opens an issue with a PR comparison link so you can review and update easily.

```bash
kubebuilder edit --plugins="autoupdate/v1-alpha"
```

</aside>

## Next steps

- [Getting Started Guide][getting-started] (~30 min) - build a solid foundation
- [CronJob Tutorial][cronjob-tutorial] - learn by building a demo project
- [Groups, Versions, and Kinds][gkv-doc] - understand API design concepts

[pre-rbc-gke]: https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#iam-rolebinding-bootstrap
[cronjob-tutorial]: ./cronjob-tutorial/cronjob-tutorial.md
[GOPATH-golang-docs]: https://go.dev/doc/code.html#GOPATH
[go-modules-blogpost]: https://blog.go.dev/using-go-modules
[architecture-concept-diagram]: architecture.md
[kustomize]: https://github.com/kubernetes-sigs/kustomize
[getting-started]: getting-started.md
[plugins]: plugins/plugins.md
[available-plugins]: plugins/available-plugins.md
[envtest]: ./reference/envtest.md
[autoupdate-v1-alpha]: plugins/available/autoupdate-v1-alpha.md
[deploy-image-v1-alpha]: plugins/available/deploy-image-plugin-v1-alpha.md
[gkv-doc]: cronjob-tutorial/gvks.md
[kind]: https://sigs.k8s.io/kind
[markers]: reference/markers.md
[controller-gen]: https://sigs.k8s.io/controller-tools/cmd/controller-gen
[scaffolding-markers]: reference/markers/scaffold.md
