Kubeadm: De onde o kubeadm obtém as configurações de proxy?

Criado em 28 jun. 2017  ·  13Comentários  ·  Fonte: kubernetes/kubeadm

Não é / etc / environment, não é a sessão bash atual em que o kubeadm está sendo executado, não é docker ou ambiente kubelet. Eu verifiquei isso definindo no_proxy com um valor diferente em todas essas instâncias. E por alguma razão, depois de kubeadm init ele ainda continua a definir outro valor para no_proxy . Reiniciar, recarregar daemon, reiniciar todos os serviços não muda esse fato.

Honestamente, é realmente irritante que ele imprima apenas a linha "o endereço ip fo.oo.ba.rr tem um proxy definido como blubb" em vez de dizer de onde tira o valor. E por que ele simplesmente não lê o valor de / etc / environment, que é a única verdadeira fonte da verdade quando se trata de configuração de proxy, ou a sessão bash atual na qual chamo kubeadm que é a mais fácil lugar para fazer alterações?

O que eu espero seria algo assim:

  1. O kubeadm verifica a variável env atual http_proxy . (ou https_proxy se a comunicação segura estiver configurada)
  2. O kubeadm verifica a variável env atual HTTP_PROXY e avisa se ela é diferente.
  3. O kubeadm verifica http_proxy em / etc / environment. Avisa se é diferente.
  4. semelhante para maiúsculas.
  5. se não houver nenhuma variável em nenhum contexto, ele assume que não há proxy e informa sobre isso.
  6. O kubeadm grava os arquivos de manifesto (suponho que isso seja feito antes de criar os contêineres do docker) com o proxy fornecido, dando preferência à configuração do ambiente de processo em letras minúsculas, depois em maiúsculas, em seguida em minúsculas / etc / environment e, em seguida, em maiúsculas / etc /ambiente.
  7. kubeadm inicia os pods.
  8. O kubeadm verifica se o gerenciador do controlador pode se comunicar com o servidor API. Se receber um "proibido" ou "tempo limite", ele assume que as configurações de proxy estão erradas e com erros , chamando kubeadm reset internamente.
  9. não há nenhum evento onde ele apenas espere para sempre sem qualquer saída. Ele pode, pelo menos razoavelmente, descobrir se há erros contínuos nos logs do api-server e do controller-manager, bem como se há novos logs por> = 10 minutos. E então pode ocorrer um erro com uma mensagem de erro correspondente.
  10. O kubeadm pré- adiciona internamente o endereço do anúncio para todas as configurações de no_proxy (adicione o final que pode ser cortado). <- Além disso, seria muito melhor usar um nome de host, se possível, uma vez que no_proxy na verdade se destina a nomes, não IPs.

Sério, não consigo expressar quantas horas de trabalho isso economizaria pessoas em redes corporativas.

help wanted prioritbacklog

Comentários muito úteis

Eu "consertei" esse problema incluindo todos os meus IPs de nó de cluster em NO_PROXY e usando o mesmo NO_PROXY em todos os lacaios ao ingressar no cluster.

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

Para ser honesto, não tenho certeza se foram todos os endereços IP sendo enumerados ou o .example.com que corrigiu o problema.

Todos 13 comentários

@erikbgithub Muito obrigado por esta edição!
Para começar, devo dizer que não sou um especialista em proxy, pois não experimentei muito nesses ambientes.

Portanto, não posso comentar sobre as declarações exatas acima, mas ficaria muito feliz se você quisesse contribuir com o kubeadm para melhorar o comportamento por trás de um proxy.

Para responder à sua pergunta, aqui está o código go relevante:
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
}

Sério, não consigo expressar quantas horas de trabalho isso economizaria pessoas em redes corporativas.

Não poderia concordar mais

cc @kad @timothysc

@luxas Obrigado. Vou resolver isso quando conseguir uma tuitinha redonda. Antes de poder fornecer os patches, preciso aprender alguns, portanto, agradeceria se outros pudessem usar agora. ;-)

A primeira subquestão que examinarei é o que vai realmente obter por meio de os.Environ() .

@erikbgithub Deixe-me saber se você precisa de alguma ajuda com a criação de patches e eu ajudarei

@erikbgithub como autor original desse cheque, ficarei feliz em responder a quaisquer perguntas.
Primeiras respostas:

  • O kubeadm obtém e verifica o ambiente da sessão em execução no momento. Você pode ver o que tem se executar $ env | grep -i _proxy= | sort . Por exemplo, dentro do firewall da nossa empresa, tenho algo assim:
    !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 $
  • Problema comum que as pessoas estão pisando sem perceber, que a variável no_proxy NÃO suporta intervalos de rede. portanto, colocar algo como NO_PROXY=10.0.0.0/8, 192.168.0.0/16 não terá nenhum efeito e ainda produzirá um aviso na verificação pré-voo.
  • A diferença de conteúdo entre as variáveis ​​maiúsculas / minúsculas * _proxy não importa. O código Go que lida com variáveis ​​de ambiente de proxy tem sua lógica interna na ordem em que ele o processa (pelo que me lembro, primeiro maiúsculas, depois minúsculas, mas isso não importa, você não pode garantir em que ordem cada aplicativo as processa)
  • arquivos como / etc / environment são específicos da distro e não são lidos por cada binário individual. eles são lidos e injetados em variáveis ​​de ambiente de processo por scripts de login, módulos PAM, etc. Variáveis ​​de ambiente também podem vir de, por exemplo, sessões SSH ou de ferramentas de gerenciamento externas (como ansible) enquanto chama outros binários, como kubeadm. Portanto, ser dependente de um / etc / ambiente específico ou semelhante não é viável nem lógico.
  • Para 8 pontos, a verificação preflight é especificamente sobre isso. Ele avisa se o kubeadm detecta que está passando do proxy para o servidor da API. Embora tenha havido uma discussão sobre essa verificação preflight inicialmente, foi acordado que esses casos podem ser legítimos, portanto, apenas avisa , não produzindo erro.
  • para 10: também eram objeções sobre a manipulação dessas variáveis ​​de várias pessoas. (minha ideia inicial era descartar todas as configurações de * _proxy para forçar conexões diretas, mas foi rejeitado, pois podem ser razões legítimas para conectar por proxies).

Eu "consertei" esse problema incluindo todos os meus IPs de nó de cluster em NO_PROXY e usando o mesmo NO_PROXY em todos os lacaios ao ingressar no cluster.

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

Para ser honesto, não tenho certeza se foram todos os endereços IP sendo enumerados ou o .example.com que corrigiu o problema.

se PR kubernetes / kubernetes # 52788 for mesclado, será possível especificar os intervalos de IP NO_PROXY para seus nós. vai simplificar muito as coisas.

Um pouco estranho. se eu olhar para o código "checks.go".
ele sempre retorna mensagem de erro se houver valor no proxy.

se proxy! = nil {
return [] error {fmt.Errorf ("A conexão com% q usa proxy% q. Se não for essa a intenção, ajuste suas configurações de proxy", url, proxy)}, nil
}
retornar nulo, nulo

Na empresa ... existem necessariamente três opções de proxy. (http_proxy, https_proxy, no_proxy)
http_ * é uma opção obrigatória para obter imagens para conexão com a internet.
se não houver uma opção no_proxy definida ... então ele deve retornar uma mensagem de erro.

"pl, defina a opção (no_proxy) para não ser roteado para o proxy para conexão interna"

Eu quero perguntar se o kubeadm join oferece suporte a http_proxy.

Consigo fazer o kubeadm init funcionar com http_proxy e no_proxy, mas parece que a junção do kubeadm produz erros como

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

e também
/ etc / environment está vazio em vez de preenchido com a configuração como no mestre.

o que me permite acreditar que http_proxy e no_proxy ainda não são compatíveis com o kubeadm join.

Encontrando este problema mais uma vez. Ele ainda usa o proxy incorretamente e não consigo modificar as configurações de proxy e no_proxy.

Pela minha experiência, o kubeadm usa o proxy definido em / etc / environment

Pela minha experiência, o kubeadm usa o proxy definido em / etc / environment

Sim - no meu caso também é / etc / environment

Esta página foi útil?
0 / 5 - 0 avaliações