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

逻辑比较简单,判断当前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}

  1. 第三个执行的是OverlaySidecar
func (os *OverlaySidecar) execute(ipd *InjectProcessData) admission.Response {log.Info("=============== OverlaySidecar ================")if !ipd.injectFileds.OverlaySidecar(*ipd.annotation, ipd.annotationOverlay, &ipd.pod.ObjectMeta.Annotations) {return PatchReq(ipd.pod, ipd.req)}return os.next.execute(ipd)}// OverlaySidecar overlays default configfunc (s *SidecarInjectField) OverlaySidecar(a Annotations, ao *AnnotationOverlay, annotation *map[string]string) bool {s.Initcontainer.Command = make([]string, 1)s.Initcontainer.Args = make([]string, 2)if nil == s.ConfigmapVolume.ConfigMap {s.ConfigmapVolume.ConfigMap = new(corev1.ConfigMapVolumeSource)}limitsStr := ""requestStr := ""// 创建sidercar注解map对象,其初始值从上一步执行结果中获取.map中的key为sidecar注解去掉前缀后的名称annoField := map[string]*string{"initcontainer.Name":&s.Initcontainer.Name,"initcontainer.Image":&s.Initcontainer.Image,"initcontainer.Command":&s.Initcontainer.Command[0],"initcontainer.args.Option":&s.Initcontainer.Args[0],"initcontainer.args.Command":&s.Initcontainer.Args[1],"initcontainer.resources.limits":&limitsStr,"initcontainer.resources.requests": &requestStr,"sidecarVolume.Name":&s.SidecarVolume.Name,"sidecarVolumeMount.MountPath":&s.SidecarVolumeMount.MountPath,"configmapVolume.ConfigMap.Name":&s.ConfigmapVolume.ConfigMap.Name,"configmapVolume.Name":&s.ConfigmapVolume.Name,"configmapVolumeMount.MountPath":&s.ConfigmapVolumeMount.MountPath,"env.Name":&s.Env.Name,"env.Value":&s.Env.Value,}// 从全量注解中获取sidercar前缀的注解,遍历,检查Pod有没有设置相应sidercar注解,如果设置了,则覆盖map中对应key原来的值anno := GetAnnotationsByPrefix(a, sidecarAnnotationPrefix)for _, v := range anno.Annotations {fieldName := strings.TrimPrefix(v.Name, sidecarAnnotationPrefix)if pointer, ok := annoField[fieldName]; ok {if !s.setValue(pointer, ao, annotation, v) {return false}}}s.SidecarVolumeMount.Name = s.SidecarVolume.Names.ConfigmapVolumeMount.Name = s.ConfigmapVolume.Names.Initcontainer.VolumeMounts = []corev1.VolumeMount{s.SidecarVolumeMount}// 设置init container的资源限制if limitsStr != "nil" {limits := make(corev1.ResourceList)err := json.Unmarshal([]byte(limitsStr), &limits)if err != nil {log.Error(err, "unmarshal limitsStr error")return false}s.Initcontainer.Resources.Limits = limits}// 设置init container需要申请的资源if requestStr != "nil" {requests := make(corev1.ResourceList)err := json.Unmarshal([]byte(requestStr), &requests)if err != nil {log.Error(err, "unmarshal requestStr error")return false}s.Initcontainer.Resources.Requests = requests}// the sidecar volume's type is determineds.SidecarVolume.VolumeSource.EmptyDir = nilreturn true}

经验总结扩展阅读