Skip to content

Commit

Permalink
v1alpha3-compliant cluster API provideri implementor's guide
Browse files Browse the repository at this point in the history
  • Loading branch information
liztio committed Dec 4, 2019
1 parent 2e649a0 commit 8505b27
Show file tree
Hide file tree
Showing 10 changed files with 841 additions and 31 deletions.
30 changes: 0 additions & 30 deletions docs/book/SUMMARY.md

This file was deleted.

7 changes: 6 additions & 1 deletion docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
- [Provider Implementers](./providers/implementers.md)
- [v1alpha1 to v1alpha2](./providers/v1alpha1-to-v1alpha2.md)
- [Cluster Infrastructure](./providers/cluster-infrastructure.md)

- [Implementer's Guide](./providers/implementers-guide/overview.md)
- [Naming](./providers/implementers-guide/naming.md)
- [Create Repo and Generate CRDs](./providers/implementers-guide/generate_crds.md)
- [Create API](./providers/implementers-guide/create_api.md)
- [Controllers and Reconciliation](./providers/implementers-guide/controllers_and_reconciliation.md)
- [Building, Running, Testing](./providers/implementers-guide/building_running_and_testing.md)
- [Reference](./reference/reference.md)
- [Glossary](./reference/glossary.md)
- [Provider List](./reference/providers.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Building, Running, Testing

## Docker Image Name

The patch in `config/default/manager_image_patch.yaml` will be applied to the manager pod.
Right now there is a placeholder `IMAGE_URL`, which you will need to change to your actual image.

### Development Images
It's likely that you will want one location and tag for release development, and another during development.

The approach most Cluster API projects is using [a `Makefile` that uses `sed` to replace the image URL][sed] on demand during development.

[sed]: https://github.com/kubernetes-sigs/cluster-api/blob/e0fb83a839b2755b14fbefbe6f93db9a58c76952/Makefile#L201-L204

## Deployment

### cert-manager

Cluster API uses [cert-manager] to manage the certificates it needs for its webhooks.
Before you apply Cluster API's yaml, you should [install `cert-manager`][cm-install]

[cert-manager]: https://github.com/jetstack/cert-manager
[cm-install]: https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html

```
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/<version>/cert-manager.yaml
```

### Cluster API

Before you can deploy the infrastructure controller, you'll need to deploy Cluster API itself.

You can [use a precompiled manifest][install], or clone [`cluster-api`][capi] and apply its manifests using `kustomize`.

``` shell
cd cluster-api
kustomize build config/default | kubectl apply -f-
```

Check the status of the manager to make sure it's running properly

```shell
$ kubectl describe -n capi-system pod | grep -A 5 Conditions
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
```


[install]: https://cluster-api.sigs.k8s.io/tasks/installation.html#install-cluster-api

### Your provider

Now you can apply your provider as well:

```
$ cd cluster-api-provider-mailgun
$ kustomize build config/default | envsubst | kubectl apply -f-
$ kubectl describe -n cluster-api-provider-mailgun-system pod | grep -A 5 Conditions
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
```

### Tiltfile
Cluster API development requires a lot of iteration, and the "build, tag, push, update deployment" workflow can be very tedious.
[Tilt](https://tilt.dev) makes this process much simpler by watching for updates, then automatically building and deploying them.

You can visit [some example repositories][capidev], but you can get started by writing out a yaml manifest and using the following [`Tiltfile`][tiltfile]
`kustomize build config/default | envsubst > capm.yaml`

[capidev]: https://github.com/chuckha/capi-dev
[tiltfile]: https://docs.tilt.dev/tiltfile_concepts.html

```starlark
allow_k8s_contexts('kubernetes-admin@kind)

k8s_yaml('capm.yaml')

docker_build('<your docker username or repository url>/cluster-api-controller-mailgun-amd64', '.')
```

You can then use Tilt to watch the logs coming off your container


## Your first Cluster

Let's try our cluster out. We'll make some simple YAML:

```yaml
apiVersion: cluster.x-k8s.io/v1alpha2
kind: Cluster
metadata:
name: hello-mailgun
spec:
clusterNetwork:
pods:
cidrBlocks: ["192.168.0.0/16"]
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
kind: MailgunCluster
name: hello-mailgun
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
kind: MailgunCluster
metadata:
name: hello-mailgun
spec:
priority: "ExtremelyUrgent"
request: "Please make me a cluster, with sugar on top?"
requester: "[email protected]"
```

We apply it as normal with `kubectl apply -f <filename>.yaml`.

If all goes well, you should be getting an email to the address you configured when you set up your management cluster:

![An email from mailgun urgently requesting a cluster](cluster-email.png)

## Conclusion

Obviously, this is only the first step.
We need to implement our Machine object too, and log events, handle updates, and many more things.

Hopefully you feel empowered to go out and create your own provider now.
The world is your Kubernetes-based oyster!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
159 changes: 159 additions & 0 deletions docs/book/src/providers/implementers-guide/configure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Configure

## YAML

`kubebuilder` generates most of the YAML you'll need to deploy a container.
We just need to modify it to add our new secrets.

First, let's add our secret as a [patch] to the manager yaml.

`config/default/manager_config.yaml`:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
env:
- name: MAILGUN_API_KEY
valueFrom:
secretKeyRef:
name: mailgun-secret
key: api_key
- name: MAILGUN_DOMAIN
valueFrom:
configMapKeyRef:
name: mailgun-config
key: mailgun_domain
- name: MAIL_RECIPIENT
valueFrom:
configMapKeyRef:
name: mailgun-config
key: mail_recipient
```
And then, we have to add that patch to [`config/default/kustomization.yaml`][kustomizeyaml]:

```yaml
patchesStrategicMerge
- manager_image_patch.yaml
# Protect the /metrics endpoint by putting it behind auth.
# Only one of manager_auth_proxy_patch.yaml and
# manager_prometheus_metrics_patch.yaml should be enabled.
- manager_auth_proxy_patch.yaml
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, uncomment the following line and
# comment manager_auth_proxy_patch.yaml.
# Only one of manager_auth_proxy_patch.yaml and
# manager_prometheus_metrics_patch.yaml should be enabled.
- manager_config.yaml
```

[kustomizeyaml]: https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#kustomization
[patch]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md

## Our configuration

There's many ways to manage configuration in production.
The convention many Cluster-API projects use is enviroment variables.

`config/manager/configuration.yaml`

```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: mailgun-config
namespace: system
type: Opaque
stringData:
api_key: ${MAILGUN_API_KEY}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mailgun-config
namespace: system
data:
mailgun_domain: ${MAILGUN_DOMAIN}
mail_recipient: ${MAILGUN_RECIPIENT}
```

And add this to `config/manager/kustomization.yaml`

```yaml
resources:
- manager.yaml
- credentials.yaml
```

You can now (hopefully) generate your yaml!

```
kustomize build config/default
```
## RBAC Role
The default [RBAC role][role] contains permissions for accessing your cluster infrastructure CRDs, but not for accessing Cluster API resources.
You'll need to add these to `config/rbac/role.yaml`
[role]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
```diff
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index e9352ce..29008db 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -6,6 +6,24 @@ metadata:
creationTimestamp: null
name: manager-role
rules:
+- apiGroups:
+ - cluster.x-k8s.io
+ resources:
+ - clusters
+ - clusters/status
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - cluster.x-k8s.io
+ resources:
+ - machines
+ - machines/status
+ verbs:
+ - get
+ - list
+ - watch
- apiGroups:
- infrastructure.cluster.x-k8s.io
resources:
```

## EnvSubst

_A tool like [direnv](https://direnv.net/) can be used to help manage enviroment variables._


`kustomize` does not handle replacing those `${VARIABLES}` with actual values.
For that, we use [`envsubst`][envsubst].

You'll need to have those environment variables (`MAILGUN_API_KEY`, `MAILGUN_DOMAIN`, `MAILGUN_RECIPIENT`) in your environment when you generate the final yaml file.

Then we call envsubst in line, like so:

```
kustomize build config/default | envsubst
```

[envsubst]: https://linux.die.net/man/1/envsubst

Loading

0 comments on commit 8505b27

Please sign in to comment.