Kubeadm: kubeadm从哪里获取代理设置?

创建于 2017-06-28  ·  13评论  ·  资料来源: kubernetes/kubeadm

不是/ etc / environment,不是kubeadm正在运行的当前bash会话,不是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检查当前的环境变量HTTP_PROXY警告它是否不同。
  3. kubeadm在/ etc / environment中检查http_proxy 。 它警告是否不同。
  4. 大写字母类似。
  5. 如果在两种情况下都没有变量,则假定没有代理并通知它。
  6. kubeadm使用给定的代理写入清单文件(我假设这是在创建docker容器之前完成的),优先选择进程环境设置,小写,大写,小写/ etc / environment,大写/ etc /环境。
  7. kubeadm启动豆荚。
  8. kubeadm检查控制器管理器是否可以与api服务器对话。 如果收到“禁止”或“超时”,则假定代理设置错误并且错误,内部调用kubeadm reset
  9. 没有任何事件会永远等待而没有任何输出。 它至少可以合理地确定api-server和controller-manager日志中是否连续出现错误,以及是否在10分钟内有新日志。 然后它可能会出错并显示相应的错误消息。
  10. kubeadm在内部将广告地址设置为所有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做出贡献以使代理的行为更好,我将感到非常高兴。

要回答您的问题,以下是相关的go代码:
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
}

我严重无法说明它将为企业网络中的人员节省多少工作时间。

完全同意

cc @kad @timothysc

@luxas谢谢,当我得到一轮学费的时候,我会解决这个问题的。 在提供补丁之前,我需要学习一些知识,因此,如果其他人可以暂时加入,我将不胜感激。 ;-)

我要研究的第一个子问题是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范围内为您的节点指定。 它将简化很多事情。

有点奇怪。 如果我看着代码“ checks.go”。
如果代理中有值,它总是返回错误消息。

如果proxy!= nil {
return [] error {fmt.Errorf(“与%q的连接使用代理%q。如果这不是故意的,请调整您的代理设置”,URL,代理)},无
}
返回nil,nil

在企业中……必然有三个代理选项。 (http_proxy,https_proxy,no_proxy)
http_ *是拉取图像以连接到Internet的必选选项。
如果没有设置no_proxy选项,那么它应该返回错误消息。

“ pl,设置选项(no_proxy)不会路由到内部连接的代理”

我想问kubeadm join是否支持http_proxy?

我设法使kubeadm初始化可与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为空,而不是像主服务器那样填充配置。

这让我相信也许kubeadm连接尚不支持http_proxy和no_proxy。

再次遇到这个问题。 它仍然使用不正确的代理服务器,我似乎无法修改代理服务器和no_proxy设置。

请参阅#687,#182或堆栈溢出: https :

根据我的经验,kubeadm使用/ etc / environment中定义的代理

根据我的经验,kubeadm使用/ etc / environment中定义的代理

是的-就我而言,它也是/ etc / environment

此页面是否有帮助?
0 / 5 - 0 等级