使用Kube-builder构建K8S Operator

1. 准备工作

1.1 安装kubebuilder

https://github.com/kubernetes-sigs/kubebuilder

1
2
3
4
5
6
7
8
9
os=$(go env GOOS)
arch=$(go env GOARCH)

# download kubebuilder and extract it to tmp
curl -sL https://go.kubebuilder.io/dl/2.0.0-beta.0/${os}/${arch} | tar -xz -C /tmp/
# move to a long-term location and put it on your path
# (you'll need to set the KUBEBUILDER_ASSETS env var if you put it somewhere else)
mv /tmp/kubebuilder_2.0.0-beta.0_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin

1.2 安装kustomize

https://github.com/kubernetes-sigs/kustomize/blob/master/docs/INSTALL.md#installation

2. 名词解释

CRD: 自定义资源定义,Kubernetes中的资源类型。
CR: Custom Resource,对使用 CRD 创建出来的自定义资源的统称

3. 创建Operator项目

首先将使用自动配置创建一个项目,该项目在创建 CR 时不会触发任何资源生成。

3.1 初始化和创建API

创建的项目路径位于 $GOPATH/src/workspace/operator

在项目路径下使用下面的命令初始化项目。

1
$ kubebuilder init --domain app.com

在项目根目录下执行下面的命令创建 API。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ kubebuilder create api --group webapp --version v1 --kind Guestbook
Create Resource [y/n]
y
Create Controller [y/n]
y
Writing scaffold for you to edit...
api/v1/guestbook_types.go
controllers/guestbook_controller.go
Running make:
$ make
go: creating new go.mod: module tmp
go: found sigs.k8s.io/controller-tools/cmd/controller-gen in sigs.k8s.io/controller-tools v0.2.5
/Users/dongzezhao/go/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
go vet ./...
go build -o bin/manager main.go

API 创建完成后,在项目根目录下查看目录结构。

3.2 安装CRD

执行下面的命令安装 CRD

1
2
3
4
5
6
$ make install
go: creating new go.mod: module tmp
go: found sigs.k8s.io/controller-tools/cmd/controller-gen in sigs.k8s.io/controller-tools v0.2.5
/Users/dongzezhao/go/bin/controller-gen "crd:trivialVersions=true" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
kustomize build config/crd > crd.yaml
$ kubectl create -f crd.yaml

3.3 部署 controller

在开始部署 controller 之前,需要先检查 kubebuilder 自动生成的 YAML 文件。

有两种方式运行 controller:

  • 本地运行,用于调试
  • 部署到 Kubernetes 上运行,作为生产使用
3.3.1 本地运行 controller

在本地运行 controller,只需要执行下面的命令。

1
$ make run

将看到 controller 启动和运行时输出。

3.3.2 部署到 Kubernetes 集群上

执行下面的命令部署 controller 到 Kubernetes 上,这一步将会在本地构建 controller 的镜像,并推送到 DockerHub 上,然后在 Kubernetes 上部署 Deployment 资源。

1
2
make docker-build docker-push IMG=jimmysong/kubebuilder-example:latest
make deploy IMG=jimmysong/kubebuilder-example:latest

在初始化项目时,kubebuilder 会自动根据项目名称创建一个 Namespace,如本文中的 kubebuilder-example-system,查看 Deployment 对象和 Pod 资源。

3.4 创建 CR

Kubebuilder 在初始化项目的时候已生成了示例 CR,执行下面的命令部署 CR。

1
kubectl apply -f config/samples/webapp_v1_guestbook.yaml

执行下面的命令查看新创建的 CR。

1
$ kubectl get guestbooks.webapp.app.com guestbook-sample -o yaml

你将看到类似如下的输出:

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: webapp.app.com/v1
kind: Guestbook
metadata:
creationTimestamp: "2021-03-14T04:50:35Z"
generation: 1
name: guestbook-sample
namespace: default
resourceVersion: "5900377"
selfLink: /apis/webapp.app.com/v1/namespaces/default/guestbooks/guestbook-sample
uid: 26161131-866f-4db3-9fc2-2fa896fb6124
spec:
foo: bar

至此一个基本的 Operator 框架已经创建完成,但这个 Operator 只是修改了 etcd 中的数据而已,实际上什么事情也没做,因为我们没有在 Operator 中的增加业务逻辑。