Operator模式 #
一、Operator概述 #
Operator是Kubernetes的扩展模式,用于自动化管理复杂应用。
1.1 Operator概念 #
text
Operator组成
│
├── CRD (Custom Resource Definition)
│ └── 自定义资源定义
│
├── CR (Custom Resource)
│ └── 自定义资源实例
│
└── Controller
└── 控制器逻辑
1.2 Operator优势 #
| 优势 | 说明 |
|---|---|
| 自动化管理 | 自动化运维任务 |
| 声明式配置 | 声明期望状态 |
| 知识封装 | 封装运维知识 |
| 可扩展性 | 扩展Kubernetes |
二、CRD定义 #
2.1 创建CRD #
yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: applications.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
minimum: 1
maximum: 10
image:
type: string
version:
type: string
status:
type: object
properties:
availableReplicas:
type: integer
conditions:
type: array
items:
type: object
properties:
type:
type: string
status:
type: string
scope: Namespaced
names:
plural: applications
singular: application
kind: Application
shortNames:
- app
2.2 创建CR #
yaml
apiVersion: example.com/v1
kind: Application
metadata:
name: myapp
spec:
replicas: 3
image: nginx
version: "1.25"
2.3 查看CRD #
bash
# 查看CRD列表
kubectl get crd
# 查看CRD详情
kubectl describe crd applications.example.com
# 查看CR
kubectl get applications
kubectl get app
三、Controller开发 #
3.1 Controller架构 #
text
Controller架构
│
├── Informer
│ └── 监听资源变化
│
├── WorkQueue
│ └── 工作队列
│
├── Reconcile
│ └── 调谐逻辑
│
└── Cache
└── 资源缓存
3.2 使用kubebuilder创建Operator #
bash
# 安装kubebuilder
curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
# 创建项目
mkdir myoperator
cd myoperator
kubebuilder init --domain example.com --repo example.com/myoperator
# 创建API
kubebuilder create api --group example --version v1 --kind Application
# 安装CRD
make install
# 运行Controller
make run
3.3 Reconcile逻辑 #
go
// application_controller.go
func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := log.FromContext(ctx)
// 获取Application实例
var app examplev1.Application
if err := r.Get(ctx, req.NamespacedName, &app); err != nil {
log.Error(err, "unable to fetch Application")
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 检查Deployment是否存在
var deploy appsv1.Deployment
err := r.Get(ctx, req.NamespacedName, &deploy)
if err != nil && errors.IsNotFound(err) {
// 创建Deployment
deploy := r.createDeployment(&app)
if err := r.Create(ctx, deploy); err != nil {
log.Error(err, "unable to create Deployment")
return ctrl.Result{}, err
}
return ctrl.Result{Requeue: true}, nil
}
// 更新Deployment
if !reflect.DeepEqual(deploy.Spec.Replicas, app.Spec.Replicas) {
deploy.Spec.Replicas = &app.Spec.Replicas
if err := r.Update(ctx, &deploy); err != nil {
return ctrl.Result{}, err
}
}
// 更新状态
app.Status.AvailableReplicas = deploy.Status.AvailableReplicas
if err := r.Status().Update(ctx, &app); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
3.4 完整Controller示例 #
go
// application_types.go
type ApplicationSpec struct {
Replicas int32 `json:"replicas"`
Image string `json:"image"`
Version string `json:"version"`
}
type ApplicationStatus struct {
AvailableReplicas int32 `json:"availableReplicas"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
type Application struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ApplicationSpec `json:"spec,omitempty"`
Status ApplicationStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
type ApplicationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Application `json:"items"`
}
func init() {
SchemeBuilder.Register(&Application{}, &ApplicationList{})
}
四、Operator SDK #
4.1 使用Operator SDK #
bash
# 安装Operator SDK
curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.28.0/operator-sdk_linux_amd64
chmod +x operator-sdk_linux_amd64 && sudo mv operator-sdk_linux_amd64 /usr/local/bin/operator-sdk
# 创建项目
operator-sdk init --domain example.com --repo github.com/example/myoperator
# 创建API
operator-sdk create api --group example --version v1 --kind Application --resource --controller
# 创建Webhook
operator-sdk create webhook --group example --version v1 --kind Application --defaulting --programmatic-validation
4.2 Webhook配置 #
go
// application_webhook.go
func (r *Application) ValidateCreate() error {
if r.Spec.Replicas < 1 {
return fmt.Errorf("replicas must be at least 1")
}
return nil
}
func (r *Application) ValidateUpdate(old runtime.Object) error {
if r.Spec.Replicas < 1 {
return fmt.Errorf("replicas must be at least 1")
}
return nil
}
func (r *Application) Default() {
if r.Spec.Replicas == 0 {
r.Spec.Replicas = 1
}
}
五、Operator部署 #
5.1 构建镜像 #
bash
# 构建镜像
make docker-build IMG=myoperator:v1.0.0
# 推送镜像
make docker-push IMG=myoperator:v1.0.0
5.2 部署Operator #
bash
# 部署CRD
make install
# 部署Controller
make deploy IMG=myoperator:v1.0.0
# 查看部署
kubectl get pods -n myoperator-system
5.3 使用Operator #
yaml
# 创建Application
apiVersion: example.com/v1
kind: Application
metadata:
name: myapp
spec:
replicas: 3
image: nginx
version: "1.25"
bash
# 创建Application
kubectl apply -f application.yaml
# 查看状态
kubectl get application myapp -o yaml
# 查看创建的资源
kubectl get deployment
kubectl get pods
六、Operator最佳实践 #
6.1 设计原则 #
text
Operator设计原则
│
├── 单一职责
│ └── 一个Operator管理一种资源
│
├── 幂等性
│ └── Reconcile可重复执行
│
├── 状态管理
│ └── 正确更新状态
│
└── 错误处理
└── 合理处理错误和重试
6.2 状态条件 #
go
// 更新状态条件
func (r *ApplicationReconciler) updateStatus(ctx context.Context, app *examplev1.Application, conditionType string, status metav1.ConditionStatus, reason, message string) error {
condition := metav1.Condition{
Type: conditionType,
Status: status,
Reason: reason,
Message: message,
LastTransitionTime: metav1.Now(),
}
meta.SetStatusCondition(&app.Status.Conditions, condition)
return r.Status().Update(ctx, app)
}
七、总结 #
7.1 核心要点 #
| 概念 | 说明 |
|---|---|
| CRD | 自定义资源定义 |
| CR | 自定义资源实例 |
| Controller | 控制器逻辑 |
| Reconcile | 调谐循环 |
7.2 下一步 #
掌握了Operator后,让我们学习 资源限制,了解Kubernetes资源管理机制。
最后更新:2026-03-28