当前位置:网站首页>基於Kubebuilder開發Operator(入門使用)

基於Kubebuilder開發Operator(入門使用)

2022-06-26 16:13:00 chenxy02

原文地址:使用kubebuilder 理解k8s crd - 知乎

理解k8s的crd需要先理解k8s的controller模式

 

  • 比如kube-controller-manager中的deployment控制器,在初始化的時候就會傳入要監聽Deployments、ReplicaSet和pod的三個informer對象
  • 首先list一下對象到本地緩存,同時watch對象的變更,等於增量更新
func startDeploymentController(ctx ControllerContext) (controller.Interface, bool, error) {
    dc, err := deployment.NewDeploymentController(
        ctx.InformerFactory.Apps().V1().Deployments(),
        ctx.InformerFactory.Apps().V1().ReplicaSets(),
        ctx.InformerFactory.Core().V1().Pods(),
        ctx.ClientBuilder.ClientOrDie("deployment-controller"),
    )
    if err != nil {
        return nil, true, fmt.Errorf("error creating Deployment controller: %v", err)
    }
    go dc.Run(int(ctx.ComponentConfig.DeploymentController.ConcurrentDeploymentSyncs), ctx.Stop)
    return nil, true, nil
}
  • 然後內部會做sync其實就是Reconcile loop, 即調諧循環——說白了就是對比對象的actualState和expectState的差异,執行對應的增删操作 比如deployment中擴縮容操作

  • 計算差值,可以創建出的 pod 數减去所有活躍 rs的副本數之和
    • 如果差值為正,說明需要擴容,並且從ReplicaSetsBySizeNewer排序看是按照從新到舊擴容
    • 如果差值為負,說明需要縮容,並且從ReplicaSetsBySizeOlder排序看是按照從舊到新縮容
  • 算差值如下

deploymentReplicasToAdd := allowedSize - allRSsReplicas

var scalingOperation string
switch {
case deploymentReplicasToAdd > 0:
    sort.Sort(controller.ReplicaSetsBySizeNewer(allRSs))
    scalingOperation = "up"
case deploymentReplicasToAdd < 0:
    sort.Sort(controller.ReplicaSetsBySizeOlder(allRSs))
    scalingOperation = "down"
}

理解了k8s的controller模式後,crd就是你自己寫的controller

  • 監聽並處理你自己定義的資源,
  • 下面這張圖很形象

安裝 Kubebuilder

wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v3.1.0/kubebuilder_linux_amd64
mv kubebuilder_linux_amd64  /usr/local/bin/kubebuilder

創建脚手架工程

  • 創建一個目錄,並且指定這個目錄為代碼倉庫
mkdir -p ~/projects/guestbook
cd ~/projects/guestbook
kubebuilder init --domain my.domain --repo my.domain/guestbook
  • 查看這個目錄下的文件結果
[[email protected] guestbook]# tree
.
├── config
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   └── rbac
│       ├── auth_proxy_client_clusterrole.yaml
│       ├── auth_proxy_role_binding.yaml
│       ├── auth_proxy_role.yaml
│       ├── auth_proxy_service.yaml
│       ├── kustomization.yaml
│       ├── leader_election_role_binding.yaml
│       ├── leader_election_role.yaml
│       ├── role_binding.yaml
│       └── service_account.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

6 directories, 24 files

創建api

  • 創建一個名為 webapp/v1的 API (group/version)
  • 創建新的類型 Guestbook
kubebuilder create api --group webapp --version v1 --kind Guestbook
  • 追踪結果,發現又多了很多文件 ,其中api/v1/guestbook_types.go代錶定義API的地方 ,controllers/guestbook_controller.go代錶調諧的邏輯
[[email protected] guestbook]# tree
.
├── api
│   └── v1
│       ├── groupversion_info.go
│       ├── guestbook_types.go
│       └── zz_generated.deepcopy.go
├── bin
│   └── controller-gen
├── config
│   ├── crd
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches
│   │       ├── cainjection_in_guestbooks.yaml
│   │       └── webhook_in_guestbooks.yaml
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   ├── rbac
│   │   ├── auth_proxy_client_clusterrole.yaml
│   │   ├── auth_proxy_role_binding.yaml
│   │   ├── auth_proxy_role.yaml
│   │   ├── auth_proxy_service.yaml
│   │   ├── guestbook_editor_role.yaml
│   │   ├── guestbook_viewer_role.yaml
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── role_binding.yaml
│   │   └── service_account.yaml
│   └── samples
│       └── webapp_v1_guestbook.yaml
├── controllers
│   ├── guestbook_controller.go
│   └── suite_test.go
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

13 directories, 37 files
  • 在調諧函數中添加打印日志,比特於 controller/guestbook_controller.go
func (r *GuestbookReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    _ = log.FromContext(ctx)

    // your logic here
    log.FromContext(ctx).Info("print_req", "req", req.String())
    return ctrl.Result{}, nil
}

部署到k8s集群中

  • 編譯打鏡像
make docker-build IMG=guestbook:v1.0     # 實際執行 docker build -t guestbook:v1.0 .
  • 一般我們需要修改項目裏的 dockerfile,給 go 設置proxy代理,這樣 go mod download時不至於超時連不上

  •  然後需要將鏡像手動推送到本地倉庫中,如果底層的runtime是ctr的話 需要docker save出來並導入
docker save guestbook:v1.0 > a.tar
ctr --namespace k8s.io images import a.tar
  • 因為項目中用到了 kube-rbac-proxy,這個鏡像也可能出現下載不到的問題,需要自己手動處理一下,如下:

  •  現在部署crd
make deploy IMG=guestbook:v1.0 #實際執行 kustomize build config/default | kubectl apply -f -
  • 檢查在guestbook-system ns 下部署的對象

  •  檢查api-resources

  • 部署guestbook
kubectl apply -f config/samples/webapp_v1_guestbook.yaml
# guestbook.webapp.my.domain/guestbook-cxy created
  •  查看crd中的日志可以看到調諧函數中打印

 

原网站

版权声明
本文为[chenxy02]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206261607015522.html