Kubeadm: Откуда kubeadm берет настройки прокси?

Созданный на 28 июн. 2017  ·  13Комментарии  ·  Источник: kubernetes/kubeadm

Это не / etc / environment, это не текущий сеанс bash, в котором работает kubeadm, это не среда docker или kubelet. Я проверил это, установив для no_proxy другое значение во всех этих случаях. И по какой-то причине после kubeadm init он все еще продолжает устанавливать другое значение для no_proxy . Перезагрузка, перезагрузка демона, перезапуск служб - все это не меняет этого факта.

Честно говоря, действительно раздражает то, что он печатает только строку «ip-адрес fo.oo.ba.rr имеет прокси, установленный на blubb» вместо того, чтобы указать, откуда он берет значение. И почему он просто не считывает значение из / etc / environment, который является единственным истинным источником истины, когда дело доходит до настройки прокси, или текущего сеанса bash, в котором я вызываю kubeadm что является самым простым место для внесения изменений?

Я ожидал, что будет что-то вроде этого:

  1. kubeadm проверяет текущую переменную окружения http_proxy . (или https_proxy если настроена безопасная связь)
  2. kubeadm проверяет текущую переменную env HTTP_PROXY и предупреждает, если она отличается.
  3. kubeadm проверяет http_proxy в / etc / environment. Предупреждает, если другое.
  4. аналогично для верхнего регистра.
  5. если нет ни одной переменной ни в одном контексте, он предполагает, что прокси не существует, и сообщает об этом.
  6. kubeadm записывает файлы манифеста (я предполагаю, что это делается до создания контейнеров докеров) с заданным прокси, отдавая предпочтение настройке среды процесса в нижнем регистре, затем в верхнем регистре, затем в нижнем регистре / etc / environment, затем в верхнем регистре / etc /среда.
  7. kubeadm запускает поды.
  8. kubeadm проверяет, может ли диспетчер-диспетчер взаимодействовать с сервером api. Если он получает «запрещено» или «тайм-аут», он предполагает, что настройки прокси неправильные и ошибаются , вызывая kubeadm reset внутри.
  9. нет события, где он просто ждет вечно без какого-либо вывода. Он может, по крайней мере, достаточно хорошо определить, есть ли постоянные ошибки в журналах api-server и controller-manager, а также есть ли какие-либо новые журналы в течение> = 10 минут. И тогда он может выдать соответствующее сообщение об ошибке.
  10. kubeadm внутри предварительно pends рекламировать адрес всем no_proxy настройки (добавить конец он может получить срез). <- Также было бы намного лучше использовать имя хоста, если это возможно, поскольку no_proxy на самом деле предназначено для имен, а не IP-адресов.

Я серьезно не могу выразить, сколько рабочих часов это сэкономило бы людям в корпоративных сетях.

help wanted prioritbacklog

Самый полезный комментарий

Я «исправил» эту проблему, включив IP-адреса всех моих узлов кластера в NO_PROXY и используя тот же NO_PROXY для всех миньонов при присоединении к кластеру.

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

Честно говоря, я не уверен, все ли перечисленные IP-адреса или .example.com устранили проблему.

Все 13 Комментарий

@erikbgithub Большое спасибо за эту проблему!
Сразу должен сказать, что я не эксперт по прокси, так как я мало экспериментировал в таких средах.

Так что я не могу комментировать точные утверждения выше, но я был бы очень рад, если бы вы захотели внести свой вклад в kubeadm, чтобы улучшить поведение прокси.

Чтобы ответить на ваш вопрос, вот соответствующий код перехода:
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
}

Я серьезно не могу выразить, сколько рабочих часов это сэкономило бы людям в корпоративных сетях.

Не могу больше согласиться

Копия @kad @timothysc

@luxas Спасибо, я разберусь с этим, когда получу круглый урок. Прежде чем я смогу предоставить патчи, мне нужно выучить некоторые из них, поэтому я был бы признателен, если бы другие могли добавить их на данный момент. ;-)

Первый подвопрос, который я рассмотрю, это то, что go на самом деле получает через os.Environ() .

@erikbgithub Дайте мне знать, если вам понадобится помощь с созданием патчей, и я помогу

@erikbgithub как автор этой проверки, я буду рад ответить на любые вопросы.
Первые несколько ответов:

  • kubeadm получает и проверяет среду из вашего текущего сеанса. Вы можете увидеть, что у вас получится, если вы выполните $ env | grep -i _proxy= | sort . Например, внутри брандмауэра нашей компании есть что-то вроде этого:
    !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 $
  • Обычная проблема, на которую люди наступают, не осознавая этого, заключается в том, что переменная no_proxy НЕ поддерживает сетевые диапазоны. поэтому добавление чего-то вроде NO_PROXY=10.0.0.0/8, 192.168.0.0/16 не будет иметь никакого эффекта и по-прежнему будет вызывать предупреждение при предполетной проверке.
  • Разница в содержании переменных * _proxy в верхнем / нижнем регистре не имеет значения. Код Go, который обрабатывает переменные среды прокси, имеет свою внутреннюю логику, в которой он обрабатывает их (как я помню, сначала в верхнем регистре, затем в нижнем регистре, но это не имеет значения, вы не можете гарантировать, в каком порядке каждое приложение их обрабатывает)
  • такие файлы, как / etc / environment, относятся к конкретному дистрибутиву и не читаются каждым отдельным двоичным файлом. они считываются и вводятся в переменные среды процесса с помощью сценариев входа в систему, модулей PAM и т. д. Переменные среды также могут поступать, например, из сеансов SSH или из внешних инструментов управления (например, ansible) при вызове других двоичных файлов, таких как kubeadm. Таким образом, быть зависимым от конкретного / etc / environment или подобного невозможно и не логично.
  • Для 8 балла именно об этом и идет предполетная проверка. Он выдает предупреждение, если kubeadm обнаруживает, что он переходит через прокси-сервер на сервер API. Хотя изначально обсуждалась эта предполетная проверка, было решено, что эти случаи могут быть законными, поэтому она только предупреждает , а не приводит к ошибке.
  • для 10: это были также возражения против манипулирования этими переменными от нескольких людей. (Моя первоначальная идея заключалась в том, чтобы отказаться от всех настроек * _proxy для принудительного прямого подключения, но она была отклонена, поскольку это могло быть законной причиной для подключения через прокси).

Я «исправил» эту проблему, включив IP-адреса всех моих узлов кластера в NO_PROXY и используя тот же NO_PROXY для всех миньонов при присоединении к кластеру.

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

Честно говоря, я не уверен, все ли перечисленные IP-адреса или .example.com устранили проблему.

если PR kubernetes / kubernetes # 52788 будет объединен, можно будет указать в NO_PROXY диапазоны IP-адресов для ваших узлов. это сильно упростит жизнь.

Немного утомлен. если я загляну в код "check.go".
он всегда возвращает сообщение об ошибке, если в прокси есть значение.

if proxy! = nil {
return [] error {fmt.Errorf ("Соединение с% q использует прокси% q. Если это не предназначено, измените настройки прокси", url, прокси)}, nil
}
вернуть ноль, ноль

На предприятии ... обязательно есть три варианта прокси. (http_proxy, https_proxy, no_proxy)
http_ * - обязательный параметр для получения изображений для подключения к Интернету.
если не задана опция no_proxy ... тогда она должна вернуть сообщение об ошибке.

"pl, установите параметр (no_proxy), чтобы он не перенаправлялся на прокси для внутреннего подключения"

Я хочу спросить, поддерживает ли kubeadm join http_proxy?

Мне удалось заставить kubeadm init работать с http_proxy и no_proxy, но кажется, что соединение kubeadm вызывает такие ошибки, как

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

а также
/ etc / environment пуст, а не заполнен конфигурацией, как в мастере.

что позволяет мне поверить, что, возможно, http_proxy и no_proxy еще не поддерживаются для kubeadm join.

Еще раз сталкиваюсь с этой проблемой. Он по-прежнему неправильно использует прокси, и мне кажется, что я не могу изменить настройки прокси и no_proxy.

По моему опыту, kubeadm использует прокси, определенный в / etc / environment.

По моему опыту, kubeadm использует прокси, определенный в / etc / environment.

Ага - в моем случае это тоже / etc / environment

Была ли эта страница полезной?
0 / 5 - 0 рейтинги