kubernetes 的源码解读(三)

kubelet.go

server.go:NewKubeletCommand()-->>
kubeletDeps, err := UnsecuredDependencies(kubeletServer, utilfeature.DefaultFeatureGate)-->>
	plugins, err := ProbeVolumePlugins(featureGate)
server.go:Run(kubeletServer, kubeletDeps, utilfeature.DefaultFeatureGate, stopCh)-->>
	run(s, kubeDeps, featureGate, stopCh)-->>
		kubeDeps.ContainerManager, err = cm.NewContainerManager() // init runtime service(CRI), -container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///var/containerd/containerd.sock
		kubelet.PreInitRuntimeService()-->>
			remote.NewRemoteRuntimeService(remoteRuntimeEndpoint, kubeCfg.RuntimeRequestTimeout.Duration)
		RunKubelet(s, kubeDeps, s.RunOnce)-->>
			createAndInitKubelet()-->>
				kubelet.NewMainKubelet()-->>
					makePodSourceConfig(kubeCfg, kubeDeps, nodeName, bootstrapCheckpointPath)-->>
						updatechannel = cfg.Channel(kubetypes.ApiserverSource)
					klet := &Kubelet{}
					//*******init volume plugins
					runtime, err := kuberuntime.NewKubeGenericRuntimeManager()
					NewInitializedVolumePluginMgr()-->>
						kvh.volumePluginMgr.InitPlugins(plugins, prober, kvh)-->>
			startKubelet()-->>
				k.Run(podCfg.Updates())-->>
					//*******run volume manager, and reconcile function would attach volume for attachable plugin and mount volume
					go kl.volumeManager.Run(kl.sourcesReady, wait.NeverStop)-->>
						vm.desiredStateOfWorldPopulator.Run(sourcesReady, stopCh)-->>
							populatorLoop-->>
								dswp.findAndAddNewPods()-->>
									dswp.processPodVolumes(pod, mountedVolumesForPod, processedVolumesForFSResize)-->>
										mounts, devices := util.GetPodVolumeNames(pod)
										dswp.createVolumeSpec(podVolume, pod.Name, pod.Namespace, mounts, devices)
										dswp.desiredStateOfWorld.AddPodToVolume(uniquePodName, pod, volumeSpec, podVolume.Name, volumeGidValue)-->>
											dsw.volumesToMount[volumeName] = volumeToMount{}
						vm.reconciler.Run(stopCh)-->>	
							reconciliationLoopFunc() -->> // reconcile every 100 ms
								mountAttachVolumes-->>
									rc.desiredStateOfWorld.GetVolumesToMount()
									rc.operationExecutor.AttachVolume()-->>	// attachable plugin, e.g. 	CSI plugin
										operationGenerator.GenerateAttachVolumeFunc(volumeToAttach, actualStateOfWorld).Run()
									rc.operationExecutor.MountVolume()-->>  // volume need to mount, like ceph, configmap, emptyDir
										oe.operationGenerator.GenerateMapVolumeFunc().Run()-->>
											volumePlugin, err := og.volumePluginMgr.FindPluginBySpec(volumeToMount.VolumeSpec)
											volumePlugin.NewMounter()
											volumeMounter.SetUp()
					kl.syncLoop(updates, kl)-->>
						kl.syncLoopIteration(updates, handler, syncTicker.C, housekeepingTicker.C, plegCh)-->>
							//*******handle pod creation event
							handler.HandlePodAdditions(u.Pods)-->>
								kl.podManager.AddPod(pod)
								kl.canAdmitPod(activePods, pod) // check admit, if admit check fail, it will error out
								kl.dispatchWork(pod, kubetypes.SyncPodCreate, mirrorPod, start)-->>
									kl.podWorkers.UpdatePod()-->>
										p.managePodLoop(podUpdates)-->>
											p.syncPodFn()-->>
												kubelet.go:syncPod()-->>
													runnable := kl.canRunPod(pod) // check soft admin, pod will be pending if check fails
													kl.runtimeState.networkErrors() // check network plugin status
													kl.containerManager.UpdateQOSCgroups()
													kl.makePodDataDirs(pod)
													kl.volumeManager.WaitForAttachAndMount(pod)
													(kubeGenericRuntimeManager)kl.containerRuntime.SyncPod()-->>
														m.computePodActions(pod, podStatus) // create sandbox container?
														m.createPodSandbox(pod, podContainerChanges.Attempt)-->>
															m.osInterface.MkdirAll(podSandboxConfig.LogDirectory, 0755)
															//*******calling CRI
															m.runtimeService.RunPodSandbox(podSandboxConfig, runtimeHandler)-->>// k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.pb.go
																c.cc.Invoke(ctx, "/runtime.v1alpha2.RuntimeService/RunPodSandbox") // call remote runtime service which is served by containerd
															start("init container", containerStartSpec(container))-->>
																startContainer()
															start("container", containerStartSpec(&pod.Spec.Containers[idx]))-->>
																startContainer()-->>
																	m.imagePuller.EnsureImageExists(pod, container, pullSecrets, podSandboxConfig)-->>
																		c.cc.Invoke(ctx, "/runtime.v1alpha2.ImageService/PullImage"
																	m.runtimeService.CreateContainer(podSandboxID, containerConfig, podSandboxConfig)-->>
																		c.cc.Invoke(ctx, "/runtime.v1alpha2.RuntimeService/CreateContainer")
																	m.internalLifecycle.PreStartContainer(pod, container, containerID) // set cpu set
																	m.runtimeService.StartContainer(containerID)-->>
																		c.cc.Invoke(ctx, "/runtime.v1alpha2.RuntimeService/StartContainer")
															
containerd
server.go:service.Register(grpcServer)-->>
	runtime.RegisterRuntimeServiceServer(s, instrumented)-->>
			s.RegisterService(&_RuntimeService_serviceDesc, srv)-->>
				Handler:    _RuntimeService_RunPodSandbox_Handler,	// api.pb.go
				srv.(RuntimeServiceServer).RunPodSandbox(ctx, in)-->> //"/runtime.v1alpha2.RuntimeService/RunPodSandbox"
					RunPodSandbox()-->> // pkg/server/sandbox_run.go
						sandboxstore.NewSandbox()
						c.ensureImageExists()
						c.getSandboxRuntime(config, r.GetRuntimeHandler())
						netns.NewNetNS()
						c.setupPodNetwork(ctx, &sandbox)-->>
							c.netPlugin.Setup(ctx, id, path, opts...)-->>
								network.Attach(ctx, ns)-->>
									n.cni.AddNetworkList(ctx, n.config, ns.config(n.ifName))-->>
										c.addNetwork(ctx, list.Name, list.CNIVersion, net, result, rt)-->>// for each network plugin
											c.exec.FindInPath(net.Network.Type, c.Path)
											buildOneConfig(name, cniVersion, net, prevResult, rt)
											invoke.ExecPluginWithResult(ctx, pluginPath, newConf.Bytes, c.args("ADD", rt), c.exec)
						c.client.NewContainer(ctx, id, opts...)
						c.os.MkdirAll(sandboxRootDir, 0755)
						c.os.MkdirAll(volatileSandboxRootDir, 0755)
						c.setupSandboxFiles(id, config)
						container.NewTask(ctx, containerdio.NullIO, taskOpts...)
						task.Start(ctx)-->>
							c.client.TaskService().Create(ctx, request)-->>
								s.local.Create(ctx, r)-->>
									l.getRuntime(container.Runtime.Name)
									rtime.Create(ctx, r.ContainerID, opts)-->>
										b := shimBinary(ctx, bundle, opts.Runtime, m.containerdAddress, m.containerdTTRPCAddress, m.events, m.tasks)
										b.Start()
										shim.Create(ctx, opts)-->>
											c.client.Call(ctx, "containerd.task.v2.Task", "Create", req, &resp)


	runtime.RegisterImageServiceServer(s, instrumented)

kube-apiserver

cmd/kube-apiserver/app/server.go:NewAPIServerCommand()-->
completedOptions, err := Complete(s)-->
	s.Etcd.WatchCacheSizes, err = serveroptions.WriteWatchCacheSizes(sizes)
Run(completedOptions, genericapiserver.SetupSignalHandler())-->CreateServerChain()-->
	CreateServerChain()-->
		CreateKubeAPIServerConfig-->
			buildGenericConfig(s.ServerRunOptions, proxyTransport)-->
				genericapiserver.NewConfig(legacyscheme.Codecs) // create codec factory for encoding/decoding
				controlplane.DefaultAPIResourceConfigSource() // group version: enabled/disabled
				storageFactoryConfig.Complete(s.Etcd)
				completedStorageFactoryConfig.New()--> // register access path in etcd for all k8s objects
					storageFactory.AddCohabitatingResources(networking.Resource("networkpolicies"), extensions.Resource("networkpolicies"))
				s.Etcd.ApplyWithStorageFactoryTo(storageFactory, genericConfig)-->
					c.AddHealthChecks()
					c.RESTOptionsGetter = &StorageFactoryRestOptionsFactory{Options: *s, StorageFactory: factory}
// 认证
				s.Authentication.ApplyTo()--> // clientcert, serviceaccount, bootstrap token, 
					authenticatorConfig.New()-->
						newWebhookTokenAuthenticator(config) // webhook
// 鉴权
				BuildAuthorizer(s, genericConfig.EgressSelector, versionedInformers)-->
					authorizationConfig.New()-->
						rbacAuthorizer := rbac.New()--> // if authorizer type is rbac
// 准入
				buildServiceResolver(s.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers)
				admissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver)-->
					admission.PluginInitializer{webhookPluginInitializer, kubePluginInitializer}

			net.SplitHostPort(s.Etcd.StorageConfig.Transport.ServerList[0])
			utilwait.PollImmediate(etcdRetryInterval, etcdRetryLimit*etcdRetryInterval, preflight.EtcdConnection{ServerList: s.Etcd.StorageConfig.Transport.ServerList}.CheckEtcdServers)
			capabilities.Initialize() // allow privillage?
			config := &controlplane.Config{}
		createAPIExtensionsConfig()
		createAPIExtensionsServer()-->
			apiextensionsConfig.Complete().New(delegateAPIServer)-->
				s.AddHealthChecks(delegateCheck)
// 注册通用handler
				installAPI(s, c.Config) // register generic api handler e.g. index, profiling, metrics, flow control
		CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer)
			kubeAPIServerConfig.Complete().New(delegateAPIServer)
				m.InstallLegacyAPI(&c, c.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider)-->
					m.GenericAPIServer.AddPostStartHookOrDie(controllerName, bootstrapController.PostStartHook)-->
						controlplane.controller.Start()-->
							async.NewRunner(c.RunKubernetesNamespaces, c.RunKubernetesService, repairClusterIPs.RunUntil, repairNodePorts.RunUntil)
					m.GenericAPIServer.AddPreShutdownHookOrDie(controllerName, bootstrapController.PreShutdownHook)
// 注册core group API handler
					m.GenericAPIServer.InstallLegacyAPIGroup() // register handler for /api
					restStorageProviders := []RESTStorageProvider{appsrest.StorageProvider{}}
				m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...)-->
// 初始化对应group中对象的watch cache
					restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)--> // trigger appsrest.StorageProvider
						p.v1Storage(apiResourceConfigSource, restOptionsGetter)-->
							daemonsetstore.NewREST(restOptionsGetter)-->
								store.CompleteWithOptions(options)-->
									opts, err := options.RESTOptions.GetRESTOptions(e.DefaultQualifiedResource)--> // etcd.go
										ret.Decorator = genericregistry.StorageWithCacher()-->
											cacherstorage.NewCacherFromConfig(cacherConfig)-->
												watchCache := newWatchCache()-->
// 注册API handler
					m.GenericAPIServer.InstallAPIGroups(apiGroupsInfo...)-->  // register handler for /apis
						s.installAPIResources(APIGroupPrefix, apiGroupInfo, openAPIModels)-->
							apiGroupVersion.InstallREST(s.Handler.GoRestfulContainer)-->
								discovery.NewAPIVersionHandler(g.Serializer, g.GroupVersion, staticLister{apiResources})
		createAggregatorServer(aggregatorConfig, kubeAPIServer.GenericAPIServer, apiExtensionsServer.Informers)-->
			apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)
	server.PrepareRun()-->
		s.GenericAPIServer.PrepareRun()-->
			s.installHealthz()
			s.installLivez()
			s.installReadyz()
	prepared.Run(stopCh)-->
		s.runnable.Run(stopCh)--> // preparedGenericAPIServer.Run()
			s.NonBlockingRun(delayedStopCh)-->
				s.SecureServingInfo.Serve(s.Handler, s.ShutdownTimeout, internalStopCh)-->
					RunServer(secureServer, s.Listener, shutdownTimeout, stopCh)
posted @ 2022-04-06 16:28  Chuan_Chen  阅读(192)  评论(0编辑  收藏  举报
#waifu-toggle { background-color: #fa0; border-radius: 5px; bottom: 66px; color: #fff; cursor: pointer; font-size: 12px; right: 0; margin-right: -100px; padding: 5px 2px 5px 5px; position: fixed; transition: margin-right 1s; width: 60px; writing-mode: vertical-lr; } #waifu-toggle.waifu-toggle-active { margin-right: -40px; } #waifu-toggle.waifu-toggle-active:hover { margin-right: -30px; } #waifu { bottom: -1000px; right: 0; line-height: 0; margin-bottom: -10px; position: fixed; transform: translateY(3px); transition: transform .3s ease-in-out, bottom 3s ease-in-out; z-index: 1; } #waifu:hover { transform: translateY(0); } #waifu-tips { animation: shake 50s ease-in-out 5s infinite; background-color: rgba(236, 217, 188, .5); border: 1px solid rgba(224, 186, 140, .62); border-radius: 12px; box-shadow: 0 3px 15px 2px rgba(191, 158, 118, .2); font-size: 14px; line-height: 24px; margin: -30px 20px; min-height: 70px; opacity: 0; overflow: hidden; padding: 5px 10px; position: absolute; text-overflow: ellipsis; transition: opacity 1s; width: 250px; word-break: break-all; } #waifu-tips.waifu-tips-active { opacity: 1; transition: opacity .2s; } #waifu-tips span { color: #0099cc; } #waifu #live2d { cursor: grab; height: 300px; position: relative; width: 300px; } #waifu #live2d:active { cursor: grabbing; } #waifu-tool { color: #aaa; opacity: 0; position: absolute; left: -10px; top: 70px; transition: opacity 1s; } #waifu:hover #waifu-tool { opacity: 1; } #waifu-tool span { color: #7b8c9d; cursor: pointer; display: block; line-height: 30px; text-align: center; transition: color .3s; } #waifu-tool span:hover { color: #0684bd; /* #34495e */ } @keyframes shake { 2% { transform: translate(.5px, -1.5px) rotate(-.5deg); } 4% { transform: translate(.5px, 1.5px) rotate(1.5deg); } 6% { transform: translate(1.5px, 1.5px) rotate(1.5deg); } 8% { transform: translate(2.5px, 1.5px) rotate(.5deg); } 10% { transform: translate(.5px, 2.5px) rotate(.5deg); } 12% { transform: translate(1.5px, 1.5px) rotate(.5deg); } 14% { transform: translate(.5px, .5px) rotate(.5deg); } 16% { transform: translate(-1.5px, -.5px) rotate(1.5deg); } 18% { transform: translate(.5px, .5px) rotate(1.5deg); } 20% { transform: translate(2.5px, 2.5px) rotate(1.5deg); } 22% { transform: translate(.5px, -1.5px) rotate(1.5deg); } 24% { transform: translate(-1.5px, 1.5px) rotate(-.5deg); } 26% { transform: translate(1.5px, .5px) rotate(1.5deg); } 28% { transform: translate(-.5px, -.5px) rotate(-.5deg); } 30% { transform: translate(1.5px, -.5px) rotate(-.5deg); } 32% { transform: translate(2.5px, -1.5px) rotate(1.5deg); } 34% { transform: translate(2.5px, 2.5px) rotate(-.5deg); } 36% { transform: translate(.5px, -1.5px) rotate(.5deg); } 38% { transform: translate(2.5px, -.5px) rotate(-.5deg); } 40% { transform: translate(-.5px, 2.5px) rotate(.5deg); } 42% { transform: translate(-1.5px, 2.5px) rotate(.5deg); } 44% { transform: translate(-1.5px, 1.5px) rotate(.5deg); } 46% { transform: translate(1.5px, -.5px) rotate(-.5deg); } 48% { transform: translate(2.5px, -.5px) rotate(.5deg); } 50% { transform: translate(-1.5px, 1.5px) rotate(.5deg); } 52% { transform: translate(-.5px, 1.5px) rotate(.5deg); } 54% { transform: translate(-1.5px, 1.5px) rotate(.5deg); } 56% { transform: translate(.5px, 2.5px) rotate(1.5deg); } 58% { transform: translate(2.5px, 2.5px) rotate(.5deg); } 60% { transform: translate(2.5px, -1.5px) rotate(1.5deg); } 62% { transform: translate(-1.5px, .5px) rotate(1.5deg); } 64% { transform: translate(-1.5px, 1.5px) rotate(1.5deg); } 66% { transform: translate(.5px, 2.5px) rotate(1.5deg); } 68% { transform: translate(2.5px, -1.5px) rotate(1.5deg); } 70% { transform: translate(2.5px, 2.5px) rotate(.5deg); } 72% { transform: translate(-.5px, -1.5px) rotate(1.5deg); } 74% { transform: translate(-1.5px, 2.5px) rotate(1.5deg); } 76% { transform: translate(-1.5px, 2.5px) rotate(1.5deg); } 78% { transform: translate(-1.5px, 2.5px) rotate(.5deg); } 80% { transform: translate(-1.5px, .5px) rotate(-.5deg); } 82% { transform: translate(-1.5px, .5px) rotate(-.5deg); } 84% { transform: translate(-.5px, .5px) rotate(1.5deg); } 86% { transform: translate(2.5px, 1.5px) rotate(.5deg); } 88% { transform: translate(-1.5px, .5px) rotate(1.5deg); } 90% { transform: translate(-1.5px, -.5px) rotate(-.5deg); } 92% { transform: translate(-1.5px, -1.5px) rotate(1.5deg); } 94% { transform: translate(.5px, .5px) rotate(-.5deg); } 96% { transform: translate(2.5px, -.5px) rotate(-.5deg); } 98% { transform: translate(-1.5px, -1.5px) rotate(-.5deg); } 0%, 100% { transform: translate(0, 0) rotate(0); } } © 2022 GitHub, Inc. Terms Privacy Securi