Kubernetes

Troubleshooting your Kubernetes Cluster

When faced with a cluster that’s not doing what you expect it do, what should you do to find out why it’s not behaving?

Assuming that you have (tried to) configured your cluster to be something in the order of “Ingress listens for traffic on port 80, meant for domain name example.com” then passes that traffic to a service that passes the traffic to a pod which is your container, then the first job is to check that the ingress is receiving the traffic intended for the domain.

Start by looking at all the pods

$ kubectl get pods --all-namespaces
NAMESPACE       NAME                                        READY   STATUS      RESTARTS        AGE
ingress-nginx   ingress-nginx-admission-create-ghh8z        0/1     Completed   0               23h
ingress-nginx   ingress-nginx-admission-patch-pxf2q         0/1     Completed   0               23h
ingress-nginx   ingress-nginx-controller-7c6974c4d8-2x5vq   1/1     Running     1 (5h39m ago)   23h
kube-system     coredns-5dd5756b68-rn4td                    1/1     Running     1 (19h ago)     30h
kube-system     etcd-minikube                               1/1     Running     1 (19h ago)     30h
kube-system     kube-apiserver-minikube                     1/1     Running     1 (5h39m ago)   30h
kube-system     kube-controller-manager-minikube            1/1     Running     1 (19h ago)     30h
kube-system     kube-proxy-kv2xd                            1/1     Running     1 (19h ago)     30h
kube-system     kube-scheduler-minikube                     1/1     Running     1 (19h ago)     30h
kube-system     storage-provisioner                         1/1     Running     3 (5h38m ago)   30h

Then check the status of the pods in your namespace

$ kubectl get pods -n shane
NAME                             READY   STATUS              RESTARTS     AGE
accountserver-56b469dbbd-9q492   0/1     ErrImageNeverPull   0            12h
apiserver-6687c679f-tzgsw        1/1     Running             1 (9h ago)   14h

We can see in that snippet that there’s a problem with the accountserver image, but the apiserver is claiming to be happy.

Assuming that we’re checking the apiserver we continue -

Check that the ingress is receiving traffic (requires two shells, one to send the command, one to log what’s happening)

The logging shell:

$ kubectl logs -n ingress-nginx ingress-nginx-controller-7c6974c4d8-2x5vq -f

The command shell: First I want the address that the ingress has

$ kubectl get ingress -n shane
NAME    CLASS    HOSTS       ADDRESS        PORTS   AGE
shane   <none>   example.com   192.168.58.2   80      3h15m

Test if that IP is receiving traffic

wget 192.168.58.2
--2023-12-04 15:17:53--  http://192.168.58.2/
Connecting to 192.168.58.2:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2023-12-04 15:17:53 ERROR 404: Not Found.

Well, wget reports connecting ok, but then it got a 404

So, let’s try with the domain name (For the record, I set the IP of the domain I want to pretend I have in /etc/hosts)

 $ wget example.com
--2023-12-04 15:27:03--  http://example.com/
Resolving example.com (example.com)... 192.168.58.2
Connecting to example.com (example.com)|192.168.58.2|:80... connected.
HTTP request sent, awaiting response... 502 Bad Gateway
2023-12-04 15:27:03 ERROR 502: Bad Gateway.

This tells us that the ingress is listening, and will only respond to requests on example.com which is fine. But it’s returning a 502 error, let’s see what the logs say (the other shell)

2023/12/04 04:27:03 [error] 577#577: *342388 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.58.1, server: example.com, request: "GET / HTTP/1.1", upstream: "http://10.244.0.11:8080/", host: "example.com"
2023/12/04 04:27:03 [error] 577#577: *342388 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.58.1, server: example.com, request: "GET / HTTP/1.1", upstream: "http://10.244.0.11:8080/", host: "example.com"
2023/12/04 04:27:03 [error] 577#577: *342388 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.58.1, server: example.com, request: "GET / HTTP/1.1", upstream: "http://10.244.0.11:8080/", host: "example.com"
192.168.58.1 - - [04/Dec/2023:04:27:03 +0000] "GET / HTTP/1.1" 502 150 "-" "Wget/1.21.2" 124 0.001 [example-api-service-8080] [] 10.244.0.11:8080, 10.244.0.11:8080, 10.244.0.11:8080 0, 0, 0 0.001, 0.000, 0.000 502, 502, 502 3cee74a2a4e97297f6ef379689bda677

The ingress is telling us that it the connection attempt upstream was refused.

We now turn our attention to the pod that the ingress is trying to connect to.

What have the logs been for apiserver?

$ kubectl logs apiserver-86c595ccfc-lpd2x -n shane

Ooo, empty, that’s curious.

From here it’s time to look at the configuration in kubernetes as well as in the container. It’s clear that kubernetes has directed traffic from the ingress to the accountserver service, but it’s not been accepted.

Upon inspection I found that the port configured in the service definition did not match the port configured in the container - so I have made a permanent fix, using an environment variable passed from the service to the container to define the port, meaning that the two will (from hence forth) have the same value for port number.

Published:
comments powered by Disqus