kubectl — Check Service Health with one Line Command
Follow up on my Kubernetes blogs about
So you knew Kubernetes, and familar kubectl
command a lot. :-) Here is a challenge for you.
How can you run one-line command with kubectl to check the kubernetes service health with curl or wget?
Two solutions would be popped in your mind already
- Set
port-forward
kubectl port-forward service/myservice 8443:https
With this command, we set a tunnel (keep it opening) , then you can access this service and check the health from localhost:8443
So you need two actions.
kubectl exec
to an exist pod , then run the curl command
# make sure the exist pod has curl installed, otherwise, you need extra
# steps to install curl first.
$ kubectl exec -ti <pod_name> -- sh
/ # curl -sS myservice.default:443
You still require two commands, and an existing pod with the curl
command already installed
Tell me the solution.
Most of you would also consider kubectl run
for this case. Finally make it work
$ kubectl run curl --rm -it --image=alpine/curl -- -sS myservice.default:8443
With this command, kubectl will create a pod on fly and automatically delete it after job is done. It is similar as docker run -it --rm
when you run command with docker
So if you need run this command frequency, you can create alias on it and put in your local ~/_profile
or other default shell profile
# put it in ~/.profile
alias kubecurl="kubectl run curl --rm -it --image=alpine/curl --"
# now youc an run this command in any shell terminal
kubectl -sS myservice:8443
kubectl -sS www.google.com
So simple! No, it is not covered all scenarios. Keep reading.
If you are working in Istio system (or similar service mesh and sidecar solution) and if one namespace is labelled as istio-injection=enabled
above command doesn’t work any more in that namespace, halt for a while, until timeout (default is 1 minute), the pod is always in “Error” status before it is killed.
# no output
$ kubectl run curl --rm -it --image=alpine/curl -- -sS myservice.default:8443
pod "curl" deleted
error: timed out waiting for the condition
$ kk get pod
NAME READY STATUS RESTARTS AGE
curl 1/2 Error 2 (18s ago) 25s
Wait, why it is 1/2
, that means two containers in this pod. Check its status kubectl describe pod/curl
, a sidecar containeristio-proxy
is automatically injected into the pod curl
. Yes, that’s the intended functionality of Istio; it’s part of its design
Secondary, from its log, the pod has network issue now, it can’t resolve IP of the kubernetes service properly
$ kubectl logs -f curl
curl: (6) Could not resolve host: myservice.default
After research, I found the istio official document and confirmed this issue.
Pod or containers start with network issues if istio-proxy is not ready
We need disable the auto-injection when run pod curl
.
Here is the final one-line command when you need run the curl command from istio managed namespace
kubectl run curl --rm -it --overrides='{ "metadata": { "labels": { "sidecar.istio.io/inject": "false" } } }' --image=alpine/curl -- -sS myservice.default:443
kubectl run curl --rm -it --overrides='{ "metadata": { "labels": { "sidecar.istio.io/inject": "false" } } }' --image=alpine/curl -- -sS www.google.com
Learning is fun
# kubernetes # istio # Service mesh # sidecar # docker # DevOps