Created
April 24, 2021 14:08
-
-
Save eggsbenjamin/d1837e0b0dd707ea398574cb8a1ec65a to your computer and use it in GitHub Desktop.
Minimal Kubebuilder Local Setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.PHONY: kubebuilder | |
# Directory to store local binaries in - can be overridden where necessary | |
BIN_PATH ?= $(CURDIR)/bin | |
SHELL := /bin/bash | |
# Ensure binaries in bin are used | |
PATH := $(BIN_PATH):$(BIN_PATH)/bin:$(PATH) | |
export PATH | |
OS := $(shell go env GOOS) | |
ARCH := $(shell go env GOARCH) | |
KUBEBUILDER_VERSION := 2.3.1 | |
KUBEBUILDER_URL := https://go.kubebuilder.io/dl/$(KUBEBUILDER_VERSION)/$(OS)/$(ARCH) | |
KUBEBUILDER_DIR := kubebuilder | |
KUBEBUILDER_RESOURCE_GROUP := webapp | |
KUBEBUILDER_RESOURCE_VERSION := v1 | |
KUBEBUILDER_RESOURCES := Guestbook Eagle # resource names must begin with a capital letter | |
KUBEBUILDER_CONTROLLERS := $(foreach resource, $(KUBEBUILDER_RESOURCES), $(KUBEBUILDER_DIR)/controllers/$(shell echo $(resource) | tr '[:upper:]' '[:lower:]')_controller.go) | |
KUBEBUILDER_CONTROLLER_IMG := controller:test | |
KUBEBUILDER_NAMESPACE ?= kubebuilder-system | |
KUBEBUILDER_NAME_PREFIX ?= kubebuilder- | |
KUBEBUILDER_INITIALISED_FILE = $(CURDIR)/.KUBEBUILDER_INITIALISED | |
KIND_URL := sigs.k8s.io/kind | |
KIND_VERSION := v0.8.1 | |
KIND_KUBERNETES_VERSION := v1.12.10 | |
KIND_CLUSTER_NAME := kubebuilder-test | |
KIND_CONTEXT := kind-$(KIND_CLUSTER_NAME) | |
KIND_CLUSTER_FILE = $(CURDIR)/.KIND_CLUSTER | |
KUBERNETES_LOCAL_CONTEXT ?= $(KIND_CONTEXT) | |
KUBECTL_VERSION := v1.13.10 | |
KUBECTL_URL := https://dl.k8s.io/$(KUBECTL_VERSION)/kubernetes-client-$(OS)-$(ARCH).tar.gz | |
# Source based on OS | |
ifeq ($(OS),linux) | |
SHASUM := sha256sum -c | |
endif | |
ifeq ($(OS),darwin) | |
SHASUM := shasum -a 256 -c | |
endif | |
all: kubebuilder_run_local_kind ## build all resources defined in KUBEBUILDER_RESOURCES and deploy to kind cluster | |
clean: kind_delete_cluster ## removes all artifacts produced via this makefile *use with caution* | |
ifneq (,$(wildcard $(BIN_PATH))) | |
rm -rf $(BIN_PATH) | |
endif | |
ifneq (,$(wildcard $(KUBEBUILDER_DIR))) | |
rm -rf $(KUBEBUILDER_DIR) | |
endif | |
ifneq (,$(wildcard $(KUBEBUILDER_INITIALISED_FILE))) | |
rm $(KUBEBUILDER_INITIALISED_FILE) | |
endif | |
# from https://suva.sh/posts/well-documented-makefiles/ | |
help: ## Display this help | |
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-30s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) | |
deps: $(BIN_PATH) $(BIN_PATH)/kubebuilder $(BIN_PATH)/kubectl $(BIN_PATH)/kind ## install deps | |
kubebuilder: kubebuilder_init $(KUBEBUILDER_CONTROLLERS) ## scaffold minimal kubebuilder project with controllers defined in KUBEBUILDER_CONTROLLERS | |
$(KUBEBUILDER_DIR)/go.mod: | |
mkdir -p $(KUBEBUILDER_DIR) | |
cd $(KUBEBUILDER_DIR) && go mod init kubebuilder | |
kubebuilder_init: deps $(KUBEBUILDER_DIR)/go.mod ## scaffold kubebuilder project and remove cruft | |
mkdir -p $(KUBEBUILDER_DIR) | |
ifeq (,$(wildcard $(KUBEBUILDER_INITIALISED_FILE))) | |
cd $(KUBEBUILDER_DIR) && kubebuilder init --domain my.domain | |
# remove unwanted generated files and cruft. | |
rm -rf $(KUBEBUILDER_DIR)/config/{certmanager,prometheus,webhook} | |
rm $(KUBEBUILDER_DIR)/config/default/*patch.yaml | |
rm $(KUBEBUILDER_DIR)/config/rbac/auth_proxy*.yaml | |
echo -e \ | |
namespace: kubebuilder-system\\n\ | |
namePrefix: kubebuilder-\\n\ | |
bases:\\n\ | |
- ../crd\\n\ | |
- ../rbac\\n\ | |
- ../manager\\n > $(KUBEBUILDER_DIR)/config/default/kustomization.yaml | |
head -n 5 $(KUBEBUILDER_DIR)/config/rbac/kustomization.yaml > $(KUBEBUILDER_DIR)/config/rbac/kustomization.yaml | |
touch $(KUBEBUILDER_INITIALISED_FILE) | |
else | |
echo "kubebuilder pre-initialised..." | |
endif | |
# define template for controller target | |
define make-controller-target | |
$(KUBEBUILDER_DIR)/controllers/$(shell echo $1 | tr '[:upper:]' '[:lower:]')_controller.go: kubebuilder_init | |
if [ ! -f $(KUBEBUILDER_DIR)/controllers/$(shell echo $1 | tr '[:upper:]' '[:lower:]')_controller.go ]; then \ | |
cd $(KUBEBUILDER_DIR) && kubebuilder create api --group $(KUBEBUILDER_RESOURCE_GROUP) --version $(KUBEBUILDER_RESOURCE_VERSION) --kind $1 --resource --controller ; \ | |
fi | |
endef | |
# dynamically generate controller targets for each resource | |
$(foreach resource,$(KUBEBUILDER_RESOURCES),$(eval $(call make-controller-target,$(resource)))) | |
kubebuilder_run_local: kubebuilder ## run kubebuilder controller manager against local cluster defined in KUBERNETES_LOCAL_CONTEXT. Defaults to kind cluster. | |
kubectl config use-context $(KUBERNETES_LOCAL_CONTEXT) | |
make -C kubebuilder | |
make -C kubebuilder install | |
make -C kubebuilder run | |
kubebuilder_run_local_kind: kubebuilder kind_create_cluster ## create and run controller manager against local kind cluster. Cluster created if not pre-existing | |
kubectl config use-context $(KIND_CONTEXT) | |
make -C kubebuilder | |
make -C kubebuilder install | |
make -C kubebuilder docker-build IMG=$(KUBEBUILDER_CONTROLLER_IMG) | |
kind load docker-image $(KUBEBUILDER_CONTROLLER_IMG) --name $(KIND_CLUSTER_NAME) | |
make -C kubebuilder deploy IMG=$(KUBEBUILDER_CONTROLLER_IMG) | |
kind_create_cluster: ## creates a local kind cluster with name KIND_CLUSTER_NAME | |
ifeq (,$(wildcard $(KIND_CLUSTER_FILE))) | |
kind create cluster --image=kindest/node:$(KIND_KUBERNETES_VERSION) --name=$(KIND_CLUSTER_NAME) | |
echo $(KIND_CONTEXT) > $(KIND_CLUSTER_FILE) | |
else | |
echo "pre-existing kind cluster $(KIND_CLUSTER_NAME)" | |
endif | |
kind_delete_cluster: ## deletes local kind cluster with name KIND_CLUSTER_NAME | |
ifneq (,$(wildcard $(KIND_CLUSTER_FILE))) | |
kind delete cluster --name $(KIND_CLUSTER_NAME) | |
rm $(KIND_CLUSTER_FILE) | |
else | |
echo "kind cluster $(KIND_CLUSTER_NAME) does not exist" | |
endif | |
# Dependencies | |
$(BIN_PATH): | |
mkdir -p $(BIN_PATH) | |
$(BIN_PATH)/kubebuilder: | |
curl --fail -sL $(KUBEBUILDER_URL) | tar -xz -C $(BIN_PATH) | |
mv $(BIN_PATH)/kubebuilder_$(KUBEBUILDER_VERSION)_$(OS)_$(ARCH)/bin/{kubebuilder,etcd,kube-apiserver} $(BIN_PATH) | |
rm -rf $(BIN_PATH)/kubebuilder_$(KUBEBUILDER_VERSION)_$(OS)_$(ARCH) | |
$(BIN_PATH)/kind: | |
GOBIN=$(BIN_PATH) GO111MODULE=on go get $(KIND_URL)@$(KIND_VERSION) | |
$(BIN_PATH)/kubectl: | |
curl --fail -sL $(KUBECTL_URL) | tar -xz -C $(BIN_PATH) | |
mv $(BIN_PATH)/kubernetes/client/bin/kubectl $(BIN_PATH) | |
rm -rf $(BIN_PATH)/kubernetes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dependencies
1.13+
Usage
make help
for available targetsmake
to scaffold a local kubebuilder project and deploy to a local kind cluster (idempotent).KUBEBUILDER_RESOURCES
variable and then runmake
to scaffold and deploy them to the local kind cluster.make
after making changes to controller source code to update deployed controllermake clean
(idempotent) to remove all artifacts created from runningmake
.