controller-manager代码走读心得(deployment controller篇)

controller-manager概念以及原理

在Kubernetes集群当中有有很多控制器,它们可以通过API Server提供的(list and watch机制)接口去实时的监听集群中的资源对象的状态变化。当某个资源发生故障,导致资源对象的状态发生变化时,Controller就会尝试着将其状态调整为预期的状态。

控制器的基本原理,我们在写Kubernetes资源的时候,通常都写YAML文件。这时我们通常会写一个Spec的字段,当我们使用kubectl apply命令将这个资源创建之后,由API Server负责把这些资源创建起来。在这个过程中,我们使用kubectl describe命令,我们会发现YAML文件里面会多出一个Status的字段,这个字段就是代表着当前的对象实例的一个状态,而Spec字段就是我预期的一个状态。而控制器就是负责将Status字段(当前状态)不断的进行调整达到Spec字段(预期状态)。

API Server的话是用来去读取资源对象的一个期望状态和当前状态,然后我们比较两者的一个差异,然后在控制器当中去操作这些资源对象,将这个资源对象的一个真实状态修正为Spec中的定义的期望状态。当这个执行完成之后,我们再将结果返回到API Server的一个目标资源对象的一个Status字段中。其实就是一个左手倒右手的一个过程。

在这里插入图片描述

那我们在学习controller manager的时候,我们最一开始碰到的一个控制器,那就是deployment controller。下面我将重点讲解deployment controller的原理。

Deployment Controller概念

Deployment Controller 是 Kube-Controller-Manager 中最常用的 Controller 之一管理 Deployment 资源。而 Deployment 的本质就是通过管理 ReplicaSet 和 Pod 在 Kubernetes 集群中部署 无状态 Workload。

通过控制Deployment,ReplicaSet,Pod这三个资源去完成无状态部署,我们就要重点回顾一下控制器的协同工作原理,可以做到简单的描述就可以。

在这里插入图片描述

深入Deployment Controller代码

cmd/kube-controller-manager/controller-manager.go

func main() {
   
	command := app.NewControllerManagerCommand()
	code := cli.Run(command)
	os.Exit(code)
}

在cmd中找到controller-manager的一个启动入口。我们点击NewControllerManagerCommand。

// NewControllerManagerCommand creates a *cobra.Command object with default parameters
func NewControllerManagerCommand() *cobra.Command {
	s, err := options.NewKubeControllerManagerOptions()
	if err != nil {
		klog.Background().Error(err, "Unable to initialize command options")
		klog.FlushAndExit(klog.ExitFlushTimeout, 1)
	}

	cmd := &cobra.Command{
		Use: "kube-controller-manager",
		Long: `The Kubernetes controller manager is a daemon that embeds
the core control loops shipped with Kubernetes. In applications of robotics and
automation, a control loop is a non-terminating loop that regulates the state of
the system. In Kubernetes, a controller is a control loop that watches the shared
state of the cluster through the apiserver and makes changes attempting to move the
current state towards the desired state. Examples of controllers that ship with
Kubernetes today are the replication controller, endpoints controller, namespace
controller, and serviceaccounts controller.`,
		PersistentPreRunE: func(*cobra.Command, []string) error {
			// silence client-go warnings.
			// kube-controller-manager generically watches APIs (including deprecated ones),
			// and CI ensures it works properly against matching kube-apiserver versions.
			restclient.SetDefaultWarningHandler(restclient.NoWarnings{})
			return nil
		},
		RunE: func(cmd *cobra.Command, args []string) error {
			verflag.PrintAndExitIfRequested()

			// Activate logging as soon as possible, after that
			// show flags with the final logging configuration.
			if err := logsapi.ValidateAndApply(s.Logs, utilfeature.DefaultFeatureGate); err != nil {
				return err
			}
			cliflag.PrintFlags(cmd.Flags())

			c, err := s.Config(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
			if err != nil {
				return err
			}
			// add feature enablement metrics
			utilfeature.DefaultMutableFeatureGate.AddMetrics()
			return Run(context.Background(), c.Complete())
		},
		Args: func(cmd *cobra.Command, args []string) error {
			for _, arg := range args {
				if len(arg) > 0 {
					return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
				}
			}
			return nil
		},
	}

	fs := cmd.Flags()
	namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
	verflag.AddFlags(namedFlagSets.FlagSet("global"))
	globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
	registerLegacyGlobalFlags(namedFlagSets)
	for _, f := range na
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值