概述
Deployment是Kubernetes中最常用的Object,也是最典型的面试题,通过阅读源码,可以学习到标准的k8s-controller模式应该如何开发。
details
processNextWorkItem流程
- 拿到deploy对象: dc.dLister.Deployments(namespace).Get(name)
- 拿到replica对象: dc.getReplicaSetsForDeployment(ctx, d)
- 根据repicaset ID聚合pods: dc.getPodMapForDeployment(d, rsList)
- 逻辑分支
- dp已被删除: dc.syncStatusOnly(ctx, d, rsList)
- d.Spec.Paused: return dc.sync(ctx, d, rsList)
- rollback: 已废弃annotation回滚功能
- desired-replicas annotation(ScalingEvent): return dc.sync(ctx, d, rsList)
- 根据d.Spec.Strategy.Type,这中间可能会创建新的replicaset: rolloutRecreate/rolloutRolling
dInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: dc.addDeployment,
UpdateFunc: dc.updateDeployment,
// This will enter the sync loop and no-op, because the deployment has been deleted from the store.
DeleteFunc: dc.deleteDeployment,
})
rsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: dc.addReplicaSet,
UpdateFunc: dc.updateReplicaSet,
DeleteFunc: dc.deleteReplicaSet,
})
func (dc *DeploymentController) processNextWorkItem(ctx context.Context) bool {
key, quit := dc.queue.Get()
if quit {
return false
}
defer dc.queue.Done(key)
err := dc.syncHandler(ctx, key.(string))
dc.handleErr(err, key)
return true
}
syncDeployment
- replicaset分为最新的和其他,最新的含义是和deploy tmpl字段一样中最新的
- 如果发现deploy没有对应的最新replicaset,会创建出新的replicaset
- 为什么deployment不直接管理Pod,而是要通过replicaset?
- 我们通常只使用了deployment的基础功能,所以会觉得dp和rs很类似,但这是先入为主的概念
- 实际上,rs所代表的副本集的功能确实是非常稳定的,但是k8s的开发者预见到了deployment的强大潜力,因此副本集的功能分离了出来
- 事实上,deployment确实在应用中统治了一切无状态的workload,甚至能模拟出daemonset
func (dc *DeploymentController) syncDeployment(ctx context.Context, key string)
func (dc *DeploymentController) rolloutRolling(ctx context.Context, d *apps.Deployment, rsList []*apps.ReplicaSet) error
func (dc *DeploymentController) getAllReplicaSetsAndSyncRevision(ctx context.Context, d *apps.Deployment, rsList []*apps.ReplicaSet, createIfNotExisted bool) (*apps.ReplicaSet, []*apps.ReplicaSet, error)