# K8s控制器部署为Deployment实操
技术栈:Kubernetes v1.32.13 + CustomResourceDefinition + Operator SDK v1.34.x + Rocky Linux 8.6
操作环境 / 对接原理 / 详细步骤 / 完整命令 / 配置文件 / 验证流程 / 排错方案
# K8s控制器部署为Deployment实操
## 操作环境
- K8s 集群版本 v1.32.13,支持 CRD v1 版本
- 已安装 kubectl v1.32.13,配置集群访问权限
- 开发环境安装 Go 1.22.x、Operator SDK v1.34.x、controller-gen
- 已部署 Cert-Manager v1.14.x、Ingress-NGINX v1.10.x、ExternalDNS v0.14.x
- 命名空间默认 default,可按需创建专用命名空间
## 对接原理
CRD(CustomResourceDefinition)是 K8s 扩展机制,允许用户定义自定义资源类型。CRD 定义资源的名称、组、版本、作用域、字段校验 Schema(OpenAPI v3)、子资源(status/scale)、打印列、短名称等。Operator 模式通过自定义控制器监听 CRD 资源的增删改事件,在 Reconcile 循环中调谐实际状态至期望状态,实现自动化运维。Cert-Manager 通过 Issuer/Certificate CRD 自动化证书签发和续期;Ingress-NGINX 通过 Ingress CRD 配置七层路由;ExternalDNS 通过 DNSRecord 同步域名解析。
## 详细步骤
**1. 使用 Operator SDK 开发 Operator**
```bash
# 安装 Operator SDK
export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; esac)
export OS=$(uname | awk '{print tolower($0)}')
curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.34.1/operator-sdk_${OS}_${ARCH}
chmod +x operator-sdk_${OS}_${ARCH}
mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk
# 初始化项目
mkdir my-operator && cd my-operator
operator-sdk init --domain example.com --repo github.com/example/my-operator
# 创建 API
operator-sdk create api --group app --version v1 --kind MyApp --resource --controller
# 实现 Reconcile 逻辑
# 编辑 api/v1/myapp_types.go 定义字段
# 编辑 internal/controller/myapp_controller.go 实现调谐逻辑
# 生成 CRD 和 RBAC
make manifests
# 安装 CRD
make install
# 运行控制器(本地)
make run
# 部署到集群
make docker-build docker-push IMG=registry.example.com/my-operator:v0.1
make deploy IMG=registry.example.com/my-operator:v0.1
```
**2. 控制器 Reconcile 循环编写**
```bash
# 核心 Reconcile 方法示例(Go)
# func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
# // 1. 获取自定义资源
# var myApp appv1.MyApp
# if err := r.Get(ctx, req.NamespacedName, &myApp); err != nil {
# return ctrl.Result{}, client.IgnoreNotFound(err)
# }
# // 2. 检查子资源是否存在,不存在则创建
# // 3. 对比期望状态和实际状态,执行调谐
# // 4. 更新 Status
# // 5. 返回结果(可设置 RequeueAfter)
# return ctrl.Result{RequeueAfter: 5 * time.Minute}, nil
# }
# 关键概念:
# - OwnerReference:子资源关联父资源,实现级联删除
# - Finalizer:删除前执行清理逻辑
# - Status:记录实际状态
# - Requeue:重新入队调谐
```
## 验证流程
```bash
# 1. 验证 CRD 创建
kubectl get crd <crd-name>
# 显示 ESTABLISHED 条件为 True
# 2. 验证自定义资源创建
kubectl get <resource-plural>
# 资源列表正常显示
# 3. 验证字段校验
kubectl apply -f invalid-resource.yaml
# 不合规资源应被 APIServer 拒绝并返回错误
# 4. 验证子资源 status
kubectl get <resource> <name> -o jsonpath='{.status}'
# status 字段可更新
# 5. 验证打印列
kubectl get <resource>
# 自定义列正常显示
# 6. 验证控制器调谐
kubectl logs -f deployment/<operator-name>
# 控制器日志显示 Reconcile 循环正常执行
```
## 排错方案
- CRD 创建失败:检查 API 版本(apiextensions.k8s.io/v1),group/name 是否符合规范,Schema 是否有语法错误
- 自定义资源创建被拒:检查 spec 字段是否符合 OpenAPI Schema,required 字段是否提供,类型是否匹配,枚举值是否合法
- 控制器不调谐:检查控制器是否 Running,RBAC 权限是否允许 watch/list 自定义资源,日志是否有报错
- Status 无法更新:确认 CRD 启用了 status 子资源(subresources.status: {}),控制器有 update status 权限
- Webhook 调用失败:检查 webhook 服务是否可达,TLS 证书是否正确,conversionReviewVersions 是否匹配
- Cert-Manager 证书不签发:检查 Issuer 状态,DNS01/HTTP01 验证是否通过,域名是否指向正确,查看 Certificate 事件
- Ingress 不生效:检查 ingressClassName 是否为 nginx,Ingress 控制器是否运行,Service 和端口是否正确,注解语法是否正确
- ExternalDNS 不同步:检查 Provider 配置和凭据,域名过滤是否正确,TXT 记录所有权是否冲突,查看 Pod 日志