ingress-nginx-helm/docs/troubleshooting.md
Ricardo Katz 90c79689c4
Release v1 (#7470)
* Drop v1beta1 from ingress nginx (#7156)

* Drop v1beta1 from ingress nginx

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Fix intorstr logic in controller

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* fixing admission

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* more intorstr fixing

* correct template rendering

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Fix e2e tests for v1 api

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Fix gofmt errors

* This is finally working...almost there...

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Re-add removed validation of AdmissionReview

* Prepare for v1.0.0-alpha.1 release

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Update changelog and matrix table for v1.0.0-alpha.1 (#7274)

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* add docs for syslog feature (#7219)

* Fix link to e2e-tests.md in developer-guide (#7201)

* Use ENV expansion for namespace in args (#7146)

Update the DaemonSet namespace references to use the `POD_NAMESPACE` environment variable in the same way that the Deployment does.

* chart: using Helm builtin capabilities check (#7190)

Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>

* Update proper default value for HTTP2MaxConcurrentStreams in Docs (#6944)

It should be 128 as documented in https://github.com/kubernetes/ingress-nginx/blob/master/internal/ingress/controller/config/config.go#L780

* Fix MaxWorkerOpenFiles calculation on high cores nodes (#7107)

* Fix MaxWorkerOpenFiles calculation on high cores nodes

* Add e2e test for rlimit_nofile

* Fix doc for max-worker-open-files

* ingress/tcp: add additional error logging on failed (#7208)

* Add file containing stable release (#7313)

* Handle named (non-numeric) ports correctly (#7311)

Signed-off-by: Carlos Panato <ctadeu@gmail.com>

* Updated v1beta1 to v1 as its deprecated (#7308)

* remove mercurial from build (#7031)

* Retry to download maxmind DB if it fails (#7242)

* Retry to download maxmind DB if it fails.

Signed-off-by: Sergey Shakuto <sshakuto@infoblox.com>

* Add retries count arg, move retry logic into DownloadGeoLite2DB function

Signed-off-by: Sergey Shakuto <sshakuto@infoblox.com>

* Reorder parameters in DownloadGeoLite2DB

Signed-off-by: Sergey Shakuto <sshakuto@infoblox.com>

* Remove hardcoded value

Signed-off-by: Sergey Shakuto <sshakuto@infoblox.com>

* Release v1.0.0-alpha.1

* Add changelog for v1.0.0-alpha.2

* controller: ignore non-service backends (#7332)

* controller: ignore non-service backends

Signed-off-by: Carlos Panato <ctadeu@gmail.com>

* update per feedback

Signed-off-by: Carlos Panato <ctadeu@gmail.com>

* fix: allow scope/tcp/udp configmap namespace to altered (#7161)

* Lower webhook timeout for digital ocean (#7319)

* Lower webhook timeout for digital ocean

* Set Digital Ocean value controller.admissionWebhooks.timeoutSeconds to 29

* update OWNERS and aliases files (#7365) (#7366)

Signed-off-by: Carlos Panato <ctadeu@gmail.com>

* Downgrade Lua modules for s390x (#7355)

Downgrade Lua modules to last known working version.

* Fix IngressClass logic for newer releases (#7341)

* Fix IngressClass logic for newer releases

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Change e2e tests for the new IngressClass presence

* Fix chart and admission tests

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Fix helm chart test

Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>

* Fix reviews

* Remove ingressclass code from admission

* update tag to v1.0.0-beta.1

* update readme and changelog for v1.0.0-beta.1

* Release v1.0.0-beta.1 - helm and manifests (#7422)

* Change the order of annotation just to trigger a new helm release (#7425)

* [cherry-pick] Add dev-v1 branch into helm releaser (#7428)

* Add dev-v1 branch into helm releaser (#7424)

* chore: add link for artifacthub.io/prerelease annotations

Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>

Co-authored-by: Ricardo Katz <rikatz@users.noreply.github.com>

* k8s job ci pipeline for dev-v1 br v1.22.0 (#7453)

* k8s job ci pipeline for dev-v1 br v1.22.0

Signed-off-by: Neha Lohia <nehapithadiya444@gmail.com>

* k8s job ci pipeline for dev-v1 br v1.21.2

Signed-off-by: Neha Lohia <nehapithadiya444@gmail.com>

* remove v1.21.1 version

Signed-off-by: Neha Lohia <nehapithadiya444@gmail.com>

* Add controller.watchIngressWithoutClass config option (#7459)

Signed-off-by: Akshit Grover <akshit.grover2016@gmail.com>

* Release new helm chart with certgen fixed (#7478)

* Update go version, modules and remove ioutil

* Release new helm chart with certgen fixed

* changed appversion, chartversion, TAG, image (#7490)

* Fix CI conflict

* Fix CI conflict

* Fix build.sh from rebase process

* Fix controller_test post rebase

Co-authored-by: Tianhao Guo <rggth09@gmail.com>
Co-authored-by: Ray <61553+rctay@users.noreply.github.com>
Co-authored-by: Bill Cassidy <cassid4@gmail.com>
Co-authored-by: Jintao Zhang <tao12345666333@163.com>
Co-authored-by: Sathish Ramani <rsathishx87@gmail.com>
Co-authored-by: Mansur Marvanov <nanorobocop@gmail.com>
Co-authored-by: Matt1360 <568198+Matt1360@users.noreply.github.com>
Co-authored-by: Carlos Tadeu Panato Junior <ctadeu@gmail.com>
Co-authored-by: Kundan Kumar <kundan.kumar@india.nec.com>
Co-authored-by: Tom Hayward <thayward@infoblox.com>
Co-authored-by: Sergey Shakuto <sshakuto@infoblox.com>
Co-authored-by: Tore <tore.lonoy@gmail.com>
Co-authored-by: Bouke Versteegh <info@boukeversteegh.nl>
Co-authored-by: Shahid <shahid@us.ibm.com>
Co-authored-by: James Strong <strong.james.e@gmail.com>
Co-authored-by: Long Wu Yuan <longwuyuan@gmail.com>
Co-authored-by: Jintao Zhang <zhangjintao9020@gmail.com>
Co-authored-by: Neha Lohia <nehapithadiya444@gmail.com>
Co-authored-by: Akshit Grover <akshit.grover2016@gmail.com>
2021-08-21 13:42:00 -07:00

13 KiB

Troubleshooting

Ingress-Controller Logs and Events

There are many ways to troubleshoot the ingress-controller. The following are basic troubleshooting methods to obtain more information.

Check the Ingress Resource Events

$ 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
  ----      ----  --------
  cafe.com
            /tea      tea-svc:80 (<none>)
            /coffee   coffee-svc:80 (<none>)
Annotations:
  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"}]}}}

Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  1m    nginx-ingress-controller  Ingress default/cafe-ingress
  Normal  UPDATE  58s   nginx-ingress-controller  Ingress default/cafe-ingress

Check the Ingress Controller Logs

$ kubectl get pods -n <namespace-of-ingress-controller>
NAME                                        READY     STATUS    RESTARTS   AGE
nginx-ingress-controller-67956bf89d-fv58j   1/1       Running   0          1m

$ kubectl logs -n <namespace> nginx-ingress-controller-67956bf89d-fv58j
-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:    0.14.0
  Build:      git-734361d
  Repository: https://github.com/kubernetes/ingress-nginx
-------------------------------------------------------------------------------
....

Check the Nginx Configuration

$ kubectl get pods -n <namespace-of-ingress-controller>
NAME                                        READY     STATUS    RESTARTS   AGE
nginx-ingress-controller-67956bf89d-fv58j   1/1       Running   0          1m

$ kubectl exec -it -n <namespace-of-ingress-controller> nginx-ingress-controller-67956bf89d-fv58j -- cat /etc/nginx/nginx.conf
daemon off;
worker_processes 2;
pid /run/nginx.pid;
worker_rlimit_nofile 523264;
worker_shutdown_timeout 240s;
events {
	multi_accept        on;
	worker_connections  16384;
	use                 epoll;
}
http {
....

Check if used Services Exist

$ 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

Debug Logging

Using the flag --v=XX it is possible to increase the level of logging. This is performed by editing the deployment.

$ kubectl get deploy -n <namespace-of-ingress-controller>
NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
default-http-backend       1         1         1            1           35m
nginx-ingress-controller   1         1         1            1           35m

$ kubectl edit deploy -n <namespace-of-ingress-controller> nginx-ingress-controller
# Add --v=X to "- args", where X is an integer
  • --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

Authentication to the Kubernetes API Server

A number of components are involved in the authentication process and the first step is to narrow down the source of the problem, namely whether it is a problem with service authentication or with the kubeconfig file.

Both authentications must work:

+-------------+   service          +------------+
|             |   authentication   |            |
+  apiserver  +<-------------------+  ingress   |
|             |                    | controller |
+-------------+                    +------------+

Service authentication

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.

  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. 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.

  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. Please do not use this approach in production.

In the diagram below you can see the full authentication flow with all options, starting with the browser on the lower left hand side.

Kubernetes                                                  Workstation
+---------------------------------------------------+     +------------------+
|                                                   |     |                  |
|  +-----------+   apiserver        +------------+  |     |  +------------+  |
|  |           |   proxy            |            |  |     |  |            |  |
|  | apiserver |                    |  ingress   |  |     |  |  ingress   |  |
|  |           |                    | controller |  |     |  | controller |  |
|  |           |                    |            |  |     |  |            |  |
|  |           |                    |            |  |     |  |            |  |
|  |           |  service account/  |            |  |     |  |            |  |
|  |           |  kubeconfig        |            |  |     |  |            |  |
|  |           +<-------------------+            |  |     |  |            |  |
|  |           |                    |            |  |     |  |            |  |
|  +------+----+      kubeconfig    +------+-----+  |     |  +------+-----+  |
|         |<--------------------------------------------------------|        |
|                                                   |     |                  |
+---------------------------------------------------+     +------------------+

Service Account

If using a service account to connect to the API server, the ingress-controller expects the file /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:

# start a container that contains curl
$ kubectl run -it --rm test --image=curlimages/curl --restart=Never -- /bin/sh

# check if secret exists
/ $ ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt     namespace  token
/ $

# check base connectivity from cluster inside
/ $ 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
}/ $

# connect using tokens
}/ $ 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
{
  "paths": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    ... TRUNCATED
    "/readyz/shutdown",
    "/version"
  ]
}
/ $

# when you type `exit` or `^D` the test pod will be deleted.

If it is not working, there are two possible reasons:

  1. The contents of the tokens are invalid. Find the secret name with kubectl get secrets | grep service-account and delete it with kubectl delete secret <name>. It will automatically be recreated.

  2. You have a non-standard Kubernetes installation and the file containing the token may not be present. 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.

More information:

Kube-Config

If you want to use a kubeconfig file for authentication, follow the deploy procedure and add the flag --kubeconfig=/etc/kubernetes/kubeconfig.yaml to the args section of the deployment.

Using GDB with Nginx

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.

  1. SSH into the worker
$ ssh user@workerIP
  1. Obtain the Docker Container Running nginx
$ docker ps | grep nginx-ingress-controller
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
d9e1d243156a        quay.io/kubernetes-ingress-controller/nginx-ingress-controller   "/usr/bin/dumb-init …"   19 minutes ago      Up 19 minutes                                                                            k8s_nginx-ingress-controller_nginx-ingress-controller-67956bf89d-mqxzt_kube-system_079f31ec-aa37-11e8-ad39-080027a227db_0
  1. Exec into the container
$ docker exec -it --user=0 --privileged d9e1d243156a bash
  1. Make sure nginx is running in --with-debug
$ nginx -V 2>&1 | grep -- '--with-debug'
  1. Get list of processes running on container
$ 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
root         5     1  0 20:23 ?        00:00:05 /nginx-ingress-controller --defa
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
  1. Attach gdb to the nginx master process
$ gdb -p 21
....
Attaching to process 21
Reading symbols from /usr/sbin/nginx...done.
....
(gdb)
  1. Copy and paste the following:
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
  1. Quit GDB by pressing CTRL+D

  2. Open nginx_conf.txt

cat nginx_conf.txt