Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Controllers section #611

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions docs/8-kubernetes-container-orchestration/8.8-controllers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
docs/8-kubernetes-container-orchestration/8.8-controllers.md:
category: Container Orchestration
estReadingMinutes: 45
exercises:
-
name: Setup
description: Set up the environment for a custom controller by deploying a k3d cluster.
estMinutes: 30
technologies:
- Kubernetes
- k3d
-
name: Pod Labelling Controller
description: Use given skeleton to create a controller that will give a pod a label if it has a certain annotation
estMinutes: 240
technologies:
- Kubernetes
- k3d
- client-go
-
name: Open-ended Custom Controller
description: Use what you've learned to create a custom controller with a function of our own choosing
estMinutes: 240
technologies:
- Kubernetes
- k3d
- client-go
---

# 8.8 Controllers

## Controllers in Kubernetes

One of the core principles of Kubernetes is the maintenance of a desired state of your applications and infrastructure. [Controllers are one of the critical components that make this possible](https://kubernetes.io/docs/concepts/architecture/controller/). They act as the “watchers” and “correctors” in the Kubernetes ecosystem, continuously monitoring resources to ensure that the real-time state aligns with the desired state you've defined.

Due the the declarative nature of Kubernetes manifests, every time you deploy something in Kubernetes—whether it's a set of pods, a load balancer, or a job—you’re effectively telling Kubernetes what you want the end result to look like. Controllers make this happen by performing ongoing checks on the cluster’s state and taking corrective action when discrepancies are found. This could mean restarting a failed pod, scaling up replicas, or re-creating a missing resource.

## Controllers and CRDs (Custom Resource Definitions)

Although Kubernetes comes with numerous built-in controllers that handle core functionalities—like maintaining replica counts, managing rollouts, and ensuring nodes are healthy—one of the most powerful use cases for controllers is actually to extend Kubernetes with [Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (CRDs). CRDs allow developers to create custom resources that Kubernetes doesn’t natively support, and custom controllers that then manage these new resource types, bringing them into the Kubernetes control loop. This means that by writing your own controllers, you can leverage Kubernetes to automate virtually any process or infrastructure task specific to your environment, from monitoring external services to managing custom application lifecycles.

If you've been working through the bootcamp, you've already been exposed to both CRDs and custom controllers. In the first exercise of chapter 8.6, Webhooks, you were tasked with setting up a basic admission webhook, which required installing cert-manager. `cert-manager` is a powerful tool that combines a set of custom resource definitions (CRDs) with a custom controller to automate the issuance, renewal, and management of TLS certificates that webhooks require to securely interact with the Kubernetes API server. By leveraging CRDs like Certificate, Issuer, and ClusterIssuer, cert-manager enables you to declare and manage certificates directly within Kubernetes, removing the need for manual intervention in obtaining and maintaining certificates. This automation is not only convenient but essential in high-scale environments where TLS certificates need frequent renewal to ensure secure connections across applications and services.

The custom controller within cert-manager works in tandem with these CRDs, continuously monitoring the cluster to issue, validate, and renew certificates as needed. This example illustrates the true power of custom controllers and CRDs in Kubernetes: they allow you to extend Kubernetes' native functionality, transforming it from a platform primarily for container orchestration to a versatile tool for managing infrastructure components.

## Example 1: Creating a simple custom controller

That being said, custom controllers aren’t limited to only managing custom resources. They can also be designed to interact with and manage native Kubernetes resources, enabling a wide range of powerful functionalities. By observing and modifying built-in resources like Pods, Deployments, or Services, custom controllers allow you to implement advanced automation, enforce policies, enhance security, and streamline operational workflows directly within Kubernetes.

> Your controller will be using the `client-go` library provided by Kubernetes to communicate with the Kubernetes API server and manage resources. You can learn more about client-go [here](https://github.com/kubernetes/client-go).

In this exercise, you are responsible for creating a custom controller that will monitor the cluster, looking for pods in a particular namespace with a particular label. If a pod is found in the namespace with that label, your controller should attach an annotation to said pod.

### Setup

___
- If you don't have it already install `k3d`
```shell
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
```

- Verify you have at least v1.30 of `k3s` installed
```shell
➜ devops-bootcamp ✗ k3d --version
k3d version v5.7.3
k3s version v1.30.3-k3s1 (default)
```

- Create a new cluster `unset KUBECONFIG; k3d cluster create <cluster-name>`

___

1. In your k3d cluster, create a namespace to use for this exercise, i.e. `kubectl create namespace my-namespae`

2. Clone the [bootcamp repository](https://github.com/liatrio/devops-bootcamp) if you haven't already, and navigate to the `examples/ch8/controllers` folder, where you will find a skeleton file for a custom controller

3. Create a directory *pod-controller-module*

4. Move a copy of the skeleton file to your *pod-controller-module* directory, navigate there, and run `go mod init .` to initialize the directory as a go module

5. Change the skeleton file so that the controller will:
- Only look at pods within your namespace.
- Look for pods with the annotation `add-pod-name-label=true`:
- If the pod has this annotation, add a label with the name `pod` and the value being the name of the actual pod.

6. Run your controller locally by running `go build [your-controller.go] -o controller` and `./controller`. You will have to write a basic pod to test your controller's functionality.

7. Once you have confirmed that your controller is working as expected, you will have to be able to create a deployment to run your controller. Use the deployment manifest in the examples folder as a starting point.

> This exercise is based off of [this tutorial](https://kubernetes.io/blog/2021/06/21/writing-a-controller-for-pod-labels/), which has you create the same controller using the operator-sdk framework (which uses kubebuilder under the hood). Client-go is a lightweight and less abstracted alternative to frameworks like operator-sdk, making it ideal for both simple and complex controller development.

## Exercise 2: Make your own controller!

Controllers have a lot more uses than labeling pods. Controllers are an excellent tool to extend the functionality of your Kubernetes cluster. They can manage internal resources, CRD's, and communicate with external API's.

Write your own controller to do whatever you want! Take your time with this exercise and try to create something that has some practical, real-world use cases.

## Deliverables

- When would you want to use a controller? When would you not?
- What is the difference between between an admission webhook and a controller? When would one be more practical than another?
- What is a CRD? Give an example of one and explain why it was made.
- What role does an Informer have in a client-go controller?
- What key components are there in a controller, and what roles do they have?
- How can Leader Elections relate to controllers?
34 changes: 25 additions & 9 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1107,20 +1107,36 @@ docs/8-kubernetes-container-orchestration/8.7.2-helm.md:
- Kubernetes
- Helm
- Kustomize
docs/8-kubernetes-container-orchestration/8.8-hello-k8s.md:
docs/8-kubernetes-container-orchestration/8.8-controllers.md:
category: Container Orchestration
estReadingMinutes: 15
estReadingMinutes: 45
exercises:
- name: Kubernetes Custom Project
- name: Setup
description: >-
Create a custom Kubernetes project, utilizing kubebuilder,Kubebuilder to
create a kubernetes custom resource definition and controller which
reconciles changes to the custom resource.
estMinutes: 4800
Set up the environment for a custom controller by deploying a k3d
cluster.
estMinutes: 30
technologies:
- Kubernetes
- Custom Resources
- Kubebuilder
- k3d
- name: Pod Labelling Controller
description: >-
Use given skeleton to create a controller that will give a pod a label
if it has a certain annotation
estMinutes: 240
technologies:
- Kubernetes
- k3d
- client-go
- name: Open-ended Custom Controller
description: >-
Use what you've learned to create a custom controller with a function of
our own choosing
estMinutes: 240
technologies:
- Kubernetes
- k3d
- client-go
docs/9-platform-engineering/9.0-overview.md:
category: Platform Engineering
estReadingMinutes: 15
Expand Down
5 changes: 3 additions & 2 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
- [8.7 - Declarative Configuration](8-kubernetes-container-orchestration/8.7-declarative-configuration.md)
- [8.7.1 - Kustomize](8-kubernetes-container-orchestration/8.7.1-kustomize.md)
- [8.7.2 - Helm](8-kubernetes-container-orchestration/8.7.2-helm.md)
- [8.8 - Hello K8s](8-kubernetes-container-orchestration/8.8-hello-k8s.md)
- [8.8 - Controllers](8-kubernetes-container-orchestration/8.8-controllers.md)

- **Chapter 9**

Expand All @@ -162,5 +162,6 @@
- [Jira](addendum/jira.md)
- [Artifactory](addendum/artifactory.md)
- [Docker Registry](addendum/docker-registry.md)
- [K8 The Hard Way](addendum/k8s-the-hard-way.md)
- [K8s The Hard Way](addendum/k8s-the-hard-way.md)
- [Chef](addendum/chef.md)
- [Hello K8s](addendum/Hello-K8s.md)