sidecar 注入原理

func (s *Server) initSidecarInjector(args *PilotArgs) (*inject.Webhook, error) {
    // 当前常量: "./var/lib/istio/inject"
    injectPath := args.InjectionOptions.InjectionDirectory
    if injectPath == "" || !injectionEnabled.Get() {
        log.Infof("Skipping sidecar injector, injection path is missing or disabled.")
        return nil, nil
    }

    // 本地或者远程配置存在将启动注入
    var watcher inject.Watcher
    // 查看本地是否有配置
    if _, err := os.Stat(filepath.Join(injectPath, "config")); !os.IsNotExist(err) {
        configFile := filepath.Join(injectPath, "config")
        valuesFile := filepath.Join(injectPath, "values")
        watcher, err = inject.NewFileWatcher(configFile, valuesFile)
        if err != nil {
            return nil, err
        }
    } else {
        //访问configmap,常量istio-sidecar-injector
        configMapName := getInjectorConfigMapName(args.Revision)
        cms := s.kubeClient.CoreV1().ConfigMaps(args.Namespace)
        if _, err := cms.Get(context.TODO(), configMapName, metav1.GetOptions{}); err != nil {
            if errors.IsNotFound(err) {
                log.Infof("Skipping sidecar injector, template not found")
                return nil, nil
            }
            return nil, err
        }
        watcher = inject.NewConfigMapWatcher(s.kubeClient, args.Namespace, configMapName, "config", "values")
    }

    log.Info("initializing sidecar injector")

    parameters := inject.WebhookParameters{
        Watcher: watcher,
        Env:     s.environment,
        // Disable monitoring. The injection metrics will be picked up by Pilots metrics exporter already
        MonitoringPort: -1,
        Mux:            s.httpsMux,
        Revision:       args.Revision,
    }

    wh, err := inject.NewWebhook(parameters)
    if err != nil {
        return nil, fmt.Errorf("failed to create injection webhook: %v", err)
    }
    // Patch cert if a webhook config name is provided.
    // This requires RBAC permissions - a low-priv Istiod should not attempt to patch but rely on
    // operator or CI/CD
    if features.InjectionWebhookConfigName.Get() != "" {
        s.addStartFunc(func(stop <-chan struct{}) error {
            // No leader election - different istiod revisions will patch their own cert.
            caBundlePath := s.caBundlePath
            if hasCustomTLSCerts(args.ServerOptions.TLSOptions) {
                caBundlePath = args.ServerOptions.TLSOptions.CaCertFile
            }
            webhooks.PatchCertLoop(features.InjectionWebhookConfigName.Get(), webhookName, caBundlePath, s.kubeClient, stop)
            return nil
        })
    }
    s.addStartFunc(func(stop <-chan struct{}) error {
        go wh.Run(stop)
        return nil
    })
    return wh, nil
}

```go func (wh Webhook) inject(ar kube.AdmissionReview, path string) *kube.AdmissionResponse { ... // 生成patch patchBytes, err := injectPod(params) if err != nil { handleError(fmt.Sprintf("Pod injection failed: %v", err)) return toAdmissionResponse(err) }

}

Last updated

Was this helpful?