I'm trying to run a kubectl command from ansible.
Basically the command will tell me if at least one pod is running from a deployment.
kubectl get deploy sample-v1-deployment -o json -n sample | jq '.status.conditions[] | select(.reason == "MinimumReplicasAvailable") | .status' | tr -d '"'
I tried to run it from a playbook but I'm getting
Unable to connect to the server: net/http: TLS handshake timeout
This is my playbook:
- hosts: master
gather_facts: no
become: true
tasks:
- name: test command
shell: kubectl get deploy sample-v1-deployment -o json -n sample | jq '.status.conditions[] | select(.reason == "MinimumReplicasAvailable") | .status' | tr -d '"'
register: result
This is the output from ansible:
changed: [k8smaster01.test.com] => {
"changed": true,
"cmd": "kubectl get deploy sample-v1-deployment -o json -n sample | jq '.status.conditions[] | select(.reason == \"MinimumReplicasAvailable\") | .status' | tr -d '\"'",
"delta": "0:00:10.507704",
"end": "2019-04-02 20:59:17.882277",
"invocation": {
"module_args": {
"_raw_params": "kubectl get deploy sample-v1-deployment -o json -n sample | jq '.status.conditions[] | select(.reason == \"MinimumReplicasAvailable\") | .status' | tr -d '\"'",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"rc": 0,
"start": "2019-04-02 20:59:07.374573",
"stderr": "Unable to connect to the server: net/http: TLS handshake timeout",
"stderr_lines": [
"Unable to connect to the server: net/http: TLS handshake timeout"
],
"stdout": "",
"stdout_lines": []
}
I can run the command manually on the master server without problems. I was also able to use k8s module to create different things on my kubernetes cluster.
I know there is a kubectl module on ansible, could it be the problem?
Thanks
Looks like you can connect to your kube-apiserver on the master from a shell, but not from ansible. The error message indicates differences in the kubeconfig.
You can see the kube-apiserver endpoint configured on your ~/.kube/config
like this:
$ kubectl config view --minify -o jsonpath='{.clusters[].cluster.server}'
It's typically something like this: https://<servername>:6443
. You can try running the command from ansible to see if you get the same kube-apiserver.
Another thing is you can try is to print the value of the KUBECONFIG
env variable from ansible to see if it's set to something different from ~/.kube/config
Hope it helps!
I found a couple of workarounds.
One was to use the k8s_facts module
- name: Ensure running application
k8s_facts:
namespace: sample
kind: Pod
label_selectors:
- app=sample-v1-app
register: pod_list
until: pod_list.resources[0].status.phase == 'Running'
delay: 10
retries: 3
Its simple and gets the works done.
The second workaround was to use the raw module instead of shell or command
- name: Get running status
raw: kubectl get deploy sample-v1-deployment -o json -n sample | jq -r '.status.conditions[] | select(.reason == "MinimumReplicasAvailable") | .status'
I'm not sure about using raw. It looks like a hammer for a simple task.
But reading about the module makes me think this problem is related with the syntax (quotes, double quotes, |) more than the command it self.
Executes a low-down and dirty SSH command, not going through the module subsystem. This is useful and should only be done in a few cases. A common case is installing python on a system without python installed by default. Another is speaking to any devices such as routers that do not have any Python installed.