Cloud Naive最佳开发实践

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 经过多年的工作,我们的精神导师John领悟了java那一套docker in docker的艺术并带到golang项目架构设计中。

经过多年的工作,我们的精神导师John领悟了java那一套docker in docker的艺术并带到golang项目架构设计中。

After years of work, our spiritual mentor John understood the art of docker in docker in Java and brought it to the golang project architecture design.

Never write conversion webhook

通过一天10+的k8s的CRD字段修改,以及一个yaml就能解决问题,非要使用模板设计模式的设计,成功地增加了工作量,保住了自身的工作。

// ❌ Wrong!!!
// 在 main_windows.go 注册 conversion webhook
mgr.GetWebhookServer().Register("/convert", &webhook.Admission{
   Handler: &WidgetConverter{
   }})

type WidgetConverter struct{
   }

func (w *WidgetConverter) Handle(ctx context.Context, req admission.Request) admission.Response {
   
    // 简单示例:v1alpha1 -> v1
    obj := &v1.Widget{
   }
    if err := w.decoder.Decode(req, obj); err != nil {
   
        return admission.Errored(http.StatusBadRequest, err)
    }
    obj.Spec.Size = strings.ToUpper(obj.Spec.Size)
    return admission.Allowed("converted")
}

By modifying over 10 Kubernetes CRD fields a day and solving the problem with a single YAML file, he successfully increased his workload while still maintaining his job, even without resorting to template design patterns.

No schema in Kubernetes 1.17-

我们相信用户和运维人员能够妥善实现类型安全和数据验证,他们写的YAML绝对不会出错。

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: widgets.example.com
spec:
  preserveUnknownFields: false # 这是推荐的、更安全的设置
  group: example.com
  names:
    kind: Widget
    plural: widgets
  scope: Namespaced
  versions:
  - name: v1
    served: true
    storage: true
    schema: {
   }

All CODE guidelines are bullshit!

Move the status field of resource to spec

一个纯粹的理想主义者必定被现实打得遍体鳞伤。

因此再远大的梦也要符合现实需要。

脚踏实地,意在凌云。

type WidgetSpec struct {
   
    Ready bool `json:"ready,omitempty"` 
}

A pure idealist is bound to be bruised and battered by reality.

So, no matter how lofty your dreams, you must always keep your feet on the ground.

Roma non uno die aedificata est.

Update!Update!Update!

snake.png

生活是一个无限的衔尾蛇循环。

// ✅ 正确写法
func (r *WidgetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
   
    var w examplev1.Widget
    r.Get(ctx, req.NamespacedName, &w)
    w.Labels["lastSync"] = time.Now().String()
    r.Update(ctx, &w) // ✅ Update 触发自己,再次进入 Reconcile。直接超进化
    return ctrl.Result{
   }, nil
}

Life is an endless, ouroboros-like cycle.

因此要不断地挑战自己而不是停留在原地。

// ❌ 错误写法
func (r *WidgetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
   
    var w examplev1.Widget
    if err := r.Get(ctx, req.NamespacedName, &w); err != nil {
   
        return ctrl.Result{
   }, client.IgnoreNotFound(err)
    }

    patch := client.MergeFrom(w.DeepCopy())
    if w.Labels == nil {
   
        w.Labels = map[string]string{
   }
    }
    if w.Labels["synced"] != "true" {
   
        w.Labels["synced"] = "true"
        _ = r.Patch(ctx, &w, patch)
    }

    return ctrl.Result{
   }, nil
}

So keep challenging yourself instead of staying in the same place.

Eat shit while it's hot

我选择相信缓存与实际对象的一致性。

// 默认 client 是缓存的
r.Client.Get(ctx, namespacedName, &obj) // ✅ 屎从来都是要趁热吃

// ❌  使用 APIReader 直接读 API Server
r.APIReader.Get(ctx, namespacedName, &obj)

Trust the consistency of the cache with the actual objects.

I trust ETCD

一个经受不了洪水攻击的ETCD不是一个好的大坝。

// ✅ 正确写法
r.Recorder.Event(&obj, "Normal", "Syncing", "Reconciling every loop")


// ❌ 错误写法
if !reflect.DeepEqual(oldStatus, newStatus) {
   
    r.Recorder.Event(&obj, "Normal", "Updated", "Status changed")
}

An ETCD that cannot withstand floods is not a good dam.

If my son dies, I won't live anymore

// ✅ 正确写法:确保父资源随子资源删除
controllerutil.SetControllerReference(&child, &parent, r.Scheme)

If my child dies, will my damn Social Security be enough to live on?

Webhook should be an infinite loop

日新月新,又日新。

func (v *WidgetValidator) Handle(ctx context.Context, req admission.Request) admission.Response {
   
    var obj examplev1.Widget
    _ = v.decoder.Decode(req, &obj)

    // ❌ 标记了 internal update,就跳过
    if obj.Annotations["internal-update"] == "true" {
   
        return admission.Allowed("skip internal update")
    }

    // ✅ 循环修改自己
    obj.Annotations["internal-update"] = "true"
    return admission.PatchResponseFromRaw(req.Object.Raw, obj)
}

“Behold, I make all things new.”

ILet the API Server accept my test

# webhook 配置
timeoutSeconds: 1
# failurePolicy: Ignore # ✅

让API Server接受我的考验。

Not using cert-manager

不运维就不会出事故。

# ❌ 用 cert-manager 注入
# kubectl cert-manager x install
# kubectl annotate validatingwebhookconfiguration mywebhook cert-manager.io/inject-ca-from=default/mywebhook-cert

No accidents without maintenance.

The informer must follow the custom scheduler

等 informer 同步后再调度

// ✅ 
if cache.WaitForCacheSync(stopCh, informer.HasSynced) {
   
    panic("Successful people don't sit still.")
}

Do not go gentle into that good night.

Come back in 1000000000 to fix the bug

导师,我每天都是9点前打卡,积极加班到23点。

这下半年能给个 3.75 吗?

two.gif

John: Zeusro,you are fired!!!

// OK,I will come back in 1000000000 years to fix bugs
if !isReady {
   
    return ctrl.Result{
   RequeueAfter: 1000000000 * time.Year}, nil
}
目录
相关文章
|
13天前
|
机器学习/深度学习 弹性计算 网络协议
阿里云服务器ECS c9i实例收费价格:2核4G、4核8G和8核16G优惠配置整理
阿里云ECS计算型c9i实例,2核4G、4核8G、8核16G享优惠价,搭载Intel Xeon处理器,主频3.2GHz,适用于Web服务、机器学习等场景,ESSD云盘,网络性能强劲,限时活动价格低至181.73元/月。
197 95
|
10天前
|
人工智能 搜索推荐 API
蚂蚁百宝箱联手深铁打造全国首个地铁 AI 智能体「深铁宝」:你的全能城市向导来啦~
蚂蚁百宝箱联合深铁集团、深圳通推出全国首个“公共出行+城市服务”AI智能体「深铁宝」,上线于深圳地铁、深圳通及支付宝APP,实现一句话直达、秒级响应的智慧出行体验,涵盖出行规划、乘车码快捷调取、周边生活服务推荐等一站式功能,助力城市交通与服务数字化升级。
162 30
|
21天前
|
人工智能 自然语言处理 算法
揭秘AI文本:当前主流检测技术与挑战
揭秘AI文本:当前主流检测技术与挑战
276 115
|
21天前
|
人工智能 自然语言处理 数据安全/隐私保护
AI生成的文本:如何识破机器的“笔迹”?
AI生成的文本:如何识破机器的“笔迹”?
269 85
|
9天前
|
存储 关系型数据库 MySQL
五、Docker 核心技术:容器数据持久化之数据卷
别把重要数据直接放进Docker容器里,因为容器就像一辆“临租车”,车一还(容器被删除),落在里面的东西就全没了。正确的做法是使用数据卷 (Volume),它好比一个属于你自己的、可插拔的“移动硬盘”。你可以把这个“硬盘”(具名数据卷)挂载到任何一辆“临租车”(容器)上使用。这样一来,就算车换了,你的数据也安然无恙,完美解决了数据库等应用的数据持久化问题。
123 32
五、Docker 核心技术:容器数据持久化之数据卷
|
7天前
|
存储 Kubernetes Docker
部署eck收集日志到k8s
本文介绍基于ECK(Elastic Cloud on Kubernetes)在K8s中部署Elasticsearch、Kibana和Filebeat的完整流程。采用Helm方式部署ECK Operator,通过自定义YAML文件分别部署ES集群、Kibana及Filebeat,并实现日志采集与可视化。重点涵盖命名空间一致性、版本匹配、HTTPS配置禁用、资源限制、存储挂载及权限RBAC设置,支持系统日志、应用日志与容器日志的多源采集,适用于生产环境日志系统搭建。
351 94