Kubernetes-Operator篇-03-kubebuilder的Makefile文件熟悉

1、Makefile简介

Makefile 是一种用于自动化构建软件项目的文件。它通常用于管理和执行编译、链接、测试等一系列任务,以提高开发效率。

1.1 目标与依赖

1.1.1目标(Targets)

  • 代表一个任务或一个文件的生成结果。例如,编译生成的可执行文件、库文件等都可以是目标。
  • 常见的目标有 “all”(表示构建整个项目)、“clean”(用于清理生成的文件)等。

1.1.2 依赖(Dependencies)

  • 目标所依赖的其他文件或目标。只有当依赖发生变化时,才会重新执行生成目标的命令。
  • 例如,一个可执行文件可能依赖于多个源文件和库文件。

1.2 规则与命令

1.2.1 规则(Rules)

  • 描述了如何从依赖生成目标。通常由目标、依赖和命令三部分组成。
  • 格式一般为:target: dependencies,接着是命令部分,每行命令前面必须以制表符(Tab)开头。

1.2.2 命令(Commands)

  • 用于执行生成目标的具体操作。可以是编译器命令、链接器命令、文件复制命令等。
  • 例如,编译 C 语言源文件的命令可能是gcc -o target source.c。

1.3 变量与函数

1.3.1 变量(Variables)

  • 可以定义和使用变量来存储常用的值,如编译器名称、编译选项、源文件列表等。
  • 变量定义方式为VARIABLE = value,使用时用$(VARIABLE)。

1.3.2 函数(Functions)

  • Makefile 提供了一些内置函数,可以进行字符串处理、文件操作等。
  • 例如,$(wildcard *.c)可以获取当前目录下所有的 C 语言源文件。

1.4 优势

1.4.1 自动化构建

  • 可以自动执行一系列构建步骤,减少手动操作和错误。
  • 当源文件发生变化时,只重新构建受影响的部分,提高构建效率。

1.4.2 可重复性

确保在不同的环境中都能以相同的方式构建项目。

1.4.3 易于维护

项目的构建过程集中在一个文件中,便于修改和管理。

2、kubebuilder makefile

2.1 kubebuilder 项目makefile

一个kubebuilder创建的operator项目的makefile文件内容:

# Image URL to use all building/pushing image targets
IMG ?= controller:latest
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.31.0

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

# CONTAINER_TOOL defines the container tool to be used for building images.
# Be aware that the target commands are only tested with Docker which is
# scaffolded by default. However, you might want to replace it to use other
# tools. (i.e. podman)
CONTAINER_TOOL ?= docker

# Setting SHELL to bash allows bash commands to be executed by recipes.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

.PHONY: all
all: build

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk command is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

.PHONY: help
help: ## Display this help.
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Development

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
	$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
	$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

.PHONY: fmt
fmt: ## Run go fmt against code.
	go fmt ./...

.PHONY: vet
vet: ## Run go vet against code.
	go vet ./...

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out

# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
.PHONY: test-e2e  # Run the e2e tests against a Kind k8s instance that is spun up.
test-e2e:
	go test ./test/e2e/ -v -ginkgo.v

.PHONY: lint
lint: golangci-lint ## Run golangci-lint linter
	$(GOLANGCI_LINT) run

.PHONY: lint-fix
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
	$(GOLANGCI_LINT) run --fix

##@ Build

.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
	go build -o bin/manager cmd/main.go

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
	go run ./cmd/main.go

# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: ## Build docker image with the manager.
	$(CONTAINER_TOOL) build -t ${IMG} .

.PHONY: docker-push
docker-push: ## Push docker image with the manager.
	$(CONTAINER_TOOL) push ${IMG}

# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
docker-buildx: ## Build and push docker image for the manager for cross-platform support
	# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
	sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
	- $(CONTAINER_TOOL) buildx create --name myapp-operator-builder
	$(CONTAINER_TOOL) buildx use myapp-operator-builder
	- $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
	- $(CONTAINER_TOOL) buildx rm myapp-operator-builder
	rm Dockerfile.cross

.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
	mkdir -p dist
	cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
	$(KUSTOMIZE) build config/default > dist/install.yaml

##@ Deployment

ifndef ignore-not-found
  ignore-not-found = false
endif

.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
	$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

.PHONY: uninstall
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
	$(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
	cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
	$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -

.PHONY: undeploy
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
	$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

##@ Dependencies

## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
	mkdir -p $(LOCALBIN)

## Tool Binaries
KUBECTL ?= kubectl
KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint

## Tool Versions
KUSTOMIZE_VERSION ?= v5.4.3
CONTROLLER_TOOLS_VERSION ?= v0.16.1
ENVTEST_VERSION ?= release-0.19
GOLANGCI_LINT_VERSION ?= v1.59.1

.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
$(KUSTOMIZE): $(LOCALBIN)
	$(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION))

.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
$(CONTROLLER_GEN): $(LOCALBIN)
	$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION))

.PHONY: envtest
envtest: $(ENVTEST) ## Download setup-envtest locally if necessary.
$(ENVTEST): $(LOCALBIN)
	$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION))

.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
	$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary
# $2 - package url which can be installed
# $3 - specific version of package
define go-install-tool
@[ -f "$(1)-$(3)" ] || { \
set -e; \
package=$(2)@$(3) ;\
echo "Downloading $${package}" ;\
rm -f $(1) || true ;\
GOBIN=$(LOCALBIN) go install $${package} ;\
mv $(1) $(1)-$(3) ;\
} ;\
ln -sf $(1)-$(3) $(1)
endef

2.2 变量定义部分

2.2.1 IMG(定义构建和推送Docker镜像的目标镜像URL)

# Image URL to use all building/pushing image targets
IMG ?= controller:latest

作用:定义构建和推送Docker镜像的目标镜像URL
解释:如果没有在命令中指定IMG,则默认值为controller:latest

2.2.2 ENVTEST_K8S_VERSION(定义envtest工具下载的Kubernetes资产版本)

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.31.0

作用:定义envtest工具下载的Kubernetes资产版本
解释:envtest是一个用于测试的工具,这个变量制定了要下载的Kubernetes版本。

2.2.3 GOBIN(当前使用的Go的安装路径)

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

作用:获取当前使用的Go的安装路径
解释:如果GONBIN环境变量未设置,则使用GOPATCH/bin作为默认路径;否则使用GOBIN的值。

2.2.4 CONTAINER_TOOL(用于构建镜像的容器工具)

# CONTAINER_TOOL defines the container tool to be used for building images.
# Be aware that the target commands are only tested with Docker which is
# scaffolded by default. However, you might want to replace it to use other
# tools. (i.e. podman)
CONTAINER_TOOL ?= docker

作用:定义用于构建镜像的容器工具
解释:默认值为docker,但是可以替换为其他工具,例如podman

2.2.5 SHELL 和 .SHELLFLAGS(设置Makefile使用的shell和shell选项)

# Setting SHELL to bash allows bash commands to be executed by recipes.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

作用:设置Makefile使用的shell和shell选项
解释:

  • SHELL设置为/usr/bin/env bash -o pipefail
  • .SHELLFLAGS 设置为-ec,表示shell应该立即退出并在任何命令失败时报告错误

2.3 目标定义部分

2.3.1 通用目标

2.3.1.1 all(定义默认目标,调用build目标)
.PHONY: all
all: build

作用:定义默认目标,调用build目标
解释:当运行make时,如果没有指定目标。默认会执行build目标。

2.3.1.2 help(显示帮助信息)
.PHONY: help
help: ## Display this help.
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

作用:显示帮助信息
解释:使用awk命令解析Makefile,提取每个目标的描述,并按类别组织显示。##@表示类别,##表示目标描述

2.3.2 开发目标

2.3.2.1 manifests(生成WebhookConfiguration、ClusterRole和CustomResourceDefinition 对象)
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
	$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases

作用:生成WebhookConfiguration、ClusterRole和CustomResourceDefinition 对象
解释:使用controller-gen工具生成必要的Kubernetes资源文件,并保存到config/crd/bases目录

2.3.2.2 generate(生成包含DeepCopy、DeepCopyInto, 和DeepCopyObject方法实现的代码。)
.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
	$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

作用:生成包含DeepCopy、DeepCopyInto, 和DeepCopyObject方法实现的代码。
解释:使用controller-gen工具生成GO代码,这些代码自动生成对象的深拷贝方法。

2.3.2.3 fmt(格式化代码)
.PHONY: fmt
fmt: ## Run go fmt against code.
	go fmt ./...

作用:格式化代码
解释:使用go fmt命令格式化项目中的所有Go代码

2.3.2.4 vet(检查代码中的潜在问题)
.PHONY: vet
vet: ## Run go vet against code.
	go vet ./...

作用:检查代码中的潜在问题
解释:使用go vet命令检查项目中的所有Go代码,查找可能的问题。

2.3.2.5 test(运行测试)
.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out

作用:运行测试
解释:

  • 先运行manifests、generate、fmt和vet目标
  • 使用envtest工具设置环境变量KUBEBUILDER_ASSETS,然后运行项目中的所有测试(排除e2e测试)
2.3.2.6 test-e2e(运行端到端测试)
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
.PHONY: test-e2e  # Run the e2e tests against a Kind k8s instance that is spun up.
test-e2e:
	go test ./test/e2e/ -v -ginkgo.v

作用:运行端到端测试
解释:使用go test命令运行test/e2e目录中的端到端测试,并启动详细输出。

2.3.2.7 lint(运行代码风格检查)
.PHONY: lint
lint: golangci-lint ## Run golangci-lint linter
	$(GOLANGCI_LINT) run

作用:运行代码风格检查
解释:使用golangci-lint工具运行代码风格检查

2.3.2.8 lint-fix (运行代码风格检查并自动修复问题)
.PHONY: lint-fix
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
	$(GOLANGCI_LINT) run --fix

作用:运行代码风格检查并自动修复问题
解释:使用golangci-lint工具运行代码风格检查,并使用–fix选项自动修复发现的问题。

2.3.3 构建目标

2.3.3.1 build(构建controller的二进制文件)
.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
	go build -o bin/manager cmd/main.go

作用:构建controller的二进制文件
解释:

  • 先运行manifests、generate、fmt和vet目标
  • 使用go build命令编译cmd/main.go文件,并将生成的二进制文件保存到bin/manager。
2.3.3.2 run(在主机上运行controller)
.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
	go run ./cmd/main.go

作用:在主机上运行controller
解释:

  • 先运行manifests、generate、fmt和vet目标
  • 使用go run命令运行cmd/main.go文件
2.3.3.3 docker-build(构建Docker镜像)
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: ## Build docker image with the manager.
	$(CONTAINER_TOOL) build -t ${IMG} .

作用:构建Docker镜像
解释:使用CONTAINER_TOOL(默认为docker)构建docker镜像,并使用IMG变量指定镜像名称和标签

2.3.3.4 docker-push(推送Docker镜像)
.PHONY: docker-push
docker-push: ## Push docker image with the manager.
	$(CONTAINER_TOOL) push ${IMG}

作用:推送Docker镜像
解释:使用CONTAINER_TOOL(默认为docker)推送构建好的Docker镜像到指定的仓库

2.3.3.5 docker-buildx(构建并推送多平台支持的Docker镜像)
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
docker-buildx: ## Build and push docker image for the manager for cross-platform support
	# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
	sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
	- $(CONTAINER_TOOL) buildx create --name myapp-operator-builder
	$(CONTAINER_TOOL) buildx use myapp-operator-builder
	- $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
	- $(CONTAINER_TOOL) buildx rm myapp-operator-builder
	rm Dockerfile.cross

作用:构建并推送多平台支持的Docker镜像
解释:

  • 使用sed命令复制现有的Dockerfile并插入--platform=${BUILDPLATFORM}选项,生成Dockerfile.cross
  • 创建一个名为myapp-builder的构建器
  • 使用buildx构建并推送多平台镜像
  • 删除构建器和临时生成的Dockerfile.cross
2.3.3.6 docker-installer(生成包含CRDs和部署的合并YAML文件)
.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
	mkdir -p dist
	cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
	$(KUSTOMIZE) build config/default > dist/install.yaml

作用:生成包含CRDs和部署的合并YAML文件
解释:

  • 创建dist目录
  • 使用kustomize工具设置controller镜像为IMG
  • 使用kustomize构建config/default目录中的资源,并保存到dist/install.yaml

2.3.4 部署目标

2.3.4.1 install(安装CRDs到Kubernetes集群)
.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
	$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

作用:安装CRDs到Kubernetes集群
解释:

  • 先运行manifests和kustomize目标
  • 使用kustomize 构建config/crd目录中的资源,并使用kubectl将其应用到集群。
2.3.4.2 uninstall(从Kubernetes集群卸载CRDs)
.PHONY: uninstall
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
	$(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

作用:从Kubernetes集群卸载CRDs
解释:

  • 先运行manifests和kustomize目标
  • 使用kustomize 构建config/crd目录中的资源,并使用kubectl将其从集群中删除,可以通过ignore-not-found=true忽略资源未找到的错误
2.3.4.3 deploy(部署controller到Kubernetes集群)
.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
	cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
	$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -

作用:部署controller到Kubernetes集群
解释:

  • 先运行manifests和kustomize目标
  • 使用kustomize设置controller镜像为IMG
  • 使用kustomize构建config/default目录中的资源,并使用kubectl将其应用到集群
2.3.4.4 undeploy(从Kubernetes集群中卸载Controller)
.PHONY: undeploy
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
	$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

作用:从Kubernetes集群中卸载Controller
解释:使用kustomize 构建config/default目录中的资源,并使用kubectl将其从集群中删除。可以通过ignore-not-found=true忽略资源未找到的错误

2.3.5 依赖目标

2.3.5.1 ignore-not-found(定义ignore-not-found变量,默认值为false)
ifndef ignore-not-found
  ignore-not-found = false
endif

作用:定义ignore-not-found变量,默认值为false
解释:如果命令行中未指定ignore-not-found,则默认值为false

2.3.5.2 LOCALBIN(定义本地二进制文件的安装目录)
## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
	mkdir -p $(LOCALBIN)

作用:定义本地二进制文件的安装目录,默认为当前目录下的bin目录
解释:如果LOCALBIN未设置,则默认为$(shell pwd)/bin。如果LOCALBIN目录不存在,则创建它。

2.3.5.3 工具二进制文件(定义各种工具的路径和默认值)
## Tool Binaries
KUBECTL ?= kubectl
KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint

作用:定义各种工具的路径和默认值
解释:

  • KUBECTL:默认为kubectl
  • KUSTOMIZE:默认为$(LOCALBIN)/kustomize
  • CONTROLLER_GEN:默认为$(LOCALBIN)/controller-gen
  • ENVTEST:默认为$(LOCALBIN)/setup-envtest
  • GOLANGCI_LINT: 默认为$(LOCALBIN)/golangci-lint
2.3.5.4 工具版本(定义各个工具的版本)
## Tool Versions
KUSTOMIZE_VERSION ?= v5.4.3
CONTROLLER_TOOLS_VERSION ?= v0.16.1
ENVTEST_VERSION ?= release-0.19
GOLANGCI_LINT_VERSION ?= v1.59.1

作用:定义各个工具的版本
解释:

  • KUSTOMIZE_VERSION:默认为v5.4.3
  • CONTROLLER_TOOLS_VERSION:默认为v0.16.1
  • ENVTEST_VERSION:默认为release-0.19
  • GOLANGCI_LINT_VERSION:默认为v1.59.1
2.3.5.5 kustomize(下载kustomize工具)
.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
$(KUSTOMIZE): $(LOCALBIN)
	$(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION))

作用:下载kustomize工具(如有必要)
解释:如果kustomize文件不存在,则调用 go-install-tool函数下载kustomize工具

2.3.5.6 controller-gen(下载controller-gen工具)
.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
$(CONTROLLER_GEN): $(LOCALBIN)
	$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION))

作用:下载controller-gen工具(如有必要)
解释:如果$(CONTROLLER_GEN)文件不存在,则调用 go-install-tool函数下载controller-gen工具

2.3.5.7 envtest(下载setup-envtest工具)
.PHONY: envtest
envtest: $(ENVTEST) ## Download setup-envtest locally if necessary.
$(ENVTEST): $(LOCALBIN)
	$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION))

作用:下载setup-envtest工具(如有必要)
解释:如果$(ENVTEST)文件不存在,则调用go-install-tool函数下载setup-envtes工具

2.3.5.8 golangci-lint(下载golangci-lint工具)
.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
	$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))

作用:下载golangci-lint工具(如有必要)
解释:如果$(GOLANGCI_LINT)文件不存在,则调用go-install-tool函数下载golangci-lint工具。

2.4 自定义函数

2.4.1 go-install-tool(下载并安装指定的Go包)

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary
# $2 - package url which can be installed
# $3 - specific version of package
define go-install-tool
@[ -f "$(1)-$(3)" ] || { \
set -e; \
package=$(2)@$(3) ;\
echo "Downloading $${package}" ;\
rm -f $(1) || true ;\
GOBIN=$(LOCALBIN) go install $${package} ;\
mv $(1) $(1)-$(3) ;\
} ;\
ln -sf $(1)-$(3) $(1)
endef

作用:下载并安装指定的Go包
解释:

  • $1:目标路径和二进制文件名
  • $2:包的URL
  • $3:包的具体版本
  • 如果目标文件$(1)~$(3)不存在,则执行以下步骤
  • 设置set -e,确保任何命令执行失败立即退出
  • 设置package变量为包的URL和版本
  • 输出下载信息
  • 删除旧的二进制文件(如果存在)
  • 使用go install命令安装包,并将二进制文件保存在LOCALBIN目录
  • 将生成的二进制文件重命令为$(1)-$(3)
  • 最后创建一个符号链接,指向$(1)-$(3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值