控制平面组件控制器
[云原生 模块7](https://shimo.im/docs/1lq7M06mw5FRxZAe/read)
## controller manager
### 控制器的工作流程

### Informer的内部机制

### 控制器的协同工作原理

### 通用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)
}
```