I want to automate kubectl and helm commands using Ansible. The target machine is configured properly, so that both works on the cli in a manual shell (e.g. kubectl get nodes or helm list). But when trying to make any API calls like get the server version
- name: List charts
shell: kubectl version -v=8
It breaks with a Forbidden error. The verbose logging doesn't give me much more details:
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>
However, when sending a manual request to those API url like this
- name: Test master connection
shell: curl -k https://k8smaster01:6443/version?timeout=32s
It works:
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"
}
kubectl doesn't work when executed with Ansible?I'm behind a proxy server, but k8smaster01 is set in no_proxy. Ansible got it, I printed $no_proxy in the task for testing purpose.
For curl I used -k since its a self signed cert from k8s. This sould harm kubectl (which itself works when not running from Ansible). It also doesn't work when calling kubectl --insecure-skip-tls-verify=true get node with Ansible.
I tried to unset the env variables from the proxy (since the proxy is required just for internet access) by setting empty environment variables:
- name: Kubectl test
become: false
shell: kubectl get no -v=10
environment:
http_proxy:
https_proxy:
no_proxy:
HTTP_PROXY:
HTTPS_PROXY:
NO_PROXY:
This was a bad idea, since curl (which seems to be used inside kubectl) parse this to None and fail. Strangely, kubectl failed with an dns error:
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
Found out that the main problem was that I set NO_PROXY=$no_proxy in /etc/environment, where no_proxy contains the hostname k8smaster01. Since /etc/environment doesn't resolve bash variables, the uppercase NO_PROXY just contains $no_proxy as string. So it was enough to replace NO_PROXY=$no_proxy by the corresponding value (e.h. NO_PROXY=k8smaster01).
It wasn't an issue before, because most applications seems to follow the Linux specification of using lowercase environment variables for proxy usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With