仅在使用 Ansible 运行时 kubectl 和 helm 命令上的“无法连接到服务器:禁止”

Lio*_*ion 0 ansible kubernetes kubectl

我想使用 Ansible自动化kubectlhelm命令。目标机器已正确配置,因此两者都可以在手动 shell(例如kubectl get nodeshelm list)中在 cli 上工作。但是当尝试进行任何 API 调用时,例如获取服务器版本

- name: List charts
  shell: kubectl version -v=8
Run Code Online (Sandbox Code Playgroud)

它因Forbidden错误而中断。详细的日志记录并没有给我更多的细节:

fatal: [127.0.0.1]: FAILED! => changed=true 
  cmd: kubectl version -v=10
  delta: '0:00:00.072452'
  end: '2020-02-27 15:22:36.227928'
  msg: non-zero return code
  rc: 255
  start: '2020-02-27 15:22:36.155476'
  stderr: |-
    I0227 15:22:36.224517   27321 loader.go:359] Config loaded from file /home/user/.kube/config
    I0227 15:22:36.225211   27321 round_trippers.go:386] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: kubectl/v1.11.3 (linux/amd64) kubernetes/a452946" 'https://k8smaster01:6443/version?timeout=32s'
    I0227 15:22:36.225975   27321 round_trippers.go:405] GET https://k8smaster01:6443/version?timeout=32s  in 0 milliseconds
    I0227 15:22:36.225986   27321 round_trippers.go:411] Response Headers:
    I0227 15:22:36.226062   27321 helpers.go:219] Connection error: Get https://k8smaster01:6443/version?timeout=32s: Forbidden
    F0227 15:22:36.226080   27321 helpers.go:119] Unable to connect to the server: Forbidden
  stderr_lines: <omitted>
  stdout: 'Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T18:02:47Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}'
  stdout_lines: <omitted>
Run Code Online (Sandbox Code Playgroud)

但是,当像这样向那些 API url 发送手动请求时

- name: Test master connection
  shell: curl -k https://k8smaster01:6443/version?timeout=32s
Run Code Online (Sandbox Code Playgroud)

有用:

stderr_lines: <omitted>
  stdout: |-
    {
      "major": "1",
      "minor": "11",
      "gitVersion": "v1.11.3",
      "gitCommit": "a4529464e4629c21224b3d52edfe0ea91b072862",
      "gitTreeState": "clean",
      "buildDate": "2018-09-09T17:53:03Z",
      "goVersion": "go1.10.3",
      "compiler": "gc",
      "platform": "linux/amd64"
    }
Run Code Online (Sandbox Code Playgroud)

为什么kubectl使用 Ansible 执行时API 调用不起作用?

我在代理服务器后面,但k8smaster01设置在no_proxy. Ansible 明白了,我$no_proxy在任务中打印出来进行测试。

因为curl我使用-k了来自 k8s 的自签名证书。这种灵魂伤害kubectl(它本身在不运行 Ansible 时有效)。kubectl --insecure-skip-tls-verify=true get node使用 Ansible调用时它也不起作用。

Lio*_*ion 5

我试图通过设置空的环境变量来从代理中取消设置 env 变量(因为代理仅用于 Internet 访问):

- name: Kubectl test
  become: false
  shell: kubectl get no -v=10
  environment:
    http_proxy:
    https_proxy:
    no_proxy:
    HTTP_PROXY:
    HTTPS_PROXY:
    NO_PROXY:
Run Code Online (Sandbox Code Playgroud)

这是一个坏主意,因为curl(似乎在内部使用kubectl)将其解析为None并失败。奇怪的是,kubectl由于 dns 错误而失败:

skipped caching discovery info due to Get https://k8smaster01:6443/api?timeout=32s: proxyconnect tcp: dial tcp: lookup None on 127.0.0.53:53: server misbehaving
Run Code Online (Sandbox Code Playgroud)

发现主要问题是我设置NO_PROXY=$no_proxy/etc/environment,其中no_proxy包含主机名k8smaster01。由于/etc/environment不解析 bash 变量,因此大写字母NO_PROXY仅包含$no_proxy字符串。所以NO_PROXY=$no_proxy用相应的值 (eh NO_PROXY=k8smaster01)替换就足够了。

以前这不是问题,因为大多数应用程序似乎都遵循使用小写环境变量进行代理使用的 Linux 规范。