控制平面组件控制器

[云原生 模块7](https://shimo.im/docs/1lq7M06mw5FRxZAe/read) ## controller manager ### 控制器的工作流程 ![image.png](https://cos.easydoc.net/97954506/files/l18w4k7k.png) ### Informer的内部机制 ![image.png](https://cos.easydoc.net/97954506/files/l18w7t7s.png) ### 控制器的协同工作原理 ![image.png](https://cos.easydoc.net/97954506/files/l18w8w5b.png) ### 通用controller Job Controller:处理job。 Pod AutoScaler:处理Pod的自动缩容/扩容。 RelicaSet:依据Replicaset Spec创建Pod。 Service Controller:为LoadBalancer type的service创建LB VIP。 ServiceAccount Controller:确保serviceaccount在当前namespace存在。 StatefulSet Controller:处理statefulset中的Pod。 Volume Controller:依据PV spec创建volume。 Resource quota Controller:在用户使用资源之后,更新状态。 Namespace Controller:保证namespace删除时,该namespace下的所有资源都先被删除 Replication Controller:创建RC后,负责创建Pod。 Node Controller:维护node状态,处理evict请求等。 Daemon Controller:依据damonset创建Pod。 Deployment Controller:依据deployment spec创建replicaset。 Endpoint Controller:依据service spec创建endpoint,依据podip更新endpoint。 Garbage Collector:处理级联删除,比如删除deployment的同时删除replicaset以及Pod。 CronJob Controller:处理cronjob。 ### 需要定制的Cloud Controller ●Ingress controller; ●Service Controller; ●自主研发的controller,比如之前提到的: - RBAC controller; - Account controller。 ### 来自生产的经验 保护好controller manager的kubeconfig: ●此kubeconfig拥有所有资源的所有操作权限,防止普通用户通过`kubectl exec kube-controller- manager cat`获取该文件。 ●用户可能做任何你想象不到的操作,然后来找你support。 Pod evict后IP发生变化,但endpoint中的address更新失败: ●分析stacktrace发现endpoint在更新LoadBalancer时调用gophercloud连接无响应,导致endpoint worker线程全部卡死。 ## Namespace Controller代码片段 ```golang discoverResourcesFn := namespaceKubeClient.Discovery().ServerPreferredNamespacedResources--> // fetch all api resources all, err := ServerPreferredResources(d)--> serverGroupList, err := d.ServerGroups() groupVersionResources, failedGroups := fetchGroupVersionResources(d, serverGroupList) apiResourceList, ok := groupVersionResources[groupVersion] NewNamespaceController()--> namespaceController := &NamespaceController{ queue: workqueue.NewNamedRateLimitingQueue(nsControllerRateLimiter(), "namespace"), namespacedResourcesDeleter: deletion.NewNamespacedResourcesDeleter(kubeClient.CoreV1().Namespaces(), metadataClient, kubeClient.CoreV1(), discoverResourcesFn, finalizerToken), } namespaceInformer.Informer().AddEventHandlerWithResyncPeriod()--> AddFunc: func(obj interface{}) { namespace := obj.(*v1.Namespace) namespaceController.enqueueNamespace(namespace) } Run(workers int, stopCh <-chan struct{})--> for i := 0; i < workers; i++ { go wait.Until(nm.worker, time.Second, stopCh)--> key, quit := nm.queue.Get() err := nm.syncNamespaceFromKey(key.(string)) namespace, err := nm.lister.Get(key) nm.namespacedResourcesDeleter.Delete(namespace.Name)--> //func (d *namespacedResourcesDeleter) Delete(nsName string) error namespace, err := d.nsClient.Get(context.TODO(), nsName, metav1.GetOptions{}) if namespace.DeletionTimestamp == nil { return nil } d.deleteAllContent(namespace)--> resources, err := d.discoverResourcesFn() gvrDeletionMetadata, err := d.deleteAllContentForGroupVersionResource(gvr, namespace, namespaceDeletedAt) deletableResources := discovery.FilteredBy(discovery.SupportsAllVerbs{Verbs: []string{"delete"}}, resources) } ```