Skywalking Swck Agent注入实现分析( 二 )

  1. 创建inject chain对象Inject chain对象集合了此次有变更的Pod, webhook request, k8s client以及注解、swagent等对象
// NewInjectProcess create a new InjectProcessfunc NewInjectProcess(ctx context.Context, injectFileds *SidecarInjectField, annotation *Annotations,annotationOverlay *AnnotationOverlay, swAgentL *v1alpha1.SwAgentList, pod *corev1.Pod, req admission.Request, log logr.Logger,kubeclient client.Client) *InjectProcessData {return &InjectProcessData{ctx:ctx,injectFileds:injectFileds,annotation:annotation,annotationOverlay: annotationOverlay,swAgentL:swAgentL,pod:pod,req:req,log:log,kubeclient:kubeclient,}}
  1. 看下ip.Run()方法经过了前面铺垫,终于到了主题了,run方法首先按照执行顺序倒序构造了一个执行链,然后执行 。
// Run will connect the above six steps into a chain and start to execute the first stepfunc (ipd *InjectProcessData) Run() admission.Response {// set final steppodInject := &PodInject{}// set next step is PodInjectgetConfigmap := &GetConfigmap{}getConfigmap.setNext(podInject)// set next step is GetConfigmapoverlayPlugins := &OverlayPlugins{}overlayPlugins.setNext(getConfigmap)// set next step is OverlayPluginsoverlayAgent := &OverlayAgent{}overlayAgent.setNext(overlayPlugins)// set next step is OverlayAgentoverlaysidecar := &OverlaySidecar{}overlaysidecar.setNext(overlayAgent)// set next step is OverlaySwAgentCRoverlaySwAgentCR := &OverlaySwAgentCR{}overlaySwAgentCR.setNext(overlaysidecar)// set next step is OverlaySidecargetStrategy := &GetStrategy{}getStrategy.setNext(overlaySwAgentCR)// this is first step and do real injectionreturn getStrategy.execute(ipd)}
  1. 首先执行的是GetStrategy
func (gs *GetStrategy) execute(ipd *InjectProcessData) admission.Response {log.Info("=============== GetStrategy ================")ipd.injectFileds.GetInjectStrategy(*ipd.annotation, &ipd.pod.ObjectMeta.Labels, &ipd.pod.ObjectMeta.Annotations)if !ipd.injectFileds.NeedInject {log.Info("don't inject agent")return admission.Allowed("ok")}return gs.next.execute(ipd)}// GetInjectStrategy gets user's injection strategyfunc (s *SidecarInjectField) GetInjectStrategy(a Annotations, labels,annotation *map[string]string) {// set default values.NeedInject = false// set NeedInject's value , if the pod has the label "swck-java-agent-injected=true", means need injectif *labels == nil {return}if strings.EqualFold((*labels)[ActiveInjectorLabel], "true") {s.NeedInject = true}if *annotation == nil {return}// set injectContainer's valueif v, ok := (*annotation)[sidecarInjectContainerAnno]; ok {s.InjectContainer = v}}逻辑比较简单,判断当前pod需不需要inject,以及获取inject的container名字的正则表达式 。8. 第二个执行的是OverlaySwAgentCR
// get configs from SwAgent CRfunc (gs *OverlaySwAgentCR) execute(ipd *InjectProcessData) admission.Response {log.Info(fmt.Sprintf("=============== OverlaySwAgentCR(%d) ================ ", len(ipd.swAgentL.Items)))if !ipd.injectFileds.OverlaySwAgentCR(ipd.swAgentL, ipd.pod) {log.Info("overlay SwAgent cr config error.")return PatchReq(ipd.pod, ipd.req)}return gs.next.execute(ipd)}func (s *SidecarInjectField) OverlaySwAgentCR(swAgentL *v1alpha1.SwAgentList, pod *corev1.Pod) bool {s.ConfigmapVolume.ConfigMap = new(corev1.ConfigMapVolumeSource)// 如果找到多个匹配的SwAgent,则应用最后一个,其它几个忽略if len(swAgentL.Items) > 0 {swAgent := swAgentL.Items[len(swAgentL.Items)-1]log.Info(fmt.Sprintf("agent %s loaded.", swAgent.Name))// 首先配置了shared volume, mount path 。默认sharedVolumeName是sky-agent,mount path是/sky/agent// volume name可以更改, mountPath无法更改, mount path是业务容器上的paths.SidecarVolume.Name = swAgent.Spec.SharedVolumeNames.SidecarVolume.VolumeSource.EmptyDir = &corev1.EmptyDirVolumeSource{}s.SidecarVolumeMount.Name = swAgent.Spec.SharedVolumeNames.SidecarVolumeMount.MountPath = mountPath// 如果swagent配置了configmap,则设置业务容器mount path,实际是由configmap中的agent配置// 覆盖agent镜像中的配置if swAgent.Spec.SwConfigMapVolume != nil {if len(swAgent.Spec.SwConfigMapVolume.Name) > 0 &&len(swAgent.Spec.SwConfigMapVolume.ConfigMapName) > 0 &&len(swAgent.Spec.SwConfigMapVolume.ConfigMapMountFile) > 0 {//s.ConfigmapVolume = corev1.Volume{}s.ConfigmapVolume.Name = swAgent.Spec.SwConfigMapVolume.Names.ConfigmapVolume.ConfigMap = new(corev1.ConfigMapVolumeSource)s.ConfigmapVolume.ConfigMap.Name = swAgent.Spec.SwConfigMapVolume.ConfigMapName//s.ConfigmapVolumeMount = corev1.VolumeMount{}s.ConfigmapVolumeMount.Name = swAgent.Spec.SwConfigMapVolume.Names.ConfigmapVolumeMount.MountPath = "/sky/agent/config/" + swAgent.Spec.SwConfigMapVolume.ConfigMapMountFiles.ConfigmapVolumeMount.SubPath = swAgent.Spec.SwConfigMapVolume.ConfigMapMountFile}}// init containers.Initcontainer.Name = swAgent.Spec.JavaSidecar.Names.Initcontainer.Image = swAgent.Spec.JavaSidecar.Images.Initcontainer.Args = swAgent.Spec.JavaSidecar.Argss.Initcontainer.Command = swAgent.Spec.JavaSidecar.Commands.Initcontainer.VolumeMounts = append(s.Initcontainer.VolumeMounts, corev1.VolumeMount{Name:swAgent.Spec.SharedVolumeName,MountPath: mountPath,})// 将swagent配置的环境变量设置为业务容器的环境变量s.Envs = swAgent.Spec.JavaSidecar.Envs.InjectContainer = swAgent.Spec.ContainerMatcher}return true}

推荐阅读