2017-01-19 05:05:46 +00:00
<!--
-----------------NOTICE------------------------
This file is referenced in code as
2021-08-07 00:07:29 +00:00
https://github.com/kubernetes/ingress-nginx/blob/main/docs/troubleshooting.md
2017-01-19 05:05:46 +00:00
Do not move it without providing redirects.
-----------------------------------------------
-->
2018-08-28 18:00:19 +00:00
# Troubleshooting
2017-01-19 05:05:46 +00:00
2018-08-28 18:00:19 +00:00
## Ingress-Controller Logs and Events
2017-01-19 05:05:46 +00:00
2018-08-28 18:00:19 +00:00
There are many ways to troubleshoot the ingress-controller. The following are basic troubleshooting
methods to obtain more information.
2017-10-13 13:55:03 +00:00
2018-08-28 18:00:19 +00:00
Check the Ingress Resource Events
2018-08-29 01:57:28 +00:00
```console
2018-08-28 18:00:19 +00:00
$ kubectl get ing -n < namespace-of-ingress-resource >
NAME HOSTS ADDRESS PORTS AGE
cafe-ingress cafe.com 10.0.2.15 80 25s
$ kubectl describe ing < ingress-resource-name > -n < namespace-of-ingress-resource >
Name: cafe-ingress
Namespace: default
Address: 10.0.2.15
Default backend: default-http-backend:80 (172.17.0.5:8080)
Rules:
Host Path Backends
---- ---- --------
2018-08-29 01:57:28 +00:00
cafe.com
2018-08-28 18:00:19 +00:00
/tea tea-svc:80 (< none > )
/coffee coffee-svc:80 (< none > )
Annotations:
2021-08-21 20:42:00 +00:00
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{},"name":"cafe-ingress","namespace":"default","selfLink":"/apis/networking/v1/namespaces/default/ingresses/cafe-ingress"},"spec":{"rules":[{"host":"cafe.com","http":{"paths":[{"backend":{"serviceName":"tea-svc","servicePort":80},"path":"/tea"},{"backend":{"serviceName":"coffee-svc","servicePort":80},"path":"/coffee"}]}}]},"status":{"loadBalancer":{"ingress":[{"ip":"169.48.142.110"}]}}}
2018-08-28 18:00:19 +00:00
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
2021-11-28 21:11:22 +00:00
Normal CREATE 1m ingress-nginx-controller Ingress default/cafe-ingress
Normal UPDATE 58s ingress-nginx-controller Ingress default/cafe-ingress
2018-08-28 18:00:19 +00:00
```
2017-10-13 13:55:03 +00:00
2018-08-28 18:00:19 +00:00
Check the Ingress Controller Logs
2018-08-29 01:57:28 +00:00
```console
2018-08-28 18:00:19 +00:00
$ kubectl get pods -n < namespace-of-ingress-controller >
NAME READY STATUS RESTARTS AGE
2021-11-28 21:11:22 +00:00
ingress-nginx-controller-67956bf89d-fv58j 1/1 Running 0 1m
2018-08-28 18:00:19 +00:00
2021-11-28 21:11:22 +00:00
$ kubectl logs -n < namespace > ingress-nginx-controller-67956bf89d-fv58j
2018-08-28 18:00:19 +00:00
-------------------------------------------------------------------------------
NGINX Ingress controller
Release: 0.14.0
Build: git-734361d
Repository: https://github.com/kubernetes/ingress-nginx
-------------------------------------------------------------------------------
....
```
2017-10-13 13:55:03 +00:00
2018-08-28 18:00:19 +00:00
Check the Nginx Configuration
2018-08-29 01:57:28 +00:00
```console
2018-08-28 18:00:19 +00:00
$ kubectl get pods -n < namespace-of-ingress-controller >
NAME READY STATUS RESTARTS AGE
2021-11-28 21:11:22 +00:00
ingress-nginx-controller-67956bf89d-fv58j 1/1 Running 0 1m
2018-08-28 18:00:19 +00:00
2021-11-28 21:11:22 +00:00
$ kubectl exec -it -n < namespace-of-ingress-controller > ingress-nginx-controller-67956bf89d-fv58j -- cat /etc/nginx/nginx.conf
2018-08-28 18:00:19 +00:00
daemon off;
worker_processes 2;
pid /run/nginx.pid;
worker_rlimit_nofile 523264;
2019-09-27 13:23:12 +00:00
worker_shutdown_timeout 240s;
2018-08-28 18:00:19 +00:00
events {
multi_accept on;
worker_connections 16384;
use epoll;
}
http {
....
```
2017-10-13 13:55:03 +00:00
2018-08-28 18:00:19 +00:00
Check if used Services Exist
2018-08-29 01:57:28 +00:00
```console
2018-08-28 18:00:19 +00:00
$ kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default coffee-svc ClusterIP 10.106.154.35 < none > 80/TCP 18m
default kubernetes ClusterIP 10.96.0.1 < none > 443/TCP 30m
default tea-svc ClusterIP 10.104.172.12 < none > 80/TCP 18m
kube-system default-http-backend NodePort 10.108.189.236 < none > 80:30001/TCP 30m
kube-system kube-dns ClusterIP 10.96.0.10 < none > 53/UDP,53/TCP 30m
kube-system kubernetes-dashboard NodePort 10.103.128.17 < none > 80:30000/TCP 30m
2017-10-13 13:55:03 +00:00
```
2018-08-28 18:00:19 +00:00
## Debug Logging
2017-10-13 13:55:03 +00:00
2018-08-28 18:00:19 +00:00
Using the flag `--v=XX` it is possible to increase the level of logging. This is performed by editing
the deployment.
2017-10-13 13:55:03 +00:00
2018-08-29 01:57:28 +00:00
```console
2018-08-28 18:00:19 +00:00
$ kubectl get deploy -n < namespace-of-ingress-controller >
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
default-http-backend 1 1 1 1 35m
2021-11-28 21:11:22 +00:00
ingress-nginx-controller 1 1 1 1 35m
2017-10-13 13:55:03 +00:00
2021-11-28 21:11:22 +00:00
$ kubectl edit deploy -n < namespace-of-ingress-controller > ingress-nginx-controller
2018-08-28 18:00:19 +00:00
# Add --v=X to "- args", where X is an integer
```
2017-01-19 05:05:46 +00:00
2018-08-28 18:00:19 +00:00
- `--v=2` shows details using `diff` about the changes in the configuration in nginx
- `--v=3` shows details about the service, Ingress rule, endpoint changes and it dumps the nginx configuration in JSON format
- `--v=5` configures NGINX in [debug mode ](http://nginx.org/en/docs/debugging_log.html )
## Authentication to the Kubernetes API Server
2017-01-19 05:05:46 +00:00
A number of components are involved in the authentication process and the first step is to narrow
2018-08-28 18:00:19 +00:00
down the source of the problem, namely whether it is a problem with service authentication or
with the kubeconfig file.
2017-01-19 05:05:46 +00:00
Both authentications must work:
```
+-------------+ service +------------+
| | authentication | |
+ apiserver +< ------------------- + ingress |
| | | controller |
+-------------+ +------------+
```
2018-08-29 01:57:28 +00:00
**Service authentication**
2017-01-19 05:05:46 +00:00
The Ingress controller needs information from apiserver. Therefore, authentication is required, which can be achieved in two different ways:
1. _Service Account:_ This is recommended, because nothing has to be configured. The Ingress controller will use information provided by the system to communicate with the API server. See 'Service Account' section for details.
2017-03-31 01:34:18 +00:00
2. _Kubeconfig file:_ In some Kubernetes environments service accounts are not available. In this case a manual configuration is required. The Ingress controller binary can be started with the `--kubeconfig` flag. The value of the flag is a path to a file specifying how to connect to the API server. Using the `--kubeconfig` does not requires the flag `--apiserver-host` .
2018-08-29 01:57:28 +00:00
The format of the file is identical to `~/.kube/config` which is used by kubectl to connect to the API server. See 'kubeconfig' section for details.
2017-01-19 05:05:46 +00:00
2018-03-03 12:02:28 +00:00
3. _Using the flag `--apiserver-host`:_ Using this flag `--apiserver-host=http://localhost:8080` it is possible to specify an unsecured API server or reach a remote kubernetes cluster using [kubectl proxy ](https://kubernetes.io/docs/user-guide/kubectl/kubectl_proxy/ ).
2018-08-29 01:57:28 +00:00
Please do not use this approach in production.
2017-03-31 01:34:18 +00:00
2017-01-19 05:05:46 +00:00
In the diagram below you can see the full authentication flow with all options, starting with the browser
on the lower left hand side.
2018-08-29 01:57:28 +00:00
```
2017-01-19 05:05:46 +00:00
Kubernetes Workstation
+---------------------------------------------------+ +------------------+
| | | |
| +-----------+ apiserver +------------+ | | +------------+ |
| | | proxy | | | | | | |
| | apiserver | | ingress | | | | ingress | |
| | | | controller | | | | controller | |
| | | | | | | | | |
| | | | | | | | | |
| | | service account/ | | | | | | |
| | | kubeconfig | | | | | | |
| | +< ------------------- + | | | | | |
| | | | | | | | | |
| +------+----+ kubeconfig +------+-----+ | | +------+-----+ |
| |< -------------------------------------------------------- | |
| | | |
+---------------------------------------------------+ +------------------+
```
2017-10-13 13:55:03 +00:00
### Service Account
2018-08-28 18:00:19 +00:00
2020-06-16 07:17:34 +00:00
If using a service account to connect to the API server, the ingress-controller expects the file
2017-01-19 05:05:46 +00:00
`/var/run/secrets/kubernetes.io/serviceaccount/token` to be present. It provides a secret
token that is required to authenticate with the API server.
Verify with the following commands:
2018-08-29 01:57:28 +00:00
```console
2017-01-19 05:05:46 +00:00
# start a container that contains curl
2021-07-27 00:04:45 +00:00
$ kubectl run -it --rm test --image=curlimages/curl --restart=Never -- /bin/sh
2017-01-19 05:05:46 +00:00
# check if secret exists
2021-07-27 00:04:45 +00:00
/ $ ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt namespace token
/ $
2017-01-19 05:05:46 +00:00
# check base connectivity from cluster inside
2021-07-27 00:04:45 +00:00
/ $ curl -k https://kubernetes.default.svc.cluster.local
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}/ $
2017-01-19 05:05:46 +00:00
# connect using tokens
2021-07-27 00:04:45 +00:00
}/ $ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local
& & echo
2017-01-19 05:05:46 +00:00
{
"paths": [
"/api",
"/api/v1",
"/apis",
2021-07-27 00:04:45 +00:00
"/apis/",
... TRUNCATED
"/readyz/shutdown",
2017-01-19 05:05:46 +00:00
"/version"
]
}
2021-07-27 00:04:45 +00:00
/ $
# when you type `exit` or `^D` the test pod will be deleted.
2017-01-19 05:05:46 +00:00
```
If it is not working, there are two possible reasons:
2017-08-21 03:54:56 +00:00
1. The contents of the tokens are invalid. Find the secret name with `kubectl get secrets | grep service-account` and
2018-08-29 01:57:28 +00:00
delete it with `kubectl delete secret <name>` . It will automatically be recreated.
2017-01-19 05:05:46 +00:00
2017-10-13 21:50:37 +00:00
2. You have a non-standard Kubernetes installation and the file containing the token may not be present.
2018-08-29 01:57:28 +00:00
The API server will mount a volume containing this file, but only if the API server is configured to use
the ServiceAccount admission controller.
If you experience this error, verify that your API server is using the ServiceAccount admission controller.
If you are configuring the API server by hand, you can set this with the `--admission-control` parameter.
> Note that you should use other admission controllers as well. Before configuring this option, you should read about admission controllers.
2017-01-19 05:05:46 +00:00
More information:
2018-08-29 01:57:28 +00:00
- [User Guide: Service Accounts ](http://kubernetes.io/docs/user-guide/service-accounts/ )
- [Cluster Administrator Guide: Managing Service Accounts ](http://kubernetes.io/docs/admin/service-accounts-admin/ )
2017-01-19 05:05:46 +00:00
2018-08-28 18:00:19 +00:00
## Kube-Config
2018-08-30 17:59:50 +00:00
If you want to use a kubeconfig file for authentication, follow the [deploy procedure ](deploy/index.md ) and
2018-08-28 18:00:19 +00:00
add the flag `--kubeconfig=/etc/kubernetes/kubeconfig.yaml` to the args section of the deployment.
## Using GDB with Nginx
[Gdb ](https://www.gnu.org/software/gdb/ ) can be used to with nginx to perform a configuration
dump. This allows us to see which configuration is being used, as well as older configurations.
Note: The below is based on the nginx [documentation ](https://docs.nginx.com/nginx/admin-guide/monitoring/debugging/#dumping-nginx-configuration-from-a-running-process ).
1. SSH into the worker
2018-08-29 01:57:28 +00:00
```console
$ ssh user@workerIP
```
2018-08-28 18:00:19 +00:00
2. Obtain the Docker Container Running nginx
2018-08-29 01:57:28 +00:00
```console
2021-11-28 21:11:22 +00:00
$ docker ps | grep ingress-nginx-controller
2018-08-29 01:57:28 +00:00
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2021-11-28 21:11:22 +00:00
d9e1d243156a k8s.gcr.io/ingress-nginx/controller "/usr/bin/dumb-init …" 19 minutes ago Up 19 minutes k8s_ingress-nginx-controller_ingress-nginx-controller-67956bf89d-mqxzt_kube-system_079f31ec-aa37-11e8-ad39-080027a227db_0
2018-08-29 01:57:28 +00:00
```
2018-08-28 18:00:19 +00:00
3. Exec into the container
2018-08-29 01:57:28 +00:00
```console
$ docker exec -it --user=0 --privileged d9e1d243156a bash
```
2018-08-28 18:00:19 +00:00
4. Make sure nginx is running in `--with-debug`
2018-08-29 01:57:28 +00:00
```console
$ nginx -V 2>& 1 | grep -- '--with-debug'
```
5. Get list of processes running on container
```console
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 20:23 ? 00:00:00 /usr/bin/dumb-init /nginx-ingres
2021-11-28 21:11:22 +00:00
root 5 1 0 20:23 ? 00:00:05 /ingress-nginx-controller --defa
2018-08-29 01:57:28 +00:00
root 21 5 0 20:23 ? 00:00:00 nginx: master process /usr/sbin/
nobody 106 21 0 20:23 ? 00:00:00 nginx: worker process
nobody 107 21 0 20:23 ? 00:00:00 nginx: worker process
root 172 0 0 20:43 pts/0 00:00:00 bash
```
2018-08-28 18:00:19 +00:00
7. Attach gdb to the nginx master process
2018-08-29 01:57:28 +00:00
```console
$ gdb -p 21
....
Attaching to process 21
Reading symbols from /usr/sbin/nginx...done.
....
(gdb)
```
2018-08-28 18:00:19 +00:00
8. Copy and paste the following:
2018-08-29 01:57:28 +00:00
```console
set $cd = ngx_cycle->config_dump
set $nelts = $cd.nelts
set $elts = (ngx_conf_dump_t*)($cd.elts)
while ($nelts-- > 0)
set $name = $elts[$nelts]->name.data
printf "Dumping %s to nginx_conf.txt\n", $name
append memory nginx_conf.txt \
$elts[$nelts]->buffer.start $elts[$nelts]->buffer.end
end
```
2018-08-28 18:00:19 +00:00
9. Quit GDB by pressing CTRL+D
10. Open nginx_conf.txt
2018-08-29 01:57:28 +00:00
```console
cat nginx_conf.txt
```