概述
用于在Go中快速构建和发布Kubernetes API的SDK 它建立在用于构建核心Kubernetes API的规范技术之上,以提供简化的抽象来减少开发工作。
功能
- 使用包括基本结构的项目初始化
-
- 在规范版本中获取包依赖性。
-
- 主程序入口点
-
- 用于格式化,生成,测试和构建的Makefile
-
- 用于构建容器映像的Dockerfile
- 脚手架API
-
- 资源(模型)定义
-
- 控制器实现
-
- 资源和控制器的集成测试
-
- CRD定义
- 用于实现API的简单抽象
-
- Controllers
-
- Resource Schema Validation
-
- Validating Webhooks
- 用于发布API以安装到集群中的工件
-
- Namespace
-
- CRDs
-
- RBAC Roles and RoleBindings
-
- Controller StatefulSet + Service
- API参考文档和示例
运行流程
client-go给的一个workQueue的例子
- 把代码分为通用的Common part和Special Part
-
- 前者是client-go的基本流程
-
- 后者部分是controller自身逻辑部分
安装和使用
安装
源码安装
git clone https://github.com/kubernetes-sigs/kubebuilder
cd kubebuilder
make build
cp bin/kubebuilder $GOPATH/bin
二进制安装
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/
# extract the archive
sudo mv /tmp/kubebuilder_2.0.0-beta.0_${os}_${arch} /usr/local/kubebuilder
# update your PATH to include /usr/local/kubebuilder/bin
export PATH=$PATH:/usr/local/kubebuilder/bin
辅助工具 kustomize
go install sigs.k8s.io/kustomize
使用
创建新API
先切换目录,kubebuilder 这点不好,不自动创建一个专用目录
mkdir -p $GOPATH/src/github.com/crdAPIDemo/
cd $GOPATH/src/github.com/crdAPIDemo/
初始化项目目录
export GO111MODULE="on"
export GOPROXY=https://goproxy.cn
kubebuilder init --domain k8s.io --license apache2 --owner "The Kubernetes Authors"
API创建
- 创建一个名为Sloop的新API
kubebuilder create api --group ships --version v1beta1 --kind Sloop
运行
make install & make run
启动一个实例
- config/samples 下有示例配置可用
kubectl apply -f config/samples/ships_v1beta1_sloop.yaml
可通过
kubectl get crd
查看
执行的内容
- yaml内容
apiVersion: ships.k8s.io/v1beta1
kind: Sloop
metadata:
name: sloop-sample
spec:
# Add fields here
foo: bar
仅将yaml存入etcd controller监听到事件时,没有做任何动作
- 部署 controller
make docker-build docker-push IMG=fanux/ships-controller // 执行总失败,提示有git拉取不到
make deploy // 但忽略上一步的失败,本操作可以执行
开发
编辑原yaml文件内容(config/samples/ships_v1beta1_sloop.yaml )
apiVersion: ships.k8s.io/v1beta1
kind: Sloop
metadata:
name: sloop-sample
spec:
# Add fields here
foo: bar
cpu: "1" // 增加内容
memory: "500M" // 增加内容
生效
kubectl apply -f config/samples/
查看
kubectl get Sloop.ships.k8s.io -o yaml
新的CRD定义内容
apiVersion: v1
items:
- apiVersion: ships.k8s.io/v1beta1
kind: Sloop
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"ships.k8s.io/v1beta1","kind":"Sloop","metadata":{"annotations":{},"name":"sloop-sample","namespace":"default"},"spec":{"cpu":"1","foo":"bar","memory":"500M"}}
creationTimestamp: "2020-01-19T09:07:41Z"
generation: 2
name: sloop-sample
namespace: default
resourceVersion: "150773"
selfLink: /apis/ships.k8s.io/v1beta1/namespaces/default/sloops/sloop-sample
uid: 6a715921-86af-4dae-b25d-be193d64c4b2
spec:
cpu: "1" //变化内容,已生效
foo: bar
memory: 500M //变化内容,已生效
kind: List
metadata:
resourceVersion: ""
selfLink: "
Reconcile 唯一需要实现的接口
作用
-
CRD只是定义资源,controller才是实现
-
- controller把轮训与事件监听都封装在这一个接口里了.你不需要关心怎么事件监听的
-
controller内部
-
- CURD及其他逻辑,都由Reconcile()来做分发
代码示例
(controllers/sloop_controller.go)
- 原内容
package controllers
import (
"context"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
shipsv1beta1 "github.com/crdAPIDemo/api/v1beta1"
)
// SloopReconciler reconciles a Sloop object
type SloopReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
}
// +kubebuilder:rbac:groups=ships.k8s.io,resources=sloops,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=ships.k8s.io,resources=sloops/status,verbs=get;update;patch
func (r *SloopReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
_ = context.Background()
_ = r.Log.WithValues("sloop", req.NamespacedName)
return ctrl.Result{}, nil
}
func (r *SloopReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&shipsv1beta1.Sloop{}).
Complete(r)
}
- 修改为
package controllers
import (
"context"
"fmt"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
shipsv1beta1 "github.com/crdAPIDemo/api/v1beta1"
)
// SloopReconciler reconciles a Sloop object
type SloopReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
}
// +kubebuilder:rbac:groups=ships.k8s.io,resources=sloops,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=ships.k8s.io,resources=sloops/status,verbs=get;update;patch
func (r *SloopReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
ctx := context.Background()
log := r.Log.WithValues("sloop", req.NamespacedName)
// your logic here
vm := &shipsv1beta1.Sloop{}
if err := r.Get(ctx, req.NamespacedName, vm); err != nil {
log.Info("unable to fetch vm : %v", err)
} else {
fmt.Println("INFO:", vm.Spec.CPU, vm.Spec.Memory)
}
return ctrl.Result{}, nil
}
func (r *SloopReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&shipsv1beta1.Sloop{}).
Complete(r)
}
- 编译和使用
make & make install & make run
kubectl apply -f config/samples // 会打印出日志
来源:oschina
链接:https://my.oschina.net/kakablue/blog/3280395