数据库驱动的 Kubernetes 自动化实际是如何运作的

发布: (2025年12月4日 GMT+8 08:13)
6 min read
原文: Dev.to

Source: Dev.to

心智模型

  1. LynqHub – 连接到你的数据库并监听变化。
  2. LynqForm – 定义要创建的 Kubernetes 资源(模板)。
  3. LynqNode – 实际实例,每个数据库行对应每个模板生成一个实例。

当数据库中出现一行时,hub 会创建一个 LynqNode。节点控制器渲染模板并应用资源。当该行消失或被停用时,清理会自动进行。

LynqHub

hub 告诉 Lynq 你的数据位于何处以及如何将列映射到模板变量。

apiVersion: operator.lynq.sh/v1
kind: LynqHub
metadata:
  name: my-saas-hub
spec:
  source:
    type: mysql
    mysql:
      host: mysql.default.svc.cluster.local
      port: 3306
      database: nodes
      table: node_data
      username: node_reader
      passwordRef:
        name: mysql-secret
        key: password
  syncInterval: 30s
  valueMappings:
    uid: node_id          # unique identifier for each node
    activate: is_active  # boolean controlling resource existence
  extraValueMappings:
    planId: subscription_plan
    region: deployment_region
  • valueMappings – 必填列(uidactivate)。
  • extraValueMappings – 可选自定义字段,会成为模板变量。

hub 会在 syncInterval 指定的间隔轮询数据库。如果 activate=true,Lynq 会创建资源;如果变为 false,则开始清理。

LynqForm

表单是蓝图,定义了针对每个数据库行要创建的资源。

apiVersion: operator.lynq.sh/v1
kind: LynqForm
metadata:
  name: web-app
spec:
  hubId: my-saas-hub
  deployments:
    - id: app
      nameTemplate: "{{ .uid }}-app"
      labelsTemplate:
        app: "{{ .uid }}"
        plan: "{{ .planId | default \"basic\" }}"
      spec:
        apiVersion: apps/v1
        kind: Deployment
        spec:
          replicas: 2
          template:
            spec:
              containers:
                - name: app
                  image: "{{ .deployImage | default \"nginx:latest\" }}"
  services:
    - id: svc
      nameTemplate: "{{ .uid }}-svc"
      dependIds: ["app"]
      spec:
        apiVersion: v1
        kind: Service
        # …

模板使用 Go 的 text/template 语法并支持 Sprig 函数,内置超过 200 个辅助函数。常用变量:

  • {{ .uid }} – 唯一名称后缀。
  • {{ .planId | default "basic" }} – 为可空列提供安全默认值。
  • {{ .uid | trunc63 }} – 符合 Kubernetes 命名限制。

资源策略

每个资源可以自行定义创建、删除和冲突处理策略。

创建策略

deployments:
  - id: app
    creationPolicy: WhenNeeded   # default
    deletionPolicy: Delete
    conflictPolicy: Stuck
    patchStrategy: apply
  • WhenNeeded – 持续同步;手动删除会被恢复,模板更新会被应用。
  • Once – 创建一次后不再触碰(适用于初始化作业)。
jobs:
  - id: init-job
    creationPolicy: Once
    nameTemplate: "{{ .uid }}-init"
    spec:
      apiVersion: batch/v1
      kind: Job
      spec:
        template:
          spec:
            containers:
              - name: init
                command: ["sh", "-c", "echo 'one-time setup'"]
            restartPolicy: Never

删除策略

  • Delete(默认)– 设置 OwnerReference;Kubernetes 垃圾回收会删除资源。
  • Retain – 保留资源;Lynq 会添加孤儿标签以便后续发现(对 PVC 很有用)。
persistentVolumeClaims:
  - id: data-pvc
    deletionPolicy: Retain
    nameTemplate: "{{ .uid }}-data"

冲突策略

  • Stuck(默认)– 在冲突时停止调和并产生事件。
  • Force – 通过 Server‑Side Apply 并使用 force=true 强制获取所有权(迁移期间常用)。

依赖管理

资源之间可以相互依赖,确保正确的创建顺序并可选进行就绪检查。

secrets:
  - id: db-creds
    nameTemplate: "{{ .uid }}-creds"

deployments:
  - id: db
    dependIds: ["db-creds"]
    waitForReady: true

  - id: app
    dependIds: ["db"]
    waitForReady: true

Lynq 根据 dependIds 构建有向无环图(DAG),并按拓扑顺序应用资源。出现环会快速失败。

  • waitForReady: true – Lynq 会等待依赖资源就绪后再继续。
  • skipOnDependencyFailure(默认 true)– 如果依赖失败,跳过后续资源;设为 false 则强制执行。
jobs:
  - id: cleanup-job
    dependIds: ["main-app"]
    skipOnDependencyFailure: false

完整调和流程

  1. Hub 控制器 每个 syncInterval 轮询数据库。
  2. 对每个活跃行,创建/更新一个 LynqNode CR。
  3. Node 控制器 读取 LynqNode
  4. 使用行数据渲染所有模板。
  5. 构建依赖图并排序资源。
  6. 按顺序使用 Server‑Side Apply 应用每个资源。
  7. 如配置则等待就绪。
  8. 将结果写入 LynqNode 状态。

停用 / 删除

  1. Hub 检测到行被停用或删除。
  2. 对应的 LynqNode CR 被删除。
  3. Finalizer 根据每个资源的 deletionPolicy 执行清理。
    • Delete → 资源被移除。
    • Retain → 添加孤儿标签。

你可以实时观察过程:

kubectl get lynqnodes -w
kubectl describe lynqnode 

示例状态输出:

status:
  desiredResources: 5
  readyResources: 5
  failedResources: 0
  appliedResources:
    - "Deployment/default/acme-app@app"
    - "Service/default/acme-svc@svc"

何时使用此模式

  • 业务数据已经存放在关系型数据库中(用户、租户、组织等)。
  • 需要快速供给,而不想走典型的提交‑同步‑调和循环。
  • 必须以不同的值多次复用同一套资源。
  • 模板版本管理比单实例版本管理更重要。

不适合 那些只有少量独特环境、传统 IaC 工具已足够的场景。对于大规模、数据驱动的供给,Lynq 提供了一种简洁、声明式的方式。

参考与实操

  • Killercoda 快速入门(≈10 分钟)
  • 文档
  • GitHub 仓库

欢迎在评论区提问!

Back to Blog

相关文章

阅读更多 »

被遗忘的 tech 墓地 by kiroween

一次 Hackathon 之旅:走进旧发明的墓园 每年十月,创意世界里总会掀起一阵奇异的波动。今年,Kiroween 发起挑战,……