Create development guide section (#7104)

* Create development guide section

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

* Apply suggestions from code review

Co-authored-by: Alex Zhang <tokers@apache.org>

* Typo solving and removing some TODOs

Co-authored-by: Alex Zhang <tokers@apache.org>
This commit is contained in:
Ricardo Katz 2021-05-12 21:16:25 -03:00 committed by GitHub
parent 7339ef7860
commit 714783c052
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 159 additions and 0 deletions

View file

@ -0,0 +1,156 @@
# Ingress NGINX - Code Overview
This document provides an overview of Ingress NGINX code.
## Core Golang code
This part of the code is responsible for the main logic of Ingress NGINX. It contains all the logics that parses [Ingress Objects](https://kubernetes.io/docs/concepts/services-networking/ingress/),
[annotations](https://kubernetes.io/docs/reference/glossary/?fundamental=true#term-annotation), watches Endpoints and turn them into usable nginx.conf configuration.
### Core Sync Logics:
Ingress-nginx has an internal model of the ingresses, secrets and endpoints in a given cluster. It maintains two copy of that (1) currently running configuration model and (2) the one generated in response to some changes in the cluster.
The sync logic diffs the two models and if there's a change it tries to converge the running configuration to the new one.
There are static and dynamic configuration changes.
All endpoints and certificate changes are handled dynamically by posting the payload to an internal NGINX endpoint that is handled by Lua.
---
The following parts of the code can be found:
### Entrypoint
Is the `main` package, responsible for starting ingress-nginx program.
It can be found in [cmd/nginx](https://github.com/kubernetes/ingress-nginx/tree/master/cmd/nginx) directory.
### Version
Is the package of the code responsible for adding `version` subcommand, and can be found in [version](https://github.com/kubernetes/ingress-nginx/tree/master/version) directory.
### Internal code
This part of the code contains the internal logics that compose Ingress NGINX Controller, and it's split in:
#### Admission Controller
Contains the code of [Kubernetes Admission Controller](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/) which validates the syntax of ingress objects before accepting it.
This code can be found in [internal/admission/controller](https://github.com/kubernetes/ingress-nginx/tree/master/internal/admission/controller) directory.
#### File functions
Contains auxiliary codes that deal with files, such as generating the SHA1 checksum of a file, or creating required directories.
This code can be found in [internal/file](https://github.com/kubernetes/ingress-nginx/blob/master/internal/file) directory.
#### Ingress functions
Contains all the logics from NGINX Ingress Controller, with some examples being:
* Expected Golang structures that will be used in templates and other parts of the codes - [internal/ingress/types.go](https://github.com/kubernetes/ingress-nginx/blob/master/internal/ingress/types.go).
* supported annotations and its parsing logics - [internal/ingress/annotations](https://github.com/kubernetes/ingress-nginx/tree/master/internal/ingress/annotations).
* reconciliation loops and logics - [internal/ingress/controller](https://github.com/kubernetes/ingress-nginx/tree/master/internal/ingress/controller)
* Defaults - define the default struct.
* Error interface and types implementation - [internal/ingress/errors](https://github.com/kubernetes/ingress-nginx/tree/master/internal/ingress/errors)
* Metrics collectors for Prometheus exporting - [internal/ingress/metric](https://github.com/kubernetes/ingress-nginx/tree/master/internal/ingress/metric).
* Resolver - Extracts information from a controller.
* Ingress Object status publisher - [internal/ingress/status](https://github.com/kubernetes/ingress-nginx/tree/master/internal/ingress/status).
And other parts of the code that will be written in this document in a future.
#### K8s functions
Contains helper functions for parsing Kubernetes objects.
This part of the code can be found in [internal/k8s](https://github.com/kubernetes/ingress-nginx/tree/master/internal/k8s) directory.
#### Networking functions
Contains helper functions for networking, such as IPv4 and IPv6 parsing, SSL certificate parsing, etc.
This part of the code can be found in [internal/net](https://github.com/kubernetes/ingress-nginx/tree/master/internal/net) directory.
#### NGINX functions
Contains helper function to deal with NGINX, such as verify if it's running and reading it's configuration file parts.
This part of the code can be found in [internal/nginx](https://github.com/kubernetes/ingress-nginx/tree/master/internal/nginx) directory.
#### Tasks / Queue
Contains the functions responsible for the sync queue part of the controller.
This part of the code can be found in [internal/task](https://github.com/kubernetes/ingress-nginx/tree/master/internal/task) directory.
#### Other parts of internal
Other parts of internal code might not be covered here, like runtime and watch but they can be added in a future.
## E2E Test
The e2e tests code is in [test](https://github.com/kubernetes/ingress-nginx/tree/master/test) directory.
## Other programs
Describe here `kubectl plugin`, `dbg`, `waitshutdown` and cover the hack scripts.
## Deploy files
This directory contains the `yaml` deploy files used as examples or references in the docs to deploy Ingress NGINX and other componentes.
Those files are in [deploy](https://github.com/kubernetes/ingress-nginx/tree/master/deploy) directory.
## Helm Chart
Used to generate the Helm chart published.
Code is in [charts/ingress-nginx](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx).
## Documentation/Website
The documentation used to generate the website https://kubernetes.github.io/ingress-nginx/
This code is available in [docs](https://github.com/kubernetes/ingress-nginx/tree/master/docs) and it's main "language" is `Markdown`, used by [mkdocs](https://github.com/kubernetes/ingress-nginx/blob/master/mkdocs.yml) file to generate static pages.
## Container Images
Container images used to run ingress-nginx, or to build the final image.
### Base Images
Contains the `Dockerfiles` and scripts used to build base images that are used in other parts of the repo. They are present in [images](https://github.com/kubernetes/ingress-nginx/tree/master/images) repo. Some examples:
* [nginx](https://github.com/kubernetes/ingress-nginx/tree/master/images/nginx) - The base NGINX image ingress-nginx uses is not a vanilla NGINX. It bundles many libraries together and it is a job in itself to maintain that and keep things up-to-date.
* [custom-error-pages](https://github.com/kubernetes/ingress-nginx/tree/master/images/custom-error-pages) - Used on the custom error page examples.
There are other images inside this directory.
### Ingress Controller Image
The image used to build the final ingress controller, used in deploy scripts and Helm charts.
This is NGINX with some Lua enhancement. We do dynamic certificate, endpoints handling, canary traffic split, custom load balancing etc at this component. One can also add new functionalities using Lua plugin system.
The files are in [rootfs](https://github.com/kubernetes/ingress-nginx/tree/master/rootfs) directory and contains:
* The Dockerfile
* [Auxiliary scripts](https://github.com/kubernetes/ingress-nginx/tree/master/rootfs/ingress-controller)
#### Ingress NGINX Lua Scripts
Ingress NGINX uses Lua Scripts to enable features like hot reloading, rate limiting and monitoring. Some are written using the [OpenResty](https://openresty.org/en/) helper.
The directory containing Lua scripts is [rootfs/etc/nginx/lua](https://github.com/kubernetes/ingress-nginx/tree/master/rootfs/etc/nginx/lua).
#### Nginx Go template file
One of the functions of Ingress NGINX is to turn [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) objects into nginx.conf file.
To do so, the final step is to apply those configurations in [nginx.tmpl](https://github.com/kubernetes/ingress-nginx/tree/master/rootfs/etc/nginx/template) turning it into a final nginx.conf file.

View file

@ -0,0 +1,89 @@
# Developing for NGINX Ingress Controller
This document explains how to get started with developing for NGINX Ingress controller.
## Prerequisites
Install [Go 1.14](https://golang.org/dl/) or later.
!!! note
The project uses [Go Modules](https://github.com/golang/go/wiki/Modules)
Install [Docker](https://docs.docker.com/engine/install/) (v19.03.0 or later with experimental feature on)
!!! important
The majority of make tasks run as docker containers
## Quick Start
1. Fork the repository
2. Clone the repository to any location in your work station
3. Add a `GO111MODULE` environment variable with `export GO111MODULE=on`
4. Run `go mod download` to install dependencies
### Local build
Start a local Kubernetes cluster using [kind](https://kind.sigs.k8s.io/), build and deploy the ingress controller
```console
make dev-env
```
### Testing
**Run go unit tests**
```console
make test
```
**Run unit-tests for lua code**
```console
make lua-test
```
Lua tests are located in the directory `rootfs/etc/nginx/lua/test`
!!! important
Test files must follow the naming convention `<mytest>_test.lua` or it will be ignored
**Run e2e test suite**
```console
make kind-e2e-test
```
To limit the scope of the tests to execute, we can use the environment variable `FOCUS`
```console
FOCUS="no-auth-locations" make kind-e2e-test
```
!!! note
The variable `FOCUS` defines Ginkgo [Focused Specs](https://onsi.github.io/ginkgo/#focused-specs)
Valid values are defined in the describe definition of the e2e tests like [Default Backend](https://github.com/kubernetes/ingress-nginx/blob/master/test/e2e/defaultbackend/default_backend.go#L29)
The complete list of tests can be found [here](e2e-tests.md)
### Custom docker image
In some cases, it can be useful to build a docker image and publish such an image to a private or custom registry location.
This can be done setting two environment variables, `REGISTRY` and `TAG`
```console
export TAG="dev"
export REGISTRY="$USER"
make build image
```
and then publish such version with
```console
docker push $REGISTRY/controller:$TAG
```