I’ve been looking into Kubernetes-related issues lately. For a locally built cluster, we need Ingress to expose services. I encountered some problems during use, but searching with Google didn’t yield answers. Much of the content may come from my own exploration; please point out any incorrect usage. While debugging, I actually also read part of the Ingress implementation code — one article probably can’t cover it, so I’ll open another.
!! This article does NOT cover how to install a kubernetes cluster — please install one first!!
The Role of Ingress in K8s
The official Ingress introduction explains Ingress’s role in a K8s cluster.
Ingress exposes HTTP or HTTPS routes, allowing access to in-cluster services from outside the cluster. The routing policy for this part is defined by Ingress resources.

If you’ve configured multi-domain Nginx before, you know that for different domains, server_name can determine the backend. Ingress’s basic principle is also choosing the corresponding backend location via different server_names — though the concrete implementations of various Ingresses may differ somewhat.
1 | server { |
Two Ingress Implementations I’ve Used
When we normally speak of Ingress, we should be speaking of the Ingress service or the Ingress API. Different implementations can follow this same API. I recently researched and used two implementations: one by the Nginx company (Nginx Inc), the other by the open source community (Kubernetes). When using them, be sure to understand the differences between the two Ingress implementations and choose the Ingress reasonably.
Nginx Inc’s Implementation
https://github.com/nginxinc/kubernetes-ingress
The Kubernetes Community’s Implementation
https://github.com/kubernetes/ingress-nginx
Comparison of the Ingresses
The original table comes from nginx-ingress-controllers.md.
This is the 2019-11-05 version; the future may differ — please follow the link for the latest version.
| Aspect or Feature | kubernetes/ingress-nginx | nginxinc/kubernetes-ingress with NGINX | nginxinc/kubernetes-ingress with NGINX Plus |
|---|---|---|---|
| Fundamental | |||
| Authors | Kubernetes community | NGINX Inc and community | NGINX Inc and community |
| NGINX version | Custom NGINX build that includes several third-party modules | NGINX official mainline build | NGINX Plus |
| Commercial support | N/A | N/A | Included |
| Load balancing configuration via the Ingress resource | |||
| Merging Ingress rules with the same host | Supported | Supported via Mergeable Ingresses | Supported via Mergeable Ingresses |
| HTTP load balancing extensions - Annotations | See the supported annotations | See the supported annotations | See the supported annotations |
| HTTP load balancing extensions – ConfigMap | See the supported ConfigMap keys | See the supported ConfigMap keys | See the supported ConfigMap keys |
| TCP/UDP | Supported via a ConfigMap | Supported via a ConfigMap with native NGINX configuration | Supported via a ConfigMap with native NGINX configuration |
| Websocket | Supported | Supported via an annotation | Supported via an annotation |
| TCP SSL Passthrough | Supported via a ConfigMap | Not supported | Not supported |
| JWT validation | Not supported | Not supported | Supported |
| Session persistence | Supported via a third-party module | Not supported | Supported |
| Canary testing (by header, cookie, weight) | Supported via annotations | Supported via custom resources | Supported via custom resources |
| Configuration templates *1 | See the template | See the templates | See the templates |
| Load balancing configuration via Custom Resources | |||
| HTTP load balancing | Not supported | See VirtualServer and VirtualServerRoute resources. | See VirtualServer and VirtualServerRoute resources. |
| Deployment | |||
| Command-line arguments *2 | See the arguments | See the arguments | See the arguments |
| TLS certificate and key for the default server | Required as a command-line argument/ auto-generated | Required as a command-line argument | Required as a command-line argument |
| Helm chart | Supported | Supported | Supported |
| Operational | |||
| Reporting the IP address(es) of the Ingress controller into Ingress resources | Supported | Supported | Supported |
| Extended Status | Supported via a third-party module | Not supported | Supported |
| Prometheus Integration | Supported | Supported | Supported |
| Dynamic reconfiguration of endpoints (no configuration reloading) | Supported with a third-party Lua module | Not supported | Supported |
Ingress Usage in Practice
The sections below introduce some of my Ingress practices. Although fairly simple, I think these are the most common usages.
Selecting Some Cluster Machines When Creating the Ingress
When creating the Ingress Pod, a cluster may only need 2-4 machines serving externally — there’s no need to create one on every
node. Below is part of the configuration when creating this Pod; note that it’s deployed as a DaemonSet,
and this deployment form allows us to select the corresponding machines.
1 | apiVersion: apps/v1 |
Node selection is done through the nodeSelector configuration; in the config below, the nodes with run_ingress=true
are selected.
1 | apiVersion: apps/v1 |
Nodes can be labeled like this:
1 | kubectl label node <node name> run_ingress="true" |
Basic Ingress Configuration
In the structure above, a simple service generally consists of several pods + 1 service + 1 ingress:
1 | # start a python3.7 container listening on port 6000 |
The result is as follows:
1 | ~ ❤ curl arya.example.com |
Canary Releases with Ingress
Our usual work also needs the canary release feature. After investigating I found that Nginx Inc’s Ingress implementation cannot do canary releases directly — it needs custom resource support. So I chose the Kubernetes community’s Ingress. Through gradual use I discovered the two Ingress implementations differ: Nginx Inc uses ordinary Nginx, while Kubernetes uses OpenResty. The specific differences will be introduced in the next blog post; this one only covers canary usage.
For detailed configuration see the official canary documentation
A canary release needs two versions of the program, one of which is the live version while the other is not yet online. The two versions correspond to different service and ingress configurations. Let’s look at the live version first.
1 | # prod_arya.yaml — the live version corresponds to 753 |
For the version needing canary treatment, please note: the two hosts — i.e. the externally served domain — must be consistent; what differs is
the related configuration added in annotations.
1 | # canary_arya.yaml |
With this configuration, you can test with the following commands:
1 | # direct requests — requests randomly reach one of the two version environments |
Summary
This blog mainly introduced Ingress’s role in Kubernetes and some practical work. The next Ingress-related blog will introduce the differences between the two Ingress implementations (Nginx Inc and the Kubernetes community), and explore the use of OpenResty in finer detail.