Kubeadm: Woher nimmt kubeadm die Proxy-Einstellungen?

Erstellt am 28. Juni 2017  ·  13Kommentare  ·  Quelle: kubernetes/kubeadm

Es ist nicht / etc / environment, es ist nicht die aktuelle Bash-Sitzung, in der kubeadm ausgeführt wird, es ist keine Docker- oder Kubelet-Umgebung. Ich habe dies überprüft, indem ich no_proxy in all diesen Fällen auf einen anderen Wert gesetzt habe. Und aus irgendeinem Grund setzt es nach einem kubeadm init immer noch einen anderen Wert für no_proxy . Neustart, Daemon-Reload, Neustart der Dienste ändern nichts an dieser Tatsache.

Ehrlich gesagt ist es wirklich ärgerlich, dass nur die Zeile "Die IP-Adresse fo.oo.ba.rr hat einen Proxy auf blubb gesetzt" gedruckt wird, anstatt zu sagen, woher der Wert stammt. Und warum liest es nicht einfach den Wert aus / etc / environment, was die einzig wahre Quelle der Wahrheit ist, wenn es um die Proxy-Einstellung geht, oder die aktuelle Bash-Sitzung, in der ich kubeadm nenne, was am einfachsten ist Ort, an dem Änderungen vorgenommen werden können?

Was ich erwarte, wäre ungefähr so:

  1. kubeadm überprüft die aktuelle env-Variable http_proxy . (oder https_proxy wenn die sichere Kommunikation konfiguriert ist)
  2. kubeadm überprüft die aktuelle env-Variable HTTP_PROXY und warnt, wenn sie anders ist.
  3. kubeadm prüft http_proxy in / etc / environment. Es warnt, wenn es anders ist.
  4. ähnlich für Großbuchstaben.
  5. Wenn in keinem Kontext eine Variable vorhanden ist, wird davon ausgegangen, dass kein Proxy vorhanden ist, und darüber informiert .
  6. kubeadm schreibt die Manifestdateien (ich gehe davon aus, dass dies vor dem Erstellen der Docker-Container erfolgt) mit dem angegebenen Proxy, wobei die Einstellung der Prozessumgebung in Kleinbuchstaben, dann in Großbuchstaben, dann in Kleinbuchstaben / etc / environment und dann in Großbuchstaben / etc. bevorzugt wird /Umgebung.
  7. kubeadm startet die pods.
  8. kubeadm prüft, ob der Controller-Manager mit dem API-Server kommunizieren kann. Wenn es zu einem "verbotenen" oder "Timeout" kommt, wird davon ausgegangen , dass die Proxy-Einstellungen falsch sind und intern ein kubeadm reset aufgerufen .
  9. Es gibt kein Ereignis, bei dem es ohne Ausgabe für immer wartet. Es kann zumindest einigermaßen gut herausgefunden werden, ob es fortlaufende Fehler in den Protokollen von API-Server und Controller-Manager gibt und ob es neue Protokolle für> = 10 Minuten gibt. Und dann kann es mit einer entsprechenden Fehlermeldung zu einem Fehler kommen.
  10. kubeadm intern vorge pends die werben Adresse für alle no_proxy Einstellungen (das Ende hinzufügen kann Schnitt bekommen). <- Außerdem wäre es viel besser, wenn möglich einen Hostnamen zu verwenden, da no_proxy eigentlich für Namen gedacht ist, nicht für IPs.

Ich kann ernsthaft nicht ausdrücken, wie viele Arbeitsstunden dadurch Menschen in Unternehmensnetzwerken sparen würden.

help wanted prioritbacklog

Hilfreichster Kommentar

Ich habe dieses Problem "behoben", indem ich alle IP-Adressen meiner Clusterknoten in NO_PROXY aufgenommen und bei allen Minions beim Beitritt zum Cluster dasselbe NO_PROXY verwendet habe.

$ export NO_PROXY = 'ip, ip, ip, ip, .example.com'
[master] $ kubeadm init
[minion] $ kubeadm join --token = {token} abcd: 6443

Um ehrlich zu sein, bin ich mir nicht sicher, ob es alle IP-Adressen sind, die aufgelistet werden, oder ob .example.com das Problem behoben hat.

Alle 13 Kommentare

@erikbgithub Vielen Dank für diese Ausgabe!
Vorab muss ich sagen, dass ich kein Proxy-Experte bin, da ich in solchen Umgebungen nicht viel experimentiert habe.

Daher kann ich die genauen Aussagen oben nicht wirklich kommentieren, aber ich würde mich sehr freuen, wenn Sie zu kubeadm beitragen möchten, um das Verhalten hinter einem Proxy zu verbessern.

Um Ihre Frage zu beantworten, finden Sie hier den entsprechenden Go-Code:
https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/phases/controlplane/manifests.go#L432

func getProxyEnvVars() []v1.EnvVar {
    envs := []v1.EnvVar{}
    for _, env := range os.Environ() {
        pos := strings.Index(env, "=")
        if pos == -1 {
            // malformed environment variable, skip it.
            continue
        }
        name := env[:pos]
        value := env[pos+1:]
        if strings.HasSuffix(strings.ToLower(name), "_proxy") && value != "" {
            envVar := v1.EnvVar{Name: name, Value: value}
            envs = append(envs, envVar)
        }
    }
    return envs
}

https://github.com/kubernetes/kubernetes/blob/master/cmd/kubeadm/app/preflight/checks.go#L291

// HTTPProxyCheck checks if https connection to specific host is going
// to be done directly or over proxy. If proxy detected, it will return warning.
type HTTPProxyCheck struct {
    Proto string
    Host  string
    Port  int
}

func (hst HTTPProxyCheck) Check() (warnings, errors []error) {

    url := fmt.Sprintf("%s://%s:%d", hst.Proto, hst.Host, hst.Port)

    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, []error{err}
    }

    proxy, err := http.DefaultTransport.(*http.Transport).Proxy(req)
    if err != nil {
        return nil, []error{err}
    }
    if proxy != nil {
        return []error{fmt.Errorf("Connection to %q uses proxy %q. If that is not intended, adjust your proxy settings", url, proxy)}, nil
    }
    return nil, nil
}

Ich kann ernsthaft nicht ausdrücken, wie viele Arbeitsstunden dadurch Menschen in Unternehmensnetzwerken sparen würden.

Konnte nicht mehr zustimmen

cc @kad @timothysc

@luxas Danke, ich werde das

Die erste Unterfrage, die ich untersuchen werde, ist, was go tatsächlich über os.Environ() bekommt.

@erikbgithub Lassen Sie mich wissen, wenn Sie Hilfe beim Erstellen von Patches benötigen, und ich werde Ihnen helfen

@erikbgithub Als Originalautor dieses Schecks beantworte ich gerne alle Fragen.
Erste Antworten:

  • kubeadm ruft die Umgebung von Ihrer aktuell ausgeführten Sitzung ab und überprüft sie. Sie können sehen, was Sie haben, wenn Sie $ env | grep -i _proxy= | sort ausführen. ZB in unserer Firmenfirewall habe ich so etwas:
    !shell $ env | grep -i _proxy= | sort ALL_PROXY=http://proxy-ir.example.com:911 FTP_PROXY=http://proxy-ir.example.com:911 HTTPS_PROXY=http://proxy-ir.example.com:911 HTTP_PROXY=http://proxy-ir.example.com:911 NO_PROXY=.example.com all_proxy=http://proxy-ir.example.com:911 ftp_proxy=http://proxy-ir.example.com:911 http_proxy=http://proxy-ir.example.com:911 https_proxy=http://proxy-ir.example.com:911 no_proxy=.example.com $
  • Übliches Problem, auf das Benutzer treten, ohne es zu bemerken, dass die Variable no_proxy KEINE Netzwerkbereiche unterstützt. Wenn Sie also so etwas wie NO_PROXY=10.0.0.0/8, 192.168.0.0/16 , hat dies keine Auswirkung und führt weiterhin zu einer Warnung bei der Überprüfung vor dem Flug.
  • Der Inhaltsunterschied zwischen Groß- / Kleinbuchstaben * _proxy-Variablen spielt keine Rolle. Go-Code, der Proxy-Umgebungsvariablen verarbeitet, hat seine interne Logik in der Reihenfolge, in der er verarbeitet wird (wie ich mich erinnere, zuerst in Groß- und Kleinbuchstaben, aber das sollte keine Rolle spielen, Sie können nicht garantieren, in welcher Reihenfolge jede App sie verarbeitet).
  • Dateien wie / etc / environment sind distro-spezifisch und werden nicht von jeder einzelnen Binärdatei gelesen. Sie werden von Anmeldeskripten, PAM-Modulen usw. gelesen und in Prozessumgebungsvariablen eingefügt. Umgebungsvariablen können auch von z. B. SSH-Sitzungen oder von externen Verwaltungstools (wie ansible) stammen, während andere Binärdateien wie kubeadm aufgerufen werden. Es ist also weder machbar noch logisch, von einer bestimmten / etc / Umgebung oder ähnlichem abhängig zu sein.
  • Bei 8 Punkten geht es bei der Preflight-Prüfung speziell darum. Es gibt eine Warnung aus, wenn kubeadm erkennt, dass es über den Proxy zum API-Server geht. Während anfangs über diese Preflight-Prüfung diskutiert wurde, wurde vereinbart, dass diese Fälle legitim sein könnten, daher warnt sie nur und erzeugt keinen Fehler.
  • für 10: Es gab auch Einwände gegen die Manipulation dieser Variablen von mehreren Personen. (Meine ursprüngliche Idee war es, alle * _proxy-Einstellungen zu löschen, um direkte Verbindungen zu erzwingen, aber sie wurde abgelehnt, da dies legitime Gründe für eine Verbindung über Proxys sein könnten.)

Ich habe dieses Problem "behoben", indem ich alle IP-Adressen meiner Clusterknoten in NO_PROXY aufgenommen und bei allen Minions beim Beitritt zum Cluster dasselbe NO_PROXY verwendet habe.

$ export NO_PROXY = 'ip, ip, ip, ip, .example.com'
[master] $ kubeadm init
[minion] $ kubeadm join --token = {token} abcd: 6443

Um ehrlich zu sein, bin ich mir nicht sicher, ob es alle IP-Adressen sind, die aufgelistet werden, oder ob .example.com das Problem behoben hat.

Wenn PR-Kubernetes / Kubernetes # 52788 zusammengeführt werden, können Sie in NO_PROXY IP-Bereichen für Ihre Knoten angeben. es wird die Dinge sehr vereinfachen.

Ein bisschen komisch. wenn ich in den Code "checks.go" schaue.
Es wird immer eine Fehlermeldung zurückgegeben, wenn der Proxy einen Wert enthält.

wenn Proxy! = nil {
return [] error {fmt.Errorf ("Verbindung zu% q verwendet Proxy% q. Wenn dies nicht beabsichtigt ist, passen Sie Ihre Proxy-Einstellungen an", URL, Proxy)}, nil
}}
return nil, nil

Im Unternehmen ... gibt es notwendigerweise drei Proxy-Optionen. (http_proxy, https_proxy, no_proxy)
http_ * ist eine obligatorische Option, um Bilder für die Verbindung zum Internet abzurufen.
Wenn die Option no_proxy festgelegt ist, sollte eine Fehlermeldung zurückgegeben werden.

"pl, setze die Option (no_proxy) so, dass sie nicht für die interne Verbindung an den Proxy weitergeleitet wird."

Ich möchte fragen, ob kubeadm join http_proxy unterstützt.

Ich schaffe es, kubeadm init dazu zu bringen, mit http_proxy und no_proxy zu arbeiten, aber es scheint, dass kubeadm join Fehler wie erzeugt

kubelet.go:2105] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

remote_runtime.go:92] RunPodSandbox from runtime service failed: rpc error: code = Unknown desc = failed pulling image "gcr.io/google_containers/pause-amd64:3.0": Get https://gcr.io/v1/_ping: read tcp <my-ip>:58742->74.125.68.82:443: read: connection reset by peer

und auch
/ etc / environment ist leer anstatt mit der Konfiguration wie im Master gefüllt.

was mich glauben lässt, dass vielleicht http_proxy und no_proxy für kubeadm join noch nicht unterstützt werden.

Noch einmal auf dieses Problem stoßen. Der Proxy wird immer noch falsch verwendet, und ich kann anscheinend die Proxy- und no_proxy-Einstellungen nicht ändern.

Nach meiner Erfahrung verwendet kubeadm den in / etc / environment definierten Proxy

Nach meiner Erfahrung verwendet kubeadm den in / etc / environment definierten Proxy

Ja - in meinem Fall ist es auch / etc / environment

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen