k8s deployment通用模板

本文详细介绍了如何使用Kubernetes Deployment进行应用部署,包括配置文件的各项参数设置,如滚动更新策略、资源限制、容器探针及优雅停机等,并展示了如何通过自定义注解优化Istio服务网格的配置。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {APP_NAME}-deployment
  labels:
    app: {APP_NAME}
    #version: v{IMAGE_TAG}
  namespace: depoly
spec:
  replicas: 1
  minReadySeconds: 30
  strategy:
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 0
  selector:
    matchLabels:
      app: {APP_NAME}
     # version: v{IMAGE_TAG}
  template:
    metadata:
      labels:
        app: {APP_NAME}
       # version: v{IMAGE_TAG}
      annotations:
        k8s.aliyun.com/eci-use-specs : {ECI_SPECS}   #指定ECI实例的vCPU和内存
        proxy.istio.io/config: '{ "terminationDrainDuration": 60s }'

#istio 提供了 terminationDrainDuration 这个连接优雅终止时长的自定义配置,表示 sleep 多长时间之后才强制杀死 envoy,默认是 5s,结合下面的terminationGracePeriodSeconds使用
    spec:
      terminationGracePeriodSeconds: 70 

#调整优雅终止时间,terminationGracePeriodSeconds 默认是30s。自己视情况而定(terminationGracePeriodSeconds 一定大于sleep的时间)


      containers:
      - name: {APP_NAME}
        image: registry.aliyuncs.com/{APP_NAME}:{IMAGE_TAG}
        lifecycle:
#          postStart:
#            exec: 
#              command:  ["/bin/sh", "-c", "echo nacos-update.sh > /usr/local/depoly/start.sh"]
          preStop:
            exec:
#              command:  ["/bin/sh", "-c", "/bin/sh /usr/local/depoly/offline.sh ; sleep 30; kill -15 1"]
              command:  ["/bin/sh", "-c", "/bin/sh /usr/local/depoly/offline.sh ; sleep 60 ; kill -15 1; while [ ! -f 'kill.conf' ]; do sleep 10 && echo 1 >>1.txt; done"]
        readinessProbe:
          timeoutSeconds: 5 
          failureThreshold: 5
          initialDelaySeconds: 50   #延迟检测时间
          periodSeconds: 10 
          exec:
            command:  ["/bin/sh", "-c", "/bin/sh /usr/local/depoly/nacos-update.sh "]
      
        ports:
        - containerPort: {APP_PORT}
        env:
          - name: SPRING_PROFILES_ACTIVE
            value: {SPRING_PROFILE}
          - name: TZ
            value: "Asia/Shanghai"
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
     #   volumeMounts:
     #     - name: tz
     #       mountPath: /etc/localtime
     #       subPath: Shanghai
        resources:
          limits:
            cpu: {LIMITS_CPU}
            memory: {LIMITS_MEM}
          requests:
            cpu: {REQ_CPU}
            memory: {REQ_MEM}
        volumeMounts:
          - mountPath: /home/jvm
            name: pvc-jvm
      volumes:
        - name: tz
          configMap:
            name: tz
        - name: pvc-jvm
          persistentVolumeClaim:
            claimName: pvc-jvm
      imagePullSecrets:
      - name: registry-pull-secret

<think>嗯,用户现在想要了解如何编写一个调谐通用资源的Kubernetes控制器。首先,我需要明确用户的需求。他们可能已经知道Kubernetes的基本概念,但想深入控制器的工作原理,特别是如何编写一个自定义控制器来管理通用资源。这里的“通用资源”可能指的是用户自定义的CRD(Custom Resource Definition),或者是Kubernetes中的某些标准资源,但需要更灵活的调谐逻辑。 接下来,我应该回顾用户之前的问题历史。之前他们询问过GORM无法修改字段类型或删除字段的问题,可能是在开发过程中遇到了数据库迁移的问题。现在转向Kubernetes控制器,可能他们的工作涉及云原生应用开发,需要自动化资源管理。用户可能是开发人员或DevOps工程师,需要实现自定义逻辑来管理Kubernetes集群中的资源。 用户的需求可能包括控制器的基本结构、使用哪些客户端库、如何监听事件、调谐逻辑的实现,以及如何处理状态更新。他们可能希望有一个具体的例子,而不仅仅是理论上的解释。此外,他们可能关心最佳实践,比如错误处理、性能优化和测试方法。 我需要考虑用户可能存在的深层需求。比如,他们是否了解Kubernetes的Operator模式?是否需要解释控制器与Operator的区别?或者是否需要指导如何打包和部署控制器?可能还需要提到一些工具或框架,如Kubebuilder或Operator SDK,这些可以简化控制器的开发流程。 在回答结构上,应该分步骤介绍,从创建CRD开始,到初始化控制器,定义事件处理,实现调谐逻辑,处理状态更新,最后部署和测试。需要提供代码示例,但确保代码正确且符合Go语言的惯例。同时,要提醒用户注意关键点,比如并发控制、重试机制、权限设置等。 另外,用户可能对调谐循环(Reconcile Loop)的具体实现细节感兴趣,比如如何处理资源的创建、更新、删除,如何与API服务器交互。需要解释Informer和Workqueue的作用,以及如何高效地处理事件而不会阻塞系统。 最后,应该总结最佳实践,比如使用声明式API、幂等操作、资源版本控制等,帮助用户编写健壮且高效的控制器。可能还需要推荐一些扩展学习资源,如官方文档或开源项目,供用户进一步参考。</think>以下是编写 Kubernetes 通用资源控制器的完整指南,包含核心模式和实践方案: --- ### 一、控制器核心架构 ```mermaid graph TD A[API Server] -->|Watch| B(Informer) B --> C[Resource Event] C --> D{事件类型} D -->|Add| E[Workqueue] D -->|Update| E D -->|Delete| E E --> F[Worker] F --> G[Reconcile逻辑] G --> H[调谐实际状态] ``` --- ### 二、标准开发流程 #### 1. 创建 CRD(以 MyApp 为例) ```yaml # myapp-crd.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myapps.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 image: type: string scope: Namespaced names: plural: myapps singular: myapp kind: MyApp ``` #### 2. 初始化控制器 ```go import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" ) type Controller struct { clientset clientset.Interface informer cache.SharedIndexInformer queue workqueue.RateLimitingInterface } func NewController(clientset clientset.Interface) *Controller { c := &Controller{ clientset: clientset, queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), } c.informer = cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { return clientset.ExampleV1().MyApps(metav1.NamespaceAll).List(context.TODO(), options) }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { return clientset.ExampleV1().MyApps(metav1.NamespaceAll).Watch(context.TODO(), options) }, }, &v1.MyApp{}, 0, // 无重新同步周期 cache.Indexers{}, ) c.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: c.handleAdd, UpdateFunc: c.handleUpdate, DeleteFunc: c.handleDelete, }) return c } ``` #### 3. 事件处理核心逻辑 ```go func (c *Controller) handleAdd(obj interface{}) { key, err := cache.MetaNamespaceKeyFunc(obj) if err == nil { c.queue.Add(key) } } func (c *Controller) handleUpdate(oldObj, newObj interface{}) { if !reflect.DeepEqual(oldObj.(*v1.MyApp).Spec, newObj.(*v1.MyApp).Spec) { key, err := cache.MetaNamespaceKeyFunc(newObj) if err == nil { c.queue.Add(key) } } } func (c *Controller) handleDelete(obj interface{}) { key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) if err == nil { c.queue.Add(key) } } ``` #### 4. 调谐逻辑实现 ```go func (c *Controller) reconcile(key string) error { namespace, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { return err } obj, err := c.clientset.ExampleV1().MyApps(namespace).Get(context.TODO(), name, metav1.GetOptions{}) if errors.IsNotFound(err) { // 处理删除逻辑 return nil } if err != nil { return err } // 实际调谐逻辑 desiredDeployments := generateDeployments(obj) currentDeployments, err := c.getCurrentDeployments(obj) if err := c.manageDeployments(currentDeployments, desiredDeployments); err != nil { return err } return c.updateStatus(obj) } ``` --- ### 三、关键优化策略 #### 1. 事件合并处理 ```go // 设置队列参数 c.queue = workqueue.NewRateLimitingQueue( workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second), ) ``` #### 2. 状态更新模式 ```go func (c *Controller) updateStatus(obj *v1.MyApp) error { newStatus := calculateNewStatus(obj) if reflect.DeepEqual(obj.Status, newStatus) { return nil } obj.Status = newStatus _, err := c.clientset.ExampleV1().MyApps(obj.Namespace).UpdateStatus(context.TODO(), obj, metav1.UpdateOptions{}) return err } ``` --- ### 四、生产级最佳实践 #### 1. 错误处理策略 ```go const maxRetries = 5 func (c *Controller) processNextItem() bool { key, quit := c.queue.Get() if quit { return false } defer c.queue.Done(key) err := c.reconcile(key.(string)) if err != nil { if c.queue.NumRequeues(key) < maxRetries { c.queue.AddRateLimited(key) return true } // 记录错误日志并放弃重试 } c.queue.Forget(key) return true } ``` #### 2. Leader 选举配置 ```yaml # deployment.yaml spec: replicas: 3 template: spec: containers: - args: - --leader-elect=true - --leader-elect-lease-duration=15s - --leader-elect-renew-deadline=10s - --leader-elect-retry-period=2s ``` --- ### 五、调试与测试方案 #### 1. 单元测试框架 ```go func TestReconcile(t *testing.T) { testCases := []struct { name string input *v1.MyApp expectedErr bool }{ { name: "normal case", input: &v1.MyApp{ Spec: v1.MyAppSpec{ Replicas: 3, Image: "nginx:latest", }, }, expectedErr: false, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { // 初始化 fake client // 执行 reconcile // 断言结果 }) } } ``` #### 2. 集成测试环境 ```bash kind create cluster --name controller-test go test ./... -tags=integration -v ``` --- ### 六、性能优化技巧 #### 1. 缓存优化配置 ```go c.informer = cache.NewSharedIndexInformer( ... cache.Indexers{ "byNamespace": func(obj interface{}) ([]string, error) { return []string{obj.(*v1.MyApp).Namespace}, nil }, }, ) ``` #### 2. 并发控制策略 ```go func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) { for i := 0; i < threadiness; i++ { go wait.Until(c.runWorker, time.Second, stopCh) } <-stopCh } ``` --- ### 七、扩展模式推荐 #### 1. Finalizer 机制实现 ```go const finalizerName = "example.com/finalizer" func (c *Controller) handleFinalizers(obj *v1.MyApp) error { if obj.DeletionTimestamp.IsZero() { if !controllerutil.ContainsFinalizer(obj, finalizerName) { controllerutil.AddFinalizer(obj, finalizerName) return c.updateObject(obj) } } else { if controllerutil.ContainsFinalizer(obj, finalizerName) { // 执行清理逻辑 controllerutil.RemoveFinalizer(obj, finalizerName) return c.updateObject(obj) } } return nil } ``` #### 2. 多版本兼容处理 ```go func convertToNewVersion(oldObj runtime.Object) (runtime.Object, error) { switch old := oldObj.(type) { case *v1beta1.MyApp: newObj := &v1.MyApp{} // 转换逻辑 return newObj, nil default: return nil, fmt.Errorf("unsupported version") } } ``` --- ### 八、部署架构推荐 ```mermaid graph TD A[Controller Pod] -->|Watch| B(API Server) B --> C[Custom Resources] C --> D[Controller] D -->|Create/Update| E[Deployment] D -->|Manage| F[Service] D -->|Sync| G[ConfigMap] H(Metrics Server) --> D I(Prometheus) -->|监控指标| D ``` 建议使用 Operator SDK 或 Kubebuilder 框架加速开发,这两个工具提供了完整的脚手架生成和代码模板功能。对于复杂业务场景,可以结合使用 Admission Webhook 实现更精细的控制策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值