1.为什么要用operator
kubernetes对管理无状态的应用有很好的优势,但对于有状态应用,kubernetes有很大的不足。像数据库、缓存等在进行升级和弹性扩缩容时,不能很好的将现有的数据配置到新的实例上。Operator就是为了解决上述问题而出现的,其目的是能够正对不同应用(有状态)的特点,开发特定的控制器,来监听Kubernetes API,在实例创建,伸缩,死亡等各个生命周期中做相应的处理来保证有状态应用中的数据连续性。
2.operator的原理
Operator 实际上作为kubernetes自定义扩展资源注册到controller-manager,通过list and watch的方式监听对应资源的变化,然后在周期内的各个环节做相应的协调处理。所谓的处理就是operator实现由状态的应用的核心部分,当然不同应用其处理的方式也不同。
3.operator开发
operator-sdk(来自于CoreOS) 和 Kubebuilder (来自于kubernetes) 是目前开发operator两种常用的SDK,或者叫framework,不管是哪种方式只是规范了步骤和一些必要的元素,生成相应的模板而已,实际上如果自己熟悉的话也可以按照自己的方式写,主要满足controller-manager中的controller要求就行。
3.1 operator-sdk
OPERATOR-SDK: https://github.com/operator-framework/operator-sdk
- 开发环境的安装
3.2 Kubebuilder
kubebuilder: https://github.com/kubernetes-sigs/kubebuilder
- 开发环境的安装
golang:下载解压,配置环境变量即可
Kubebuilder:下载解压,配置环境变量即可
export GOROOT=/data/go
export GOPATH=/data/work/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
export KBPATH=/data/kubebuilder
export PATH=$PATH:$KBPATH/bin
- 开发自己的operator
#1.在golang的工作目录src下创建自己的工程,工程域名和模块名称
[root@node3 src]# mkdir -p cloud.io/etcd-op
#2.初始化工程依赖,注意开启 export GO111MODULE=on
[root@node3 src]# cd cloud.io/etcd-op/
[root@node3 etcd-op]# export GO111MODULE=on
[root@node3 etcd-op]# go mod init etcd-op
go: creating new go.mod: module etcd-op
#3.初始化operator工程,此处会有包下载不了的问题,见后续QA
[root@node3 etcd-op]# kubebuilder init --domain cloud.io
go mod tidy
此处省略n行...
#在实际创建过程中由于golang很多包无妨下载,需要在go.mod中replace,文件内容贴在文章末尾
[root@node3 etcd-op]# kubebuilder create api --group etcd --version v1 --kind EtcdCluster
Create Resource [y/n]
y
Create Controller [y/n]
y
Writing scaffold for you to edit...
此处省略n行...
go build -o bin/manager main.go
- 生成的工程结构
[root@node3 src]# tree cloud.io/etcd-op/
cloud.io/etcd-op/
├── api
│ └── v1
│ ├── etcdcluster_types.go # ①定义EtcdOp的数据结构,对应部署yaml中的属性,同时注册结构体
│ ├── groupversion_info.go # 定义Group和version信息
│ └── zz_generated.deepcopy.go # 封装了①中结构体的相关方法,主要是用于深度拷贝
├── bin
│ └── manager # 编译生成的可执行文件,执行包含三个参数。是否启用选主(-enable-leader-election);kubecofnig路径(-kubeconfig)运行在集群外是需要指定;组件指标接口地址(-metrics-addr)
├── config
│ ├── certmanager # 整个目录下的内容用于为 TLS(https)双向认证机制签名生成证书
│ │ ├── certificate.yaml
│ │ ├── kustomization.yaml
│ │ └── kustomizeconfig.yaml
│ ├── crd # 用于将该工程注册到k8s使之成为controller-manager中的一个controller,即CRD,但是仅仅是结构
│ │ ├── kustomization.yaml
│ │ ├── kustomizeconfig.yaml
│ │ └── patches
│ │ ├── cainjection_in_etcdclusters.yaml
│ │ └── webhook_in_etcdclusters.yaml
│ ├── default # 是对crd,rbac,manager三个目录的整合,及其本身需要的配置
│ │ ├── kustomization.yaml
│ │ ├── manager_auth_proxy_patch.yaml
│ │ ├── manager_image_patch.yaml
│ │ ├── manager_prometheus_metrics_patch.yaml
│ │ ├── manager_webhook_patch.yaml
│ │ └── webhookcainjection_patch.yaml
│ ├── manager # 该工程实际的部署实例
│ │ ├── kustomization.yaml
│ │ └── manager.yaml
│ ├── rbac # 默认需要的ClusterRole,ServiceAccount ,绑定关系ClusterRoleBinding,及其具体需要的权限
│ │ ├── 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
│ ├── samples # 实际部署的demo
│ │ └── etcd_v1_etcdcluster.yaml
│ └── webhook # k8s中需要经过的webhooks拦截器
│ ├── kustomization.yaml
│ ├── kustomizeconfig.yaml
│ └── service.yaml
├── controllers
│ ├── etcdcluster_controller.go ## ②具体的执行控制逻辑,结合上面① etcdop_types.go ,在Reconcile中完成执行逻辑,
│ └── suite_test.go # 测试单元
├── Dockerfile # 为该控制器生成镜像的配置文件
├── go.mod # 依赖golang包
├── go.sum
├── hack
│ └── boilerplate.go.txt
├── main.go # 执行入口
├── Makefile # 通过make编译,其中包含上述的镜像打包,安装部署的一系列流程
└── PROJECT
- 编译打镜像
[root@node3 etcd-op]# go build -o bin/manager main.go
[root@node3 etcd-op]# docker build -t controller:latest .
#安装CRD
[root@node3 etcd-op]# kubectl apply -f config/crd/bases
customresourcedefinition.apiextensions.k8s.io/etcdclusters.etcd.cloud.io configured
[root@node3 etcd-op]# kubectl get crd
NAME CREATED AT
etcdclusters.etcd.cloud.io 2019-08-14T08:27:58Z
//TODO:
4.QA
Q:安装golangci-lint
A: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin version
go.mod文件中replace内容
module cloud.io/etcd-op
go 1.12
require (
github.com/go-logr/logr v0.1.0
github.com/gogo/protobuf v1.2.1 // indirect
github.com/json-iterator/go v1.1.7 // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/onsi/ginkgo v1.6.0
github.com/onsi/gomega v1.4.2
github.com/spf13/pflag v1.0.3 // indirect
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
sigs.k8s.io/controller-runtime v0.0.0-00010101000000-000000000000
)
replace (
cloud.google.com/go => github.com/googleapis/google-cloud-go v0.26.0
go.uber.org/atomic => github.com/uber-go/atomic v1.4.0
go.uber.org/zap => github.com/uber-go/zap v1.10.0
golang.org/x/crypto => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac
golang.org/x/net => github.com/golang/net v0.0.0-20180906233101-161cd47e91fd
golang.org/x/oauth2 => github.com/golang/oauth2 v0.0.0-20180821212333-d2e6202438be
golang.org/x/sync => github.com/golang/sync v0.0.0-20190423024810-112230192c58
golang.org/x/sys => github.com/golang/sys v0.0.0-20180909124046-d0be0721c37e
golang.org/x/text => github.com/golang/text v0.3.0
golang.org/x/time => github.com/golang/time v0.0.0-20180412165947-fbb02b2291d2
golang.org/x/tools => github.com/golang/tools v0.0.0-20180221164845-07fd8470d635
google.golang.org/appengine => github.com/golang/appengine v1.1.0
k8s.io/api => github.com/kubernetes/api v0.0.0-20190409021203-6e4e0e4f393b
k8s.io/apiextensions-apiserver => github.com/kubernetes/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8
k8s.io/apimachinery => github.com/kubernetes/apimachinery v0.0.0-20190404173353-6a84e37a896d
k8s.io/client-go => github.com/kubernetes/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
k8s.io/klog => github.com/kubernetes/klog v0.3.0
k8s.io/kube-openapi => github.com/kubernetes/kube-openapi v0.0.0-20180731170545-e3762e86a74c
k8s.io/utils => github.com/kubernetes/utils v0.0.0-20190506122338-8fab8cb257d5
sigs.k8s.io/controller-runtime => github.com/kubernetes-sigs/controller-runtime v0.2.0-beta.4
sigs.k8s.io/testing_frameworks => github.com/kubernetes-sigs/testing_frameworks v0.1.1
sigs.k8s.io/yaml => github.com/kubernetes-sigs/yaml v1.1.0
)
有疑问加站长微信联系(非本文作者)