Skip to content

Commit

Permalink
Merge pull request #51 from pwittrock/docs
Browse files Browse the repository at this point in the history
Flesh out documentation on homepage
  • Loading branch information
Phillip Wittrock committed Apr 4, 2018
2 parents f6d0548 + 1ceb15c commit 12f1fba
Showing 1 changed file with 239 additions and 2 deletions.
241 changes: 239 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,245 @@ kubebuilder docs

See the [user guide](docs/tools_user_guide.md) for more details

## Godocs
## Project structure

Following describes the project structure setup by kubebuilder commands.

### cmd/

*Most users do not need to edit this package.*

The `cmd` package contains the main function for launching a new controller manager. It is responsible for parsing
a `rest.Config` and invoking the `inject` package to run the various controllers. It may optionally install CRDs
as part of starting up.

This package is created automatically by running:

```sh
kubebuilder init --domain k8s.io
```

### pkg/apis

**Users must edit packages under this package**

The `apis` package contains the schema definitions for the resource types you define. Resources are defined under
`pkg/apis/<group>/<version>/<kind>_types.go`. Resources may be annotated with comments to identify resources
to code generators. Comments are also used to generated field validation.

Notably client generation, CRD generation, docs generation and config generation are all driven off of annotations
on resources package.

See documentation and examples of annotations in godoc format here:
[gen/apis](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/gen/apis#example-package)

Subpackages of apis are created when running the following command to create a new resource and controller:

```sh
kubebuilder create resource --group mygroup --version v1beta1 --kind MyKind
```

### pkg/controllers

**Users must packages under this package**

The `controllers` package contains the controllers to implement the resource APIs. Controllers are defined under
`pkg/controllers/<kind>/controller.go`. Controllers may be annotated with comments to wire the controller into the
inject package, start informers they require and install RBAC rules they require.

Subpackages of controllers are created when running the following command to create a new resource and controller:

```sh
kubebuilder create resource --group mygroup --version v1beta1 --kind MyKind
```

See documentation and examples of annotations in godoc format here:
- [gen/controller](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/gen/controller#example-package)

### pkg/inject

*Most users do not need to edit this package.*

The `inject` package contains the `RunAll` function used to start all of the registered controllers and informers.
Wiring is autogenerated based on resource and controller annotations.

Generated wiring:
- Installing CRDs
- Instantiating and starting controllers
- Starting sharedinformers
- Installing RBAC rules

### pkg/inject/args

*Only some users need to edit this package.*

The `args` package contains the struct passed to the `ProvideController` function used to instantiating controllers.
The `InjectArgs` struct and `CreateInjectArgs` function in this package may be edited to pass additional information
to the controller provider functions. This is typically an advanced use case.

The `args` package uses the `kubebuilder/pkg/inject/args` package documented here:
[inject/args](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/inject/args)

### hack/

The `hack` directory contains generated samples and config.

The hack/install.yaml config file for installing the API extension into a cluster will be created under this
directory by running.

```sh
kubebuilder create config --controller-image mycontrollerimage --name myextensionname
```

### docs/

The `docs` package contains your examples and content for generating reference documentation for your APIs.

The docs package is created when running either

```sh
kubebuilder docs
```

or

```sh
kubebuilder create example --group mygroup --version v1beta1 --kind MyKind
```

Example reference documentation lives under `docs/reference/examples`. Conceptual reference documentation
lives under `docs/reference/static_includes`.

### /

The project root directory contains several files

- Dockerfile.controller

Running `docker build` on this file will build a container image for running your controller.

- Gopkg.toml / Gopkg.lock

These files are used to update vendored go dependencies.

## Available controller operations

Controllers watch Kubernetes resources and call a "Reconcile" function in response to events. Reconcile functions
are typically "level-based", that is they are notified that something has changed for given resource namespace/name key,
but not specifically what changed (e.g. add, delete, update). This allows Reconcile functions to reconcile multiple
events at a time and more easily self-heal, as actions are taken by comparing the current desired state (resource Spec)
and the observed state of the system.

### Creating a new controller

A new GenericController is created for you by kubebuilder when creating a resource. If you are not using
kubebuilder to create resources and manage your project, you may create a controller directly by following
this example:

[GenericController](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/controller#example-GenericController)

Use the following annotation to start additional informers for any resources you are watching in your controller.

```go
// +informers:group=apps,version=v1,kind=Deployment
```

Use the following annotation to generate RBAC rules to allow your controller to read and write resources when
running in a container in a Kubernetes cluster.

```go
// +rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
```


### Watching resources

Controllers watch resources to trigger reconcile functions. It is common for controllers to reconcile a single resource
type, but watch many other resource types to trigger a reconcile. An example of this is a Deployment controller that
watches Deployments, ReplicaSets (created by the controller) and Pods (created by the ReplicaSet controller). Pod
status events, such as becoming healthy, may trigger actions in the Deployment controller, such as continuing
a rolling update.

#### Watching the resource managed by the controller

Controllers typically watch for events on the resource they control and in response reconcile that resource instance.

Note: Kubebuilder will automatically call the Watch function for controllers it creates when creating a resources. If
you are not using kubebuilder to create resources and manager your project, you may have your controller watch
a resource by following this example:

[GenericController.Watch](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/controller#example-GenericController-Watch)

#### Watching resources created by a controller and reconciling in the controller

Controllers frequently watch for events on the resources created by the controller or transitively created by the
controller (e.g. controller creates a ReplicaSet and the ReplicaSet creates a Pod).

Events for created resources need to be mapped back to the resource instance responsible for their creation -
e.g. if there is a Pod event -then reconcile the Deployment that owns the Pod. The owning resource is found by
looking at the instance (Pod) controller reference, looking up the object with the same namespace and name as the
owner reference and comparing the UID of the found object to the UID in the owner reference. This is check is done
to ensure the object is infact the owner and to disambiguate multiple resources with the same name and Kind that
are logically different (e.g. they are in different groups and are totally different things).

e.g. In response to a Pod event, find the owner reference for the Pod that has `controller=true`.
Lookup the ReplicaSet with this name and compare its UID to the ownerref UID. If they are the same
find the owner reference for the ReplicaSet that has `controller=true`. Lookup the Deployment
with this name and compare the UID to the ownerref UID. If they are the same reconcile the Deployment with
this namespace/name.

In order to watch objects created by a controller and reconcile the owning resource in response, the functions
to lookup the ancestors object must be provided (e.g. lookup a ReplicaSet for a namespace/name,
lookup a Deployment for a namespace/name).

You may have you controller watch a resource created by the controller and then reconcile the owning object by
following this example:

[GenericController.WatchControllerOf](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/controller#example-GenericController-WatchControllerOf)

[Sample](https://github.com/kubernetes-sigs/kubebuilder/blob/master/samples/controller/controller.go#L91)

#### Watching arbitrary resources and mapping them so the are reconciled in the controller

In some cases it may be necessary to watch resources not owned or created by your controller, but respond to them.
An example would be taking some action in response to the deletion or creation of Nodes in the cluster. To do
this, your controller must watch that object (Node) and map events to the resource type of the controller.

You may watch a resource and transform it into the key of the resource the controller manages by following this example:

[GenericController.WatchTransformationOf](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/controller#example-GenericController-WatchTransformationOf)

#### Watching arbitrary resources and handling the events that may caused a reconciliation in the controller

In some cases it may be necessary to directly handle events and enqueue keys to be reconciled. You may do so
by following this example:

[GenericController.WatchEvents](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/controller#example-GenericController-WatchEvents)

### Watching a channel for resource names and reconciling them in the controller

In some cases it may be necessary to respond to external events such as webhooks. You may enqueue reconcile events
from arbitrary sources by using a channel and following this example:

[GenericController.WatchChannel](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/controller#example-GenericController-WatchChannel)

## Running tests

In order to run the integration tests, the following environment variables must be set to bring up the test environment:

```sh
export TEST_ASSET_KUBECTL=/usr/local/kubebuilder/bin/kubectl
export TEST_ASSET_KUBE_APISERVER=/usr/local/kubebuilder/bin/kube-apiserver
export TEST_ASSET_ETCD=/usr/local/kubebuilder/bin/etcd
```

Tests can then be run with:

```sh
go test ./pkg/...
```

## Godoc Links

Many of the kubebuilder libraries can be used on their own without the kubebuilder code generation and scaffolding.

Expand All @@ -64,7 +302,6 @@ Kubebuilder generates codes for custom resource fields, and controller component
- [resource code generation tags](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/gen/apis)
- [controller code generation tags](https://godoc.org/github.com/kubernetes-sigs/kubebuilder/pkg/gen/controller)


For example, you have to add controller code generation tags such as `+rbac` and `+informers` in `pkg/controller/foo/controller.go` file:
```
// +controller:group=foo,version=v1beta1,kind=Bar,resource=bars
Expand Down

0 comments on commit 12f1fba

Please sign in to comment.